Search in sources :

Example 41 with IdentifierTree

use of com.sun.source.tree.IdentifierTree in project checker-framework by typetools.

the class CFGTranslationPhaseOne method visitEnhancedForLoop.

@Override
public Node visitEnhancedForLoop(EnhancedForLoopTree tree, Void p) {
    // see JLS 14.14.2
    Name parentLabel = getLabel(getCurrentPath());
    Label conditionStart = new Label();
    Label loopEntry = new Label();
    Label loopExit = new Label();
    // If the loop is a labeled statement, then its continue target is identical for continues with
    // no label and continues with the loop's label.
    Label updateStart;
    if (parentLabel != null) {
        updateStart = continueLabels.get(parentLabel);
    } else {
        updateStart = new Label();
    }
    TryFinallyScopeCell oldBreakTargetL = breakTargetL;
    breakTargetL = new TryFinallyScopeCell(loopExit);
    TryFinallyScopeCell oldContinueTargetL = continueTargetL;
    continueTargetL = new TryFinallyScopeCell(updateStart);
    // Distinguish loops over Iterables from loops over arrays.
    VariableTree variable = tree.getVariable();
    VariableElement variableElement = TreeUtils.elementFromDeclaration(variable);
    ExpressionTree expression = tree.getExpression();
    StatementTree statement = tree.getStatement();
    TypeMirror exprType = TreeUtils.typeOf(expression);
    if (types.isSubtype(exprType, iterableType)) {
        // Take the upper bound of a type variable or wildcard
        exprType = TypesUtils.upperBound(exprType);
        assert (exprType instanceof DeclaredType) : "an Iterable must be a DeclaredType";
        DeclaredType declaredExprType = (DeclaredType) exprType;
        declaredExprType.getTypeArguments();
        MemberSelectTree iteratorSelect = treeBuilder.buildIteratorMethodAccess(expression);
        handleArtificialTree(iteratorSelect);
        MethodInvocationTree iteratorCall = treeBuilder.buildMethodInvocation(iteratorSelect);
        handleArtificialTree(iteratorCall);
        VariableTree iteratorVariable = createEnhancedForLoopIteratorVariable(iteratorCall, variableElement);
        handleArtificialTree(iteratorVariable);
        VariableDeclarationNode iteratorVariableDecl = new VariableDeclarationNode(iteratorVariable);
        iteratorVariableDecl.setInSource(false);
        extendWithNode(iteratorVariableDecl);
        Node expressionNode = scan(expression, p);
        MethodAccessNode iteratorAccessNode = new MethodAccessNode(iteratorSelect, expressionNode);
        iteratorAccessNode.setInSource(false);
        extendWithNode(iteratorAccessNode);
        MethodInvocationNode iteratorCallNode = new MethodInvocationNode(iteratorCall, iteratorAccessNode, Collections.emptyList(), getCurrentPath());
        iteratorCallNode.setInSource(false);
        extendWithNode(iteratorCallNode);
        translateAssignment(iteratorVariable, new LocalVariableNode(iteratorVariable), iteratorCallNode);
        // Test the loop ending condition
        addLabelForNextNode(conditionStart);
        IdentifierTree iteratorUse1 = treeBuilder.buildVariableUse(iteratorVariable);
        handleArtificialTree(iteratorUse1);
        LocalVariableNode iteratorReceiverNode = new LocalVariableNode(iteratorUse1);
        iteratorReceiverNode.setInSource(false);
        extendWithNode(iteratorReceiverNode);
        MemberSelectTree hasNextSelect = treeBuilder.buildHasNextMethodAccess(iteratorUse1);
        handleArtificialTree(hasNextSelect);
        MethodAccessNode hasNextAccessNode = new MethodAccessNode(hasNextSelect, iteratorReceiverNode);
        hasNextAccessNode.setInSource(false);
        extendWithNode(hasNextAccessNode);
        MethodInvocationTree hasNextCall = treeBuilder.buildMethodInvocation(hasNextSelect);
        handleArtificialTree(hasNextCall);
        MethodInvocationNode hasNextCallNode = new MethodInvocationNode(hasNextCall, hasNextAccessNode, Collections.emptyList(), getCurrentPath());
        hasNextCallNode.setInSource(false);
        extendWithNode(hasNextCallNode);
        extendWithExtendedNode(new ConditionalJump(loopEntry, loopExit));
        // Loop body, starting with declaration of the loop iteration variable
        addLabelForNextNode(loopEntry);
        extendWithNode(new VariableDeclarationNode(variable));
        IdentifierTree iteratorUse2 = treeBuilder.buildVariableUse(iteratorVariable);
        handleArtificialTree(iteratorUse2);
        LocalVariableNode iteratorReceiverNode2 = new LocalVariableNode(iteratorUse2);
        iteratorReceiverNode2.setInSource(false);
        extendWithNode(iteratorReceiverNode2);
        MemberSelectTree nextSelect = treeBuilder.buildNextMethodAccess(iteratorUse2);
        handleArtificialTree(nextSelect);
        MethodAccessNode nextAccessNode = new MethodAccessNode(nextSelect, iteratorReceiverNode2);
        nextAccessNode.setInSource(false);
        extendWithNode(nextAccessNode);
        MethodInvocationTree nextCall = treeBuilder.buildMethodInvocation(nextSelect);
        handleArtificialTree(nextCall);
        MethodInvocationNode nextCallNode = new MethodInvocationNode(nextCall, nextAccessNode, Collections.emptyList(), getCurrentPath());
        // If the type of iteratorVariable is a capture, its type tree may be missing annotations, so
        // save the expression in the node so that the full type can be found later.
        nextCallNode.setIterableExpression(expression);
        nextCallNode.setInSource(false);
        extendWithNode(nextCallNode);
        AssignmentNode assignNode = translateAssignment(variable, new LocalVariableNode(variable), nextCall);
        // translateAssignment() scans variable and creates new nodes, so set the expression
        // there, too.
        ((MethodInvocationNode) assignNode.getExpression()).setIterableExpression(expression);
        assert statement != null;
        scan(statement, p);
        // Loop back edge
        addLabelForNextNode(updateStart);
        extendWithExtendedNode(new UnconditionalJump(conditionStart));
    } else {
        // TODO: Shift any labels after the initialization of the
        // temporary array variable.
        VariableTree arrayVariable = createEnhancedForLoopArrayVariable(expression, variableElement);
        handleArtificialTree(arrayVariable);
        VariableDeclarationNode arrayVariableNode = new VariableDeclarationNode(arrayVariable);
        arrayVariableNode.setInSource(false);
        extendWithNode(arrayVariableNode);
        Node expressionNode = scan(expression, p);
        translateAssignment(arrayVariable, new LocalVariableNode(arrayVariable), expressionNode);
        // Declare and initialize the loop index variable
        TypeMirror intType = types.getPrimitiveType(TypeKind.INT);
        LiteralTree zero = treeBuilder.buildLiteral(Integer.valueOf(0));
        handleArtificialTree(zero);
        VariableTree indexVariable = treeBuilder.buildVariableDecl(intType, uniqueName("index"), variableElement.getEnclosingElement(), zero);
        handleArtificialTree(indexVariable);
        VariableDeclarationNode indexVariableNode = new VariableDeclarationNode(indexVariable);
        indexVariableNode.setInSource(false);
        extendWithNode(indexVariableNode);
        IntegerLiteralNode zeroNode = new IntegerLiteralNode(zero);
        extendWithNode(zeroNode);
        translateAssignment(indexVariable, new LocalVariableNode(indexVariable), zeroNode);
        // Compare index to array length
        addLabelForNextNode(conditionStart);
        IdentifierTree indexUse1 = treeBuilder.buildVariableUse(indexVariable);
        handleArtificialTree(indexUse1);
        LocalVariableNode indexNode1 = new LocalVariableNode(indexUse1);
        indexNode1.setInSource(false);
        extendWithNode(indexNode1);
        IdentifierTree arrayUse1 = treeBuilder.buildVariableUse(arrayVariable);
        handleArtificialTree(arrayUse1);
        LocalVariableNode arrayNode1 = new LocalVariableNode(arrayUse1);
        extendWithNode(arrayNode1);
        MemberSelectTree lengthSelect = treeBuilder.buildArrayLengthAccess(arrayUse1);
        handleArtificialTree(lengthSelect);
        FieldAccessNode lengthAccessNode = new FieldAccessNode(lengthSelect, arrayNode1);
        lengthAccessNode.setInSource(false);
        extendWithNode(lengthAccessNode);
        BinaryTree lessThan = treeBuilder.buildLessThan(indexUse1, lengthSelect);
        handleArtificialTree(lessThan);
        LessThanNode lessThanNode = new LessThanNode(lessThan, indexNode1, lengthAccessNode);
        lessThanNode.setInSource(false);
        extendWithNode(lessThanNode);
        extendWithExtendedNode(new ConditionalJump(loopEntry, loopExit));
        // Loop body, starting with declaration of the loop iteration variable
        addLabelForNextNode(loopEntry);
        extendWithNode(new VariableDeclarationNode(variable));
        IdentifierTree arrayUse2 = treeBuilder.buildVariableUse(arrayVariable);
        handleArtificialTree(arrayUse2);
        LocalVariableNode arrayNode2 = new LocalVariableNode(arrayUse2);
        arrayNode2.setInSource(false);
        extendWithNode(arrayNode2);
        IdentifierTree indexUse2 = treeBuilder.buildVariableUse(indexVariable);
        handleArtificialTree(indexUse2);
        LocalVariableNode indexNode2 = new LocalVariableNode(indexUse2);
        indexNode2.setInSource(false);
        extendWithNode(indexNode2);
        ArrayAccessTree arrayAccess = treeBuilder.buildArrayAccess(arrayUse2, indexUse2);
        handleArtificialTree(arrayAccess);
        ArrayAccessNode arrayAccessNode = new ArrayAccessNode(arrayAccess, arrayNode2, indexNode2);
        arrayAccessNode.setArrayExpression(expression);
        arrayAccessNode.setInSource(false);
        extendWithNode(arrayAccessNode);
        AssignmentNode arrayAccessAssignNode = translateAssignment(variable, new LocalVariableNode(variable), arrayAccessNode);
        extendWithNodeWithException(arrayAccessNode, nullPointerExceptionType);
        // translateAssignment() scans variable and creates new nodes, so set the expression
        // there, too.
        Node arrayAccessAssignNodeExpr = arrayAccessAssignNode.getExpression();
        if (arrayAccessAssignNodeExpr instanceof ArrayAccessNode) {
            ((ArrayAccessNode) arrayAccessAssignNodeExpr).setArrayExpression(expression);
        } else if (arrayAccessAssignNodeExpr instanceof MethodInvocationNode) {
            // If the array component type is a primitive, there may be a boxing or unboxing
            // conversion. Treat that as an iterator.
            MethodInvocationNode boxingNode = (MethodInvocationNode) arrayAccessAssignNodeExpr;
            boxingNode.setIterableExpression(expression);
        }
        assert statement != null;
        scan(statement, p);
        // Loop back edge
        addLabelForNextNode(updateStart);
        IdentifierTree indexUse3 = treeBuilder.buildVariableUse(indexVariable);
        handleArtificialTree(indexUse3);
        LocalVariableNode indexNode3 = new LocalVariableNode(indexUse3);
        indexNode3.setInSource(false);
        extendWithNode(indexNode3);
        LiteralTree oneTree = treeBuilder.buildLiteral(Integer.valueOf(1));
        handleArtificialTree(oneTree);
        Node one = new IntegerLiteralNode(oneTree);
        one.setInSource(false);
        extendWithNode(one);
        BinaryTree addOneTree = treeBuilder.buildBinary(intType, Tree.Kind.PLUS, indexUse3, oneTree);
        handleArtificialTree(addOneTree);
        Node addOneNode = new NumericalAdditionNode(addOneTree, indexNode3, one);
        addOneNode.setInSource(false);
        extendWithNode(addOneNode);
        AssignmentTree assignTree = treeBuilder.buildAssignment(indexUse3, addOneTree);
        handleArtificialTree(assignTree);
        Node assignNode = new AssignmentNode(assignTree, indexNode3, addOneNode);
        assignNode.setInSource(false);
        extendWithNode(assignNode);
        extendWithExtendedNode(new UnconditionalJump(conditionStart));
    }
    // Loop exit
    addLabelForNextNode(loopExit);
    breakTargetL = oldBreakTargetL;
    continueTargetL = oldContinueTargetL;
    return null;
}
Also used : ArrayAccessTree(com.sun.source.tree.ArrayAccessTree) NumericalAdditionNode(org.checkerframework.dataflow.cfg.node.NumericalAdditionNode) MemberSelectTree(com.sun.source.tree.MemberSelectTree) NumericalMultiplicationNode(org.checkerframework.dataflow.cfg.node.NumericalMultiplicationNode) ArrayCreationNode(org.checkerframework.dataflow.cfg.node.ArrayCreationNode) ValueLiteralNode(org.checkerframework.dataflow.cfg.node.ValueLiteralNode) StringConversionNode(org.checkerframework.dataflow.cfg.node.StringConversionNode) UnsignedRightShiftNode(org.checkerframework.dataflow.cfg.node.UnsignedRightShiftNode) LeftShiftNode(org.checkerframework.dataflow.cfg.node.LeftShiftNode) PrimitiveTypeNode(org.checkerframework.dataflow.cfg.node.PrimitiveTypeNode) FloatLiteralNode(org.checkerframework.dataflow.cfg.node.FloatLiteralNode) LessThanNode(org.checkerframework.dataflow.cfg.node.LessThanNode) BitwiseOrNode(org.checkerframework.dataflow.cfg.node.BitwiseOrNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) NarrowingConversionNode(org.checkerframework.dataflow.cfg.node.NarrowingConversionNode) EqualToNode(org.checkerframework.dataflow.cfg.node.EqualToNode) NumericalPlusNode(org.checkerframework.dataflow.cfg.node.NumericalPlusNode) ConditionalAndNode(org.checkerframework.dataflow.cfg.node.ConditionalAndNode) VariableDeclarationNode(org.checkerframework.dataflow.cfg.node.VariableDeclarationNode) ClassDeclarationNode(org.checkerframework.dataflow.cfg.node.ClassDeclarationNode) IntegerDivisionNode(org.checkerframework.dataflow.cfg.node.IntegerDivisionNode) AssertionErrorNode(org.checkerframework.dataflow.cfg.node.AssertionErrorNode) InstanceOfNode(org.checkerframework.dataflow.cfg.node.InstanceOfNode) BooleanLiteralNode(org.checkerframework.dataflow.cfg.node.BooleanLiteralNode) ThisNode(org.checkerframework.dataflow.cfg.node.ThisNode) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) NullLiteralNode(org.checkerframework.dataflow.cfg.node.NullLiteralNode) ArrayTypeNode(org.checkerframework.dataflow.cfg.node.ArrayTypeNode) LambdaResultExpressionNode(org.checkerframework.dataflow.cfg.node.LambdaResultExpressionNode) IntegerRemainderNode(org.checkerframework.dataflow.cfg.node.IntegerRemainderNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) ConditionalOrNode(org.checkerframework.dataflow.cfg.node.ConditionalOrNode) NotEqualNode(org.checkerframework.dataflow.cfg.node.NotEqualNode) BitwiseXorNode(org.checkerframework.dataflow.cfg.node.BitwiseXorNode) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) ExplicitThisNode(org.checkerframework.dataflow.cfg.node.ExplicitThisNode) StringConcatenateNode(org.checkerframework.dataflow.cfg.node.StringConcatenateNode) NullChkNode(org.checkerframework.dataflow.cfg.node.NullChkNode) CharacterLiteralNode(org.checkerframework.dataflow.cfg.node.CharacterLiteralNode) FloatingDivisionNode(org.checkerframework.dataflow.cfg.node.FloatingDivisionNode) FunctionalInterfaceNode(org.checkerframework.dataflow.cfg.node.FunctionalInterfaceNode) StringConcatenateAssignmentNode(org.checkerframework.dataflow.cfg.node.StringConcatenateAssignmentNode) TypeCastNode(org.checkerframework.dataflow.cfg.node.TypeCastNode) MethodAccessNode(org.checkerframework.dataflow.cfg.node.MethodAccessNode) WideningConversionNode(org.checkerframework.dataflow.cfg.node.WideningConversionNode) LongLiteralNode(org.checkerframework.dataflow.cfg.node.LongLiteralNode) MarkerNode(org.checkerframework.dataflow.cfg.node.MarkerNode) ImplicitThisNode(org.checkerframework.dataflow.cfg.node.ImplicitThisNode) FloatingRemainderNode(org.checkerframework.dataflow.cfg.node.FloatingRemainderNode) ClassNameNode(org.checkerframework.dataflow.cfg.node.ClassNameNode) ObjectCreationNode(org.checkerframework.dataflow.cfg.node.ObjectCreationNode) PackageNameNode(org.checkerframework.dataflow.cfg.node.PackageNameNode) DoubleLiteralNode(org.checkerframework.dataflow.cfg.node.DoubleLiteralNode) SuperNode(org.checkerframework.dataflow.cfg.node.SuperNode) IntegerLiteralNode(org.checkerframework.dataflow.cfg.node.IntegerLiteralNode) SignedRightShiftNode(org.checkerframework.dataflow.cfg.node.SignedRightShiftNode) ThrowNode(org.checkerframework.dataflow.cfg.node.ThrowNode) GreaterThanOrEqualNode(org.checkerframework.dataflow.cfg.node.GreaterThanOrEqualNode) StringLiteralNode(org.checkerframework.dataflow.cfg.node.StringLiteralNode) TernaryExpressionNode(org.checkerframework.dataflow.cfg.node.TernaryExpressionNode) BitwiseAndNode(org.checkerframework.dataflow.cfg.node.BitwiseAndNode) ParameterizedTypeNode(org.checkerframework.dataflow.cfg.node.ParameterizedTypeNode) CaseNode(org.checkerframework.dataflow.cfg.node.CaseNode) SwitchExpressionNode(org.checkerframework.dataflow.cfg.node.SwitchExpressionNode) NumericalAdditionNode(org.checkerframework.dataflow.cfg.node.NumericalAdditionNode) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode) BitwiseComplementNode(org.checkerframework.dataflow.cfg.node.BitwiseComplementNode) ConditionalNotNode(org.checkerframework.dataflow.cfg.node.ConditionalNotNode) NumericalMinusNode(org.checkerframework.dataflow.cfg.node.NumericalMinusNode) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) GreaterThanNode(org.checkerframework.dataflow.cfg.node.GreaterThanNode) LessThanOrEqualNode(org.checkerframework.dataflow.cfg.node.LessThanOrEqualNode) SynchronizedNode(org.checkerframework.dataflow.cfg.node.SynchronizedNode) Node(org.checkerframework.dataflow.cfg.node.Node) VariableTree(com.sun.source.tree.VariableTree) BinaryTree(com.sun.source.tree.BinaryTree) IdentifierTree(com.sun.source.tree.IdentifierTree) VariableElement(javax.lang.model.element.VariableElement) LessThanNode(org.checkerframework.dataflow.cfg.node.LessThanNode) LiteralTree(com.sun.source.tree.LiteralTree) Name(javax.lang.model.element.Name) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) LabeledStatementTree(com.sun.source.tree.LabeledStatementTree) StatementTree(com.sun.source.tree.StatementTree) EmptyStatementTree(com.sun.source.tree.EmptyStatementTree) TypeMirror(javax.lang.model.type.TypeMirror) VariableDeclarationNode(org.checkerframework.dataflow.cfg.node.VariableDeclarationNode) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree) IntegerLiteralNode(org.checkerframework.dataflow.cfg.node.IntegerLiteralNode) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) AssignmentTree(com.sun.source.tree.AssignmentTree) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) StringConcatenateAssignmentNode(org.checkerframework.dataflow.cfg.node.StringConcatenateAssignmentNode) MethodAccessNode(org.checkerframework.dataflow.cfg.node.MethodAccessNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) DeclaredType(javax.lang.model.type.DeclaredType)

