| 
          // Copyright 2014 Stefan Matthias Aust. Licensed under http://opensource.org/licenses/MIT. | 
        
        
           | 
          library java2dart; | 
        
        
           | 
          
 | 
        
        
           | 
          import 'dart:io'; | 
        
        
           | 
          import 'dart:convert'; | 
        
        
           | 
          
 | 
        
        
           | 
          class Scanner { | 
        
        
           | 
            /// Holds the current token or the empty string on end of input | 
        
        
           | 
            String currentToken; | 
        
        
           | 
          
 | 
        
        
           | 
            int position; | 
        
        
           | 
          
 | 
        
        
           | 
            Iterator<Match> _matches; | 
        
        
           | 
          
 | 
        
        
           | 
            /// Constructs a new scanner to tokenize [source]. | 
        
        
           | 
            Scanner(String source) { | 
        
        
           | 
              _matches = new RegExp( | 
        
        
           | 
                  '\\s+|//.*\$|/\\*[\\s\\S]*?\\*/|'             // whitespace & comments | 
        
        
           | 
                  '(0x[0-9a-fA-F]+|'                            // numbers | 
        
        
           | 
                  '(?:\\d+(?:\\.\\d*)?|\\.\\d+)'                // numbers | 
        
        
           | 
                  '(?:[eE][-+]?\\d+)?[lLfF]?|'                  // numbers | 
        
        
           | 
                  '[\\w\$_]+|'                                  // names & keywords | 
        
        
           | 
                  '"(?:\\\\.|[^"])*?"|\'(?:\\\\.|[^\'])+?\'|'   // strings & characters | 
        
        
           | 
                  '&&|\\|\\||\\+\\+|--|'                        // operators | 
        
        
           | 
                  '[+\\-*/%&^|]=?|<<=?|>>>?=?|[=<>!]=?|~|'      // operators | 
        
        
           | 
                  '[.]{3}|[.,;()[\\]{}?:])|(.)',                // syntax | 
        
        
           | 
                  multiLine: true).allMatches(source).iterator; | 
        
        
           | 
              advance(); | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            /// Advances [currentToken] to the next token in the source. | 
        
        
           | 
            String advance() { | 
        
        
           | 
              String token = currentToken; | 
        
        
           | 
              while (_matches.moveNext()) { | 
        
        
           | 
                Match m = _matches.current; | 
        
        
           | 
                if (m[1] != null) { | 
        
        
           | 
          
 | 
        
        
           | 
                  position = m.input.substring(0, m.start).split("\n").length; | 
        
        
           | 
                  currentToken = m[1]; | 
        
        
           | 
                  return token; | 
        
        
           | 
                } | 
        
        
           | 
                if (m[2] != null) { | 
        
        
           | 
                  error("unknown token ${m[2]} at ${m.start}"); | 
        
        
           | 
                } | 
        
        
           | 
              } | 
        
        
           | 
              currentToken = ""; | 
        
        
           | 
              return token; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            /// Returns true if the current token matches [token] and false otherwise. | 
        
        
           | 
            /// Advances to the next token if the current token was matched. | 
        
        
           | 
            bool at(String token) { | 
        
        
           | 
              if (currentToken == token) { | 
        
        
           | 
                advance(); | 
        
        
           | 
                return true; | 
        
        
           | 
              } | 
        
        
           | 
              return false; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            /// Advances [currentToken] if it matches [token] and raises an error otherwise. | 
        
        
           | 
            void expect(String token) { | 
        
        
           | 
              if (!at(token)) { | 
        
        
           | 
                error("expected $token but found $currentToken"); | 
        
        
           | 
              } | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            /// Returns true if [currentToken] is a name. | 
        
        
           | 
            bool get isName => currentToken.startsWith(new RegExp("[\\w\$_]")); | 
        
        
           | 
          
 | 
        
        
           | 
            /// Returns true if [currentToken] is a number. | 
        
        
           | 
            bool get isNumber => currentToken.startsWith(new RegExp("\\.?[\\d]")); | 
        
        
           | 
          
 | 
        
        
           | 
            /// Returns true if [currentToken] is a string. | 
        
        
           | 
            bool get isString => currentToken.isNotEmpty && (currentToken[0] == '"' || currentToken[0] == "'"); | 
        
        
           | 
          
 | 
        
        
           | 
            void error(String message) { | 
        
        
           | 
              throw new Exception(message); | 
        
        
           | 
            } | 
        
        
           | 
          } | 
        
        
           | 
          
 | 
        
        
           | 
          class Parser extends Scanner { | 
        
        
           | 
            /// Constructs a new parser to parse [source]. | 
        
        
           | 
            Parser(String source) : super(source); | 
        
        
           | 
          
 | 
        
        
           | 
            /// Returns [node] after parsing a semicolon. | 
        
        
           | 
            andSemicolon(node) { expect(";"); return node; } | 
        
        
           | 
          
 | 
        
        
           | 
            /// Returns the result of calling [parser] if [at(token)] is true and null otherwise. | 
        
        
           | 
            parseIfAt(String token, parser()) => at(token) ? parser() : null; | 
        
        
           | 
          
 | 
        
        
           | 
            /// Returns a list of results from calling [parser] as long as [at(token)] is true. | 
        
        
           | 
            List parseWhile(String token, parser()) { | 
        
        
           | 
              var results = []; | 
        
        
           | 
              while (at(token)) { | 
        
        
           | 
                results.add(parser()); | 
        
        
           | 
              } | 
        
        
           | 
              return results; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            /// Returns a list of results from calling [parser] as long as [at(token)] is false. | 
        
        
           | 
            List parseWhileNot(token, parser()) { | 
        
        
           | 
              var results = []; | 
        
        
           | 
              while (!at(token)) { | 
        
        
           | 
                results.add(parser()); | 
        
        
           | 
              } | 
        
        
           | 
              return results; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            /// Returns a list of results from calling [parser], separated by [separator]. | 
        
        
           | 
            List parseList(parser(), {String ifAt, String separator: ","}) { | 
        
        
           | 
              if  (ifAt == null || at(ifAt)) { | 
        
        
           | 
                var results = [parser()]; | 
        
        
           | 
                while (at(separator)) { | 
        
        
           | 
                  results.add(parser()); | 
        
        
           | 
                } | 
        
        
           | 
                return results; | 
        
        
           | 
              } else { | 
        
        
           | 
                return null; | 
        
        
           | 
              } | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            // declarations --------------------------------------------------------------------------------- | 
        
        
           | 
          
 | 
        
        
           | 
            // ["package" qualifiedName ";"] { importStatement } { typeDeclaration } | 
        
        
           | 
            parseCompilationUnit() { | 
        
        
           | 
              String packageName = parseIfAt("package", () => andSemicolon(parseQualifiedName())); | 
        
        
           | 
              var imports = parseWhile("import", parseImportStatement); | 
        
        
           | 
              var declarations = parseWhileNot("", parseTypeDeclaration); | 
        
        
           | 
              return [AST.CompilationUnit, packageName, imports, declarations]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            // "import" name {"." name} ["." "*"] ";" | 
        
        
           | 
            // no static | 
        
        
           | 
            parseImportStatement() { | 
        
        
           | 
              var names = [parseName()]; | 
        
        
           | 
              while (at(".")) { | 
        
        
           | 
                names.add(at("*") ? "*" : parseName()); | 
        
        
           | 
              } | 
        
        
           | 
              expect(";"); | 
        
        
           | 
              return [AST.Import, names.join(".")]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            // classDeclaration | interfaceDeclaration | 
        
        
           | 
            // no enum | 
        
        
           | 
            parseTypeDeclaration() { | 
        
        
           | 
              var modifiers = parseModifiers(); | 
        
        
           | 
              if (at("class")) return parseClassDeclaration(modifiers); | 
        
        
           | 
              if (at("interface")) return parseInterfaceDeclaration(modifiers); | 
        
        
           | 
              error("expected class or interface but found $currentToken."); | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            static const modifierTokens = const["abstract", "public", "protected", "private", "static", "final", "synchronized"]; | 
        
        
           | 
          
 | 
        
        
           | 
            parseModifiers() { | 
        
        
           | 
              var modifiers = []; | 
        
        
           | 
              while (modifierTokens.contains(currentToken)) { | 
        
        
           | 
                modifiers.add(advance()); | 
        
        
           | 
              } | 
        
        
           | 
              return [AST.Modifiers, modifiers]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            // [modifiers] [typeParameter] "class" name ["extends" type] ["implements" type {"," type] classBody | 
        
        
           | 
            parseClassDeclaration(modifiers) { | 
        
        
           | 
              var className = parseName(); | 
        
        
           | 
              var typeParameters = parseIfAt("<", parseTypeParameters); | 
        
        
           | 
              var superclassType = parseIfAt("extends", parseType); | 
        
        
           | 
              var interfaceTypes = parseList(parseType, ifAt:"implements"); | 
        
        
           | 
              return [AST.Class, modifiers, className, typeParameters, superclassType, interfaceTypes, parseClassOrInterfaceBody()]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            // [modifiers] [typeParameter] "interface" name ["extends" type {"," type}] interfaceBody | 
        
        
           | 
            parseInterfaceDeclaration(modifiers) { | 
        
        
           | 
              var interfaceName = parseName(); | 
        
        
           | 
              var typeParameters = parseIfAt("<", parseTypeParameters); | 
        
        
           | 
              var interfaceTypes = parseList(parseType, ifAt:"extends"); | 
        
        
           | 
              return [AST.Interface, modifiers, interfaceName, typeParameters, interfaceTypes, parseClassOrInterfaceBody()]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            // "{" {memberDeclaration} "}" | 
        
        
           | 
            // should distinguish class & interface (has no static, no method bodies) | 
        
        
           | 
            parseClassOrInterfaceBody() { | 
        
        
           | 
              expect("{"); | 
        
        
           | 
              return parseWhileNot("}", parseMemberDeclaration); | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseMemberDeclaration() { | 
        
        
           | 
              parseIfAt("<", parseTypeParameters); // ignored | 
        
        
           | 
              var modifiers = parseModifiers(); | 
        
        
           | 
              if (modifiers[1].length == 1 &&  modifiers[1][0] == "static" && at("{")) { | 
        
        
           | 
                return [AST.StaticInitializer, parseStatementBlock()]; | 
        
        
           | 
              } | 
        
        
           | 
              if (at("class")) return parseClassDeclaration(modifiers); | 
        
        
           | 
              if (at("interface")) return parseInterfaceDeclaration(modifiers); | 
        
        
           | 
              String name = parseName(); // could be a type or constructor | 
        
        
           | 
              if (at("(")) { // it's a constructor declaration | 
        
        
           | 
                var parameters = parseParameterList(); | 
        
        
           | 
                var throws = parseThrowsDeclaration(); | 
        
        
           | 
                expect("{"); | 
        
        
           | 
                return [AST.Constructor, modifiers, name, parameters, throws, parseStatementBlock()]; | 
        
        
           | 
              } | 
        
        
           | 
              var type = parseArrayType(parseType(name)); | 
        
        
           | 
              name = parseName(); | 
        
        
           | 
              if (at("(")) { // it's a method declaration | 
        
        
           | 
                var parameters = parseParameterList(); | 
        
        
           | 
                type = parseArrayType(type); | 
        
        
           | 
                var throws = parseThrowsDeclaration(); | 
        
        
           | 
                var statements; | 
        
        
           | 
                if (!at(";")) { | 
        
        
           | 
                  expect("{"); | 
        
        
           | 
                  statements = parseStatementBlock(); | 
        
        
           | 
                } else { | 
        
        
           | 
                  statements = []; | 
        
        
           | 
                } | 
        
        
           | 
                return [AST.Method, modifiers, type, name, parameters, throws, statements]; | 
        
        
           | 
              } else { // must be variable declaration | 
        
        
           | 
                var declarations = parseVariableDeclarations(modifiers, type, name); | 
        
        
           | 
                expect(";"); | 
        
        
           | 
                return declarations; | 
        
        
           | 
              } | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            List parseThrowsDeclaration() { | 
        
        
           | 
              return parseList(parseType, ifAt: "throws"); | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            List parseParameterList() { | 
        
        
           | 
              var parameters = []; | 
        
        
           | 
              while (!at(")")) { | 
        
        
           | 
                parameters.add(parseParameter()); | 
        
        
           | 
                if (at(")")) break; | 
        
        
           | 
                expect(","); | 
        
        
           | 
              } | 
        
        
           | 
              return parameters; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseParameter() { | 
        
        
           | 
              var type = parseType(); | 
        
        
           | 
              type = parseArrayType(type); | 
        
        
           | 
              bool rest = at("..."); | 
        
        
           | 
              var name = parseName(); | 
        
        
           | 
              type = parseArrayType(type); | 
        
        
           | 
              return [rest ? AST.RestParameter : AST.Parameter, type, name]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseVariableDeclarations(modifiers, type, name) { | 
        
        
           | 
              var type2 = parseArrayType(type); | 
        
        
           | 
              var init = parseInitializer(); | 
        
        
           | 
              var declarations = [[AST.VariableDeclaration, modifiers, type2, name, init]]; | 
        
        
           | 
              while (at(",")) { | 
        
        
           | 
                name = parseName(); | 
        
        
           | 
                type2 = parseArrayType(type); | 
        
        
           | 
                init = parseInitializer(); | 
        
        
           | 
                declarations.add([AST.VariableDeclaration, modifiers, type2, name, init]); | 
        
        
           | 
              } | 
        
        
           | 
              return [AST.VariableDeclarations, declarations]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseInitializer() { | 
        
        
           | 
              if (at("=")) { | 
        
        
           | 
                if (at("{")) { | 
        
        
           | 
                  return parseArrayInitializer(); | 
        
        
           | 
                } else { | 
        
        
           | 
                  return parseExpression(); | 
        
        
           | 
                } | 
        
        
           | 
              } | 
        
        
           | 
              return null; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseArrayInitializer() { | 
        
        
           | 
              var elements = []; | 
        
        
           | 
              while (!at("}")) { | 
        
        
           | 
                if (at("{")) { | 
        
        
           | 
                  elements.add(parseArrayInitializer()); | 
        
        
           | 
                } else { | 
        
        
           | 
                  elements.add(parseExpression()); | 
        
        
           | 
                } | 
        
        
           | 
                if (at("}")) break; | 
        
        
           | 
                expect(","); | 
        
        
           | 
              } | 
        
        
           | 
              return [AST.ArrayInitializer, elements]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            // types ---------------------------------------------------------------------------------------- | 
        
        
           | 
          
 | 
        
        
           | 
            static const primitiveTypes = const["boolean", "byte", "char", "short", "int", "float", "long", "double", "void"]; | 
        
        
           | 
          
 | 
        
        
           | 
            parseType([String name=""]) { | 
        
        
           | 
              if (name == "") { | 
        
        
           | 
                name = advance(); | 
        
        
           | 
              } | 
        
        
           | 
              var type = parseSimpleType(name); | 
        
        
           | 
              if (at("<")) { | 
        
        
           | 
                type = [AST.GenericType, type, parseTypeParameters()]; | 
        
        
           | 
              } | 
        
        
           | 
              return type; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseSimpleType(String name) { | 
        
        
           | 
              if (primitiveTypes.contains(name)) { | 
        
        
           | 
                return [AST.PrimitiveType, name]; | 
        
        
           | 
              } else { | 
        
        
           | 
                var names = [name]; | 
        
        
           | 
                while (at(".")) { | 
        
        
           | 
                  names.add(parseName()); | 
        
        
           | 
                } | 
        
        
           | 
                return [AST.ReferenceType, names.join(".")]; | 
        
        
           | 
              } | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseArrayType(type) { | 
        
        
           | 
              while (at("[")) { | 
        
        
           | 
                expect("]"); | 
        
        
           | 
                type = [AST.ArrayType, type]; | 
        
        
           | 
              } | 
        
        
           | 
              return type; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseTypeParameters() { | 
        
        
           | 
              var parameters = [parseTypeParameter()]; | 
        
        
           | 
              while (at(",")) { | 
        
        
           | 
                parameters.add(parseTypeParameter()); | 
        
        
           | 
              } | 
        
        
           | 
              expect(">"); | 
        
        
           | 
              return [AST.TypeParameters, parameters]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            String parseTypeParameter() { | 
        
        
           | 
              return at("?") ? "?" : parseQualifiedName(); | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            // statements ----------------------------------------------------------------------------------- | 
        
        
           | 
          
 | 
        
        
           | 
            parseStatementBlock() { | 
        
        
           | 
              return [AST.Block, parseWhileNot("}", parseStatement)]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseStatement() { | 
        
        
           | 
              if (at("{")) return parseStatementBlock(); | 
        
        
           | 
              if (at("if")) return parseIfStatement(); | 
        
        
           | 
              if (at("do")) return parseDoWhileStatement(); | 
        
        
           | 
              if (at("while")) return parseWhileStatement(); | 
        
        
           | 
              if (at("for")) return parseForStatement(); | 
        
        
           | 
              if (at("try")) return parseTryStatement(); | 
        
        
           | 
              if (at("switch")) return parseSwitchStatement(); | 
        
        
           | 
              if (at("synchronized")) { | 
        
        
           | 
                var expression = parseParenthesizedExpression(); | 
        
        
           | 
                return ["synchronized", expression, parseStatement()]; | 
        
        
           | 
              } | 
        
        
           | 
              if (at("return")) { | 
        
        
           | 
                var expression; | 
        
        
           | 
                if (!at(";")) { | 
        
        
           | 
                  expression = andSemicolon(parseExpression()); | 
        
        
           | 
                } | 
        
        
           | 
                return ["return", expression]; | 
        
        
           | 
              } | 
        
        
           | 
              if (at("throw")) { | 
        
        
           | 
                return ["throw", andSemicolon(parseExpression())]; | 
        
        
           | 
              } | 
        
        
           | 
              if (at("assert")) { | 
        
        
           | 
                var e = parseExpression(); | 
        
        
           | 
                var m = parseIfAt(":", parseExpression); | 
        
        
           | 
                expect(";"); | 
        
        
           | 
                return ["assert", e, m]; | 
        
        
           | 
              } | 
        
        
           | 
              if (at("break")) { | 
        
        
           | 
                var label; | 
        
        
           | 
                if (!at(";")) { | 
        
        
           | 
                  label = andSemicolon(parseName()); | 
        
        
           | 
                } | 
        
        
           | 
                return ["break", label]; | 
        
        
           | 
              } | 
        
        
           | 
              if (at("continue")) { | 
        
        
           | 
                var label; | 
        
        
           | 
                if (!at(";")) { | 
        
        
           | 
                  label = andSemicolon(parseName()); | 
        
        
           | 
                } | 
        
        
           | 
                return ["continue", label]; | 
        
        
           | 
              } | 
        
        
           | 
              if (at(";")) return ["pass"]; | 
        
        
           | 
              var expression = parseExpression(); | 
        
        
           | 
              if (expression[0] == "variable" && at(":")) { | 
        
        
           | 
                return ["label", expression[1]]; | 
        
        
           | 
              } | 
        
        
           | 
              expect(";"); | 
        
        
           | 
              if (expression[0] == "variable_declarations") { | 
        
        
           | 
                return expression; | 
        
        
           | 
              } | 
        
        
           | 
              return ["expression", expression]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseIfStatement() { | 
        
        
           | 
              var c = parseParenthesizedExpression(); | 
        
        
           | 
              var t = parseStatement(); | 
        
        
           | 
              var e = parseIfAt("else", parseStatement); | 
        
        
           | 
              return ["if", c, t, e]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseDoWhileStatement() { | 
        
        
           | 
              var s = parseStatement(); | 
        
        
           | 
              expect("while"); | 
        
        
           | 
              var e = andSemicolon(parseParenthesizedExpression()); | 
        
        
           | 
              return ["dowhile", e, s]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseWhileStatement() { | 
        
        
           | 
              var e = parseParenthesizedExpression(); | 
        
        
           | 
              var s = parseStatement(); | 
        
        
           | 
              return ["whiledo", e, s]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseForStatement() { | 
        
        
           | 
              var a = [], b, c = []; | 
        
        
           | 
              expect("("); | 
        
        
           | 
              if (!at(";")) { | 
        
        
           | 
                var e = parseExpression(); | 
        
        
           | 
                if (at(":")) { | 
        
        
           | 
                  // e must be variable_declarations with a single variable_declaration | 
        
        
           | 
                  assert(e[0] == "variable_declarations" && e[1].length == 1); | 
        
        
           | 
                  b = parseExpression(); | 
        
        
           | 
                  expect(")"); | 
        
        
           | 
                  var s = parseStatement(); | 
        
        
           | 
                  return ["foreach", e[1][0], b, s]; | 
        
        
           | 
                } | 
        
        
           | 
                a.add(e); | 
        
        
           | 
                while (at(",")) { | 
        
        
           | 
                  a.add(parseExpression()); | 
        
        
           | 
                } | 
        
        
           | 
                expect(";"); | 
        
        
           | 
              } | 
        
        
           | 
              if (!at(";")) { | 
        
        
           | 
                b = andSemicolon(parseExpression()); | 
        
        
           | 
              } | 
        
        
           | 
              if (!at(")")) { | 
        
        
           | 
                c.add(parseExpression()); | 
        
        
           | 
                while (at(",")) { | 
        
        
           | 
                  c.add(parseExpression()); | 
        
        
           | 
                } | 
        
        
           | 
                expect(")"); | 
        
        
           | 
              } | 
        
        
           | 
              var s = parseStatement(); | 
        
        
           | 
              return ["for", a, b, c, s]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseTryStatement() { | 
        
        
           | 
              var s = parseStatement(); | 
        
        
           | 
              var c = []; | 
        
        
           | 
              while (at("catch")) { | 
        
        
           | 
                expect("("); | 
        
        
           | 
                var p = parseParameter(); | 
        
        
           | 
                expect(")"); | 
        
        
           | 
                c.add(["catch", p, parseStatement()]); | 
        
        
           | 
              } | 
        
        
           | 
              var f = parseIfAt("finally", parseStatement); | 
        
        
           | 
              return ["try", s, c, f]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseSwitchStatement() { | 
        
        
           | 
              var expression = parseParenthesizedExpression(); | 
        
        
           | 
              expect("{"); | 
        
        
           | 
              var statements = []; | 
        
        
           | 
              while (!at("}")) { | 
        
        
           | 
                if (at("case")) { | 
        
        
           | 
                  var e = parseExpression(); | 
        
        
           | 
                  expect(":"); | 
        
        
           | 
                  statements.add(["case", e]); | 
        
        
           | 
                } else if (at("default")) { | 
        
        
           | 
                  expect(":"); | 
        
        
           | 
                  statements.add(["default"]); | 
        
        
           | 
                } else { | 
        
        
           | 
                  statements.add(parseStatement()); | 
        
        
           | 
                } | 
        
        
           | 
              } | 
        
        
           | 
              return ["switch", expression, statements]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseParenthesizedExpression() { | 
        
        
           | 
              expect("("); | 
        
        
           | 
              var expression = parseExpression(); | 
        
        
           | 
              expect(")"); | 
        
        
           | 
              return expression; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            // expressions ----------------------------------------------------------------------------------------------------- | 
        
        
           | 
          
 | 
        
        
           | 
            static const assignmentOperators = const["=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>=", ">>>="]; | 
        
        
           | 
          
 | 
        
        
           | 
            parseExpression() { | 
        
        
           | 
              var e = parseConditionalExpression(); | 
        
        
           | 
              if (assignmentOperators.contains(currentToken)) { | 
        
        
           | 
                var operator = advance(); | 
        
        
           | 
                return [operator, e, parseExpression()]; | 
        
        
           | 
              } | 
        
        
           | 
              return e; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseConditionalExpression() { | 
        
        
           | 
              var e = parseOrExpression(); | 
        
        
           | 
              if (at("?")) { | 
        
        
           | 
                var t = parseConditionalExpression(); | 
        
        
           | 
                expect(":"); | 
        
        
           | 
                return ["?:", e, t, parseConditionalExpression()]; | 
        
        
           | 
              } | 
        
        
           | 
              return e; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseOrExpression() { | 
        
        
           | 
              var e = parseAndExpression(); | 
        
        
           | 
              while (at("||")) { | 
        
        
           | 
                e = ["||", e, parseAndExpression()]; | 
        
        
           | 
              } | 
        
        
           | 
              return e; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseAndExpression() { | 
        
        
           | 
              var e = parseBitIorExpression(); | 
        
        
           | 
              while (at("&&")) { | 
        
        
           | 
                e = ["&&", e, parseBitIorExpression()]; | 
        
        
           | 
              } | 
        
        
           | 
              return e; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseBitIorExpression() { | 
        
        
           | 
              var e = parseBitXorExpression(); | 
        
        
           | 
              while (at("|")) { | 
        
        
           | 
                e = ["|", e, parseBitXorExpression()]; | 
        
        
           | 
              } | 
        
        
           | 
              return e; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseBitXorExpression() { | 
        
        
           | 
              var e = parseBitAndExpression(); | 
        
        
           | 
              while (at("^")) { | 
        
        
           | 
                e = ["^", e, parseBitAndExpression()]; | 
        
        
           | 
              } | 
        
        
           | 
              return e; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseBitAndExpression() { | 
        
        
           | 
              var e = parseEqualityExpression(); | 
        
        
           | 
              while (at("&")) { | 
        
        
           | 
                e = ["&", e, parseEqualityExpression()]; | 
        
        
           | 
              } | 
        
        
           | 
              return e; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseEqualityExpression() { | 
        
        
           | 
              var e = parseRelationalExpression(); | 
        
        
           | 
              while (true) { | 
        
        
           | 
                if (at("==")) { | 
        
        
           | 
                  e = ["==", e, parseRelationalExpression()]; | 
        
        
           | 
                } else if (at("!=")) { | 
        
        
           | 
                  e = ["!=", e, parseRelationalExpression()]; | 
        
        
           | 
                } else return e; | 
        
        
           | 
              } | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseRelationalExpression() { | 
        
        
           | 
              var e = parseBitShiftExpression(); | 
        
        
           | 
              while (true) { | 
        
        
           | 
                if (at("<")) { | 
        
        
           | 
                  // hack: could be a variable declaration (still missing "?" case) | 
        
        
           | 
                  var e2 = parseBitShiftExpression(); | 
        
        
           | 
                  if (e[0] == "variable" && e2[0] == "variable" && (currentToken == "," || currentToken == ">")) { | 
        
        
           | 
                    var parameters = [e2[1]]; | 
        
        
           | 
                    while (!at(">")) { | 
        
        
           | 
                      expect(","); | 
        
        
           | 
                      parameters.add(parseQualifiedName()); | 
        
        
           | 
                    } | 
        
        
           | 
                    var type = parseArrayType(["generic_type", parseSimpleType(e[1]), ["type_parameters", parameters]]); | 
        
        
           | 
                    var name = parseName(); | 
        
        
           | 
                    return parseVariableDeclarations(null, type, name); | 
        
        
           | 
                  } | 
        
        
           | 
                  e = ["<", e, e2]; | 
        
        
           | 
                } else if (at("<=")) { | 
        
        
           | 
                  e = ["<=", e, parseBitShiftExpression()]; | 
        
        
           | 
                } else if (at(">")) { | 
        
        
           | 
                  e = [">", e, parseBitShiftExpression()]; | 
        
        
           | 
                } else if (at(">=")) { | 
        
        
           | 
                  e = [">=", e, parseBitShiftExpression()]; | 
        
        
           | 
                } else if (at("instanceof")) { | 
        
        
           | 
                  e = ["instanceof", e, parseBitShiftExpression()]; | 
        
        
           | 
                } else return e; | 
        
        
           | 
              } | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseBitShiftExpression() { | 
        
        
           | 
              var e = parseAdditionExpression(); | 
        
        
           | 
              while (true) { | 
        
        
           | 
                if (at("<<")) { | 
        
        
           | 
                  e = ["<<", e, parseAdditionExpression()]; | 
        
        
           | 
                } else if (at(">>")) { | 
        
        
           | 
                  e = [">>", e, parseAdditionExpression()]; | 
        
        
           | 
                } else if (at(">>>")) { | 
        
        
           | 
                  e = [">>>", e, parseAdditionExpression()]; | 
        
        
           | 
                } else return e; | 
        
        
           | 
              } | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseAdditionExpression() { | 
        
        
           | 
              var e = parseMultiplicationExpression(); | 
        
        
           | 
              while (true) { | 
        
        
           | 
                if (at("+")) { | 
        
        
           | 
                  e = ["+", e, parseMultiplicationExpression()]; | 
        
        
           | 
                } else if (at("-")) { | 
        
        
           | 
                  e = ["-", e, parseMultiplicationExpression()]; | 
        
        
           | 
                } else return e; | 
        
        
           | 
              } | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseMultiplicationExpression() { | 
        
        
           | 
              var e = parsePrefixExpression(); | 
        
        
           | 
              while (true) { | 
        
        
           | 
                if (at("*")) { | 
        
        
           | 
                  e = ["*", e, parsePrefixExpression()]; | 
        
        
           | 
                } else if (at("/")) { | 
        
        
           | 
                  e = ["/", e, parsePrefixExpression()]; | 
        
        
           | 
                } else if (at("%")) { | 
        
        
           | 
                  e = ["%", e, parsePrefixExpression()]; | 
        
        
           | 
                } else return e; | 
        
        
           | 
              } | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parsePrefixExpression() { | 
        
        
           | 
              if (at("++")) { | 
        
        
           | 
                return ["++p", parsePrefixExpression()]; | 
        
        
           | 
              } | 
        
        
           | 
              if (at("--")) { | 
        
        
           | 
                return ["--p", parsePrefixExpression()]; | 
        
        
           | 
              } | 
        
        
           | 
              if (at("+")) { | 
        
        
           | 
                return ["+p", parsePrefixExpression()]; | 
        
        
           | 
              } | 
        
        
           | 
              if (at("-")) { | 
        
        
           | 
                return ["-p", parsePrefixExpression()]; | 
        
        
           | 
              } | 
        
        
           | 
              if (at("!")) { | 
        
        
           | 
                return ["!", parsePrefixExpression()]; | 
        
        
           | 
              } | 
        
        
           | 
              if (at("~")) { | 
        
        
           | 
                return ["~", parsePrefixExpression()]; | 
        
        
           | 
              } | 
        
        
           | 
              return parsePostfixExpression(); | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parsePostfixExpression() { | 
        
        
           | 
              var e = parsePrimary(); | 
        
        
           | 
              if (at("++")) { | 
        
        
           | 
                return ["p++", e]; | 
        
        
           | 
              } | 
        
        
           | 
              if (at("--")) { | 
        
        
           | 
                return ["p--", e]; | 
        
        
           | 
              } | 
        
        
           | 
              return e; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parsePrimary() { | 
        
        
           | 
              var e = parseLiteral(); | 
        
        
           | 
              while (true) { | 
        
        
           | 
                if (at("(")) { // simple call | 
        
        
           | 
                  assert(e[0] == "variable"); | 
        
        
           | 
                  e = ["call", null, e[1], parseArguments()]; | 
        
        
           | 
                } else if (at("[")) { | 
        
        
           | 
                  // hack: could be a variable declaration | 
        
        
           | 
                  if (e[0] == "variable" && at("]")) { | 
        
        
           | 
                    var type = ["array_type", parseSimpleType(e[1])]; | 
        
        
           | 
                    return parseVariableDeclarations(null, parseArrayType(type), parseName()); | 
        
        
           | 
                  } | 
        
        
           | 
                  var index = parseExpression(); | 
        
        
           | 
                  expect("]"); | 
        
        
           | 
                  e = ["[]", e, index]; | 
        
        
           | 
                } else if (at(".")) { // method call or field access | 
        
        
           | 
                  var name = parseName(); | 
        
        
           | 
                  if (at("(")) { // method call | 
        
        
           | 
                    e = ["call", e, name, parseArguments()]; | 
        
        
           | 
                  } else { | 
        
        
           | 
                    e = ["field", e, name]; | 
        
        
           | 
                  } | 
        
        
           | 
                } else return e; | 
        
        
           | 
              } | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            parseArguments() { | 
        
        
           | 
              var arguments = []; | 
        
        
           | 
              while (!at(")")) { | 
        
        
           | 
                arguments.add(parseExpression()); | 
        
        
           | 
                if (at(")")) break; | 
        
        
           | 
                expect(","); | 
        
        
           | 
              } | 
        
        
           | 
              return arguments; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            // needed to distinguish casts from parenthesized expressions | 
        
        
           | 
            static const literalFirst = const["++", "+", "--", "-", "!", "~", "("]; | 
        
        
           | 
          
 | 
        
        
           | 
            parseLiteral() { | 
        
        
           | 
              if (at("null")) return ["literal", null]; | 
        
        
           | 
              if (at("true")) return ["literal", true]; | 
        
        
           | 
              if (at("false")) return ["literal", false]; | 
        
        
           | 
              if (at("new")) { | 
        
        
           | 
                var type = parseType(); | 
        
        
           | 
                if (at("[")) { | 
        
        
           | 
                  while (at("]")) { | 
        
        
           | 
                    if (at("{")) { | 
        
        
           | 
                      var list = []; | 
        
        
           | 
                      while (!at("}")) { | 
        
        
           | 
                        list.add(parseExpression()); | 
        
        
           | 
                        if (at("}")) { | 
        
        
           | 
                          break; | 
        
        
           | 
                        } | 
        
        
           | 
                        expect(","); | 
        
        
           | 
                      } | 
        
        
           | 
                      return ["new_array_from", type, list]; | 
        
        
           | 
                    } | 
        
        
           | 
                    type = ["array_type", type]; | 
        
        
           | 
                    expect("["); | 
        
        
           | 
                  } | 
        
        
           | 
                  var expression = parseExpression(); | 
        
        
           | 
                  expect("]"); | 
        
        
           | 
                  return ["new_array", type, expression]; | 
        
        
           | 
                } | 
        
        
           | 
                if (at("(")) { | 
        
        
           | 
                  return ["new_instance", type, parseArguments()]; | 
        
        
           | 
                } | 
        
        
           | 
                error("unexpected $currentToken after new $type"); | 
        
        
           | 
              } | 
        
        
           | 
              if (at("(")) { | 
        
        
           | 
                var e = parseExpression(); | 
        
        
           | 
                expect(")"); | 
        
        
           | 
                // need to distinguish expression in parentheses from a cast | 
        
        
           | 
                if (e[0] == "variable") { | 
        
        
           | 
                  if (isName || isNumber || isString || literalFirst.contains(currentToken)) { | 
        
        
           | 
                    return ["cast", e[1], parsePrefixExpression()]; | 
        
        
           | 
                  } | 
        
        
           | 
                } | 
        
        
           | 
                return e; | 
        
        
           | 
              } | 
        
        
           | 
              if (isString) { | 
        
        
           | 
                return ["literal", advance()]; | 
        
        
           | 
              } | 
        
        
           | 
              if (isNumber) { | 
        
        
           | 
                var n = advance(); | 
        
        
           | 
                if (n.contains(new RegExp("[lLfF]\$"))) { | 
        
        
           | 
                  n = n.substring(0, n.length - 1); | 
        
        
           | 
                } | 
        
        
           | 
                return ["literal", num.parse(n)]; | 
        
        
           | 
              } | 
        
        
           | 
              // need to distinguish type declarations and variables | 
        
        
           | 
              // a sequence of two names should be a type declaration | 
        
        
           | 
              // ("foo[] bar" or "foo<x> bar" is not detected, see "hack") | 
        
        
           | 
              if (isName) { | 
        
        
           | 
                var name = advance(); | 
        
        
           | 
                if (isName) { | 
        
        
           | 
                  var type = parseArrayType(parseType(name)); | 
        
        
           | 
                  return parseVariableDeclarations(null, type, parseName()); | 
        
        
           | 
                } | 
        
        
           | 
                return ["variable", name]; | 
        
        
           | 
              } | 
        
        
           | 
              error("unexpected $currentToken in expression"); | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            // utilities ------------------------------------------------------------------------------------------------------- | 
        
        
           | 
          
 | 
        
        
           | 
            String parseQualifiedName() { | 
        
        
           | 
              return parseList(parseName, separator: ".").join("."); | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            String parseName() { | 
        
        
           | 
              if (!isName) { | 
        
        
           | 
                error("expected NAME but found $currentToken"); | 
        
        
           | 
              } | 
        
        
           | 
              return advance(); | 
        
        
           | 
            } | 
        
        
           | 
          } | 
        
        
           | 
          
 | 
        
        
           | 
          abstract class AST { | 
        
        
           | 
            // declarations | 
        
        
           | 
            static const CompilationUnit = "unit"; /* String packageName, List<AST> imports, List<AST> declarations */ | 
        
        
           | 
            static const Import = "import"; /* String qualifiedName */ | 
        
        
           | 
            static const Modifiers = "modifiers"; /* List<String> modifiers */ | 
        
        
           | 
            static const Class = "class"; /* AST modifiers, String className, AST typeParameters, AST superclassType, List<AST> interfaceTypes, List<AST> classBody */ | 
        
        
           | 
            static const Interface = "interface"; /* AST modifiers, String interfaceName, AST typeParameters, List<AST> interfaceTypes, List<AST> classBody */ | 
        
        
           | 
            static const StaticInitializer = "static_initializer"; /* AST block */ | 
        
        
           | 
            static const Constructor = "constructor"; /* AST modifiers, String constructorName, List<AST> parameters, List<AST> throws, AST block */ | 
        
        
           | 
            static const Method = "method"; /* AST modifiers, AST returnType, String methodName, List<AST> parameters, List<AST> throws, AST block */ | 
        
        
           | 
            static const Parameter = "parameter"; /* AST type, AST name */ | 
        
        
           | 
            static const RestParameter = "rest_parameter"; /* AST type, AST name */ | 
        
        
           | 
            static const VariableDeclaration = "variable_declaration"; /* AST modifiers, AST type, String name, AST initializer */ | 
        
        
           | 
            static const VariableDeclarations = "variable_declarations"; /* List<AST> declarations */ | 
        
        
           | 
            static const ArrayInitializer = "array"; /* List<AST> elements */ | 
        
        
           | 
          
 | 
        
        
           | 
            // types | 
        
        
           | 
            static const GenericType = "generic_type"; /* AST type, AST parameters */ | 
        
        
           | 
            static const PrimitiveType = "primitive_type"; /* String name */ | 
        
        
           | 
            static const ReferenceType = "reference_type"; /* String qualifiedName */ | 
        
        
           | 
            static const ArrayType = "array_type"; /* AST type */ | 
        
        
           | 
            static const TypeParameters = "type_parameters"; /* List<String> parameters */ | 
        
        
           | 
          
 | 
        
        
           | 
            // statements | 
        
        
           | 
            static const Block = "block"; /* List<AST> statements */ | 
        
        
           | 
            static const Assert = "assert"; | 
        
        
           | 
            static const Break = "break"; | 
        
        
           | 
            static const Continue = "continue"; | 
        
        
           | 
            static const DoWhile = "dowhile"; | 
        
        
           | 
            static const Expression = "expression"; /* AST expression */ | 
        
        
           | 
            static const For = "for"; | 
        
        
           | 
            static const ForEach = "foreach"; | 
        
        
           | 
            static const If = "if"; | 
        
        
           | 
            static const Label = "label"; | 
        
        
           | 
            static const Pass = "pass"; | 
        
        
           | 
            static const Return = "return"; | 
        
        
           | 
            static const Throw = "throw"; | 
        
        
           | 
            static const While = "whiledo"; | 
        
        
           | 
            static const Try = "try"; | 
        
        
           | 
            static const Catch = "catch"; | 
        
        
           | 
            static const Finally = "finally"; | 
        
        
           | 
            static const Switch = "switch"; | 
        
        
           | 
            static const Case = "case"; | 
        
        
           | 
            static const Default = "default"; | 
        
        
           | 
          
 | 
        
        
           | 
            // expressions | 
        
        
           | 
            static const Assign = "="; | 
        
        
           | 
            static const PlusAssign = "+="; | 
        
        
           | 
            static const MinusAssign = "-="; | 
        
        
           | 
            static const MultiplyAssign = "*="; | 
        
        
           | 
            static const DivideAssign = "/="; | 
        
        
           | 
            static const ModuloAssign = "%="; | 
        
        
           | 
            static const AndAssign = "&="; | 
        
        
           | 
            static const IorAssign = "|="; | 
        
        
           | 
            static const XorAssign = "^="; | 
        
        
           | 
            static const LeftShiftAssign = "<<="; | 
        
        
           | 
            static const RightShiftAssign = ">>="; | 
        
        
           | 
            static const URightShiftAssign = ">>>="; | 
        
        
           | 
            static const Conditional = "?:"; | 
        
        
           | 
            static const Or = "||"; | 
        
        
           | 
            static const And = "&&"; | 
        
        
           | 
            // ... | 
        
        
           | 
          } | 
        
        
           | 
          
 | 
        
        
           | 
          /// Translates Java nodes into Dart (printed to [stdout]). | 
        
        
           | 
          class Translator { | 
        
        
           | 
            StringSink _sink; | 
        
        
           | 
            Map _funcs; | 
        
        
           | 
            int _indent = 0; | 
        
        
           | 
            Map _imports = new Map(); | 
        
        
           | 
            Set _types = new Set(); | 
        
        
           | 
            Resolver _resolver = new Resolver(); | 
        
        
           | 
          
 | 
        
        
           | 
            Translator([this._sink]) { | 
        
        
           | 
              if (_sink == null) _sink = stdout; | 
        
        
           | 
              _funcs = { | 
        
        
           | 
                AST.CompilationUnit: (node) { | 
        
        
           | 
                  if (node[1] != null) { | 
        
        
           | 
                    emit("library ${node[1]};"); | 
        
        
           | 
                    if (node[2].isNotEmpty) { | 
        
        
           | 
                      newline(); | 
        
        
           | 
                    } | 
        
        
           | 
                  } | 
        
        
           | 
                  node[2].forEach(translate); | 
        
        
           | 
                  node[3].forEach(translate); | 
        
        
           | 
                }, | 
        
        
           | 
                AST.Import: (node) { | 
        
        
           | 
                  // import a compatibility file instead | 
        
        
           | 
                  if (_imports.isEmpty) { | 
        
        
           | 
                    emit("import 'java.dart';"); | 
        
        
           | 
                  } | 
        
        
           | 
                  // to replace simple names with qualified names | 
        
        
           | 
                  _imports[node[1].split(".").last] = node[1].replaceAll(".", "_"); | 
        
        
           | 
                }, | 
        
        
           | 
                AST.Class: (node) { | 
        
        
           | 
                  newline(); | 
        
        
           | 
                  var abst = node[1][1].contains("abstract") ? "abstract " : ""; | 
        
        
           | 
                  var name = node[2]; | 
        
        
           | 
                  var type = node[3] != null ? translate(node[3]) : ""; | 
        
        
           | 
                  var ext = node[4] != null ? " extends ${translate(node[4]).replaceAll(".", "_")}" : ""; | 
        
        
           | 
                  var imp = node[5] != null ? " with ${node[5].map(translate).join(", ").replaceAll(".", "_")}" : ""; | 
        
        
           | 
                  emit("${abst}class $name$type$ext$imp"); | 
        
        
           | 
                  _resolver.beginScope(); | 
        
        
           | 
                  emit("{"); | 
        
        
           | 
                  indent(); | 
        
        
           | 
                  node[6].where((n) => n[0] != "class").forEach(translate); // See below | 
        
        
           | 
                  dedent(); | 
        
        
           | 
                  emit("}"); | 
        
        
           | 
                  _resolver.endScope(); | 
        
        
           | 
                  // Dart doesn't support nested classes | 
        
        
           | 
                  node[6].where((n) => n[0] == "class").forEach(translate); | 
        
        
           | 
                }, | 
        
        
           | 
                AST.Interface: (node) { | 
        
        
           | 
                  newline(); | 
        
        
           | 
                  var name = node[2]; | 
        
        
           | 
                  var type = node[3] != null ? translate(node[3]) : ""; | 
        
        
           | 
                  var imp = node[4] != null ? " with ${node[4].map(translate).join(", ").replaceAll(".", "_")}" : ""; | 
        
        
           | 
                  emit("abstract class $name$type$imp"); | 
        
        
           | 
                  _resolver.beginScope(); | 
        
        
           | 
                  emit("{"); | 
        
        
           | 
                  indent(); | 
        
        
           | 
                  node[5].where((n) => n[0] != "class").forEach(translate); // See below | 
        
        
           | 
                  dedent(); | 
        
        
           | 
                  emit("}"); | 
        
        
           | 
                  _resolver.endScope(); | 
        
        
           | 
                  // Dart doesn't support nested classes | 
        
        
           | 
                  node[5].where((n) => n[0] == "class").forEach(translate); | 
        
        
           | 
                }, | 
        
        
           | 
                AST.VariableDeclarations: (node) { | 
        
        
           | 
                  node[1].forEach((n) => emit(translate(n) + ";")); | 
        
        
           | 
                }, | 
        
        
           | 
                AST.VariableDeclaration: (node) { | 
        
        
           | 
                  var mods = node[1] != null ? translate(node[1]) : ""; | 
        
        
           | 
                  var type = translate(node[2]); | 
        
        
           | 
                  if (type == "int") mods = mods.replaceAll("final", "const"); | 
        
        
           | 
                  var name = _dartName(node[3]); | 
        
        
           | 
                  var init = node[4] != null ? " = ${translate(node[4])}" : ""; | 
        
        
           | 
                  _resolver.bind(name, type); | 
        
        
           | 
                  return "$mods$type $name$init"; | 
        
        
           | 
                }, | 
        
        
           | 
                AST.ArrayInitializer: (node) { | 
        
        
           | 
                  return "[${node[1].map(translate).map(_strip).join(", ")}]"; | 
        
        
           | 
                }, | 
        
        
           | 
                AST.Modifiers: (node) { | 
        
        
           | 
                  var mods = ""; | 
        
        
           | 
                  if (node[1].contains("static")) mods += "static "; | 
        
        
           | 
                  if (node[1].contains("final")) mods += "final "; | 
        
        
           | 
                  return mods; | 
        
        
           | 
                }, | 
        
        
           | 
                AST.Constructor: (node) { | 
        
        
           | 
                  _resolver.beginScope(); | 
        
        
           | 
                  newline(); | 
        
        
           | 
                  var mods = node[1] != null ? translate(node[1]) : ""; | 
        
        
           | 
                  var name = _dartName(node[2]); | 
        
        
           | 
                  emit("$mods$name(${node[3].map(translate).join(", ")})"); | 
        
        
           | 
                  emit("{"); | 
        
        
           | 
                  indent(); | 
        
        
           | 
                  translate(node[5]); | 
        
        
           | 
                  dedent(); | 
        
        
           | 
                  emit("}"); | 
        
        
           | 
                  _resolver.endScope(); | 
        
        
           | 
                }, | 
        
        
           | 
                AST.Method: (node) { | 
        
        
           | 
                  _resolver.beginScope(); | 
        
        
           | 
                  newline(); | 
        
        
           | 
                  var mods = node[1] != null ? translate(node[1]) : ""; | 
        
        
           | 
                  var type = translate(node[2]); | 
        
        
           | 
                  var name = _dartName(node[3]); | 
        
        
           | 
                  emit("$mods$type $name(${node[4].map(translate).join(", ")})${node[6].isEmpty ? ";": ""}"); | 
        
        
           | 
                  if (node[6].isNotEmpty) { | 
        
        
           | 
                    emit("{"); | 
        
        
           | 
                    indent(); | 
        
        
           | 
                    translate(node[6]); | 
        
        
           | 
                    dedent(); | 
        
        
           | 
                    emit("}"); | 
        
        
           | 
                  } | 
        
        
           | 
                  _resolver.endScope(); | 
        
        
           | 
                }, | 
        
        
           | 
                AST.Parameter: (node) { | 
        
        
           | 
                  var type = translate(node[1]), name = _dartName(node[2]); | 
        
        
           | 
                  _resolver.bind(name, type); | 
        
        
           | 
                  return "$type $name"; | 
        
        
           | 
                }, | 
        
        
           | 
                AST.RestParameter: (node) { | 
        
        
           | 
                  var type = translate(node[1]), name = _dartName(node[2]); | 
        
        
           | 
                  _resolver.bind(name, type); | 
        
        
           | 
                  return "List<$type> $name /*XXX*/"; | 
        
        
           | 
                }, | 
        
        
           | 
                AST.Block: (node) { | 
        
        
           | 
                  _resolver.beginScope(); | 
        
        
           | 
                  node[1].forEach(translate); | 
        
        
           | 
                  _resolver.endScope(); | 
        
        
           | 
                }, | 
        
        
           | 
                AST.PrimitiveType: (node) { | 
        
        
           | 
                  return _dartType(node[1]); | 
        
        
           | 
                }, | 
        
        
           | 
                AST.ReferenceType: (node) { | 
        
        
           | 
                  _types.add(node[1]); // TODO should only collect self-defined types | 
        
        
           | 
                  var imported = _imports[node[1]]; | 
        
        
           | 
                  return imported != null ? imported : node[1]; | 
        
        
           | 
                }, | 
        
        
           | 
                AST.ArrayType: (node) { | 
        
        
           | 
                  return "List<${translate(node[1])}>"; | 
        
        
           | 
                }, | 
        
        
           | 
                AST.GenericType: (node) { | 
        
        
           | 
                  var type = translate(node[1]); | 
        
        
           | 
                  if (node[2] != null && node[2][1][0] != "?") { | 
        
        
           | 
                    type = "$type${translate(node[2])}"; | 
        
        
           | 
                  } | 
        
        
           | 
                  return type; | 
        
        
           | 
                }, | 
        
        
           | 
                AST.TypeParameters: (node) { | 
        
        
           | 
                  return "<${node[1].join(", ")}>"; | 
        
        
           | 
                }, | 
        
        
           | 
                AST.Expression: (node) { | 
        
        
           | 
                  emit("${_strip(translate(node[1]))};"); | 
        
        
           | 
                }, | 
        
        
           | 
                "call": (node) { | 
        
        
           | 
                  var receiver = node[1] != null ? translate(node[1]) : ""; | 
        
        
           | 
                  if (node[1] != null && node[2] == "equals" && node[3].length == 1) { | 
        
        
           | 
                    return "($receiver == ${translate(node[3][0])})"; | 
        
        
           | 
                  } | 
        
        
           | 
                  if (node[1] != null && node[2] == "length" && node[3].length == 0) { | 
        
        
           | 
                    return "$receiver.length"; | 
        
        
           | 
                  } | 
        
        
           | 
                  if (node[1] != null && node[2] == "charAt" && node[3].length == 1) { | 
        
        
           | 
                    return "$receiver.codeUnitAt(${_strip(translate(node[3][0]))})"; | 
        
        
           | 
                  } | 
        
        
           | 
                  if (node[1] != null && node[2] == "equalsIgnoreCase" && node[3].length == 1) { | 
        
        
           | 
                    return "java_equalsIgnoreCase($receiver, ${_strip(translate(node[3][0]))})"; | 
        
        
           | 
                  } | 
        
        
           | 
                  if (node[1] != null && node[2] == "append" && node[3].length == 1) { | 
        
        
           | 
                    if (_resolver.resolve(node[1]) == "StringBuffer") { | 
        
        
           | 
                      node[2] = "write"; | 
        
        
           | 
                    } | 
        
        
           | 
                  } | 
        
        
           | 
                  if (receiver != "") receiver += "."; | 
        
        
           | 
                  return "$receiver${_dartName(node[2])}(${node[3].map(translate).map(_strip).join(", ")})"; | 
        
        
           | 
                }, | 
        
        
           | 
                "field": (node) { | 
        
        
           | 
                  return "${translate(node[1])}.${_dartName(node[2])}"; | 
        
        
           | 
                }, | 
        
        
           | 
                "literal": (node) { | 
        
        
           | 
                  if (node[1] is String) { | 
        
        
           | 
                    node[1] = node[1].replaceAll("\$", "\\\$"); | 
        
        
           | 
                    if (node[1][0] == "'") { // it's a char not a string | 
        
        
           | 
                      return "${node[1]}.codeUnitAt(0)"; | 
        
        
           | 
                    } | 
        
        
           | 
                  } | 
        
        
           | 
                  return "${node[1]}"; | 
        
        
           | 
                }, | 
        
        
           | 
                "variable": (node) { | 
        
        
           | 
                  return _dartName(node[1]); | 
        
        
           | 
                }, | 
        
        
           | 
                "new_array": (node) { | 
        
        
           | 
                  return "new List<${translate(node[1])}>(${translate(node[2])})"; | 
        
        
           | 
                }, | 
        
        
           | 
                "new_array_from": (node) { | 
        
        
           | 
                  return "new List<${translate(node[1])}>.from([${node[2].map(translate).map(_strip).join(", ")}])"; | 
        
        
           | 
                }, | 
        
        
           | 
                "new_instance": (node) { | 
        
        
           | 
                  return "new ${translate(node[1])}(${node[2].map(translate).map(_strip).join(", ")})"; | 
        
        
           | 
                }, | 
        
        
           | 
                // TODO use precedence to omit unneeded parentheses | 
        
        
           | 
                "+": _binaryExpression("+"), | 
        
        
           | 
                "-": _binaryExpression("-"), | 
        
        
           | 
                "*": _binaryExpression("*"), | 
        
        
           | 
                "/": _binaryExpression("~/"), // int only | 
        
        
           | 
                "%": _binaryExpression("%"), | 
        
        
           | 
                "&": _binaryExpression("&"), | 
        
        
           | 
                "|": _binaryExpression("|"), | 
        
        
           | 
                "^": _binaryExpression("^"), | 
        
        
           | 
                "<<": _binaryExpression("<<"), | 
        
        
           | 
                ">>": _binaryExpression(">>"), | 
        
        
           | 
                ">>>": _binaryExpression(">>"), | 
        
        
           | 
                "&&": _binaryExpression("&&"), | 
        
        
           | 
                "||": _binaryExpression("||"), | 
        
        
           | 
                "<": _binaryExpression("<"), | 
        
        
           | 
                "<=": _binaryExpression("<="), | 
        
        
           | 
                ">": _binaryExpression(">"), | 
        
        
           | 
                ">=": _binaryExpression(">="), | 
        
        
           | 
                "==": _binaryExpression("=="), | 
        
        
           | 
                "!=": _binaryExpression("!="), | 
        
        
           | 
                "=": _binaryExpression("="), | 
        
        
           | 
                "+=": _binaryExpression("+="), | 
        
        
           | 
                "-=": _binaryExpression("-="), | 
        
        
           | 
                "*=": _binaryExpression("*="), | 
        
        
           | 
                "/=": _binaryExpression("~/="), // int only | 
        
        
           | 
                "&=": _binaryExpression("&="), | 
        
        
           | 
                "|=": _binaryExpression("|="), | 
        
        
           | 
                "[]": (node) { return "${translate(node[1])}[${_strip(translate(node[2]))}]"; }, | 
        
        
           | 
                "p++": (node) { return "${translate(node[1])}++"; }, | 
        
        
           | 
                "p--": (node) { return "${translate(node[1])}--"; }, | 
        
        
           | 
                "++p": (node) { return "(++${translate(node[1])})"; }, | 
        
        
           | 
                "--p": (node) { return "(--${translate(node[1])})"; }, | 
        
        
           | 
                "!": (node) { return "(!${translate(node[1])})"; }, | 
        
        
           | 
                "~": (node) { return "(~${translate(node[1])})"; }, | 
        
        
           | 
                "-p": (node) { return "(-${translate(node[1])})"; }, | 
        
        
           | 
                "+p": (node) { return "(+${translate(node[1])})"; }, | 
        
        
           | 
                "cast": (node) { | 
        
        
           | 
                  //return "(${translate(node[2])} as ${translate(node[1])})"; | 
        
        
           | 
                  return translate(node[2]); | 
        
        
           | 
                }, | 
        
        
           | 
                "?:": (node) { | 
        
        
           | 
                  return "(${translate(node[1])} ? ${translate(node[2])} : ${translate(node[3])})"; | 
        
        
           | 
                }, | 
        
        
           | 
                "if": (node) { | 
        
        
           | 
                  emit("if (${_strip(translate(node[1]))}) {"); | 
        
        
           | 
                  indent(); | 
        
        
           | 
                  translate(node[2]); | 
        
        
           | 
                  if (node[3] != null) { | 
        
        
           | 
                    dedent(); | 
        
        
           | 
                    emit("} else {"); | 
        
        
           | 
                    indent(); | 
        
        
           | 
                    translate(node[3]); | 
        
        
           | 
                  } | 
        
        
           | 
                  dedent(); | 
        
        
           | 
                  emit("}"); | 
        
        
           | 
                }, | 
        
        
           | 
                "return": (node) { | 
        
        
           | 
                  if (node[1] != null) { | 
        
        
           | 
                    emit("return ${_strip(translate(node[1]))};"); | 
        
        
           | 
                  } else { | 
        
        
           | 
                    emit("return;"); | 
        
        
           | 
                  } | 
        
        
           | 
                }, | 
        
        
           | 
                "for": (node) { | 
        
        
           | 
                  var i = []; | 
        
        
           | 
                  node[1].forEach((n) { | 
        
        
           | 
                    if (n[0] == 'variable_declarations') i.addAll(n[1]); | 
        
        
           | 
                    else i.add(n); | 
        
        
           | 
                  }); | 
        
        
           | 
                  if (i.length > 1) { | 
        
        
           | 
                    // Dart doesn't like multiple declarations in for so we move them | 
        
        
           | 
                    i.forEach((n) => emit("${translate(n)};")); | 
        
        
           | 
                    i = []; | 
        
        
           | 
                  } | 
        
        
           | 
                  emit("for (${i.map(translate).join(", ")}; " | 
        
        
           | 
                    "${node[2] != null ? _strip(translate(node[2])) : ""}; " | 
        
        
           | 
                    "${node[3].map(translate).join(", ")}) {"); | 
        
        
           | 
                  indent(); | 
        
        
           | 
                  translate(node[4]); | 
        
        
           | 
                  dedent(); | 
        
        
           | 
                  emit("}"); | 
        
        
           | 
                }, | 
        
        
           | 
                "foreach": (node) { | 
        
        
           | 
                  emit("for (${translate(node[1])} in ${translate(node[2])}) {"); | 
        
        
           | 
                  indent(); | 
        
        
           | 
                  translate(node[3]); | 
        
        
           | 
                  dedent(); | 
        
        
           | 
                  emit("}"); | 
        
        
           | 
                }, | 
        
        
           | 
                "dowhile": (node) { | 
        
        
           | 
                  emit("do {"); | 
        
        
           | 
                  indent(); | 
        
        
           | 
                  translate(node[2]); | 
        
        
           | 
                  dedent(); | 
        
        
           | 
                  emit("} while (${_strip(translate(node[1]))});"); | 
        
        
           | 
                }, | 
        
        
           | 
                "whiledo": (node) { | 
        
        
           | 
                  emit("while (${_strip(translate(node[1]))}) {"); | 
        
        
           | 
                  indent(); | 
        
        
           | 
                  translate(node[2]); | 
        
        
           | 
                  dedent(); | 
        
        
           | 
                  emit("}"); | 
        
        
           | 
                }, | 
        
        
           | 
                "try": (node) { | 
        
        
           | 
                  emit("try {"); | 
        
        
           | 
                  indent(); | 
        
        
           | 
                  translate(node[1]); | 
        
        
           | 
                  dedent(); | 
        
        
           | 
                  node[2].forEach(translate); | 
        
        
           | 
                  if (node[3] != null) { | 
        
        
           | 
                    emit("} finally {"); | 
        
        
           | 
                    indent(); | 
        
        
           | 
                    translate(node[3]); | 
        
        
           | 
                    dedent(); | 
        
        
           | 
                  } | 
        
        
           | 
                  emit("}"); | 
        
        
           | 
                }, | 
        
        
           | 
                "catch": (node) { | 
        
        
           | 
                  emit("} on ${translate(node[1][1])} catch (${_dartName(node[1][2])}) {"); | 
        
        
           | 
                  indent(); | 
        
        
           | 
                  translate(node[2]); | 
        
        
           | 
                  dedent(); | 
        
        
           | 
                }, | 
        
        
           | 
                "assert": (node) { | 
        
        
           | 
                  emit("assert(${_strip(translate(node[1]))});"); | 
        
        
           | 
                }, | 
        
        
           | 
                "break": (node) { | 
        
        
           | 
                  if (node[1] != null) { | 
        
        
           | 
                    emit("break ${node[1]};"); | 
        
        
           | 
                  } | 
        
        
           | 
                  emit("break;"); | 
        
        
           | 
                }, | 
        
        
           | 
                "continue": (node) { | 
        
        
           | 
                  if (node[1] != null) { | 
        
        
           | 
                    emit("continue ${node[1]};"); | 
        
        
           | 
                  } | 
        
        
           | 
                  emit("continue;"); | 
        
        
           | 
                }, | 
        
        
           | 
                "switch": (node) { | 
        
        
           | 
                  emit("switch (${translate(node[1])}) {"); | 
        
        
           | 
                  indent(); | 
        
        
           | 
                  indent(); | 
        
        
           | 
                  node[2].forEach(translate); | 
        
        
           | 
                  dedent(); | 
        
        
           | 
                  dedent(); | 
        
        
           | 
                  emit("}"); | 
        
        
           | 
                }, | 
        
        
           | 
                "case": (node) { | 
        
        
           | 
                  dedent(); | 
        
        
           | 
                  emit("case ${translate(node[1])}:"); | 
        
        
           | 
                  indent(); | 
        
        
           | 
                }, | 
        
        
           | 
                "default": (node) { | 
        
        
           | 
                  dedent(); | 
        
        
           | 
                  emit("default:"); | 
        
        
           | 
                  indent(); | 
        
        
           | 
                }, | 
        
        
           | 
                "label": (node) { | 
        
        
           | 
                  emit("${node[1]}:"); | 
        
        
           | 
                }, | 
        
        
           | 
                "throw": (node) { | 
        
        
           | 
                  emit("throw ${translate(node[1])};"); | 
        
        
           | 
                }, | 
        
        
           | 
                "pass": (node) { | 
        
        
           | 
                }, | 
        
        
           | 
              }; | 
        
        
           | 
              _resolver.beginScope(); | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            Function _binaryExpression(String op) { | 
        
        
           | 
              return (node) { return "(${translate(node[1])} $op ${translate(node[2])})"; }; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            String _dartType(String type) { | 
        
        
           | 
              // map Java type to Dart type | 
        
        
           | 
              return const{ | 
        
        
           | 
                "boolean": "bool", | 
        
        
           | 
                "byte": "int", | 
        
        
           | 
                "char": "int", | 
        
        
           | 
                "short": "int", | 
        
        
           | 
                "int": "int", | 
        
        
           | 
                "float": "double", | 
        
        
           | 
                "long": "int", | 
        
        
           | 
                "double": "double", | 
        
        
           | 
                "void" : "void" | 
        
        
           | 
              }[type]; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            String _dartName(String name) { | 
        
        
           | 
              // do not use Dart reserved words | 
        
        
           | 
              if (const["in", "is"].contains(name)) name += "_"; | 
        
        
           | 
              // do not use the same name as for types | 
        
        
           | 
              if (_types.contains(name)) name += "_"; | 
        
        
           | 
              return name; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            String _strip(String s) { | 
        
        
           | 
              // ignore parentheses on top level | 
        
        
           | 
              if (s.startsWith("(") && s.endsWith(")")) { | 
        
        
           | 
                return s.substring(1, s.length - 1); | 
        
        
           | 
              } | 
        
        
           | 
              return s; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            void newline() { | 
        
        
           | 
              _sink.write("\n"); | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            void emit(String line) { | 
        
        
           | 
              for (int i = 0; i < _indent; i++) { | 
        
        
           | 
                _sink.write('    '); | 
        
        
           | 
              } | 
        
        
           | 
              _sink.writeln(line); | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            void indent() { _indent++; } | 
        
        
           | 
          
 | 
        
        
           | 
            void dedent() { _indent--; } | 
        
        
           | 
          
 | 
        
        
           | 
            translate(node) { | 
        
        
           | 
              return _funcs[node[0]](node); | 
        
        
           | 
            } | 
        
        
           | 
          } | 
        
        
           | 
          
 | 
        
        
           | 
          class Resolver { | 
        
        
           | 
            List<Map<String, String>> _scopes = []; | 
        
        
           | 
          
 | 
        
        
           | 
            void beginScope() { | 
        
        
           | 
              _scopes.add({}); | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            void endScope() { | 
        
        
           | 
              _scopes.removeLast(); | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            void bind(String variable, String type) { | 
        
        
           | 
              _scopes.last[variable] = type; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            String lookup(String variable) { | 
        
        
           | 
              for (int i = _scopes.length - 1; i >= 0; i--) { | 
        
        
           | 
                String type = _scopes[i][variable]; | 
        
        
           | 
                if (type != null) return type; | 
        
        
           | 
              } | 
        
        
           | 
              return null; | 
        
        
           | 
            } | 
        
        
           | 
          
 | 
        
        
           | 
            String resolve(node) { | 
        
        
           | 
              // we can resolve variables but nothing more | 
        
        
           | 
              if (node[0] == 'variable') return lookup(node[1]); | 
        
        
           | 
              return null; | 
        
        
           | 
            } | 
        
        
           | 
          } | 
        
        
           | 
          
 | 
        
        
           | 
          void main(List<String> args) { | 
        
        
           | 
            if (args.length > 0) { | 
        
        
           | 
              var source = new File("/Users/sma/Desktop/Atlantis.java").readAsStringSync(); | 
        
        
           | 
              var node = new Parser(source).parseCompilationUnit(); | 
        
        
           | 
              new File("/tmp/json").writeAsStringSync(JSON.encode(node)); | 
        
        
           | 
            } else { | 
        
        
           | 
              var node = JSON.decode(new File("/tmp/json").readAsStringSync()); | 
        
        
           | 
              new Translator().translate(node); | 
        
        
           | 
            } | 
        
        
           | 
          } | 
        
        
           | 
          
 | 
        
  
Hi , you might have used the java7 grammar from sablecc. Sablecc is quite easy to use and the grammar cover all the java language including java 7 specificities.
http://sablecc3.sablecc.org/wiki/Java-1.7