Search in sources :

Example 11 with MethodTree

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

the class CFAbstractTransfer method addFieldValues.

private void addFieldValues(S info, AnnotatedTypeFactory factory, ClassTree classTree, MethodTree methodTree) {
    // Add knowledge about final fields, or values of non-final fields
    // if we are inside a constructor (information about initializers)
    TypeMirror classType = TreeUtils.typeOf(classTree);
    List<Pair<VariableElement, V>> fieldValues = analysis.getFieldValues();
    for (Pair<VariableElement, V> p : fieldValues) {
        VariableElement element = p.first;
        V value = p.second;
        if (ElementUtils.isFinal(element) || TreeUtils.isConstructor(methodTree)) {
            Receiver receiver;
            if (ElementUtils.isStatic(element)) {
                receiver = new ClassName(classType);
            } else {
                receiver = new ThisReference(classType);
            }
            TypeMirror fieldType = ElementUtils.getType(element);
            Receiver field = new FieldAccess(receiver, fieldType, element);
            info.insertValue(field, value);
        }
    }
    // add properties about fields (static information from type)
    boolean isNotFullyInitializedReceiver = isNotFullyInitializedReceiver(methodTree);
    if (isNotFullyInitializedReceiver && !TreeUtils.isConstructor(methodTree)) {
        // and the method isn't a constructor
        return;
    }
    for (Tree member : classTree.getMembers()) {
        if (member instanceof VariableTree) {
            VariableTree vt = (VariableTree) member;
            final VariableElement element = TreeUtils.elementFromDeclaration(vt);
            AnnotatedTypeMirror type = ((GenericAnnotatedTypeFactory<?, ?, ?, ?>) factory).getAnnotatedTypeLhs(vt);
            TypeMirror fieldType = ElementUtils.getType(element);
            Receiver receiver;
            if (ElementUtils.isStatic(element)) {
                receiver = new ClassName(classType);
            } else {
                receiver = new ThisReference(classType);
            }
            V value = analysis.createAbstractValue(type);
            if (value == null)
                continue;
            if (TreeUtils.isConstructor(methodTree)) {
                // if we are in a constructor,
                // then we can still use the static type, but only
                // if there is also an initializer that already does
                // some initialization.
                boolean found = false;
                for (Pair<VariableElement, V> fieldValue : fieldValues) {
                    if (fieldValue.first.equals(element)) {
                        value = value.leastUpperBound(fieldValue.second);
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    // no initializer found, cannot use static type
                    continue;
                }
            }
            Receiver field = new FieldAccess(receiver, fieldType, element);
            info.insertValue(field, value);
        }
    }
}
Also used : GenericAnnotatedTypeFactory(org.checkerframework.framework.type.GenericAnnotatedTypeFactory) VariableTree(com.sun.source.tree.VariableTree) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) VariableElement(javax.lang.model.element.VariableElement) ThisReference(org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) ClassName(org.checkerframework.dataflow.analysis.FlowExpressions.ClassName) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) FieldAccess(org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess) Pair(org.checkerframework.javacutil.Pair)

Example 12 with MethodTree

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

the class SourceChecker method shouldSuppressWarnings.

/**
 * Determines whether all the warnings pertaining to a given tree should be suppressed. Returns
 * true if the tree is within the scope of a @SuppressWarnings annotation, one of whose values
 * suppresses the checker's warnings. The list of keys that suppress a checker's warnings is
 * provided by the {@link SourceChecker#getSuppressWarningsKeys} method.
 *
 * @param tree the tree that might be a source of a warning
 * @param errKey the error key the checker is emitting
 * @return true if no warning should be emitted for the given tree because it is contained by a
 *     declaration with an appropriately-valued {@literal @}SuppressWarnings annotation; false
 *     otherwise
 */