Example 42 with IdentifierTree

use of com.sun.source.tree.IdentifierTree in project checker-framework by typetools.

the class TreeUtils method isSpecificFieldAccess.

/**
 * Returns true if and only if the given {@code tree} represents a field access of the given
 * {@link VariableElement}.
 */
public static boolean isSpecificFieldAccess(Tree tree, VariableElement var) {
    if (tree instanceof MemberSelectTree) {
        MemberSelectTree memSel = (MemberSelectTree) tree;
        assert isUseOfElement(memSel) : "@AssumeAssertion(nullness): tree kind";
        Element field = TreeUtils.elementFromUse(memSel);
        return field.equals(var);
    } else if (tree instanceof IdentifierTree) {
        IdentifierTree idTree = (IdentifierTree) tree;
        assert isUseOfElement(idTree) : "@AssumeAssertion(nullness): tree kind";
        Element field = TreeUtils.elementFromUse(idTree);
        return field.equals(var);
    } else {
        return false;
    }
}
Also used : MemberSelectTree(com.sun.source.tree.MemberSelectTree) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) IdentifierTree(com.sun.source.tree.IdentifierTree)

Example 43 with IdentifierTree

use of com.sun.source.tree.IdentifierTree in project checker-framework by typetools.

the class TreeUtils method isFieldAccess.

