Example usage for org.eclipse.jdt.core.dom Expression getParent

List of usage examples for org.eclipse.jdt.core.dom Expression getParent

Introduction

In this page you can find the example usage for org.eclipse.jdt.core.dom Expression getParent.

Prototype

public final ASTNode getParent() 

Source Link

Document

Returns this node's parent node, or null if this is the root node.

Usage

From source file:com.google.devtools.j2cpp.gen.CppStatementGenerator.java

License:Open Source License

private boolean hasNilCheckParent(Expression e, IVariableBinding sym) {
    ASTNode parent = e.getParent();
    while (parent != null) {
        if (parent instanceof IfStatement) {
            Expression condition = ((IfStatement) parent).getExpression();
            if (condition instanceof InfixExpression) {
                InfixExpression infix = (InfixExpression) condition;
                IBinding lhs = Types.getBinding(infix.getLeftOperand());
                if (lhs != null && infix.getRightOperand() instanceof NullLiteral) {
                    return sym.isEqualTo(lhs);
                }/*from   w ww  .j a v  a2 s  . c o  m*/
                IBinding rhs = Types.getBinding(infix.getRightOperand());
                if (rhs != null && infix.getLeftOperand() instanceof NullLiteral) {
                    return sym.isEqualTo(rhs);
                }
            }
        }
        parent = parent.getParent();
        if (parent instanceof MethodDeclaration) {
            break;
        }
    }
    return false;
}

From source file:com.google.devtools.j2cpp.gen.CppStatementGenerator.java

License:Open Source License

private boolean printAssignmentLhs(Expression lhs) {
    boolean needClosingParen = false;

    if (Options.inlineFieldAccess()) {
        // Inline the setter for a property.
        IVariableBinding var = Types.getVariableBinding(lhs);
        ITypeBinding type = Types.getTypeBinding(lhs);
        if (Options.useReferenceCounting() && !type.isPrimitive() && lhs instanceof SimpleName
                && isProperty((SimpleName) lhs) && !isNewAssignment(lhs.getParent())
                && !Types.hasWeakAnnotation(var.getDeclaringClass())) {
            String name = NameTable.getName((SimpleName) lhs);
            String nativeName = NameTable.javaFieldToCpp(name);
            buffer.append(String.format("([%s autorelease], ", nativeName));
            needClosingParen = true;//  ww  w.  j av  a2s  .c om
        }
    }

    lhs.accept(this);
    return needClosingParen;
}

From source file:com.google.gdt.eclipse.designer.nls.GwtSource.java

License:Open Source License

@Override
protected Expression apply_renameKey_replaceKeyExpression(AstEditor editor, Expression keyExpression,
        String newKey) throws Exception {
    editor.replaceInvocationName((MethodInvocation) keyExpression.getParent(), newKey);
    return keyExpression;
}

From source file:com.kodebeagle.javaparser.MethodInvocationResolver.java

License:Apache License

/**
 * If the passed node is a method invocation or class creation then return the
 * return type of the method based on what is the returned value assigned to.
 *
 * @param node/*w  w w . j a va2 s  . c o  m*/
 * @return return type
 */
private String getReturnType(Expression node) {
    ASTNode parent = node.getParent();
    if (parent instanceof VariableDeclarationFragment) {
        ASTNode grandParent = parent.getParent();
        if (grandParent instanceof VariableDeclarationStatement) {
            Type typ = ((VariableDeclarationStatement) grandParent).getType();
            return removeSpecialSymbols(getFullyQualifiedNameFor(typ.toString()));
        }
    }
    return null;
}

From source file:edu.cmu.cs.crystal.tac.eclipse.EclipseTACInstructionFactory.java

License:Open Source License

private boolean isLoad(Expression node) {
    if (node.getParent() instanceof Assignment) {
        Assignment parent = (Assignment) node.getParent();
        if (parent.getLeftHandSide() != node)
            return true;
        // node is on the left
        // it's still a load if this is += or something like that.
        return Assignment.Operator.ASSIGN.equals(parent.getOperator()) == false;
    } else if ((node.getParent() instanceof VariableDeclaration)
            && (((VariableDeclaration) node.getParent()).getName() == node))
        // node is the name of a declaration --> not a load but a store
        return false;
    else/*from   w  w w.  j a  va  2  s.c o m*/
        return true;
}

From source file:org.autorefactor.refactoring.rules.VectorOldToNewAPIRefactoring.java

License:Open Source License

private boolean replaceWithAndSwapArguments(MethodInvocation node, String newMethodName) {
    final List<Expression> args = arguments(node);
    assertSize(args, 2);/*from  w  ww . jav a2  s.co m*/
    final Expression arg1 = args.get(1);

    final ASTBuilder b = this.ctx.getASTBuilder();
    final Refactorings r = this.ctx.getRefactorings();
    r.set(node, NAME_PROPERTY, b.simpleName(newMethodName));
    r.insertAt(b.move(arg1), 0, arg1.getLocationInParent(), arg1.getParent());
    return DO_NOT_VISIT_SUBTREE;
}

From source file:org.decojer.cavaj.transformers.TrExpressions.java

License:Open Source License