// Public so it can be called from a few places in
// org.checkerframework.framework.flow.CFAbstractTransfer
public boolean shouldSuppressWarnings(Tree tree, String errKey) {
    // Don't suppress warnings if this checker provides no key to do so.
    Collection<String> checkerKeys = this.getSuppressWarningsKeys();
    if (checkerKeys.isEmpty()) {
        return false;
    }
    // trees.getPath might be slow, but this is only used in error reporting
    // TODO: #1586 this might return null within a cloned finally block and
    // then a warning that should be suppressed isn't. Fix this when fixing #1586.
    @Nullable TreePath path = trees.getPath(this.currentRoot, tree);
    if (path == null) {
        return false;
    }
    @Nullable VariableTree var = TreeUtils.enclosingVariable(path);
    if (var != null && shouldSuppressWarnings(TreeUtils.elementFromTree(var), errKey)) {
        return true;
    }
    @Nullable MethodTree method = TreeUtils.enclosingMethod(path);
    if (method != null) {
        @Nullable Element elt = TreeUtils.elementFromTree(method);
        if (shouldSuppressWarnings(elt, errKey)) {
            return true;
        }
        if (isAnnotatedForThisCheckerOrUpstreamChecker(elt)) {
            // @AnnotatedFor.
            return false;
        }
    }
    @Nullable ClassTree cls = TreeUtils.enclosingClass(path);
    if (cls != null) {
        @Nullable Element elt = TreeUtils.elementFromTree(cls);
        if (shouldSuppressWarnings(elt, errKey)) {
            return true;
        }
        if (isAnnotatedForThisCheckerOrUpstreamChecker(elt)) {
            // @AnnotatedFor.
            return false;
        }
    }
    if (useUncheckedCodeDefault("source")) {
        // false, we DO suppress the warning.
        return true;
    }
    return false;
}
Also used : TreePath(com.sun.source.util.TreePath) MethodTree(com.sun.source.tree.MethodTree) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) VariableTree(com.sun.source.tree.VariableTree) ClassTree(com.sun.source.tree.ClassTree) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Example 13 with MethodTree

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

the class AnnotatedTypeFactory method getMostInnerClassOrMethod.

private final Element getMostInnerClassOrMethod(Tree tree) {
    if (visitorState.getMethodTree() != null) {
        return TreeUtils.elementFromDeclaration(visitorState.getMethodTree());
    }
    if (visitorState.getClassTree() != null) {
        return TreeUtils.elementFromDeclaration(visitorState.getClassTree());
    }
    TreePath path = getPath(tree);
    if (path == null) {
        ErrorReporter.errorAbort(String.format("AnnotatedTypeFactory.getMostInnerClassOrMethod: getPath(tree)=>null%n  TreePath.getPath(root, tree)=>%s\n  for tree (%s) = %s%n  root=%s", TreePath.getPath(root, tree), tree.getClass(), tree, root));
        // dead code
        return null;
    }
    for (Tree pathTree : path) {
        if (pathTree instanceof MethodTree) {
            return TreeUtils.elementFromDeclaration((MethodTree) pathTree);
        } else if (pathTree instanceof ClassTree) {
            return TreeUtils.elementFromDeclaration((ClassTree) pathTree);
        }
    }
    ErrorReporter.errorAbort("AnnotatedTypeFactory.getMostInnerClassOrMethod: cannot be here!");
    // dead code
    return null;
}
Also used : TreePath(com.sun.source.util.TreePath) MethodTree(com.sun.source.tree.MethodTree) NewClassTree(com.sun.source.tree.NewClassTree) ClassTree(com.sun.source.tree.ClassTree) 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)

Example 14 with MethodTree

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

the class GenericAnnotatedTypeFactory method analyze.

