Example usage for org.antlr.v4.runtime ParserRuleContext getChild

List of usage examples for org.antlr.v4.runtime ParserRuleContext getChild

Introduction

In this page you can find the example usage for org.antlr.v4.runtime ParserRuleContext getChild.

Prototype

public <T extends ParseTree> T getChild(Class<? extends T> ctxType, int i) 

Source Link

Usage

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;
    /*//  w  ww .jav  a2s . 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 convertVariableDeclaration(ParserRuleContext declarationCtx) {
    // Read comments in exitVariableDeclaratorId just above!

    int declarationRuleIndex = declarationCtx.getRuleIndex();
    Class<? extends ParserRuleContext> modifierContextClass = Java8Parser.VariableModifierContext.class;
    Constness constness = Constness.unknown;
    boolean isOptional = false;
    boolean hasDeclaratorList = false;
    boolean enhancedFor = false;

    switch (declarationRuleIndex) {
    case Java8Parser.RULE_constantDeclaration:
        modifierContextClass = Java8Parser.ConstantModifierContext.class;
        hasDeclaratorList = true;/*from ww  w. ja  v a2  s .c om*/
        constness = Constness.explicit;
        break;
    case Java8Parser.RULE_fieldDeclaration:
        modifierContextClass = Java8Parser.FieldModifierContext.class;
        hasDeclaratorList = true;
        break;
    case Java8Parser.RULE_localVariableDeclaration:
        hasDeclaratorList = true;
        break;
    case Java8Parser.RULE_resource:
        constness = Constness.explicit;
        break;
    case Java8Parser.RULE_formalParameter:
    case Java8Parser.RULE_lastFormalParameter:
        constness = Constness.implicit;
        break;
    case Java8Parser.RULE_catchFormalParameter:
        constness = Constness.explicit;
        break;
    case Java8Parser.RULE_enhancedForStatement:
    case Java8Parser.RULE_enhancedForStatementNoShortIf:
        enhancedFor = true;
        constness = Constness.implicit;
        break;
    default:
        return; // not our expected parameter type
    }

    // Look for and remove 'final', '@NonNull' and '@Nullable' in modifiers
    for (ParserRuleContext modifierCtx : declarationCtx.getRuleContexts(modifierContextClass)) {
        TerminalNode tn = modifierCtx.getChild(TerminalNode.class, 0);
        if (null == tn) {
            String annotationText = modifierCtx.getText();
            switch (annotationText) {
            // some spelling variations here...
            case "@Nonnull": // javax.annotation.NotNull
            case "@NonNull": // android.support.annotation.NonNull
                             // edu.umd.cs.findbugs.annotations.NonNull
            case "@NotNull": // org.jetbrains.annotations.NotNull
                isOptional = false;
                break;
            case "@Nullable":
                isOptional = true;
                break;
            default:
                continue;
            }
        } else {
            Token token = tn.getSymbol();
            mapModifierToken(token);
            switch (token.getType()) {
            case Java8Parser.FINAL:
                if (constness == Constness.unknown)
                    constness = Constness.explicit;
                break;
            default:
                continue;
            }
        }
        rewriter.deleteAndAdjustWhitespace(modifierCtx);
    }

    // Move trailing dimensions to wrap the type. First any dimensions binding to the declarator id and
    // then any dimensions binding to the right of the type.
    // a) start by finding the type context that will be wrapped.
    Java8Parser.UnannTypeContext unannTypeCtx = null;
    Java8Parser.UnannReferenceTypeContext unannReferenceTypeCtx = null;
    Java8Parser.UnannArrayTypeContext unannArrayTypeCtx = null;
    Java8Parser.DimsContext outerDimsCtx = null;
    ParserRuleContext typeCtx = null;
    if (declarationRuleIndex == Java8Parser.RULE_catchFormalParameter)
        typeCtx = declarationCtx.getChild(Java8Parser.CatchTypeContext.class, 0);
    else
        typeCtx = unannTypeCtx = declarationCtx.getChild(Java8Parser.UnannTypeContext.class, 0);
    if (null != unannTypeCtx)
        if (null != (unannReferenceTypeCtx = unannTypeCtx.unannReferenceType())
                && null != (unannArrayTypeCtx = unannReferenceTypeCtx.unannArrayType())) {
            typeCtx = unannArrayTypeCtx.getChild(ParserRuleContext.class, 0);
            outerDimsCtx = unannArrayTypeCtx.dims();
        }
    // b) process dimensions attached to declarator ids
    // ...process inside blocks below
    // c) process dimensions attached to type
    // ...process inside blocks below

    // Now insert unannTypeText at end of each variableDeclaratorId if necessary:
    ParserRuleContext ctx, varInitCtx;
    Java8Parser.VariableDeclaratorIdContext varIdCtx;
    Java8Parser.DimsContext innerDimsCtx = null;
    String unannTypeText;
    if (hasDeclaratorList) {
        // Iterate over the list of declarator-initialiser pairs backwards so that variable lists without
        // intialisers and with explicit enough types, just pick up the type from the end of the list, i.e.
        // so that we generate var a, b, c: Int, and not var a: Int, b: Int, c: Int.
        ListIterator<Java8Parser.VariableDeclaratorContext> iter;
        List<Java8Parser.VariableDeclaratorContext> list;
        String followingUnannTypeText = null;
        boolean followingVarHasExplicitType = false;
        boolean hasInitialiser;

        ctx = declarationCtx.getChild(Java8Parser.VariableDeclaratorListContext.class, 0);
        list = ctx.getRuleContexts(Java8Parser.VariableDeclaratorContext.class);
        iter = list.listIterator(list.size());
        unannTypeText = null;

        while (iter.hasPrevious()) {
            ctx = iter.previous();
            varIdCtx = ctx.getRuleContext(Java8Parser.VariableDeclaratorIdContext.class, 0);

            // Wrap the inner type string with array dimensions if we have them. Have to do this for each variable,
            // because they can have different dimensionality.
            followingUnannTypeText = unannTypeText;
            unannTypeText = rewriter.getText(typeCtx);
            if (null != (innerDimsCtx = varIdCtx.dims())) {
                unannTypeText = wrapTypeStringWithDims(unannTypeText, innerDimsCtx);
                rewriter.delete(innerDimsCtx);
            }
            if (null != outerDimsCtx)
                unannTypeText = wrapTypeStringWithDims(unannTypeText, outerDimsCtx);

            varInitCtx = ctx.getRuleContext(Java8Parser.VariableInitializerContext.class, 0);
            if (null != varInitCtx)
                varInitCtx = varInitCtx.getChild(ParserRuleContext.class, 0); // expression or arrayInitializer
            hasInitialiser = null != varInitCtx;

            // In the basic case, we have to qualify the variable with its type, but we can omit this if it has an
            // initialiser that completely implies the type, or it has no initialiser and has the same type as the
            // a contiguously following variable with explicit type.
            if (hasInitialiser
                    ? !isVariableTypeCompletelyImpliedByInitializer(unannTypeCtx, varInitCtx,
                            /*inEnhancedFor:*/false)
                    : !followingVarHasExplicitType || null == followingUnannTypeText
                            || !unannTypeText.equals(followingUnannTypeText)) {
                rewriter.insertAfter(varIdCtx, ": " + unannTypeText + (isOptional ? "?" : ""));
                followingVarHasExplicitType = !hasInitialiser;
            }
        }
    } else {
        varIdCtx = declarationCtx.getRuleContext(Java8Parser.VariableDeclaratorIdContext.class, 0);
        unannTypeText = rewriter.getText(typeCtx);
        if (null != (innerDimsCtx = varIdCtx.dims())) {
            unannTypeText = wrapTypeStringWithDims(unannTypeText, innerDimsCtx);
            rewriter.delete(innerDimsCtx);
        }
        if (null != outerDimsCtx)
            unannTypeText = wrapTypeStringWithDims(unannTypeText, outerDimsCtx);

        varInitCtx = null;
        if (declarationRuleIndex == Java8Parser.RULE_resource
                || declarationRuleIndex == Java8Parser.RULE_enhancedForStatement
                || declarationRuleIndex == Java8Parser.RULE_enhancedForStatementNoShortIf)
            varInitCtx = declarationCtx.getRuleContext(Java8Parser.ExpressionContext.class, 0);

        if (declarationRuleIndex == Java8Parser.RULE_catchFormalParameter)
            rewriter.insertAfter(varIdCtx, " as " + unannTypeText);
        else if (!isVariableTypeCompletelyImpliedByInitializer(unannTypeCtx, varInitCtx, enhancedFor))
            rewriter.insertAfter(varIdCtx, ": " + unannTypeText + (isOptional ? "?" : ""));

        // In parameter lists, add an anonymizing argument label, as argument labels not used in java method/function calls
        if (declarationRuleIndex == Java8Parser.RULE_formalParameter
                || declarationRuleIndex == Java8Parser.RULE_lastFormalParameter)
            rewriter.insertBefore(varIdCtx, "_ ");
    }

    // Finally replace the complete type context with let/var/-
    // in an enhancedForStatement, the loop var is implicitly const, but can be made variable with var if it is
    // to be modified inside the loop; we could check for this, but its a rare scenario, and a lot of work, so no.
    if (null != unannTypeCtx)
        typeCtx = unannTypeCtx;
    switch (constness) {
    case explicit:
        rewriter.replace(typeCtx, "let");
        break;
    case implicit:
        rewriter.deleteAndAdjustWhitespace(typeCtx);
        break;
    case variable:
        rewriter.replace(typeCtx, "var");
        break;
    // if still unknown, then assume variable...
    default:
        rewriter.replace(typeCtx, "var");
        break;
    }
}