/**
 * Determine whether {@code tree} is a field access expression, such as
 *
 * <pre>
 *   <em>f</em>
 *   <em>obj</em> . <em>f</em>
 * </pre>
 *
 * This method currently also returns true for class literals and qualified this.
 *
 * @param tree a tree that might be a field access
 * @return true iff if tree is a field access expression (implicit or explicit)
 */
public static boolean isFieldAccess(Tree tree) {
    if (tree.getKind() == Tree.Kind.MEMBER_SELECT) {
        // explicit member access (or a class literal or a qualified this)
        MemberSelectTree memberSelect = (MemberSelectTree) tree;
        assert isUseOfElement(memberSelect) : "@AssumeAssertion(nullness): tree kind";
        Element el = TreeUtils.elementFromUse(memberSelect);
        return el.getKind().isField();
    } else if (tree.getKind() == Tree.Kind.IDENTIFIER) {
        // implicit field access
        IdentifierTree ident = (IdentifierTree) tree;
        assert isUseOfElement(ident) : "@AssumeAssertion(nullness): tree kind";
        Element el = TreeUtils.elementFromUse(ident);
        return el.getKind().isField() && !ident.getName().contentEquals("this") && !ident.getName().contentEquals("super");
    }
    return false;
}
Also used : MemberSelectTree(com.sun.source.tree.MemberSelectTree) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) IdentifierTree(com.sun.source.tree.IdentifierTree)

