Search in sources :

Example 56 with VariableTree

use of com.sun.source.tree.VariableTree in project error-prone by google.

the class AssistedParameters method partitionParametersByType.

// Since Type doesn't have strong equality semantics, we have to use Types.isSameType to
// determine which parameters are conflicting with each other.
private Multimap<Type, VariableTree> partitionParametersByType(List<VariableTree> parameters, VisitorState state) {
    Types types = state.getTypes();
    Multimap<Type, VariableTree> multimap = LinkedListMultimap.create();
    variables: for (VariableTree node : parameters) {
        // Normalize Integer => int
        Type type = types.unboxedTypeOrType(ASTHelpers.getType(node));
        for (Type existingType : multimap.keySet()) {
            if (types.isSameType(existingType, type)) {
                multimap.put(existingType, node);
                continue variables;
            }
        }
        // A new type for the map.
        multimap.put(type, node);
    }
    return multimap;
}
Also used : Types(com.sun.tools.javac.code.Types) MatchType(com.google.errorprone.matchers.ChildMultiMatcher.MatchType) Type(com.sun.tools.javac.code.Type) VariableTree(com.sun.source.tree.VariableTree)

Example 57 with VariableTree

use of com.sun.source.tree.VariableTree in project error-prone by google.

the class MultiVariableDeclaration method checkDeclarations.

private Description checkDeclarations(List<? extends Tree> children, VisitorState state) {
    PeekingIterator<Tree> it = Iterators.<Tree>peekingIterator(children.iterator());
    while (it.hasNext()) {
        if (it.peek().getKind() != Tree.Kind.VARIABLE) {
            it.next();
            continue;
        }
        VariableTree variableTree = (VariableTree) it.next();
        ArrayList<VariableTree> fragments = new ArrayList<>();
        fragments.add(variableTree);
        // a distinct end position from the previous declaration.
        while (it.hasNext() && it.peek().getKind() == Tree.Kind.VARIABLE && ((JCTree) variableTree).getStartPosition() == ((JCTree) it.peek()).getStartPosition()) {
            fragments.add((VariableTree) it.next());
        }
        if (fragments.size() == 1) {
            continue;
        }
        Fix fix = SuggestedFix.replace(((JCTree) fragments.get(0)).getStartPosition(), state.getEndPosition(Iterables.getLast(fragments)), Joiner.on("; ").join(fragments) + ";");
        state.reportMatch(describeMatch(fragments.get(0), fix));
    }
    return NO_MATCH;
}
Also used : SuggestedFix(com.google.errorprone.fixes.SuggestedFix) Fix(com.google.errorprone.fixes.Fix) VariableTree(com.sun.source.tree.VariableTree) ArrayList(java.util.ArrayList) VariableTree(com.sun.source.tree.VariableTree) JCTree(com.sun.tools.javac.tree.JCTree) BlockTree(com.sun.source.tree.BlockTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) JCTree(com.sun.tools.javac.tree.JCTree)

Example 58 with VariableTree

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

the class AnnotatedTypeFactory method fromElement.

// **********************************************************************
// Factories for annotated types that do not account for implicit qualifiers.
// They only include qualifiers explicitly inserted by the user.
// **********************************************************************
/**
 * Creates an AnnotatedTypeMirror for {@code elt} that includes: annotations explicitly written
 * on the element and annotations from stub files
 *
 * @param elt the element
 * @return AnnotatedTypeMirror of the element with explicitly-written and stub file annotations
 */