private boolean transformOperations(@Nonnull final BB bb) {
    while (bb.getOps() > 0) {
        if (isStackUnderflow(bb)) {
            if (!mitigateStackUnderflow(bb)) {
                return false;
            }//w ww  .  j av a2  s  .  c o m
            if (bb.isRemoved()) {
                // is also a possible form of stack underflow mitigation
                return true;
            }
            // something has been mitigated...may be not to the full extend, try again
            continue;
        }
        final Op op = bb.removeOp(0);
        switch (op.getOptype()) {
        case ADD: {
            bb.push(newInfixExpressionPop(InfixExpression.Operator.PLUS, bb, op));
            break;
        }
        case ALOAD: {
            final ArrayAccess arrayAccess = setOp(getAst().newArrayAccess(), op);
            arrayAccess.setIndex(wrap(bb.pop()));
            arrayAccess.setArray(wrap(bb.pop(), Priority.ARRAY_INDEX));
            bb.push(arrayAccess);
            break;
        }
        case AND: {
            bb.push(newInfixExpressionPop(InfixExpression.Operator.AND, bb, op));
            break;
        }
        case ARRAYLENGTH: {
            final Expression expression = bb.pop();
            if (expression instanceof Name) {
                // annotationsVisible.length
                bb.push(setOp(
                        getAst().newQualifiedName((Name) wrap(expression), getAst().newSimpleName("length")),
                        op));
                break;
            }
            // FieldAccess or MethodInvocation:
            // this.code.length, getInterfaces().length
            final FieldAccess fieldAccess = setOp(getAst().newFieldAccess(), op);
            fieldAccess.setExpression(wrap(expression, Priority.MEMBER_ACCESS));
            fieldAccess.setName(getAst().newSimpleName("length"));
            bb.push(fieldAccess);
            break;
        }
        case ASTORE: {
            final Expression rightOperand = bb.pop();
            final Expression indexExpression = bb.pop();
            final Expression arrayRefExpression = bb.pop();
            if (arrayRefExpression instanceof ArrayCreation) {
                final ArrayCreation arrayCreation = (ArrayCreation) arrayRefExpression;
                ArrayInitializer arrayInitializer = arrayCreation.getInitializer();
                if (arrayInitializer == null) {
                    arrayInitializer = setOp(getAst().newArrayInitializer(), op);
                    arrayCreation.setInitializer(arrayInitializer);
                    // TODO for higher performance and for full array creation removement we
                    // could defer the 0-fill and rewrite to the final A/STORE phase
                    final Object sizeExpression = arrayCreation.dimensions().get(0);
                    final Number size = sizeExpression instanceof Expression
                            ? getNumberValue((Expression) sizeExpression)
                            : null;
                    assert size != null;
                    final T t = peekT(op);
                    assert t != null;
                    // not all indexes may be set, null/0/false in JVM 7 are not set, fill
                    for (int i = size.intValue(); i-- > 0;) {
                        arrayInitializer.expressions().add(newLiteral(t, null, getM(), op));
                    }
                    arrayCreation.dimensions().clear();
                }
                final Number numberValue = getNumberValue(indexExpression);
                assert numberValue != null;
                arrayInitializer.expressions().set(numberValue.intValue(), wrap(rightOperand));
                break;
            }
            final ArrayAccess arrayAccess = setOp(getAst().newArrayAccess(), op);
            arrayAccess.setArray(wrap(arrayRefExpression, Priority.ARRAY_INDEX));
            arrayAccess.setIndex(wrap(indexExpression));
            final Assignment assignment = newAssignment(Assignment.Operator.ASSIGN, arrayAccess, rightOperand,
                    op);
            // TODO a = a +/- 1 => a++ / a--
            // TODO a = a <op> expr => a <op>= expr
            // inline assignment, DUP(_X1) -> PUT
            if (!bb.isStackEmpty() && bb.peek() == rightOperand) {
                bb.pop();
                bb.push(assignment);
                break;
            }
            bb.addStmt(setOp(getAst().newExpressionStatement(assignment), op));
            break;
        }
        case CAST: {
            final CAST cop = (CAST) op;
            final CastExpression castExpression = setOp(getAst().newCastExpression(), op);
            castExpression.setType(newType(cop.getToT(), getM()));
            castExpression.setExpression(wrap(bb.pop(), Priority.TYPE_CAST));
            bb.push(castExpression);
            break;
        }
        case CMP: {
            // pseudo expression for following JCND, not really the correct
            // answer for -1, 0, 1
            bb.push(newInfixExpressionPop(InfixExpression.Operator.LESS_EQUALS, bb, op));
            break;
        }
        case DIV: {
            bb.push(newInfixExpressionPop(InfixExpression.Operator.DIVIDE, bb, op));
            break;
        }
        case DUP: {
            final DUP cop = (DUP) op;
            switch (cop.getKind()) {
            // for all following variants: don't change op without copying!
            case DUP:
                bb.push(bb.peek());
                break;
            case DUP_X1: {
                final Expression e1 = bb.pop();
                final Expression e2 = bb.pop();
                bb.push(e1);
                bb.push(e2);
                bb.push(e1);
                break;
            }
            case DUP_X2: {
                final Expression e1 = bb.pop();
                final Expression e2 = bb.pop();
                if (!isWide(e2)) {
                    final Expression e3 = bb.pop();
                    bb.push(e1);
                    bb.push(e3);
                    bb.push(e2);
                    bb.push(e1);
                    break;
                }
                bb.push(e1);
                bb.push(e2);
                bb.push(e1);
                break;
            }
            case DUP2: {
                final Expression e1 = bb.peek();
                if (!isWide(e1)) {
                    final Expression e2 = bb.peek(1);
                    bb.push(e2);
                    bb.push(e1);
                    break;
                }
                bb.push(e1);
                break;
            }
            case DUP2_X1: {
                final Expression e1 = bb.pop();
                if (!isWide(e1)) {
                    final Expression e2 = bb.pop();
                    final Expression e3 = bb.pop();
                    bb.push(e2);
                    bb.push(e1);
                    bb.push(e3);
                    bb.push(e2);
                    bb.push(e1);
                    break;
                }
                final Expression e3 = bb.pop();
                bb.push(e1);
                bb.push(e3);
                bb.push(e1);
                break;
            }
            case DUP2_X2: {
                final Expression e1 = bb.pop();
                if (!isWide(e1)) {
                    final Expression e2 = bb.pop();
                    final Expression e3 = bb.pop();
                    if (!isWide(e3)) {
                        final Expression e4 = bb.pop();
                        bb.push(e2);
                        bb.push(e1);
                        bb.push(e4);
                        bb.push(e3);
                        bb.push(e2);
                        bb.push(e1);
                        break;
                    }
                    bb.push(e2);
                    bb.push(e1);
                    bb.push(e3);
                    bb.push(e2);
                    bb.push(e1);
                    break;
                }
                final Expression e3 = bb.pop();
                if (!isWide(e3)) {
                    final Expression e4 = bb.pop();
                    bb.push(e1);
                    bb.push(e4);
                    bb.push(e3);
                    bb.push(e1);
                    break;
                }
                bb.push(e1);
                bb.push(e3);
                bb.push(e1);
                break;
            }
            default:
                log.warn(getM() + ": Unknown DUP type '" + cop.getKind() + "'!");
            }
            break;
        }
        case FILLARRAY: {
            final FILLARRAY cop = (FILLARRAY) op;
            final T t = peekT(op);
            final T componentT = t.getComponentT();
            assert componentT != null;

            Expression expression = bb.pop();
            if (!(expression instanceof ArrayCreation)) {
                // LOAD 0, NEWARRAY, STORE 0, LOAD 0, FILLARRAY <end>
                // TODO Dalvik: if STORE x / LOAD x are compressed then we shouldn't need this:
                expression = setOp(getAst().newArrayCreation(), op);
                ((ArrayCreation) expression).setType((ArrayType) newType(t, getM()));
            }
            final ArrayInitializer arrayInitializer = setOp(getAst().newArrayInitializer(), op);
            final Object[] values = cop.getValues();
            assert values != null;
            for (final Object value : values) {
                arrayInitializer.expressions().add(newLiteral(componentT, value, getM(), op));
            }
            ((ArrayCreation) expression).setInitializer(arrayInitializer);

            bb.push(expression);
            break;
        }
        case GET: {
            final GET cop = (GET) op;
            if (rewriteCachedClassLiteral(bb, cop)) {
                break;
            }
            final F f = cop.getF();
            if (f.isStatic()) {
                // Eclipse AST expects a Name for f.getT(), not a Type:
                // is OK - f.getT() cannot be generic
                bb.push(setOp(getAst().newQualifiedName(newTypeName(f.getT(), getM()),
                        newSimpleName(f.getName(), getAst())), op));
                break;
            }
            final FieldAccess fieldAccess = setOp(getAst().newFieldAccess(), op);
            fieldAccess.setExpression(wrap(bb.pop(), Priority.MEMBER_ACCESS));
            fieldAccess.setName(newSimpleName(f.getName(), getAst()));
            bb.push(fieldAccess);
            break;
        }
        case GOTO: {
            // not really necessary, but important for
            // 1) correct opPc blocks
            // 2) line numbers

            // TODO put line number anywhere?
            // remember as pseudo statement? but problem with boolean ops
            break;
        }
        case INC: {
            final INC cop = (INC) op;
            final int value = cop.getValue();
            if (value == 1 || value == -1) {
                // ++ / --
                if (rewriteInlinePrefixIncDec(bb, cop) || rewriteInlinePostfixIncDec(bb, cop)) {
                    break;
                }
                if (bb.isStackEmpty()) {
                    bb.addStmt(setOp(getAst().newExpressionStatement(newPrefixExpression(
                            cop.getValue() == 1 ? PrefixExpression.Operator.INCREMENT
                                    : PrefixExpression.Operator.DECREMENT,
                            getVarExpression(cop.getReg(), cop.getPc(), op), op)), op));
                    break;
                }
                log.warn(getM() + ": Inline ++/--!");
                break;
            }
            if (rewriteInlineRegAssignment(bb, cop)) {
                break;
            }
            if (bb.isStackEmpty()) {
                bb.addStmt(setOp(
                        getAst().newExpressionStatement(newAssignment(
                                value >= 0 ? Assignment.Operator.PLUS_ASSIGN : Assignment.Operator.MINUS_ASSIGN,
                                getVarExpression(cop.getReg(), cop.getPc(), op),
                                newLiteral(cop.getT(), value >= 0 ? value : -value, getCfg().getM(), op), op)),
                        op));
                break;
            }
            log.warn(getM() + ": Inline INC with value '" + value + "'!");
            break;
        }
        case INSTANCEOF: {
            final INSTANCEOF cop = (INSTANCEOF) op;
            final InstanceofExpression instanceofExpression = setOp(getAst().newInstanceofExpression(), op);
            instanceofExpression.setLeftOperand(wrap(bb.pop(), Priority.INSTANCEOF));
            instanceofExpression.setRightOperand(newType(cop.getT(), getM()));
            bb.push(instanceofExpression);
            break;
        }
        case INVOKE: {
            final INVOKE cop = (INVOKE) op;
            final M m = cop.getM();

            // read method invokation arguments, handle varargs
            final List<Expression> arguments = Lists.newArrayList();
            final int params = m.getParamTs().length;
            if (params > 0) {
                if (m.isVarargs()) {
                    final Expression array = bb.pop();
                    if (array instanceof ArrayCreation) {
                        final ArrayInitializer initializer = ((ArrayCreation) array).getInitializer();
                        if (initializer != null) {
                            for (final Expression e : (List<Expression>) initializer.expressions()) {
                                // wrap() in addAll(), DUP could happen with receiver & argument
                                arguments.add(e);
                            }
                            Collections.reverse(arguments);
                        }
                    } else {
                        // can happen if forwarded as variable
                        arguments.add(array);
                    }
                } else {
                    arguments.add(bb.pop());
                }
                // now add remaining parameters that cannot be varargs
                for (int i = params - 1; i-- > 0;) {
                    arguments.add(bb.pop());
                }
                Collections.reverse(arguments);
            }

            final Expression methodExpression;
            if (cop.isDirect()) {
                final Expression expression = bb.pop();
                if (m.isConstructor()) {
                    methodExpression = null;
                    final T ownerT = m.getT();
                    if (expression instanceof ThisExpression) {
                        enumConstructor: if (ownerT != null && ownerT.is(Enum.class)
                                && !getCfg().getCu().check(DFlag.IGNORE_ENUM)) {
                            if (arguments.size() < 2) {
                                log.warn(getM() + ": Super constructor invocation '" + m
                                        + "' for enum has less than 2 arguments!");
                                break enumConstructor;
                            }
                            if (!m.getParamTs()[0].is(String.class)) {
                                log.warn(getM() + ": Super constructor invocation '" + m
                                        + "' for enum must contain string literal as first parameter!");
                                break enumConstructor;
                            }
                            if (m.getParamTs()[1] != T.INT) {
                                log.warn(getM() + ": Super constructor invocation '" + m
                                        + "' for enum must contain number literal as first parameter!");
                                break enumConstructor;
                            }
                            arguments.remove(0);
                            arguments.remove(0);
                        }
                        if (ownerT != null && ownerT.is(getCfg().getT())) {
                            final ConstructorInvocation constructorInvocation = getAst()
                                    .newConstructorInvocation();
                            wrapAddAll(constructorInvocation.arguments(), arguments);
                            bb.addStmt(setOp(constructorInvocation, op));
                            break;
                        }
                        if (arguments.size() == 0) {
                            // implicit super callout, more checks possible but not necessary
                            break;
                        }
                        final SuperConstructorInvocation superConstructorInvocation = getAst()
                                .newSuperConstructorInvocation();
                        wrapAddAll(superConstructorInvocation.arguments(), arguments);
                        bb.addStmt(setOp(superConstructorInvocation, op));
                        break;
                    }
                    if (expression instanceof ClassInstanceCreation) {
                        if (ownerT != null && ownerT.isInner()
                                && !getCfg().getCu().check(DFlag.IGNORE_CONSTRUCTOR_THIS)) {
                            // inner class constructor invocation has synthetic this reference
                            // as first argument: remove
                            if (arguments.size() == 0) {
                                log.warn(getM()
                                        + ": Inner class constructor invocation has no synthetic this reference as first argument! No arguments given.");
                            } else if (!(arguments.get(0) instanceof ThisExpression)) {
                                log.warn(getM()
                                        + ": Inner class constructor invocation has no synthetic this reference as first argument! Wrong first argument: "
                                        + arguments.get(0));
                            } else {
                                arguments.remove(0);
                            }
                        }
                        wrapAddAll(((ClassInstanceCreation) expression).arguments(), arguments);
                        // normally there was a DUP in advance, don't use:
                        // basicBlock.pushExpression(classInstanceCreation);
                        break;
                    }
                    log.warn(getM()
                            + ": Constructor expects expression class 'ThisExpression' or 'ClassInstanceCreation' but is '"
                            + expression.getClass() + "' with value: " + expression);
                    break;
                }
                if (expression instanceof ThisExpression && !m.getAf(AF.PRIVATE)) {
                    final SuperMethodInvocation superMethodInvocation = getAst().newSuperMethodInvocation();
                    superMethodInvocation.setName(newSimpleName(m.getName(), getAst()));
                    wrapAddAll(superMethodInvocation.arguments(), arguments);
                    methodExpression = superMethodInvocation;
                } else {
                    // could be private method call in same object, nothing special in syntax,
                    // just used together with "this."
                    final MethodInvocation methodInvocation = getAst().newMethodInvocation();
                    methodInvocation.setExpression(wrap(expression, Priority.METHOD_CALL));
                    methodInvocation.setName(newSimpleName(m.getName(), getAst()));
                    wrapAddAll(methodInvocation.arguments(), arguments);
                    methodExpression = methodInvocation;
                }
            } else if (m.isDynamic()) {
                final Object[] bsArgs = cop.getBsArgs();
                if (isLambdaBootstrapMethod(cop.getBsM()) && bsArgs != null && bsArgs.length > 1
                        && bsArgs[1] instanceof M) {
                    final M dynamicM = (M) bsArgs[1];
                    if (dynamicM.isSynthetic()) {
                        // is lambda
                        final LambdaExpression lambdaExpression = getAst().newLambdaExpression();
                        // init lambda parameters
                        final T[] paramTs = dynamicM.getParamTs();
                        final A[][] paramAss = dynamicM.getParamAss();
                        // first m.paramTs.length parameters are for outer capture inits
                        for (int i = m.getParamTs().length; i < paramTs.length; ++i) {
                            lambdaExpression.parameters().add(newSingleVariableDeclaration(dynamicM, paramTs,
                                    paramAss, i, this.cfg.getT()));
                        }
                        // init lambda body
                        final CFG lambdaCfg = dynamicM.getCfg();
                        assert lambdaCfg != null;
                        if (lambdaCfg.getBlock() == null) {
                            // if synthetics are not decompiled...
                            // lambda methods are synthetic: init block, could later add more
                            // checks and alternatives here if obfuscators play with these flags
                            lambdaCfg.setBlock((Block) lambdaExpression.getBody());
                            lambdaCfg.decompile();
                        } else if (lambdaCfg.getBlock().getParent() instanceof MethodDeclaration) {
                            // if synthetics are decompiled...but not for re-decompilation:
                            // don't show this recognized (normally synthetic) method
                            // declaration
                            lambdaCfg.getBlock().delete(); // delete from parent
                            dynamicM.setAstNode(null);
                            // is our new lambda body
                            lambdaExpression.setBody(lambdaCfg.getBlock());
                        }
                        methodExpression = lambdaExpression;
                    } else {
                        // is a method reference, 4 different variants possible
                        if (dynamicM.isConstructor()) {
                            final CreationReference methodReference = getAst().newCreationReference();
                            final T ownerT = dynamicM.getT();
                            assert ownerT != null;
                            methodReference.setType(newType(ownerT, getM()));
                            methodExpression = methodReference;
                        } else if (dynamicM.isStatic()) {
                            final TypeMethodReference methodReference = getAst().newTypeMethodReference();
                            final T ownerT = dynamicM.getT();
                            assert ownerT != null;
                            methodReference.setType(newType(ownerT, getM()));
                            methodReference.setName(newSimpleName(dynamicM.getName(), getAst()));
                            methodExpression = methodReference;
                        } else {
                            assert arguments
                                    .size() == 1 : "expression method reference doesn't have 1 argument";

                            final ExpressionMethodReference methodReference = getAst()
                                    .newExpressionMethodReference();
                            methodReference.setExpression(arguments.get(0));
                            methodReference.setName(newSimpleName(dynamicM.getName(), getAst()));
                            methodExpression = methodReference;
                        }
                        // TODO is in bytecode via lambda, we could let it be or recognize this
                        // pattern and shorten down to getAst().newSuperMethodReference();
                    }
                } else {
                    final MethodInvocation methodInvocation = getAst().newMethodInvocation();
                    methodInvocation.setName(newSimpleName(m.getName(), getAst()));
                    wrapAddAll(methodInvocation.arguments(), arguments);
                    methodExpression = methodInvocation;
                }
            } else if (m.isStatic()) {
                final MethodInvocation methodInvocation = getAst().newMethodInvocation();
                methodInvocation.setExpression(newTypeName(m.getT(), getM()));
                methodInvocation.setName(newSimpleName(m.getName(), getAst()));
                wrapAddAll(methodInvocation.arguments(), arguments);
                methodExpression = methodInvocation;
            } else {
                if (rewriteStringAppend(bb, cop)) {
                    break;
                }
                final MethodInvocation methodInvocation = getAst().newMethodInvocation();
                final Expression expression = bb.pop();
                // TODO need this for switch(this.ordinal) rewrites, delete later?
                // if (!(expression instanceof ThisExpression)) {
                methodInvocation.setExpression(wrap(expression, Priority.METHOD_CALL));
                // }
                methodInvocation.setName(newSimpleName(m.getName(), getAst()));
                wrapAddAll(methodInvocation.arguments(), arguments);
                methodExpression = methodInvocation;
            }
            setOp(methodExpression, op);
            final T returnT = m.getReturnT();
            if (returnT == T.VOID) {
                bb.addStmt(setOp(setOp(getAst().newExpressionStatement(methodExpression), op), op));
                break;
            }
            assert methodExpression != null;
            bb.push(methodExpression);
            break;
        }
        case JCMP: {
            final JCMP cop = (JCMP) op;
            // invert all operators and switch out edge predicates
            final InfixExpression.Operator operator;
            switch (cop.getCmpType()) {
            case T_EQ:
                operator = InfixExpression.Operator.EQUALS;
                break;
            case T_GE:
                operator = InfixExpression.Operator.GREATER_EQUALS;
                break;
            case T_GT:
                operator = InfixExpression.Operator.GREATER;
                break;
            case T_LE:
                operator = InfixExpression.Operator.LESS_EQUALS;
                break;
            case T_LT:
                operator = InfixExpression.Operator.LESS;
                break;
            case T_NE:
                operator = InfixExpression.Operator.NOT_EQUALS;
                break;
            default:
                log.warn(getM() + ": Unknown cmp type '" + cop.getCmpType() + "'!");
                operator = null;
            }
            final IfStatement ifStatement = getAst().newIfStatement();
            ifStatement.setExpression(newInfixExpressionPop(operator, bb, op));
            bb.addStmt(setOp(ifStatement, op));
            break;
        }
        case JCND: {
            final JCND cop = (JCND) op;
            Expression expression = bb.pop();
            // check preceding CMP
            if (expression instanceof InfixExpression
                    && ((InfixExpression) expression).getOperator() == InfixExpression.Operator.LESS_EQUALS) {
                // preceding compare expression (CMP result: -1 / 0 / 1)
                final InfixExpression.Operator operator;
                switch (cop.getCmpType()) {
                case T_EQ:
                    operator = InfixExpression.Operator.EQUALS;
                    break;
                case T_GE:
                    operator = InfixExpression.Operator.GREATER_EQUALS;
                    break;
                case T_GT:
                    operator = InfixExpression.Operator.GREATER;
                    break;
                case T_LE:
                    operator = InfixExpression.Operator.LESS_EQUALS;
                    break;
                case T_LT:
                    operator = InfixExpression.Operator.LESS;
                    break;
                case T_NE:
                    operator = InfixExpression.Operator.NOT_EQUALS;
                    break;
                default:
                    log.warn(getM() + ": Unknown cmp type '" + cop.getCmpType() + "'!");
                    operator = null;
                }
                ((InfixExpression) expression).setOperator(operator);
            } else if (peekT(op).isRef()) {
                final InfixExpression.Operator operator;
                switch (cop.getCmpType()) {
                case T_EQ:
                    operator = InfixExpression.Operator.EQUALS;
                    break;
                case T_NE:
                    operator = InfixExpression.Operator.NOT_EQUALS;
                    break;
                default:
                    log.warn(getM() + ": Unknown cmp type '" + cop.getCmpType() + "' for null-expression!");
                    operator = null;
                }
                expression = newInfixExpression(operator, expression, newLiteral(T.REF, null, getM(), op), op);
            } else if (peekT(op).is(T.BOOLEAN)) {
                // "!a" or "a == 0"?
                switch (cop.getCmpType()) {
                case T_EQ:
                    // "== 0" means "is false"
                    expression = not(expression);
                    break;
                case T_NE:
                    // "!= 0" means "is true"
                    break;
                default:
                    log.warn(getM() + ": Unknown cmp type '" + cop.getCmpType() + "' for boolean expression '"
                            + expression + "'!");
                }
            } else {
                final InfixExpression.Operator operator;
                switch (cop.getCmpType()) {
                case T_EQ:
                    operator = InfixExpression.Operator.EQUALS;
                    break;
                case T_GE:
                    operator = InfixExpression.Operator.GREATER_EQUALS;
                    break;
                case T_GT:
                    operator = InfixExpression.Operator.GREATER;
                    break;
                case T_LE:
                    operator = InfixExpression.Operator.LESS_EQUALS;
                    break;
                case T_LT:
                    operator = InfixExpression.Operator.LESS;
                    break;
                case T_NE:
                    operator = InfixExpression.Operator.NOT_EQUALS;
                    break;
                default:
                    log.warn(getM() + ": Unknown cmp type '" + cop.getCmpType() + "' for 0-expression!");
                    operator = null;
                }
                expression = newInfixExpression(operator, expression, newLiteral(T.INT, 0, getM(), op), op);
            }
            final IfStatement ifStatement = getAst().newIfStatement();
            ifStatement.setExpression(wrap(expression));
            bb.addStmt(setOp(ifStatement, op));
            break;
        }
        case JSR: {
            // <finally> till JVM 6 (50), we don't really push something at the sub BB, we
            // rewrite this or catch the stack underflow for the STORE
            break;
        }
        case LOAD: {
            final LOAD cop = (LOAD) op;
            /*
             * final V v = getCfg().getFrameVar(cop.getReg(), cop.getPc()); if (v == null ||
             * v.getName() == null) { // temporary local final Expression expression =
             * bb.get(cop.getReg()); if (expression != null) { bb.push(bb.get(cop.getReg()));
             * break; } }
             */

            // must not access method parameters for fieldInits...
            fieldInitCheck: if (isFieldInit()) {
                if (!getM().isConstructor()) {
                    setFieldInit(false);
                    break fieldInitCheck;
                }
                final R r = getCfg().getInFrame(op).load(cop.getReg());
                if (r == null) {
                    break fieldInitCheck;
                }
                if (!r.isMethodParam()) {
                    setFieldInit(false);
                    break fieldInitCheck;
                }
                if (cop.getReg() == 0) {
                    break fieldInitCheck; // this
                }
                // only synthetic parameters are allowed
                final T ownerT = getM().getT();
                if (ownerT != null && ownerT.isInner()
                        && !getCfg().getCu().check(DFlag.IGNORE_CONSTRUCTOR_THIS)) {
                    if (cop.getReg() == 1 && r.getT().is(getM().getParamTs()[0])) {
                        break fieldInitCheck;
                    }
                }
                setFieldInit(false);
            }
            bb.push(getVarExpression(cop.getReg(), cop.getPc(), op));
            break;
        }
        case MONITOR: {
            final MONITOR cop = (MONITOR) op;

            switch (cop.getKind()) {
            case ENTER: {
                final SynchronizedStatement synchronizedStatement = setOp(getAst().newSynchronizedStatement(),
                        op);
                synchronizedStatement.setExpression(wrap(bb.pop()));
                bb.addStmt(setOp(synchronizedStatement, op));
                break;
            }
            case EXIT: {
                // for now: same as ENTER, blocks don't work here,
                // use getOp() to distinguish in control flow analysis
                final SynchronizedStatement synchronizedStatement = setOp(getAst().newSynchronizedStatement(),
                        op);
                synchronizedStatement.setExpression(wrap(bb.pop()));
                bb.addStmt(setOp(synchronizedStatement, op));
                break;
            }
            default:
                log.warn(getM() + ": Unknown monitor kind '" + cop.getKind() + "'!");
            }
            break;
        }
        case MUL: {
            bb.push(newInfixExpressionPop(InfixExpression.Operator.TIMES, bb, op));
            break;
        }
        case NEG: {
            bb.push(newPrefixExpression(PrefixExpression.Operator.MINUS, bb.pop(), op));
            break;
        }
        case NEW: {
            final NEW cop = (NEW) op;

            final ClassInstanceCreation classInstanceCreation = setOp(getAst().newClassInstanceCreation(), op);

            final String thisName = getCfg().getT().getName();
            final T newT = cop.getT();
            final String newName = newT.getName();
            // check for valid inner anonymous
            anonymous: if (newT.validateQualifierName(thisName)) {
                try {
                    // anonymous classes typically use a number postfix, try it
                    Integer.parseInt(newName.substring(thisName.length() + 1));

                    if (newT.isDeclaration()) {
                        // anonymous inner can only have a single interface
                        // (with generic super "Object") or a super class
                        final T[] interfaceTs = newT.getInterfaceTs();
                        switch (interfaceTs.length) {
                        case 0: {
                            final T superT = newT.getSuperT();
                            assert superT != null;
                            classInstanceCreation.setType(newType(superT, getM()));
                            break;
                        }
                        case 1: {
                            final T interfaceT = interfaceTs[0];
                            assert interfaceT != null;
                            classInstanceCreation.setType(newType(interfaceT, getM()));
                            break;
                        }
                        default:
                            break anonymous;
                        }
                        final AnonymousClassDeclaration anonymousClassDeclaration = setOp(
                                getAst().newAnonymousClassDeclaration(), op);
                        newT.setAstNode(anonymousClassDeclaration);
                        classInstanceCreation.setAnonymousClassDeclaration(anonymousClassDeclaration);
                        bb.push(classInstanceCreation);
                        break;
                    }
                } catch (final NumberFormatException e) {
                    // no int
                }
            }
            classInstanceCreation.setType(newType(newT, getM()));
            bb.push(classInstanceCreation);
            break;
        }
        case NEWARRAY: {
            final NEWARRAY cop = (NEWARRAY) op;
            final ArrayCreation arrayCreation = setOp(getAst().newArrayCreation(), op);
            arrayCreation.setType((ArrayType) newType(cop.getT(), getM()));
            for (int i = cop.getDimensions(); i-- > 0;) {
                arrayCreation.dimensions().add(0, wrap(bb.pop()));
            }
            bb.push(arrayCreation);
            break;
        }
        case OR: {
            bb.push(newInfixExpressionPop(InfixExpression.Operator.OR, bb, op));
            break;
        }
        case POP: {
            final POP cop = (POP) op;
            switch (cop.getKind()) {
            case POP2: {
                final Expression e = bb.pop();
                if (Expressions.isStatementExpression(e)) {
                    bb.addStmt(setOp(getAst().newExpressionStatement(wrap(e)), op));
                } else if (e instanceof SimpleName) {
                    // exception or simple literal
                    break;
                } else if (isBoolean(e) && !(e instanceof BooleanLiteral)) {
                    if (getCfg().getT().isAtLeast(Version.JVM_4)) {
                        log.warn(getM() + ": Boolean expression POP in '" + cop
                                + "' for >= JVM 5 code! Rewriting to empty if.");
                    }
                    final IfStatement ifStatement = getAst().newIfStatement();
                    ifStatement.setExpression(wrap(e));
                    ifStatement.setThenStatement(getAst().newEmptyStatement());
                    bb.addStmt(setOp(ifStatement, op));
                }
                if (isWide(e)) {
                    break;
                }
                // fall through for second pop iff none-wide
            }
            case POP: {
                final Expression e = bb.pop();
                if (Expressions.isStatementExpression(e)) {
                    bb.addStmt(setOp(getAst().newExpressionStatement(wrap(e)), op));
                } else if (e instanceof SimpleName) {
                    // exception or simple literal
                    break;
                } else if (isBoolean(e) && !(e instanceof BooleanLiteral)) {
                    if (getCfg().getT().isAtLeast(Version.JVM_4)) {
                        log.warn(getM() + ": Boolean expression POP in '" + cop
                                + "' for >= JVM 5 code! Rewriting to empty if.");
                    }
                    final IfStatement ifStatement = getAst().newIfStatement();
                    ifStatement.setExpression(wrap(e));
                    ifStatement.setThenStatement(getAst().newEmptyStatement());
                    bb.addStmt(setOp(ifStatement, op));
                }
                break;
            }
            default:
                log.warn(getM() + ": Unknown POP type '" + cop.getKind() + "'!");
            }
            break;
        }
        case PUSH: {
            final PUSH cop = (PUSH) op;
            final T t = getCfg().getOutFrame(op).peek().getT();
            assert t != null;
            bb.push(newLiteral(t, cop.getValue(), getCfg().getM(), op));
            break;
        }
        case PUT: {
            final PUT cop = (PUT) op;
            final F f = cop.getF();
            final Expression rightOperand = bb.pop();
            assert rightOperand != null;
            if (rewriteFieldInit(bb, f, rightOperand)) {
                // was a constructor or initializer field init, done
                break;
            }
            Expression leftOperand;
            if (f.isStatic()) {
                leftOperand = getAst().newQualifiedName(newTypeName(f.getT(), getM()),
                        newSimpleName(f.getName(), getAst()));
            } else {
                final FieldAccess fieldAccess = getAst().newFieldAccess();
                fieldAccess.setExpression(wrap(bb.pop(), Priority.MEMBER_ACCESS));
                fieldAccess.setName(newSimpleName(f.getName(), getAst()));
                leftOperand = fieldAccess;
            }
            assert leftOperand != null;
            final Assignment assignment = newAssignment(Assignment.Operator.ASSIGN, leftOperand, rightOperand,
                    op);
            // TODO a = a +/- 1 => a++ / a--
            // TODO a = a <op> expr => a <op>= expr
            // inline assignment, DUP(_X1) -> PUT
            if (!bb.isStackEmpty() && bb.peek() == rightOperand) {
                bb.pop();
                bb.push(assignment);
                break;
            }
            if (!bb.isStackEmpty() && rightOperand instanceof InfixExpression
                    && (((InfixExpression) rightOperand).getOperator() == InfixExpression.Operator.PLUS
                            || ((InfixExpression) rightOperand)
                                    .getOperator() == InfixExpression.Operator.MINUS)) {
                // if i'm an peek-1 or peek+1 expression, than we can post-inc/dec
                // TODO more checks!
                bb.push(newPostfixExpression(
                        ((InfixExpression) rightOperand).getOperator() == InfixExpression.Operator.PLUS
                                ? PostfixExpression.Operator.INCREMENT
                                : PostfixExpression.Operator.DECREMENT,
                        bb.pop(), op));
                break;
            }
            bb.addStmt(setOp(getAst().newExpressionStatement(assignment), op));
            break;
        }
        case REM: {
            bb.push(newInfixExpressionPop(InfixExpression.Operator.REMAINDER, bb, op));
            break;
        }
        case RET: {
            // TODO
            break;
        }
        case RETURN: {
            final RETURN cop = (RETURN) op;
            final ReturnStatement returnStatement = getAst().newReturnStatement();
            if (cop.getT() != T.VOID) {
                returnStatement.setExpression(wrap(bb.pop()));
            }
            bb.addStmt(setOp(returnStatement, op));
            break;
        }
        case SHL: {
            bb.push(newInfixExpressionPop(InfixExpression.Operator.LEFT_SHIFT, bb, op));
            break;
        }
        case SHR: {
            final SHR cop = (SHR) op;
            bb.push(newInfixExpressionPop(cop.isUnsigned() ? InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED
                    : InfixExpression.Operator.RIGHT_SHIFT_SIGNED, bb, op));
            break;
        }
        case STORE: {
            final STORE cop = (STORE) op;
            final Expression rightOperand = bb.pop();

            // handle exception name expression
            exceptionNameExpression: if (rightOperand instanceof SimpleName) {
                // should be an uninitialized, temporary exception name expression
                final ASTNode parent = rightOperand.getParent();
                if (!(parent instanceof VariableDeclarationFragment)) {
                    break exceptionNameExpression;
                }
                assert ((SimpleName) rightOperand).getIdentifier().equals(Expressions.EXCEPTION_NAME_TMP);
                // also renames the parent temporary throwable declaration name,
                // later used for creating catch control statements
                ((SimpleName) rightOperand).setIdentifier(getVarName(cop.getReg(), cop.getPc() + 1));
                break; // STORE end
            }
            // handle inline assignments via DUP -> STORE
            final boolean isInlineAssignment = !bb.isStackEmpty() && bb.peek() == rightOperand;

            // handle variable declaration assignments
            final V v = getCfg().getFrameVar(cop.getReg(), cop.getPc() + 1);
            if (v == null /* tmp hack */ || v.getName() == null) {
                // temporary local
                // bb.set(cop.getReg(), rightOperand);
                // break;
                // TODO else not really necessary later if this is sure
            } else {
                // TODO if () int i = 0 else int i = 1 ???
                if (!isInlineAssignment && v.getPcs()[0] /* TODO */ == cop.getPc() + 1) {
                    final VariableDeclarationFragment variableDeclarationFragment = getAst()
                            .newVariableDeclarationFragment();
                    variableDeclarationFragment.setName(newSimpleName(v.getName(), getAst()));
                    variableDeclarationFragment.setInitializer(wrap(rightOperand, Priority.ASSIGNMENT));
                    final VariableDeclarationStatement variableDeclarationStatement = getAst()
                            .newVariableDeclarationStatement(variableDeclarationFragment);
                    variableDeclarationStatement.setType(newType(v.getT(), getM()));
                    bb.addStmt(setOp(variableDeclarationStatement, op));
                    break;
                }
            }

            final Assignment assignment = newAssignment(Assignment.Operator.ASSIGN,
                    getVarExpression(cop.getReg(), cop.getPc() + 1, op), rightOperand, op);

            if (isInlineAssignment) {
                bb.pop();
                bb.push(assignment);
                break;
            }
            if (!rewriteStorePreIncDec(bb, assignment)) {
                bb.addStmt(setOp(getAst().newExpressionStatement(assignment), op));
            }
            break;
        }
        case SUB: {
            bb.push(newInfixExpressionPop(InfixExpression.Operator.MINUS, bb, op));
            break;
        }
        case SWAP: {
            final Expression e1 = bb.pop();
            final Expression e2 = bb.pop();
            bb.push(e1);
            bb.push(e2);
            break;
        }
        case SWITCH: {
            final SWITCH cop = (SWITCH) op;

            final Expression switchExpression = bb.pop();
            assert switchExpression != null;
            if (rewriteSwitchEnum(bb, cop, switchExpression)) {
                break;
            }
            if (rewriteSwitchString(bb, cop, switchExpression)) {
                break;
            }
            final T t = peekT(op);
            if (t == T.CHAR) {
                rewriteSwitchChar(bb);
            }
            final SwitchStatement switchStatement = getAst().newSwitchStatement();
            switchStatement.setExpression(wrap(switchExpression));
            bb.addStmt(setOp(switchStatement, op));
            break;
        }
        case THROW: {
            final Expression exceptionExpression = bb.pop();
            assert exceptionExpression != null;
            final ThrowStatement throwStatement = getAst().newThrowStatement();
            throwStatement.setExpression(wrap(exceptionExpression));
            bb.addStmt(setOp(throwStatement, op));
            break;
        }
        case XOR: {
            final Expression rightOperand = bb.pop();
            // "a ^ -1" => "~a"
            if (rightOperand instanceof NumberLiteral
                    && ((NumberLiteral) rightOperand).getToken().equals("-1")) {
                bb.push(newPrefixExpression(PrefixExpression.Operator.COMPLEMENT, bb.pop(), op));
                break;
            }
            // "a ^ true" => "!a" (found in JVM 1.2 boolean expressions)
            if (rightOperand instanceof BooleanLiteral && getBooleanValue(rightOperand) == Boolean.TRUE) {
                bb.push(newPrefixExpression(PrefixExpression.Operator.NOT, bb.pop(), op));
                break;
            }
            bb.push(newInfixExpression(InfixExpression.Operator.XOR, bb.pop(), rightOperand, op));
            break;
        }
        default:
            throw new DecoJerException("Unknown intermediate vm operation '" + op + "'!");
        }
    }
    return true;
}