Example 44 with IdentifierTree

use of com.sun.source.tree.IdentifierTree in project checker-framework by typetools.

the class TreeUtils method isSelfAccess.

/**
 * Returns true if the tree is a tree that 'looks like' either an access of a field or an
 * invocation of a method that are owned by the same accessing instance.
 *
 * <p>It would only return true if the access tree is of the form:
 *
 * <pre>
 *   field
 *   this.field
 *
 *   method()
 *   this.method()
 * </pre>
 *
 * It does not perform any semantical check to differentiate between fields and local variables;
 * local methods or imported static methods.
 *
 * @param tree expression tree representing an access to object member
 * @return {@code true} iff the member is a member of {@code this} instance
 */
public static boolean isSelfAccess(final ExpressionTree tree) {
    ExpressionTree tr = TreeUtils.withoutParens(tree);
    // If method invocation check the method select
    if (tr.getKind() == Tree.Kind.ARRAY_ACCESS) {
        return false;
    }
    if (tree.getKind() == Tree.Kind.METHOD_INVOCATION) {
        tr = ((MethodInvocationTree) tree).getMethodSelect();
    }
    tr = TreeUtils.withoutParens(tr);
    if (tr.getKind() == Tree.Kind.TYPE_CAST) {
        tr = ((TypeCastTree) tr).getExpression();
    }
    tr = TreeUtils.withoutParens(tr);
    if (tr.getKind() == Tree.Kind.IDENTIFIER) {
        return true;
    }
    if (tr.getKind() == Tree.Kind.MEMBER_SELECT) {
        tr = ((MemberSelectTree) tr).getExpression();
        if (tr.getKind() == Tree.Kind.IDENTIFIER) {
            Name ident = ((IdentifierTree) tr).getName();
            return ident.contentEquals("this") || ident.contentEquals("super");
        }
    }
    return false;
}
Also used : ExpressionTree(com.sun.source.tree.ExpressionTree) IdentifierTree(com.sun.source.tree.IdentifierTree) FullyQualifiedName(org.checkerframework.checker.signature.qual.FullyQualifiedName) Name(javax.lang.model.element.Name)