public AnnotatedTypeMirror fromElement(Element elt) {
    if (shouldCache && elementCache.containsKey(elt)) {
        return elementCache.get(elt).deepCopy();
    }
    if (elt.getKind() == ElementKind.PACKAGE) {
        return toAnnotatedType(elt.asType(), false);
    }
    AnnotatedTypeMirror type;
    // Because of a bug in Java 8, annotations on type parameters are not stored in elements,
    // so get explicit annotations from the tree. (This bug has been fixed in Java 9.)
    // Also, since annotations computed by the AnnotatedTypeFactory are stored in the element,
    // the annotations have to be retrived from the tree so that only explicit annotations are
    // returned.
    Tree decl = declarationFromElement(elt);
    if (decl == null && typesFromStubFiles != null && typesFromStubFiles.containsKey(elt)) {
        type = typesFromStubFiles.get(elt).deepCopy();
    } else if (decl == null && (typesFromStubFiles == null || !typesFromStubFiles.containsKey(elt))) {
        type = toAnnotatedType(elt.asType(), ElementUtils.isTypeDeclaration(elt));
        ElementAnnotationApplier.apply(type, elt, this);
        if (elt instanceof ExecutableElement || elt instanceof VariableElement) {
            annotateInheritedFromClass(type);
        }
    } else if (decl instanceof ClassTree) {
        type = fromClass((ClassTree) decl);
    } else if (decl instanceof VariableTree) {
        type = fromMember(decl);
    } else if (decl instanceof MethodTree) {
        type = fromMember(decl);
    } else if (decl.getKind() == Tree.Kind.TYPE_PARAMETER) {
        type = fromTypeTree(decl);
    } else {
        ErrorReporter.errorAbort("AnnotatedTypeFactory.fromElement: cannot be here! decl: " + decl.getKind() + " elt: " + elt);
        // dead code
        type = null;
    }
    // results.
    if (shouldCache && typesFromStubFiles != null) {
        elementCache.put(elt, type.deepCopy());
    }
    return type;
}
Also used : MethodTree(com.sun.source.tree.MethodTree) ExecutableElement(javax.lang.model.element.ExecutableElement) NewClassTree(com.sun.source.tree.NewClassTree) ClassTree(com.sun.source.tree.ClassTree) VariableTree(com.sun.source.tree.VariableTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) ReturnTree(com.sun.source.tree.ReturnTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) IdentifierTree(com.sun.source.tree.IdentifierTree) NewArrayTree(com.sun.source.tree.NewArrayTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) ClassTree(com.sun.source.tree.ClassTree) MemberReferenceTree(com.sun.source.tree.MemberReferenceTree) VariableElement(javax.lang.model.element.VariableElement)

Example 59 with VariableTree

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

the class AnnotatedTypeFactory method getFunctionalInterfaceType.

/**
 * Get the AnnotatedDeclaredType for the FunctionalInterface from assignment context of the
 * method reference or lambda expression which may be a variable assignment, a method call, or a
 * cast.
 *
 * <p>The assignment context is not always correct, so we must search up the AST. It will
 * recursively search for lambdas nested in lambdas.
 *
 * @param tree the tree of the lambda or method reference
 * @return the functional interface type
 */