protected void analyze(Queue<ClassTree> queue, Queue<Pair<LambdaExpressionTree, Store>> lambdaQueue, UnderlyingAST ast, List<Pair<VariableElement, Value>> fieldValues, ClassTree currentClass, boolean isInitializationCode, boolean updateInitializationStore, boolean isStatic, Store lambdaStore) {
    CFGBuilder builder = new CFCFGBuilder(checker, this);
    ControlFlowGraph cfg = builder.run(root, processingEnv, ast);
    FlowAnalysis newAnalysis = createFlowAnalysis(fieldValues);
    TransferFunction transfer = newAnalysis.getTransferFunction();
    if (emptyStore == null) {
        emptyStore = newAnalysis.createEmptyStore(transfer.usesSequentialSemantics());
    }
    analyses.addFirst(newAnalysis);
    if (lambdaStore != null) {
        transfer.setFixedInitialStore(lambdaStore);
    } else {
        Store initStore = !isStatic ? initializationStore : initializationStaticStore;
        if (isInitializationCode) {
            if (initStore != null) {
                // we have already seen initialization code and analyzed it, and
                // the analysis ended with the store initStore.
                // use it to start the next analysis.
                transfer.setFixedInitialStore(initStore);
            }
        }
    }
    analyses.getFirst().performAnalysis(cfg);
    AnalysisResult<Value, Store> result = analyses.getFirst().getResult();
    // store result
    flowResult.combine(result);
    if (ast.getKind() == UnderlyingAST.Kind.METHOD) {
        // store exit store (for checking postconditions)
        CFGMethod mast = (CFGMethod) ast;
        MethodTree method = mast.getMethod();
        Store regularExitStore = analyses.getFirst().getRegularExitStore();
        if (regularExitStore != null) {
            regularExitStores.put(method, regularExitStore);
        }
        returnStatementStores.put(method, analyses.getFirst().getReturnStatementStores());
    } else if (ast.getKind() == UnderlyingAST.Kind.ARBITRARY_CODE) {
        CFGStatement block = (CFGStatement) ast;
        Store regularExitStore = analyses.getFirst().getRegularExitStore();
        if (regularExitStore != null) {
            regularExitStores.put(block.getCode(), regularExitStore);
        }
    } else if (ast.getKind() == UnderlyingAST.Kind.LAMBDA) {
        // TODO: Postconditions?
        CFGLambda block = (CFGLambda) ast;
        Store regularExitStore = analyses.getFirst().getRegularExitStore();
        if (regularExitStore != null) {
            regularExitStores.put(block.getCode(), regularExitStore);
        }
    }
    if (isInitializationCode && updateInitializationStore) {
        Store newInitStore = analyses.getFirst().getRegularExitStore();
        if (!isStatic) {
            initializationStore = newInitStore;
        } else {
            initializationStaticStore = newInitStore;
        }
    }
    if (checker.hasOption("flowdotdir") || checker.hasOption("cfgviz")) {
        handleCFGViz();
    }
    analyses.removeFirst();
    // add classes declared in method
    queue.addAll(builder.getDeclaredClasses());
    for (LambdaExpressionTree lambda : builder.getDeclaredLambdas()) {
        lambdaQueue.add(Pair.of(lambda, getStoreBefore(lambda)));
    }
}
Also used : CFGMethod(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod) MethodTree(com.sun.source.tree.MethodTree) CFGStatement(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGStatement) CFCFGBuilder(org.checkerframework.framework.flow.CFCFGBuilder) CFGBuilder(org.checkerframework.dataflow.cfg.CFGBuilder) CFStore(org.checkerframework.framework.flow.CFStore) CFAbstractStore(org.checkerframework.framework.flow.CFAbstractStore) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ControlFlowGraph(org.checkerframework.dataflow.cfg.ControlFlowGraph) CFAbstractValue(org.checkerframework.framework.flow.CFAbstractValue) CFValue(org.checkerframework.framework.flow.CFValue) CFGLambda(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGLambda) CFCFGBuilder(org.checkerframework.framework.flow.CFCFGBuilder)

Example 15 with MethodTree

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

the class BaseTypeVisitor method checkContractsSubset.

/**
 * Checks that {@code mustSubset} is a subset of {@code set} in the following sense: For every
 * expression in {@code mustSubset} there must be the same expression in {@code set}, with the
 * same (or a stronger) annotation.
 */
private void checkContractsSubset(String overriderMeth, String overriderTyp, String overriddenMeth, String overriddenTyp, Set<Pair<Receiver, AnnotationMirror>> mustSubset, Set<Pair<Receiver, AnnotationMirror>> set, @CompilerMessageKey String messageKey) {
    for (Pair<Receiver, AnnotationMirror> weak : mustSubset) {
        boolean found = false;
        for (Pair<Receiver, AnnotationMirror> strong : set) {
            // are we looking at a contract of the same receiver?
            if (weak.first.equals(strong.first)) {
                // check subtyping relationship of annotations
                QualifierHierarchy qualifierHierarchy = atypeFactory.getQualifierHierarchy();
                if (qualifierHierarchy.isSubtype(strong.second, weak.second)) {
                    found = true;
                    break;
                }
            }
        }
        if (!found) {
            MethodTree method = visitorState.getMethodTree();
            checker.report(Result.failure(messageKey, overriderMeth, overriderTyp, overriddenMeth, overriddenTyp, weak.second, weak.first), method);
        }
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) MethodTree(com.sun.source.tree.MethodTree) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)

Aggregations

MethodTree (com.sun.source.tree.MethodTree)91 Tree (com.sun.source.tree.Tree)46 ClassTree (com.sun.source.tree.ClassTree)45 VariableTree (com.sun.source.tree.VariableTree)39 ExpressionTree (com.sun.source.tree.ExpressionTree)36 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)28 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)22 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)20 TreePath (com.sun.source.util.TreePath)20 IdentifierTree (com.sun.source.tree.IdentifierTree)19 NewClassTree (com.sun.source.tree.NewClassTree)19 ReturnTree (com.sun.source.tree.ReturnTree)18 ExecutableElement (javax.lang.model.element.ExecutableElement)17 Symbol (com.sun.tools.javac.code.Symbol)16 ArrayList (java.util.ArrayList)15 AssignmentTree (com.sun.source.tree.AssignmentTree)14 BlockTree (com.sun.source.tree.BlockTree)14 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)14 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)14 MemberSelectTree (com.sun.source.tree.MemberSelectTree)14