Example 45 with IdentifierTree

use of com.sun.source.tree.IdentifierTree in project bazel by bazelbuild.

the class TreeUtils method isSpecificFieldAccess.

/**
     * Returns true if and only if the given {@code tree} represents a field
     * access of the given {@link VariableElement}.
     */
public static boolean isSpecificFieldAccess(Tree tree, VariableElement var) {
    if (tree instanceof MemberSelectTree) {
        MemberSelectTree memSel = (MemberSelectTree) tree;
        Element field = TreeUtils.elementFromUse(memSel);
        return field.equals(var);
    } else if (tree instanceof IdentifierTree) {
        IdentifierTree idTree = (IdentifierTree) tree;
        Element field = TreeUtils.elementFromUse(idTree);
        return field.equals(var);
    } else {
        return false;
    }
}
Also used : MemberSelectTree(com.sun.source.tree.MemberSelectTree) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) IdentifierTree(com.sun.source.tree.IdentifierTree)

Aggregations

IdentifierTree (com.sun.source.tree.IdentifierTree)82 ExpressionTree (com.sun.source.tree.ExpressionTree)41 MemberSelectTree (com.sun.source.tree.MemberSelectTree)36 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)28 Element (javax.lang.model.element.Element)24 Tree (com.sun.source.tree.Tree)21 ExecutableElement (javax.lang.model.element.ExecutableElement)18 VariableTree (com.sun.source.tree.VariableTree)17 TypeElement (javax.lang.model.element.TypeElement)16 MethodTree (com.sun.source.tree.MethodTree)13 VariableElement (javax.lang.model.element.VariableElement)13 ClassTree (com.sun.source.tree.ClassTree)12 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)11 ArrayAccessTree (com.sun.source.tree.ArrayAccessTree)10 NewClassTree (com.sun.source.tree.NewClassTree)10 AssignmentTree (com.sun.source.tree.AssignmentTree)9 BinaryTree (com.sun.source.tree.BinaryTree)9 LiteralTree (com.sun.source.tree.LiteralTree)8 StatementTree (com.sun.source.tree.StatementTree)8 Symbol (com.sun.tools.javac.code.Symbol)8