private AnnotatedDeclaredType getFunctionalInterfaceType(Tree tree) {
    Tree parentTree = getPath(tree).getParentPath().getLeaf();
    switch(parentTree.getKind()) {
        case PARENTHESIZED:
            return getFunctionalInterfaceType(parentTree);
        case TYPE_CAST:
            TypeCastTree cast = (TypeCastTree) parentTree;
            assert isFunctionalInterface(trees.getTypeMirror(getPath(cast.getType())), parentTree, tree);
            AnnotatedTypeMirror castATM = getAnnotatedType(cast.getType());
            if (castATM.getKind() == TypeKind.INTERSECTION) {
                AnnotatedIntersectionType itype = (AnnotatedIntersectionType) castATM;
                for (AnnotatedTypeMirror t : itype.directSuperTypes()) {
                    if (TypesUtils.isFunctionalInterface(t.getUnderlyingType(), getProcessingEnv())) {
                        return (AnnotatedDeclaredType) t;
                    }
                }
                // We should never reach here: isFunctionalInterface performs the same check
                // and would have raised an error already.
                ErrorReporter.errorAbort(String.format("Expected the type of a cast tree in an assignment context to contain a functional interface bound. " + "Found type: %s for tree: %s in lambda tree: %s", castATM, cast, tree));
            }
            return (AnnotatedDeclaredType) castATM;
        case NEW_CLASS:
            NewClassTree newClass = (NewClassTree) parentTree;
            int indexOfLambda = newClass.getArguments().indexOf(tree);
            Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> con = this.constructorFromUse(newClass);
            AnnotatedTypeMirror constructorParam = AnnotatedTypes.getAnnotatedTypeMirrorOfParameter(con.first, indexOfLambda);
            assert isFunctionalInterface(constructorParam.getUnderlyingType(), parentTree, tree);
            return (AnnotatedDeclaredType) constructorParam;
        case NEW_ARRAY:
            NewArrayTree newArray = (NewArrayTree) parentTree;
            AnnotatedArrayType newArrayATM = getAnnotatedType(newArray);
            AnnotatedTypeMirror elementATM = newArrayATM.getComponentType();
            assert isFunctionalInterface(elementATM.getUnderlyingType(), parentTree, tree);
            return (AnnotatedDeclaredType) elementATM;
        case METHOD_INVOCATION:
            MethodInvocationTree method = (MethodInvocationTree) parentTree;
            int index = method.getArguments().indexOf(tree);
            Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> exe = this.methodFromUse(method);
            AnnotatedTypeMirror param = AnnotatedTypes.getAnnotatedTypeMirrorOfParameter(exe.first, index);
            if (param.getKind() == TypeKind.WILDCARD) {
                // param is an uninferred wildcard.
                TypeMirror typeMirror = TreeUtils.typeOf(tree);
                param = AnnotatedTypeMirror.createType(typeMirror, this, false);
                addDefaultAnnotations(param);
            }
            assert isFunctionalInterface(param.getUnderlyingType(), parentTree, tree);
            return (AnnotatedDeclaredType) param;
        case VARIABLE:
            VariableTree varTree = (VariableTree) parentTree;
            assert isFunctionalInterface(TreeUtils.typeOf(varTree), parentTree, tree);
            return (AnnotatedDeclaredType) getAnnotatedType(varTree.getType());
        case ASSIGNMENT:
            AssignmentTree assignmentTree = (AssignmentTree) parentTree;
            assert isFunctionalInterface(TreeUtils.typeOf(assignmentTree), parentTree, tree);
            return (AnnotatedDeclaredType) getAnnotatedType(assignmentTree.getVariable());
        case RETURN:
            Tree enclosing = TreeUtils.enclosingOfKind(getPath(parentTree), new HashSet<>(Arrays.asList(Tree.Kind.METHOD, Tree.Kind.LAMBDA_EXPRESSION)));
            if (enclosing.getKind() == Tree.Kind.METHOD) {
                MethodTree enclosingMethod = (MethodTree) enclosing;
                return (AnnotatedDeclaredType) getAnnotatedType(enclosingMethod.getReturnType());
            } else {
                LambdaExpressionTree enclosingLambda = (LambdaExpressionTree) enclosing;
                Pair<AnnotatedDeclaredType, AnnotatedExecutableType> result = getFnInterfaceFromTree(enclosingLambda);
                AnnotatedExecutableType methodExe = result.second;
                return (AnnotatedDeclaredType) methodExe.getReturnType();
            }
        case LAMBDA_EXPRESSION:
            LambdaExpressionTree enclosingLambda = (LambdaExpressionTree) parentTree;
            Pair<AnnotatedDeclaredType, AnnotatedExecutableType> result = getFnInterfaceFromTree(enclosingLambda);
            AnnotatedExecutableType methodExe = result.second;
            return (AnnotatedDeclaredType) methodExe.getReturnType();
        case CONDITIONAL_EXPRESSION:
            ConditionalExpressionTree conditionalExpressionTree = (ConditionalExpressionTree) parentTree;
            final AnnotatedTypeMirror falseType = getAnnotatedType(conditionalExpressionTree.getFalseExpression());
            final AnnotatedTypeMirror trueType = getAnnotatedType(conditionalExpressionTree.getTrueExpression());
            // Known cases where we must use LUB because falseType/trueType will not be equal:
            // a) when one of the types is a type variable that extends a functional interface
            // or extends a type variable that extends a functional interface
            // b) When one of the two sides of the expression is a reference to a sub-interface.
            // e.g.   interface ConsumeStr {
            // public void consume(String s)
            // }
            // interface SubConsumer extends ConsumeStr {
            // default void someOtherMethod() { ... }
            // }
            // SubConsumer s = ...;
            // ConsumeStr stringConsumer = (someCondition) ? s : System.out::println;
            AnnotatedTypeMirror conditionalType = AnnotatedTypes.leastUpperBound(this, trueType, falseType);
            assert isFunctionalInterface(conditionalType.getUnderlyingType(), parentTree, tree);
            return (AnnotatedDeclaredType) conditionalType;
        default:
            ErrorReporter.errorAbort("Could not find functional interface from assignment context. " + "Unexpected tree type: " + parentTree.getKind() + " For lambda tree: " + tree);
            return null;
    }
}
Also used : TypeCastTree(com.sun.source.tree.TypeCastTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) NewClassTree(com.sun.source.tree.NewClassTree) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) AnnotatedArrayType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) AnnotatedIntersectionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType) NewArrayTree(com.sun.source.tree.NewArrayTree) TypeMirror(javax.lang.model.type.TypeMirror) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) ReturnTree(com.sun.source.tree.ReturnTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) IdentifierTree(com.sun.source.tree.IdentifierTree) NewArrayTree(com.sun.source.tree.NewArrayTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) ClassTree(com.sun.source.tree.ClassTree) MemberReferenceTree(com.sun.source.tree.MemberReferenceTree) ArrayList(java.util.ArrayList) List(java.util.List) AssignmentTree(com.sun.source.tree.AssignmentTree)