From source file:com.satisfyingstructures.J2S.J2SConverter.java

License:Open Source License

@Override
public void exitExplicitConstructorInvocation(Java8Parser.ExplicitConstructorInvocationContext ctx) {
    TerminalNode tn;//from   ww w  .  ja v a  2  s .c o m
    if (null != (tn = ctx.getToken(Java8Parser.THIS, 0))) {
        //  'this' within explicit constructor invocation is calling sideways to another constructor, which implies we are a convenience constructor
        rewriter.replace(tn, "self.init");
        // put 'convenience' before type name in our constructor declarator
        ParserRuleContext context;
        if (null != (context = ctx.getParent())) // constructorBody
            if (null != (context = context.getParent())) // constructorDeclaration
                if (null != (context = context.getChild(Java8Parser.ConstructorDeclaratorContext.class, 0)))
                    if (null != (context = context.getChild(Java8Parser.SimpleTypeNameContext.class, 0)))
                        rewriter.insertBefore(context, "convenience ");
    } else if (null != (tn = ctx.getToken(Java8Parser.SUPER, 0))) {
        rewriter.replace(tn, "super.init");
    }
}

From source file:com.satisfyingstructures.J2S.J2SConverter.java

License:Open Source License

private void addBracesAroundStatementIfNecessary(ParserRuleContext ctx) {
    // Ensure the statement(s) with if(else), for, while and do is always wrapped in braces.
    // At the same time, remove the parentheses around the test/control part for the statement
    int statementRule = ctx.getRuleIndex();
    if (statementRule != Java8Parser.RULE_statement && statementRule != Java8Parser.RULE_statementNoShortIf)
        return; // not our expected parameter type
    ParserRuleContext parent = ctx.getParent();
    int parentRule = parent.getRuleIndex();
    switch (parentRule) {
    case Java8Parser.RULE_ifThenElseStatement:
    case Java8Parser.RULE_ifThenElseStatementNoShortIf: {
        // if this statement is an ifThen or an ifThenElse sitting within an ifThenElse, then 
        // check if it follows the else, because we don't wrap the trailing 'if' part of 'else if'
        int statementSubRule = ctx.getChild(ParserRuleContext.class, 0).getRuleIndex();
        if (statementSubRule == Java8Parser.RULE_ifThenStatement
                || statementSubRule == Java8Parser.RULE_ifThenElseStatement
                || statementSubRule == Java8Parser.RULE_ifThenElseStatementNoShortIf) {
            // the statement after else is the last child
            if (parent.getChild(parent.getChildCount() - 1) == ctx)
                break;
        }/*w  w w  . j a v  a2s . co  m*/
    }
    // fallthru
    case Java8Parser.RULE_ifThenStatement:
    case Java8Parser.RULE_basicForStatement:
    case Java8Parser.RULE_basicForStatementNoShortIf:
    case Java8Parser.RULE_enhancedForStatement:
    case Java8Parser.RULE_enhancedForStatementNoShortIf:
    case Java8Parser.RULE_whileStatement:
    case Java8Parser.RULE_whileStatementNoShortIf:
    case Java8Parser.RULE_doStatement:
        if (ctx.start.getType() != Java8Parser.LBRACE) {
            rewriter.insertBefore(ctx.start, "{ ");
            // rewriter.insertAfter( ctx.stop, " }" );
            // ...we don't insert, because it binds to the following token and we may need to change/modify it
            // higher up the stack. Instead, we replace the current content of the stop token. This is necessary
            // because the stop can be the end of more than one statement, e.g. last semicolon in...
            //  for(;;i++)
            //      if (i%7)
            //          break;
            // ...gets wrapped twice to give
            //  for(;;i++)
            //      { if (i%7)
            //          { break; } }
            String current = rewriter.getText(ctx.stop);
            rewriter.replace(ctx.stop, current + " }");
        }
        break;
    default:
        return;
    }

    // Remove the parentheses around the test/control part for the statement
    removeParenthesesAroundExpression(parent);
}