From source file:org.decojer.cavaj.utils.Expressions.java

License:Open Source License

/**
 * Wrap expression. Ensures that there is no parent set.
 *
 * @param expression// www. j  a v  a  2  s .c o m
 *            expression
 * @return wrapped expression
 */
@Nonnull
public static Expression wrap(@Nonnull final Expression expression) {
    if (expression.getParent() == null) {
        return expression;
    }
    return setOp(
            setValue((Expression) ASTNode.copySubtree(expression.getAST(), expression), getValue(expression)),
            getOp(expression));
}

From source file:org.eclipse.objectteams.otdt.ui.tests.dom.converter.BaseCallMessageSendTest.java

License:Open Source License

public void testChildNodesHaveCorrectParent1() {
    MethodDeclaration constructor = _role.getMethods()[1];
    ExpressionStatement statement = (ExpressionStatement) constructor.getBody().statements().get(0);
    _testObj = (BaseCallMessageSend) statement.getExpression();

    List childNodes = _testObj.getArguments();

    for (Iterator iter = childNodes.iterator(); iter.hasNext();) {
        Expression curChild = (Expression) iter.next();
        assertEquals("Base call arguments have wrong parent node", _testObj, curChild.getParent());
    }//from  ww w .  j a v a2s. co m
}

From source file:org.eclipse.objectteams.otdt.ui.tests.dom.converter.BaseConstructorInvocationTest.java

License:Open Source License

public void testChildNodesHaveCorrectParent1() {
    MethodDeclaration constructor = _role.getMethods()[1];
    _testObj = (BaseConstructorInvocation) constructor.getBody().statements().get(0);

    List childNodes = _testObj.getArguments();

    for (Iterator iter = childNodes.iterator(); iter.hasNext();) {
        Expression curChild = (Expression) iter.next();
        assertEquals("Base call arguments have wrong parent node", _testObj, curChild.getParent());
    }//from  w  w  w  .  j a v  a2s.  c  o  m
}