public void testOuterVarAccess() { resolveSource("Test", "class Test { int i; class Inner { void test() { i++; } } }"); TypeDeclaration innerNode = (TypeDeclaration) nodesByType.get(ASTNode.TYPE_DECLARATION).get(1); assertTrue(OuterReferenceResolver.needsOuterReference(innerNode.resolveBinding())); PostfixExpression increment = (PostfixExpression) nodesByType.get(ASTNode.POSTFIX_EXPRESSION).get(0); List<IVariableBinding> path = OuterReferenceResolver.getPath(increment.getOperand()); assertNotNull(path); assertEquals(2, path.size()); assertEquals("Test", path.get(0).getType().getName()); }
/* * Must be one of: * <ul> * <li>[indexBinding]++</li> * <li>++[indexBinding]</li> * <li>[indexBinding]+= 1</li> * <li>[indexBinding]= [indexBinding] + 1</li> * <li>[indexBinding]= 1 + [indexBinding]</li> * <ul> */ private boolean validateUpdaters(ForStatement statement) { List<Expression> updaters = statement.updaters(); if (updaters.size() != 1) return false; Expression updater = updaters.get(0); if (updater instanceof PostfixExpression) { PostfixExpression postfix = (PostfixExpression) updater; if (!PostfixExpression.Operator.INCREMENT.equals(postfix.getOperator())) return false; IBinding binding = getBinding(postfix.getOperand()); if (!fIndexBinding.equals(binding)) return false; return true; } else if (updater instanceof PrefixExpression) { PrefixExpression prefix = (PrefixExpression) updater; if (!PrefixExpression.Operator.INCREMENT.equals(prefix.getOperator())) return false; IBinding binding = getBinding(prefix.getOperand()); if (!fIndexBinding.equals(binding)) return false; return true; } else if (updater instanceof Assignment) { Assignment assignment = (Assignment) updater; Expression left = assignment.getLeftHandSide(); IBinding binding = getBinding(left); if (!fIndexBinding.equals(binding)) return false; if (Assignment.Operator.PLUS_ASSIGN.equals(assignment.getOperator())) { return isOneLiteral(assignment.getRightHandSide()); } else if (Assignment.Operator.ASSIGN.equals(assignment.getOperator())) { Expression right = assignment.getRightHandSide(); if (!(right instanceof InfixExpression)) return false; InfixExpression infixExpression = (InfixExpression) right; Expression leftOperand = infixExpression.getLeftOperand(); IBinding leftBinding = getBinding(leftOperand); Expression rightOperand = infixExpression.getRightOperand(); IBinding rightBinding = getBinding(rightOperand); if (fIndexBinding.equals(leftBinding)) { return isOneLiteral(rightOperand); } else if (fIndexBinding.equals(rightBinding)) { return isOneLiteral(leftOperand); } } } return false; }
public void endVisit(PostfixExpression node) { VMExpression expression = (VMExpression) expressions.pop(); PostfixExpression.Operator rawOperator = node.getOperator(); VMPostfixExpression.Operator operator = VMPostfixExpression.Operator.toOperator(rawOperator.toString()); expressions.push(new VMPostfixExpression(node, operator, expression)); };
/** * Converts an assignment, postfix expression or prefix expression into an assignable equivalent * expression using the getter. * * @param node the assignment/prefix/postfix node * @param astRewrite the astRewrite to use * @param getterExpression the expression to insert for read accesses or <code>null</code> if such * an expression does not exist * @param variableType the type of the variable that the result will be assigned to * @param is50OrHigher <code>true</code> if a 5.0 or higher environment can be used * @return an expression that can be assigned to the type variableType with node being replaced by * a equivalent expression using the getter */ public static Expression getAssignedValue( ASTNode node, ASTRewrite astRewrite, Expression getterExpression, ITypeBinding variableType, boolean is50OrHigher) { InfixExpression.Operator op = null; AST ast = astRewrite.getAST(); if (isNotInBlock(node)) return null; if (node.getNodeType() == ASTNode.ASSIGNMENT) { Assignment assignment = ((Assignment) node); Expression rightHandSide = assignment.getRightHandSide(); Expression copiedRightOp = (Expression) astRewrite.createCopyTarget(rightHandSide); if (assignment.getOperator() == Operator.ASSIGN) { ITypeBinding rightHandSideType = rightHandSide.resolveTypeBinding(); copiedRightOp = createNarrowCastIfNessecary( copiedRightOp, rightHandSideType, ast, variableType, is50OrHigher); return copiedRightOp; } if (getterExpression != null) { InfixExpression infix = ast.newInfixExpression(); infix.setLeftOperand(getterExpression); infix.setOperator(ASTNodes.convertToInfixOperator(assignment.getOperator())); infix.setRightOperand(copiedRightOp); ITypeBinding infixType = infix.resolveTypeBinding(); return createNarrowCastIfNessecary(infix, infixType, ast, variableType, is50OrHigher); } } else if (node.getNodeType() == ASTNode.POSTFIX_EXPRESSION) { PostfixExpression po = (PostfixExpression) node; if (po.getOperator() == PostfixExpression.Operator.INCREMENT) op = InfixExpression.Operator.PLUS; if (po.getOperator() == PostfixExpression.Operator.DECREMENT) op = InfixExpression.Operator.MINUS; } else if (node.getNodeType() == ASTNode.PREFIX_EXPRESSION) { PrefixExpression pe = (PrefixExpression) node; if (pe.getOperator() == PrefixExpression.Operator.INCREMENT) op = InfixExpression.Operator.PLUS; if (pe.getOperator() == PrefixExpression.Operator.DECREMENT) op = InfixExpression.Operator.MINUS; } if (op != null && getterExpression != null) { return createInfixInvocationFromPostPrefixExpression( op, getterExpression, ast, variableType, is50OrHigher); } return null; }
/* * @see ASTVisitor#visit(PostfixExpression) */ public boolean visit(PostfixExpression node) { node.getOperand().accept(this); this.fBuffer.append(node.getOperator().toString()); return false; }