Example 60 with VariableTree

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

the class GenericAnnotatedTypeFactory method performFlowAnalysis.

/**
 * Perform a org.checkerframework.dataflow analysis over a single class tree and its nested
 * classes.
 */
protected void performFlowAnalysis(ClassTree classTree) {
    if (flowResult == null) {
        regularExitStores = new IdentityHashMap<>();
        returnStatementStores = new IdentityHashMap<>();
        flowResult = new AnalysisResult<>(flowResultAnalysisCaches);
    }
    // no need to scan annotations
    if (classTree.getKind() == Kind.ANNOTATION_TYPE) {
        // Mark finished so that default annotations will be applied.
        scannedClasses.put(classTree, ScanState.FINISHED);
        return;
    }
    Queue<ClassTree> queue = new ArrayDeque<>();
    List<Pair<VariableElement, Value>> fieldValues = new ArrayList<>();
    queue.add(classTree);
    while (!queue.isEmpty()) {
        ClassTree ct = queue.remove();
        scannedClasses.put(ct, ScanState.IN_PROGRESS);
        AnnotatedDeclaredType preClassType = visitorState.getClassType();
        ClassTree preClassTree = visitorState.getClassTree();
        AnnotatedDeclaredType preAMT = visitorState.getMethodReceiver();
        MethodTree preMT = visitorState.getMethodTree();
        visitorState.setClassType(getAnnotatedType(ct));
        visitorState.setClassTree(ct);
        visitorState.setMethodReceiver(null);
        visitorState.setMethodTree(null);
        // start without a initialization store
        initializationStaticStore = null;
        initializationStore = null;
        Queue<Pair<LambdaExpressionTree, Store>> lambdaQueue = new ArrayDeque<>();
        try {
            List<CFGMethod> methods = new ArrayList<>();
            for (Tree m : ct.getMembers()) {
                switch(m.getKind()) {
                    case METHOD:
                        MethodTree mt = (MethodTree) m;
                        // Skip abstract and native methods because they have no body.
                        ModifiersTree modifiers = mt.getModifiers();
                        if (modifiers != null) {
                            Set<Modifier> flags = modifiers.getFlags();
                            if (flags.contains(Modifier.ABSTRACT) || flags.contains(Modifier.NATIVE)) {
                                break;
                            }
                        }
                        // ABSTRACT flag.
                        if (mt.getBody() == null) {
                            break;
                        }
                        // Wait with scanning the method until all other members
                        // have been processed.
                        CFGMethod met = new CFGMethod(mt, ct);
                        methods.add(met);
                        break;
                    case VARIABLE:
                        VariableTree vt = (VariableTree) m;
                        ExpressionTree initializer = vt.getInitializer();
                        // analyze initializer if present
                        if (initializer != null) {
                            boolean isStatic = vt.getModifiers().getFlags().contains(Modifier.STATIC);
                            analyze(queue, lambdaQueue, new CFGStatement(vt, ct), fieldValues, classTree, true, true, isStatic);
                            Value value = flowResult.getValue(initializer);
                            if (value != null) {
                                // Store the abstract value for the field.
                                VariableElement element = TreeUtils.elementFromDeclaration(vt);
                                fieldValues.add(Pair.of(element, value));
                            }
                        }
                        break;
                    case CLASS:
                    case ANNOTATION_TYPE:
                    case INTERFACE:
                    case ENUM:
                        // Visit inner and nested class trees.
                        queue.add((ClassTree) m);
                        break;
                    case BLOCK:
                        BlockTree b = (BlockTree) m;
                        analyze(queue, lambdaQueue, new CFGStatement(b, ct), fieldValues, ct, true, true, b.isStatic());
                        break;
                    default:
                        assert false : "Unexpected member: " + m.getKind();
                        break;
                }
            }
            // fields of superclasses.
            for (CFGMethod met : methods) {
                analyze(queue, lambdaQueue, met, fieldValues, classTree, TreeUtils.isConstructor(met.getMethod()), false, false);
            }
            while (!lambdaQueue.isEmpty()) {
                Pair<LambdaExpressionTree, Store> lambdaPair = lambdaQueue.poll();
                analyze(queue, lambdaQueue, new CFGLambda(lambdaPair.first), fieldValues, classTree, false, false, false, lambdaPair.second);
            }
            // see InitializationVisitor.visitClass
            if (initializationStaticStore == null) {
                regularExitStores.put(ct, emptyStore);
            } else {
                regularExitStores.put(ct, initializationStaticStore);
            }
        } finally {
            visitorState.setClassType(preClassType);
            visitorState.setClassTree(preClassTree);
            visitorState.setMethodReceiver(preAMT);
            visitorState.setMethodTree(preMT);
        }
        scannedClasses.put(ct, ScanState.FINISHED);
    }
}
Also used : ModifiersTree(com.sun.source.tree.ModifiersTree) MethodTree(com.sun.source.tree.MethodTree) CFGMethod(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod) CFGStatement(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGStatement) NewClassTree(com.sun.source.tree.NewClassTree) ClassTree(com.sun.source.tree.ClassTree) ArrayList(java.util.ArrayList) VariableTree(com.sun.source.tree.VariableTree) CFStore(org.checkerframework.framework.flow.CFStore) CFAbstractStore(org.checkerframework.framework.flow.CFAbstractStore) VariableElement(javax.lang.model.element.VariableElement) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) BlockTree(com.sun.source.tree.BlockTree) ReturnTree(com.sun.source.tree.ReturnTree) UnaryTree(com.sun.source.tree.UnaryTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) ModifiersTree(com.sun.source.tree.ModifiersTree) MethodTree(com.sun.source.tree.MethodTree) ClassTree(com.sun.source.tree.ClassTree) MemberReferenceTree(com.sun.source.tree.MemberReferenceTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree) BlockTree(com.sun.source.tree.BlockTree) Modifier(javax.lang.model.element.Modifier) Pair(org.checkerframework.javacutil.Pair) ArrayDeque(java.util.ArrayDeque) CFAbstractValue(org.checkerframework.framework.flow.CFAbstractValue) CFValue(org.checkerframework.framework.flow.CFValue) CFGLambda(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGLambda)

Aggregations

VariableTree (com.sun.source.tree.VariableTree)86 Tree (com.sun.source.tree.Tree)43 ClassTree (com.sun.source.tree.ClassTree)37 MethodTree (com.sun.source.tree.MethodTree)37 ExpressionTree (com.sun.source.tree.ExpressionTree)34 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)25 NewClassTree (com.sun.source.tree.NewClassTree)23 TreePath (com.sun.source.util.TreePath)23 IdentifierTree (com.sun.source.tree.IdentifierTree)22 JCTree (com.sun.tools.javac.tree.JCTree)21 MemberSelectTree (com.sun.source.tree.MemberSelectTree)19 AssignmentTree (com.sun.source.tree.AssignmentTree)17 ArrayList (java.util.ArrayList)17 BlockTree (com.sun.source.tree.BlockTree)16 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)13 Type (com.sun.tools.javac.code.Type)13 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)12 ReturnTree (com.sun.source.tree.ReturnTree)12 StatementTree (com.sun.source.tree.StatementTree)12 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)12