List of usage examples for org.antlr.v4.runtime ParserRuleContext getRuleIndex
public int getRuleIndex()
From source file:br.beholder.memelang.model.visitor.TreePrinterListener.java
@Override public void enterEveryRule(ParserRuleContext ctx) { if (builder.length() > 0) { builder.append(' '); }/*from w w w. j av a 2 s . c o m*/ if (ctx.getChildCount() > 0) { builder.append('('); } int ruleIndex = ctx.getRuleIndex(); String ruleName; if (ruleIndex >= 0 && ruleIndex < ruleNames.size()) { ruleName = ruleNames.get(ruleIndex); } else { ruleName = Integer.toString(ruleIndex); } builder.append(ruleName); }
From source file:ch.raffael.contracts.devtools.ast.AstInspector.java
License:Apache License
public void parse(final String source) { final StringBuilder errors = new StringBuilder(); final StringBuilder trace = new StringBuilder("Log:\n"); ANTLRErrorListener errorListener = new BaseErrorListener() { @Override//w w w . j ava 2 s .com public void syntaxError(Recognizer<?, ?> recognizer, @Nullable Object offendingSymbol, int line, int charPositionInLine, String msg, @Nullable RecognitionException e) { errors.append("Line ").append(line).append(':').append(charPositionInLine).append(": ").append(msg) .append('\n'); } }; final CelLexer lexer = new CelLexer(new ANTLRInputStream(source)); final CelParser parser = new CelParser(new CommonTokenStream(lexer)); lexer.addErrorListener(errorListener); parser.addErrorListener(errorListener); parser.addParseListener(new ParseTreeListener() { @Override public void enterEveryRule(ParserRuleContext ctx) { trace.append(" enter\t").append(parser.getRuleNames()[ctx.getRuleIndex()]).append(", LT(1)=") .append(parser.getTokenStream().LT(1).getText()).append('\n'); } @Override public void visitTerminal(TerminalNode node) { trace.append(" consume\t").append(node.getSymbol()).append(" rule ") .append(parser.getRuleNames()[parser.getContext().getRuleIndex()]).append('\n'); } @Override public void visitErrorNode(ErrorNode node) { } @Override public void exitEveryRule(ParserRuleContext ctx) { trace.append(" exit\t").append(parser.getRuleNames()[ctx.getRuleIndex()]).append(", LT(1)=") .append(parser.getTokenStream().LT(1).getText()).append('\n'); } }); parser.setBuildParseTree(true); AstBuilder builder = new AstBuilder(); builder.install(parser); final CelParser.ClauseContext rootContext = parser.clause(); if (errors.length() != 0) { errors.append('\n'); } Runnable guiUpdate = new Runnable() { @Override public void run() { log.setText(errors.toString() + trace.toString()); log.setSelectionStart(0); log.setSelectionEnd(0); if (rootContext == null || rootContext.node == null) { syntaxTree.setModel(new DefaultTreeModel(AstTreeNode.empty())); updateParseTree(null); } else { syntaxTree.setModel(new DefaultTreeModel(AstTreeNode.from(rootContext.node))); updateParseTree(new TreeViewer(Arrays.asList(parser.getRuleNames()), rootContext)); } for (int i = 0; i < syntaxTree.getRowCount(); i++) { syntaxTree.expandRow(i); } } }; if (SwingUtilities.isEventDispatchThread()) { guiUpdate.run(); } else { SwingUtilities.invokeLater(guiUpdate); } }
From source file:codemate.Fortran.FortranTemplater.java
License:Open Source License
@SuppressWarnings("unused") private Stack<ParserRuleContext> findRoute(ParserRuleContext startNode, int endNodeRuleIndex) { Stack<ParserRuleContext> route = new Stack<ParserRuleContext>(); ParserRuleContext node = startNode; boolean isFound = false; while (!isFound && node != null) { route.push(node);/*www.j a va2 s . c o m*/ if (node.getRuleIndex() == endNodeRuleIndex) isFound = true; else for (ParseTree child : node.children) if (child instanceof ParserRuleContext) { if (((ParserRuleContext) child).getRuleIndex() == endNodeRuleIndex) { route.pop(); // throw the useless parent node away route.push((ParserRuleContext) child); // I push a null into the stack to indicate that // the end node is a sibling node. route.push(null); isFound = true; break; } } if (!isFound) node = node.getParent(); } if (false) { if (route.lastElement() != null) System.out.println("Route (local):"); else System.out.println("Route (non-local):"); for (ParserRuleContext node_ : route) if (node_ != null) System.out.println("* " + FortranParser.ruleNames[node_.getRuleIndex()]); } return route; }
From source file:com.espertech.esper.epl.parse.ASTUtil.java
License:Open Source License
public static boolean isRecursiveParentRule(ParserRuleContext ctx, Set<Integer> rulesIds) { ParserRuleContext parent = ctx.getParent(); if (parent == null) { return false; }// ww w.jav a 2 s.c o m return rulesIds.contains(parent.getRuleIndex()) || isRecursiveParentRule(parent, rulesIds); }
From source file:com.espertech.esper.epl.parse.ASTUtil.java
License:Open Source License
private static void renderNode(char[] ident, Tree node, PrintWriter printer) { printer.print(ident);/* w ww . ja v a 2 s .co m*/ if (node == null) { printer.print("NULL NODE"); } else { if (node instanceof ParserRuleContext) { ParserRuleContext ctx = (ParserRuleContext) node; int ruleIndex = ctx.getRuleIndex(); String ruleName = EsperEPL2GrammarParser.ruleNames[ruleIndex]; printer.print(ruleName); } else { TerminalNode terminal = (TerminalNode) node; printer.print(terminal.getSymbol().getText()); printer.print(" ["); printer.print(terminal.getSymbol().getType()); printer.print("]"); } if (node instanceof ParseTree) { ParseTree parseTree = (ParseTree) node; if (parseTree.getText() == null) { printer.print(" (null value in text)"); } else if (parseTree.getText().contains("\\")) { int count = 0; for (int i = 0; i < parseTree.getText().length(); i++) { if (parseTree.getText().charAt(i) == '\\') { count++; } } printer.print(" (" + count + " backlashes)"); } } } printer.println(); }
From source file:com.khubla.jvmbasic.jvmbasicc.compiler.Dispatcher.java
License:Open Source License
/** * dispatch//from w w w . ja v a 2s . c o m */ public static boolean dispatch(GenerationContext generationContext) throws Exception { try { if (null != generationContext.getParseTree()) { final Object o = generationContext.getParseTree().getPayload(); if (o.getClass() == CommonToken.class) { final CommonToken commonToken = (CommonToken) o; final Function function = FunctionRegistry.getInstance() .getTokenFunction(commonToken.getType()); logger.info("Dispatching to '" + function.getClass().getSimpleName() + "' for token '" + jvmBasicParser.tokenNames[commonToken.getType()] + "'"); return function.execute(generationContext); } else { final ParserRuleContext parserRuleContext = (ParserRuleContext) o; final Function function = FunctionRegistry.getInstance() .getRuleFunction(parserRuleContext.getRuleIndex()); logger.info("Dispatching to '" + function.getClass().getSimpleName() + "' for rule '" + jvmBasicParser.ruleNames[parserRuleContext.getRuleIndex()] + "'"); return function.execute(generationContext); } } return true; } catch (final Exception e) { throw new Exception("Exception in dispatch at line " + generationContext.getLineNumber(), e); } }
From source file:com.khubla.jvmbasic.jvmbasicc.compiler.TreePrinter.java
License:Open Source License
@Override public void parserRule(ParserRuleContext parserRuleContext, int ctxlevel) { logger.info(indentString(ctxlevel) + "[" + parserRuleContext.getRuleIndex() + " " + jvmBasicParser.ruleNames[parserRuleContext.getRuleIndex()] + "]"); }
From source file:com.satisfyingstructures.J2S.J2SConvertBasicFor.java
License:Open Source License
private String convertBasicForStatementToForInLoopOrSayWhyNot(ParserRuleContext ctx) { int forRule = ctx.getRuleIndex(); if (forRule != Java8Parser.RULE_basicForStatement && forRule != Java8Parser.RULE_basicForStatementNoShortIf) return "statement kind is not as expected"; // not our expected parameter type // Get to know more about our for statement // 'for' '(' forInit? ';' expression? ';' forUpdate? ')' ( statement | statementNoShortIf ) Boolean noShortIf = forRule == Java8Parser.RULE_basicForStatementNoShortIf; Java8Parser.ForInitContext forInitCtx = ctx.getChild(Java8Parser.ForInitContext.class, 0); Java8Parser.ExpressionContext expressionCtx = ctx.getChild(Java8Parser.ExpressionContext.class, 0); Java8Parser.ForUpdateContext forUpdateCtx = ctx.getChild(Java8Parser.ForUpdateContext.class, 0); ParserRuleContext statementCtx = ctx.getChild( noShortIf ? Java8Parser.StatementNoShortIfContext.class : Java8Parser.StatementContext.class, 0); ParserRuleContext statementSubCtx = statementCtx.getChild(ParserRuleContext.class, 0); ParserRuleContext statementSubSubCtx = statementSubCtx.getChild(ParserRuleContext.class, 0); Boolean statementisEmpty = statementSubSubCtx.getRuleIndex() == Java8Parser.RULE_emptyStatement; /*/*from www . java2s .c o m*/ 'for' '(' forInit? ';' expression? ';' forUpdate? ')' ( statement | statementNoShortIf ) Swift 3.0 has got rid of for(;;) statements for stong business cases such as... 'It is rarely used' 'not very Swift-like' 'The value of this construct is limited' ...and other total crap. We can convert simple equivalents of for ( i = startvalue ; i < endvalue ; i += step) to for i in start..<end or for i in start.stride(to: end by: step) To identify this we look for 1) have a forUpdate, which... a) operates on a single loop variable forUpdate().statementExpressionList().statementExpression().count()==1 b) incorporates increment or decrement by a constant step (++i,i++,i+=step,--i,i--,i-=step,) statementExpression rule is RULE_(assignment|preinc|postinc|predec|postdec) c) operates on the same variable tested in expression (compare - 2b) 2) have an expression, which... a) should be a simple comparison (<,<=,!=,>,>=, implicit non-zero) b) one side should be same as the loop var (compare - 1c) c) other side should not mutate within the loop - we can't tell this, too difficult 3) forInit a) must be i) empty(start with loop var existing value), or ii) simple init of a single loop var, or iii) simple declaration of a loop var */ // 1) Update statement. We need one... if (null == forUpdateCtx) return "it lacks an update statement"; // 1a) and it must operate on a single variable if (forUpdateCtx.statementExpressionList().getChildCount() != 1) return "there is more than one expression in the update statement"; // 1b) and it must be a simple increment or decrement Java8Parser.StatementExpressionContext updateStatementExpressionCtx = forUpdateCtx.statementExpressionList() .statementExpression(0); // statementExpression : assignment | preIncrementExpression | preDecrementExpression // | postIncrementExpression | postDecrementExpression // | methodInvocation | classInstanceCreationExpression ParserRuleContext updateExpressionCtx = updateStatementExpressionCtx.getChild(ParserRuleContext.class, 0); int updateExpressionRule = updateExpressionCtx.getRuleIndex(); boolean ascending_sequence; boolean open_interval; ParserRuleContext stepExpressionCtx = null; switch (updateExpressionRule) { // unaryExpression : preIncrementExpression | preDecrementExpression // | '+' unaryExpression | '-' unaryExpression // | unaryExpressionNotPlusMinus // preDecrementExpression : '--' unaryExpression // preIncrementExpression : '++' unaryExpression case Java8Parser.RULE_preDecrementExpression: ascending_sequence = false; break; case Java8Parser.RULE_preIncrementExpression: ascending_sequence = true; break; // postfixExpression : ( primary | expressionName ) ( '++' | '--')* // postIncrementExpression : postfixExpression '++' // postDecrementExpression : postfixExpression '--' case Java8Parser.RULE_postDecrementExpression: ascending_sequence = false; break; case Java8Parser.RULE_postIncrementExpression: ascending_sequence = true; break; // assignment : leftHandSide assignmentOperator expression // leftHandSide : expressionName | fieldAccess | arrayAccess case Java8Parser.RULE_assignment: if (null != updateStatementExpressionCtx.assignment().leftHandSide().arrayAccess()) return "cant convert a loop variable that is an array element"; TerminalNode node = updateStatementExpressionCtx.assignment().assignmentOperator() .getChild(TerminalNode.class, 0); switch (node.getSymbol().getType()) { case Java8Parser.ADD_ASSIGN: ascending_sequence = true; break; case Java8Parser.SUB_ASSIGN: ascending_sequence = false; break; case Java8Parser.ASSIGN: // possibilities too complex to warrant extracting simple a=a+1 cases default: return "potentially too complex to create a sequence from this update operation"; } stepExpressionCtx = updateStatementExpressionCtx.assignment().expression(); break; default: // methodInvocation | classInstanceCreationExpression return "the expression in the update statement is too complex"; } // In each of the cases that we have not rejected, the loop variable is in the first child rule context of the // update statement. Get the text of the variable, rather than analysing the graph any further, as the // possibilities are endless; all that we require is that the loop variable text matches that in the text // expression and the init expression. ParserRuleContext loopVariable_updated_Ctx = updateExpressionCtx.getChild(ParserRuleContext.class, 0); String loopVariableTxt = loopVariable_updated_Ctx.getText(); // we want original text // 2) Expression if (null == expressionCtx) return "it lacks a test expression"; // expression : lambdaExpression | assignmentExpression if (null != expressionCtx.lambdaExpression()) return "cannot convert a lambda expression"; // assignmentExpression : conditionalExpression | assignment if (null != expressionCtx.assignmentExpression().assignment()) return "cannot convert an assignment within the test expression"; // 2a) must be a simple relation: // Descend the chain of expression rule pass-through branches until we find the one that is significant, then // test to see if expression contains a terminal that is one of !=, <, <=, >, >=. ParserRuleContext testExpressionCtx = J2SGrammarUtils.descendToSignificantExpression(expressionCtx); int testExpressionRule = testExpressionCtx.getRuleIndex(); TerminalNode node = testExpressionCtx.getChild(TerminalNode.class, 0); int testOperatorType = null != node ? node.getSymbol().getType() : 0; switch (testOperatorType) { case Java8Parser.NOTEQUAL: open_interval = true; break; case Java8Parser.LE: open_interval = false; break; case Java8Parser.GE: open_interval = false; break; case Java8Parser.LT: // can occur in relational and shift expressions case Java8Parser.GT: // can occur in relational and shift expressions if (testExpressionRule == Java8Parser.RULE_relationalExpression) { open_interval = true; break; } default: return "can only convert test expressions that use !=, <, <=, > or >="; } // 2b) relation must be testing same var as changed in update expression // The loop variable could be on the left or the right of the comparison operator int i; ParserRuleContext loopVariable_tested_Ctx = null; for (i = 0; i < 2; i++) { loopVariable_tested_Ctx = testExpressionCtx.getChild(ParserRuleContext.class, i); if (null != loopVariable_tested_Ctx && loopVariableTxt.equals(loopVariable_tested_Ctx.getText())) break; // found matching loop variable loopVariable_tested_Ctx = null; } if (null == loopVariable_tested_Ctx || (i == 1 && testExpressionCtx.getChildCount() > 3)) return "the test expression must be testing the same variable as changed in update expression"; ParserRuleContext terminalValueCtx = testExpressionCtx.getChild(ParserRuleContext.class, i ^ 1); // 2c) the terminal value side should not mutate within the loop // - way too difficult for us to determine this // 3) Loop init expression. Must be either... ParserRuleContext initialValueCtx; if (null == forInitCtx) // a) empty { // Using the loop variable's existing value from outside the scope initialValueCtx = loopVariable_tested_Ctx; } else if (null != forInitCtx.statementExpressionList()) // b) a simple init of a single loop var { /* // Could not convert... // for (i = 0; i<10; i++) // ...to a for..in statement because can only work with an assignment expression for loop variable initialisation. i = 0; while i<10 {j += 1 i += 1; } */ if (forInitCtx.statementExpressionList().getChildCount() != 1) return "can only work with initialisation of a single loop variable"; Java8Parser.StatementExpressionContext initExpressionCtx = forInitCtx.statementExpressionList() .statementExpression(0); if (null == initExpressionCtx.assignment()) return "can only work with an assignment expression for loop variable initialisation"; if (!loopVariableTxt.equals(initExpressionCtx.assignment().leftHandSide().getText())) return "the initialised variable is different from the updated variable"; // different to the loop variable initialValueCtx = initExpressionCtx.assignment().expression(); } else if (null != forInitCtx.localVariableDeclaration()) // c) a simple decl of a single loop var { // localVariableDeclaration : variableModifier* unannType variableDeclaratorList Java8Parser.VariableDeclaratorListContext vdlc = forInitCtx.localVariableDeclaration() .variableDeclaratorList(); // variableDeclaratorList : variableDeclarator (',' variableDeclarator)* if (vdlc.getChildCount() != 1) return "can only work with declaration of a single loop variable"; Java8Parser.VariableDeclaratorContext vdc = vdlc.variableDeclarator(0); // variableDeclarator : variableDeclaratorId ('=' variableInitializer)? if (!loopVariableTxt.equals(vdc.getChild(0).getText())) return "the declared loop variable is be different from the updated variable"; initialValueCtx = vdc.variableInitializer(); if (null == initialValueCtx) return "there is no initialiser for the loop variable"; } else return "loop initialisation is in unexpected form"; // Now we have all the components we need String forInLoopText; // Use actual text with replacements String initialValueTxt = rewriter.getText(initialValueCtx); String terminalValueTxt = rewriter.getText(terminalValueCtx); // !!!: watch out... // if we use the actual text from the update expression, we can find that the pre/post-inc/dec has been // converted to the add/sub-assign form and because structure is lost when rewriting, the new form can // stick to the variable when we retrieve it. There's no easy solution for this (and any similar occurrences), // but we side step it by getting the text of loop variable from the test expression: loopVariableTxt = rewriter.getText(loopVariable_tested_Ctx); if (null != stepExpressionCtx || !ascending_sequence) { String stepExpressionText = stepExpressionCtx == null ? "-1" : ascending_sequence ? rewriter.getText(stepExpressionCtx) : "-(" + rewriter.getText(stepExpressionCtx) + ")"; forInLoopText = "for " + loopVariableTxt + " in " + loopVariableTxt + ".stride(from: " + initialValueTxt + (open_interval ? ", to: " : ", through: ") + terminalValueTxt + ", by: " + stepExpressionText + ")"; } else { forInLoopText = "for " + loopVariableTxt + " in " + initialValueTxt + (open_interval ? " ..< " : " ... ") + terminalValueTxt; } Token startToken = ctx.getToken(Java8Parser.FOR, 0).getSymbol(); Token endToken = ctx.getToken(Java8Parser.RPAREN, 0).getSymbol(); CharStream cs = startToken.getInputStream(); String originalExpressionTxt = cs.getText(Interval.of(startToken.getStartIndex(), endToken.getStopIndex())); rewriter.insertComment(originalExpressionTxt + " converted to", ctx, J2SRewriter.CommentWhere.beforeLineBreak); int startIndex = startToken.getTokenIndex(); int endIndex = endToken.getTokenIndex(); // Problem: (see notes in J2SRewriter.replaceAndAdjustWhitespace) Before converting to for-in, the loop will // also have had parentheses removed (and other transforms); rewriter may have coallesced some of the changes // so that the old end boundary no longer exists. (- a shortcoming of TokenStreamRewriter) // Workaround: test if endIndex is straddled by changed interval, and if so, extend our interval to the end of // the change. (Pretty horrendous to have to work around this here, but I don't yet see an easy way of fixing // the underlying problem or a generalised way of working around it.) Interval interval = rewriter.getChangedIntervalContaining(endIndex, endIndex); if (null != interval && interval.a <= endIndex && interval.b > endIndex) endIndex = interval.b; rewriter.replaceAndAdjustWhitespace(startIndex, endIndex, forInLoopText); return null; }
From source file:com.satisfyingstructures.J2S.J2SConverter.java
License:Open Source License
private void mapInitialModifiersInContext(ParserRuleContext ctx) { ParseTree pt;/* ww w . j ava 2 s . co m*/ int i = 0; while (null != (pt = ctx.getChild(i++)) && ParserRuleContext.class.isInstance(pt)) { ParserRuleContext context = (ParserRuleContext) pt; int contextRuleIndex = context.getRuleIndex(); switch (contextRuleIndex) { case Java8Parser.RULE_interfaceModifier: case Java8Parser.RULE_interfaceMethodModifier: case Java8Parser.RULE_classModifier: case Java8Parser.RULE_constructorModifier: case Java8Parser.RULE_methodModifier: case Java8Parser.RULE_annotationTypeElementModifier: case Java8Parser.RULE_variableModifier: case Java8Parser.RULE_constantModifier: case Java8Parser.RULE_fieldModifier: break; default: return; } TerminalNode tn = context.getChild(TerminalNode.class, 0); if (null == tn) continue; // annotation - dealt with separately Token token = tn.getSymbol(); // Handle special token cases switch (token.getType()) { case Java8Parser.STATIC: if (contextRuleIndex == Java8Parser.RULE_classModifier) { rewriter.deleteAndAdjustWhitespace(tn); // static not allowed for classes in Swift continue; } break; case Java8Parser.PRIVATE: case Java8Parser.PROTECTED: case Java8Parser.PUBLIC: if (contextRuleIndex == Java8Parser.RULE_interfaceMethodModifier) { rewriter.deleteAndAdjustWhitespace(tn); // access control not allowed for protocols in Swift continue; } break; } mapModifierToken(token); } }
From source file:com.satisfyingstructures.J2S.J2SConverter.java
License:Open Source License
@Override public void exitVariableDeclaratorId(Java8Parser.VariableDeclaratorIdContext ctx) {/* variableDeclaratorId is used in two main ways: a) in constant, field and local variable declarations it has zero or more siblings all under the same type, and each sibling may optionally have an initialiser; in terms of the grammar, its parentage is ((constant|field|localVariable)Declaration).variableDeclaratorList.variableDeclarator.variableDeclaratorId e.g.: public final float r360 = 2*M_PI, r180 = M_PI, r90 = M_PIL/2; ^ ^ ^ b) in a (normal|catch) formal parameter, a resource definition, and as the variable in an enhanced for loop, it has no siblings and (except in resource def) no initialiser; in terms of the grammar, its parentage is ((formal|lastFormal|catchFormal)Parameter|enhancedForStatement(NoShortIf|)|resource).variableDeclaratorId e.g.: void f(@NotNull List<Shape> shapes) { ... } ^ The outer parents named in a) and b) each have a unannType (=type without annotations) as earlier sibling of the branch containing the variableDeclaratorId(s), and before the unannType, a list of zero or more modifiers that are legal in the context. The transformations we need to do to variable definitions (without yet deciding where they need to be done) are: i) swap type and name: int a --> a: int ii) map the type: a: int --> a: Int iii)suffix optionality indicator onto the type if known to be needed: a: Int --> a: Int? iv) omit the type if there is an initialiser which is explicitly of the same type: a: Int = 1 --> a = 1 v) precede the variable definition(s list) with 'var' (=variable) or 'let' (=constant), or nothing if mutability is implied vi) only in a formal parameter, precede the variable with the argument label suppressor '_' Handling i), ii) & iv): The type is given by the unannType at outer parent level. If we knew it was going to stay in the same place, we could map it to Swift type in exitUnannType. However, theoretically, we might need to suffix it to every variable, e.g.: int a = 1, b = f(), c = g(); --> var a = 1, b: Int = f(), c: Int = g() we don't know the return types of f() and g(), and java allows a type widening when assigning (intvar = shortvar; objectvar = shapevar) so for guaranteed compilation we need to have explicit types. However, it would be more pragmatic to assume that they are of compatible type, and that no fancy conversion is going on, as we can't reach perfection and this assumption would cover 90% of the cases. But... what about variations of: List<SomeClass> list = new ArrayList<>(); ...this is a common pattern - the declaration type is specific about conformity to an expected interface, but the concrete type in the initialiser doesn't hold any of that information. Hence, if there is an initialiser then we can drop the unannType only if we are sure that it is the same as the initialiser type, otherwise it moves to suffix the last of the uninitialised variable declarations and gets mapped at the same time. For variableDeclaratorId used in a) above (const, field or local), this is best handled in exitVariableDeclaratorList; for variableDeclaratorId use b) above (formal params / enhanced for), the unannType is retained, but moved and mapped, and this could be handled here, as a common handling bottleneck. Handling iii): nullability Java variables are assumed to be nullable if they lack a @NotNull annotation. However, there is a lot of code which has not had appropriate annotations added. Some compilers (IntelliJ, ...) show annotations inferred by analysing code paths, but these inferences need to be added as explicit annotations. For better porting, a pass over the java source to add annotations might be well advised. The annotations are in the modifiers held by the parent rules, however, their effect needs to be applied to the relocated mapped unannType. Hence, this is maybe best handled where the unannType is handled, i.e. along with i), ii) & iv) above. Handling v): var or let A 'final' keyword in the modifiers before the unannType indicates const value and that 'let' should user, otherwise use var. The enhanced for is translated elsewhere to Swift's for-in loop, which has complications: the default is that a loop variable is considered implicitly const through each pass of the loop's statement and the 'let' is omitted; however, if the loop variable is to be modified in the statement, then it has to be preceded with 'var' at declaration. A formal parameter in Swift is always implicitly constant (hidden let). As 'let' or 'var' have to occupy the original position of the unannType it is reasonable to handle this and the special cases when unannType is moved and transformed. Handling iv): argument label In Swift, the variableDeclaratorId in a formal parameter doubles up: the first is the label to precede the argument when calling, and the second is the name to use for the parameter inside the function; java doesn't use argument labelling, so suppress with '_'. Hence the variableDeclaratorId has to be preceded by '_ ' when found in a formalParameter. Handle here. */ ParserRuleContext parentCtx = ctx.getParent(); if (parentCtx.getRuleIndex() == Java8Parser.RULE_variableDeclarator) { // Call convertVariableDeclaration() from exitDeclaratorList() instead, so that sibling // declarators can be dealt with together. // ParserRuleContext declaratorListCtx = parentCtx.getParent(); // ParserRuleContext declarationCtx = declaratorListCtx.getParent(); // convertVariableDeclaration(declarationCtx); ;//from w w w.j a v a 2s. c o m } else { // Parent context is (resource|(formal|lastFormal|catchFormal)Parameter|enhancedForStatement(NoShortIf|)) convertVariableDeclaration(parentCtx); } }