From source file:com.satisfyingstructures.J2S.J2SConverter.java

License:Open Source License

private boolean statementEndsWithSwitchExit(ParserRuleContext ctx) {
    ParserRuleContext subCtx = ctx;/*from   w w w .  j a va2  s  . c  om*/
    for (ctx = subCtx; ctx != null; ctx = subCtx) {
        switch (ctx.getRuleIndex()) {
        case Java8Parser.RULE_blockStatements:
            subCtx = ctx.getChild(Java8Parser.BlockStatementContext.class, ctx.getChildCount() - 1);
            continue;
        case Java8Parser.RULE_blockStatement:
            subCtx = ctx.getChild(ParserRuleContext.class, 0); // class or local var decl, or other statement
            continue;
        case Java8Parser.RULE_localVariableDeclarationStatement:
            return false;
        case Java8Parser.RULE_classDeclaration:
            return false;
        case Java8Parser.RULE_statement:
        case Java8Parser.RULE_statementNoShortIf:
            subCtx = ctx.getChild(ParserRuleContext.class, 0);
            continue;
        case Java8Parser.RULE_statementWithoutTrailingSubstatement:
            subCtx = ctx.getChild(ParserRuleContext.class, 0);
            continue;
        case Java8Parser.RULE_labeledStatement:
        case Java8Parser.RULE_labeledStatementNoShortIf:
            // Identifier ':' (statement|statementNoShortIf)
            // nodes 1 & 2 are terminal nodes; node 3 is first rule node
            subCtx = ctx.getChild(ParserRuleContext.class, 0);
            continue;
        case Java8Parser.RULE_breakStatement:
        case Java8Parser.RULE_continueStatement:
        case Java8Parser.RULE_returnStatement:
        case Java8Parser.RULE_throwStatement:
            return true;
        case Java8Parser.RULE_ifThenStatement:
            return false;
        case Java8Parser.RULE_ifThenElseStatement:
        case Java8Parser.RULE_ifThenElseStatementNoShortIf:
            // 'if' '(' expression ')' statementNoShortIf 'else' statement
            // if-statement is second rule node; else-statement is third rule node; others are terminal nodes
            return statementEndsWithSwitchExit(ctx.getChild(ParserRuleContext.class, 1))
                    && statementEndsWithSwitchExit(ctx.getChild(ParserRuleContext.class, 2));
        case Java8Parser.RULE_whileStatement:
        case Java8Parser.RULE_whileStatementNoShortIf:
        case Java8Parser.RULE_forStatement:
        case Java8Parser.RULE_forStatementNoShortIf:
        case Java8Parser.RULE_doStatement:
            // indeterminate: whether a nested exit is hit depends on data
            return false;
        case Java8Parser.RULE_block:
            // '{' blockStatements? '}'
            // ctx.getChildCount() counts both rule and terminal nodes; nbr of rule nodes is two less here;
            subCtx = ctx.getChild(ParserRuleContext.class, ctx.getChildCount() - 3);
            continue;
        case Java8Parser.RULE_emptyStatement:
        case Java8Parser.RULE_expressionStatement:
        case Java8Parser.RULE_assertStatement:
            return false;
        case Java8Parser.RULE_switchStatement:
            // too much work
            return false;
        case Java8Parser.RULE_synchronizedStatement:
            // 'synchronized' '(' expression ')' block
        case Java8Parser.RULE_tryStatement:
            // 'try' block catches | 'try' block catches? finally_ | tryWithResourcesStatement
            subCtx = ctx.getChild(Java8Parser.BlockContext.class, 0);
            continue;
        default:
            return false;
        }
    }
    return false;
}

From source file:com.satisfyingstructures.J2S.J2SGrammarUtils.java

License:Open Source License

public static ParserRuleContext descendToSignificantExpression(ParserRuleContext ctx) {
    // These expressions are chained by precedence in the grammar. We descend into the subrulecontexts until we
    // find a rule context that is significant, i.e. its not just a context with one child that is another
    // expression.
    // First validate parameter
    switch (ctx.getRuleIndex()) {
    case Java8Parser.RULE_constantExpression:
    case Java8Parser.RULE_expression:
    case Java8Parser.RULE_assignmentExpression:
    case Java8Parser.RULE_conditionalExpression:
    case Java8Parser.RULE_conditionalOrExpression:
    case Java8Parser.RULE_conditionalAndExpression:
    case Java8Parser.RULE_inclusiveOrExpression:
    case Java8Parser.RULE_exclusiveOrExpression:
    case Java8Parser.RULE_andExpression:
    case Java8Parser.RULE_equalityExpression:
    case Java8Parser.RULE_relationalExpression:
    case Java8Parser.RULE_shiftExpression:
    case Java8Parser.RULE_additiveExpression:
    case Java8Parser.RULE_multiplicativeExpression:
    case Java8Parser.RULE_unaryExpression:
    case Java8Parser.RULE_unaryExpressionNotPlusMinus:
    case Java8Parser.RULE_postfixExpression:
    case Java8Parser.RULE_primary:
    case Java8Parser.RULE_primaryNoNewArray_lfno_primary:
        break;/*from ww  w. j  a v  a2s.c o  m*/
    default:
        return ctx; // not an acceptable parameter type
    }
    descent: while (ctx.getChildCount() == 1) {
        ParserRuleContext childCtx = ctx.getChild(ParserRuleContext.class, 0);
        if (null == childCtx)
            break;
        switch (ctx.getRuleIndex()) {
        case Java8Parser.RULE_unaryExpression:
            if (childCtx.getRuleIndex() != Java8Parser.RULE_unaryExpressionNotPlusMinus)
                break descent;
        case Java8Parser.RULE_unaryExpressionNotPlusMinus:
            if (childCtx.getRuleIndex() != Java8Parser.RULE_postfixExpression)
                break descent;
        case Java8Parser.RULE_postfixExpression:
            if (childCtx.getRuleIndex() != Java8Parser.RULE_primary)
                break descent;
        }
        ctx = childCtx;
    }
    return ctx;
}