Search in sources :

Example 46 with MethodTree

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

the class ReturnsReceiverVisitor method visitAnnotation.

@Override
public Void visitAnnotation(AnnotationTree node, Void p) {
    AnnotationMirror annot = TreeUtils.annotationFromAnnotationTree(node);
    // Warn if a @This annotation is in an illegal location.
    if (AnnotationUtils.areSame(annot, getTypeFactory().THIS_ANNOTATION)) {
        TreePath parentPath = getCurrentPath().getParentPath();
        Tree parent = parentPath.getLeaf();
        Tree grandparent = parentPath.getParentPath().getLeaf();
        Tree greatGrandparent = parentPath.getParentPath().getParentPath().getLeaf();
        boolean isReturnAnnot = grandparent instanceof MethodTree && (parent.equals(((MethodTree) grandparent).getReturnType()) || parent instanceof ModifiersTree);
        boolean isReceiverAnnot = greatGrandparent instanceof MethodTree && grandparent.equals(((MethodTree) greatGrandparent).getReceiverParameter()) && parent.equals(((VariableTree) grandparent).getModifiers());
        boolean isCastAnnot = grandparent instanceof TypeCastTree && parent.equals(((TypeCastTree) grandparent).getType());
        if (!(isReturnAnnot || isReceiverAnnot || isCastAnnot)) {
            checker.reportError(node, "this.location");
        }
        if (isReturnAnnot && ElementUtils.isStatic(TreeUtils.elementFromDeclaration((MethodTree) grandparent))) {
            checker.reportError(node, "this.location");
        }
    }
    return super.visitAnnotation(node, p);
}
Also used : TypeCastTree(com.sun.source.tree.TypeCastTree) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TreePath(com.sun.source.util.TreePath) ModifiersTree(com.sun.source.tree.ModifiersTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) TypeCastTree(com.sun.source.tree.TypeCastTree) ModifiersTree(com.sun.source.tree.ModifiersTree) Tree(com.sun.source.tree.Tree)

Example 47 with MethodTree

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

the class WholeProgramInferenceImplementation method isRecursiveCall.

/**
 * Returns true if the given call is a recursive call.
 *
 * @param methodInvNode a method invocation
 * @return true if the given call is a recursive call
 */
private boolean isRecursiveCall(MethodInvocationNode methodInvNode) {
    MethodTree enclosingMethod = TreePathUtil.enclosingMethod(methodInvNode.getTreePath());
    if (enclosingMethod == null) {
        return false;
    }
    ExecutableElement methodInvocEle = TreeUtils.elementFromUse(methodInvNode.getTree());
    ExecutableElement methodDeclEle = TreeUtils.elementFromDeclaration(enclosingMethod);
    return methodDeclEle.equals(methodInvocEle);
}
Also used : MethodTree(com.sun.source.tree.MethodTree) ExecutableElement(javax.lang.model.element.ExecutableElement)

Example 48 with MethodTree

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

the class BaseTypeVisitor method parseAndLocalizeContracts.

/**
 * Localizes some contracts -- that is, viewpoint-adapts them to some method body, according to
 * the value of {@link #methodTree}.
 *
 * <p>The input is a set of {@link Contract}s, each of which contains an expression string and an
 * annotation. In a {@link Contract}, Java expressions are exactly as written in source code, not
 * standardized or viewpoint-adapted.
 *
 * <p>The output is a set of pairs of {@link JavaExpression} (parsed expression string) and
 * standardized annotation (with respect to the path of {@link #methodTree}. This method discards
 * any contract whose expression cannot be parsed into a JavaExpression.
 *
 * @param contractSet a set of contracts
 * @param methodType the type of the method that the contracts are for
 * @return pairs of (expression, AnnotationMirror), which are localized contracts
 */
private Set<Pair<JavaExpression, AnnotationMirror>> parseAndLocalizeContracts(Set<? extends Contract> contractSet, AnnotatedExecutableType methodType) {
    if (contractSet.isEmpty()) {
        return Collections.emptySet();
    }
    // This is the path to a place where the contract is being used, which might or might not be
    // where the contract was defined.  For example, methodTree might be an overriding
    // definition, and the contract might be for a superclass.
    MethodTree methodTree = this.methodTree;
    StringToJavaExpression stringToJavaExpr = expression -> {
        JavaExpression javaExpr = StringToJavaExpression.atMethodDecl(expression, methodType.getElement(), checker);
        // viewpoint-adapt it to methodTree.
        return javaExpr.atMethodBody(methodTree);
    };
    Set<Pair<JavaExpression, AnnotationMirror>> result = new HashSet<>(contractSet.size());
    for (Contract p : contractSet) {
        String expressionString = p.expressionString;
        AnnotationMirror annotation = p.viewpointAdaptDependentTypeAnnotation(atypeFactory, stringToJavaExpr, methodTree);
        JavaExpression exprJe;
        try {
            // TODO: currently, these expressions are parsed many times.
            // This could be optimized to store the result the first time.
            // (same for other annotations)
            exprJe = stringToJavaExpr.toJavaExpression(expressionString);
        } catch (JavaExpressionParseException e) {
            // report errors here
            checker.report(methodTree, e.getDiagMessage());
            continue;
        }
        result.add(Pair.of(exprJe, annotation));
    }
    return result;
}
Also used : AnnotationEqualityVisitor(org.checkerframework.framework.ajava.AnnotationEqualityVisitor) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) Arrays(java.util.Arrays) TransferResult(org.checkerframework.dataflow.analysis.TransferResult) AnnotatedArrayType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType) Modifier(javax.lang.model.element.Modifier) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) TypeElement(javax.lang.model.element.TypeElement) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) DefaultPrettyPrinter(com.github.javaparser.printer.DefaultPrettyPrinter) GenericAnnotatedTypeFactory(org.checkerframework.framework.type.GenericAnnotatedTypeFactory) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) Vector(java.util.Vector) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) Map(java.util.Map) InstanceOfTree(com.sun.source.tree.InstanceOfTree) EnumSet(java.util.EnumSet) SideEffectFree(org.checkerframework.dataflow.qual.SideEffectFree) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) TreePath(com.sun.source.util.TreePath) Pure(org.checkerframework.dataflow.qual.Pure) Set(java.util.Set) AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType) Element(javax.lang.model.element.Element) MemberSelectTree(com.sun.source.tree.MemberSelectTree) TreeUtils(org.checkerframework.javacutil.TreeUtils) TreeScanner(com.sun.source.util.TreeScanner) ParameterizedExecutableType(org.checkerframework.framework.type.AnnotatedTypeFactory.ParameterizedExecutableType) Unused(org.checkerframework.framework.qual.Unused) ThrowTree(com.sun.source.tree.ThrowTree) JCIdent(com.sun.tools.javac.tree.JCTree.JCIdent) AnnotationValue(javax.lang.model.element.AnnotationValue) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) TypesUtils(org.checkerframework.javacutil.TypesUtils) AnnotatedPrimitiveType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedPrimitiveType) ReturnTree(com.sun.source.tree.ReturnTree) PurityResult(org.checkerframework.dataflow.util.PurityChecker.PurityResult) ArrayTypeTree(com.sun.source.tree.ArrayTypeTree) ConditionalPostcondition(org.checkerframework.framework.util.Contract.ConditionalPostcondition) UnaryTree(com.sun.source.tree.UnaryTree) CFAbstractValue(org.checkerframework.framework.flow.CFAbstractValue) VariableElement(javax.lang.model.element.VariableElement) VariableTree(com.sun.source.tree.VariableTree) BooleanLiteralNode(org.checkerframework.dataflow.cfg.node.BooleanLiteralNode) ReferenceKind(com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind) TypeParameterTree(com.sun.source.tree.TypeParameterTree) ArrayList(java.util.ArrayList) CompilerMessageKey(org.checkerframework.checker.compilermsgs.qual.CompilerMessageKey) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) Precondition(org.checkerframework.framework.util.Contract.Precondition) FindDistinct(org.checkerframework.checker.interning.qual.FindDistinct) SwitchExpressionScanner(org.checkerframework.javacutil.SwitchExpressionScanner) TreeInfo(com.sun.tools.javac.tree.TreeInfo) DeclaredType(javax.lang.model.type.DeclaredType) TreePathUtil(org.checkerframework.javacutil.TreePathUtil) ElementFilter(javax.lang.model.util.ElementFilter) Tree(com.sun.source.tree.Tree) LinkedHashSet(java.util.LinkedHashSet) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) SourceVisitor(org.checkerframework.framework.source.SourceVisitor) QualifierPolymorphism(org.checkerframework.framework.type.poly.QualifierPolymorphism) FieldInvariants(org.checkerframework.framework.util.FieldInvariants) ExpressionTree(com.sun.source.tree.ExpressionTree) IOException(java.io.IOException) Target(java.lang.annotation.Target) AnnotationMirror(javax.lang.model.element.AnnotationMirror) StringToJavaExpression(org.checkerframework.framework.util.StringToJavaExpression) ParseProblemException(com.github.javaparser.ParseProblemException) DiagMessage(org.checkerframework.framework.source.DiagMessage) SourcePositions(com.sun.source.util.SourcePositions) IntersectionTypeTree(com.sun.source.tree.IntersectionTypeTree) FunctionalSwitchExpressionScanner(org.checkerframework.javacutil.SwitchExpressionScanner.FunctionalSwitchExpressionScanner) ElementUtils(org.checkerframework.javacutil.ElementUtils) ContractsFromMethod(org.checkerframework.framework.util.ContractsFromMethod) CollectionsPlume(org.plumelib.util.CollectionsPlume) PurityUtils(org.checkerframework.dataflow.util.PurityUtils) JointVisitorWithDefaultAction(org.checkerframework.framework.ajava.JointVisitorWithDefaultAction) AnnotatedIntersectionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType) BugInCF(org.checkerframework.javacutil.BugInCF) PurityChecker(org.checkerframework.dataflow.util.PurityChecker) JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) AnnotatedTypeTree(com.sun.source.tree.AnnotatedTypeTree) InsertAjavaAnnotations(org.checkerframework.framework.ajava.InsertAjavaAnnotations) JCMemberReference(com.sun.tools.javac.tree.JCTree.JCMemberReference) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) NewArrayTree(com.sun.source.tree.NewArrayTree) CompilationUnit(com.github.javaparser.ast.CompilationUnit) Pair(org.checkerframework.javacutil.Pair) ArraysPlume(org.plumelib.util.ArraysPlume) ReferenceMode(com.sun.source.tree.MemberReferenceTree.ReferenceMode) Analysis(org.checkerframework.dataflow.analysis.Analysis) WholeProgramInference(org.checkerframework.common.wholeprograminference.WholeProgramInference) ExpectedTreesVisitor(org.checkerframework.framework.ajava.ExpectedTreesVisitor) CFAbstractStore(org.checkerframework.framework.flow.CFAbstractStore) Contract(org.checkerframework.framework.util.Contract) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) AnnotatedTypeParameterBounds(org.checkerframework.framework.type.AnnotatedTypeParameterBounds) TypeKind(javax.lang.model.type.TypeKind) List(java.util.List) LocalVariable(org.checkerframework.dataflow.expression.LocalVariable) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) TypeHierarchy(org.checkerframework.framework.type.TypeHierarchy) Annotation(java.lang.annotation.Annotation) ModifiersTree(com.sun.source.tree.ModifiersTree) AnnotatedTypes(org.checkerframework.framework.util.AnnotatedTypes) Postcondition(org.checkerframework.framework.util.Contract.Postcondition) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) HashMap(java.util.HashMap) HashSet(java.util.HashSet) Kind(javax.tools.Diagnostic.Kind) AnnotationBuilder(org.checkerframework.javacutil.AnnotationBuilder) AnnotationUtils(org.checkerframework.javacutil.AnnotationUtils) ClassTree(com.sun.source.tree.ClassTree) Nullable(org.checkerframework.checker.nullness.qual.Nullable) Name(javax.lang.model.element.Name) JavaExpressionParseException(org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException) ElementKind(javax.lang.model.element.ElementKind) MemberReferenceTree(com.sun.source.tree.MemberReferenceTree) ExecutableElement(javax.lang.model.element.ExecutableElement) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) JCTree(com.sun.tools.javac.tree.JCTree) ElementType(java.lang.annotation.ElementType) SimpleAnnotatedTypeScanner(org.checkerframework.framework.type.visitor.SimpleAnnotatedTypeScanner) JavaExpressionScanner(org.checkerframework.dataflow.expression.JavaExpressionScanner) AnnotatedTypeFactory(org.checkerframework.framework.type.AnnotatedTypeFactory) AnnotatedUnionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedUnionType) TypeMirror(javax.lang.model.type.TypeMirror) StringJoiner(java.util.StringJoiner) ProcessingEnvironment(javax.annotation.processing.ProcessingEnvironment) Deterministic(org.checkerframework.dataflow.qual.Deterministic) JavaParserUtil(org.checkerframework.framework.util.JavaParserUtil) Collections(java.util.Collections) Node(org.checkerframework.dataflow.cfg.node.Node) DefaultQualifier(org.checkerframework.framework.qual.DefaultQualifier) InputStream(java.io.InputStream) AnnotationMirror(javax.lang.model.element.AnnotationMirror) StringToJavaExpression(org.checkerframework.framework.util.StringToJavaExpression) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) MethodTree(com.sun.source.tree.MethodTree) StringToJavaExpression(org.checkerframework.framework.util.StringToJavaExpression) JavaExpressionParseException(org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException) Contract(org.checkerframework.framework.util.Contract) Pair(org.checkerframework.javacutil.Pair) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet)

Example 49 with MethodTree

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

the class BaseTypeVisitor method checkThisOrSuperConstructorCall.

/**
 * Checks that the following rule is satisfied: The type on a constructor declaration must be a
 * supertype of the return type of "this()" or "super()" invocation within that constructor.
 *
 * @param call the AST node for the constructor call
 * @param errorKey the error message key to use if the check fails
 */
protected void checkThisOrSuperConstructorCall(MethodInvocationTree call, @CompilerMessageKey String errorKey) {
    TreePath path = atypeFactory.getPath(call);
    MethodTree enclosingMethod = TreePathUtil.enclosingMethod(path);
    AnnotatedTypeMirror superType = atypeFactory.getAnnotatedType(call);
    AnnotatedExecutableType constructorType = atypeFactory.getAnnotatedType(enclosingMethod);
    Set<? extends AnnotationMirror> topAnnotations = atypeFactory.getQualifierHierarchy().getTopAnnotations();
    for (AnnotationMirror topAnno : topAnnotations) {
        AnnotationMirror superTypeMirror = superType.getAnnotationInHierarchy(topAnno);
        AnnotationMirror constructorTypeMirror = constructorType.getReturnType().getAnnotationInHierarchy(topAnno);
        if (!atypeFactory.getQualifierHierarchy().isSubtype(superTypeMirror, constructorTypeMirror)) {
            checker.reportError(call, errorKey, constructorTypeMirror, call, superTypeMirror);
        }
    }
}
Also used : AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TreePath(com.sun.source.util.TreePath) MethodTree(com.sun.source.tree.MethodTree) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 50 with MethodTree

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

the class BaseTypeVisitor method visitMethod.

/**
 * Checks that the method obeys override and subtype rules to all overridden methods. (Uses the
 * pseudo-assignment logic to do so.)
 *
 * <p>The override rule specifies that a method, m1, may override a method m2 only if:
 *
 * <ul>
 *   <li>m1 return type is a subtype of m2
 *   <li>m1 receiver type is a supertype of m2
 *   <li>m1 parameters are supertypes of corresponding m2 parameters
 * </ul>
 *
 * Also, it issues a "missing.this" error for static method annotated receivers.
 */
@Override
public Void visitMethod(MethodTree node, Void p) {
    // We copy the result from getAnnotatedType to ensure that circular types (e.g. K extends
    // Comparable<K>) are represented by circular AnnotatedTypeMirrors, which avoids problems with
    // later checks.
    // TODO: Find a cleaner way to ensure circular AnnotatedTypeMirrors.
    AnnotatedExecutableType methodType = atypeFactory.getAnnotatedType(node).deepCopy();
    MethodTree preMT = methodTree;
    methodTree = node;
    ExecutableElement methodElement = TreeUtils.elementFromDeclaration(node);
    warnAboutTypeAnnotationsTooEarly(node, node.getModifiers());
    if (node.getReturnType() != null) {
        visitAnnotatedType(node.getModifiers().getAnnotations(), node.getReturnType());
    }
    try {
        if (TreeUtils.isAnonymousConstructor(node)) {
            // We shouldn't dig deeper
            return null;
        }
        if (TreeUtils.isConstructor(node)) {
            checkConstructorResult(methodType, methodElement);
        }
        checkPurity(node);
        // Passing the whole method/constructor validates the return type
        validateTypeOf(node);
        // Validate types in throws clauses
        for (ExpressionTree thr : node.getThrows()) {
            validateTypeOf(thr);
        }
        atypeFactory.getDependentTypesHelper().checkMethodForErrorExpressions(node, methodType);
        // Check method overrides
        AnnotatedDeclaredType enclosingType = (AnnotatedDeclaredType) atypeFactory.getAnnotatedType(methodElement.getEnclosingElement());
        // Find which methods this method overrides
        Map<AnnotatedDeclaredType, ExecutableElement> overriddenMethods = AnnotatedTypes.overriddenMethods(elements, atypeFactory, methodElement);
        for (Map.Entry<AnnotatedDeclaredType, ExecutableElement> pair : overriddenMethods.entrySet()) {
            AnnotatedDeclaredType overriddenType = pair.getKey();
            ExecutableElement overriddenMethodElt = pair.getValue();
            AnnotatedExecutableType overriddenMethodType = AnnotatedTypes.asMemberOf(types, atypeFactory, overriddenType, overriddenMethodElt);
            if (!checkOverride(node, enclosingType, overriddenMethodType, overriddenType)) {
                // the same method, not adding any value. See Issue 373.
                break;
            }
        }
        // Check well-formedness of pre/postcondition
        boolean abstractMethod = methodElement.getModifiers().contains(Modifier.ABSTRACT) || methodElement.getModifiers().contains(Modifier.NATIVE);
        List<String> formalParamNames = CollectionsPlume.mapList((VariableTree param) -> param.getName().toString(), node.getParameters());
        checkContractsAtMethodDeclaration(node, methodElement, formalParamNames, abstractMethod);
        // Infer postconditions
        if (atypeFactory.getWholeProgramInference() != null) {
            assert ElementUtils.isElementFromSourceCode(methodElement);
            // TODO: Infer conditional postconditions too.
            CFAbstractStore<?, ?> store = atypeFactory.getRegularExitStore(node);
            // throw statement.
            if (store != null) {
                atypeFactory.getWholeProgramInference().updateContracts(Analysis.BeforeOrAfter.AFTER, methodElement, store);
            }
        }
        checkForPolymorphicQualifiers(node.getTypeParameters());
        return super.visitMethod(node, p);
    } finally {
        methodTree = preMT;
    }
}
Also used : MethodTree(com.sun.source.tree.MethodTree) ExecutableElement(javax.lang.model.element.ExecutableElement) VariableTree(com.sun.source.tree.VariableTree) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

MethodTree (com.sun.source.tree.MethodTree)127 ClassTree (com.sun.source.tree.ClassTree)66 Tree (com.sun.source.tree.Tree)65 VariableTree (com.sun.source.tree.VariableTree)58 ExpressionTree (com.sun.source.tree.ExpressionTree)54 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)43 ExecutableElement (javax.lang.model.element.ExecutableElement)39 NewClassTree (com.sun.source.tree.NewClassTree)38 TreePath (com.sun.source.util.TreePath)33 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)32 MemberSelectTree (com.sun.source.tree.MemberSelectTree)28 AnnotationTree (com.sun.source.tree.AnnotationTree)25 IdentifierTree (com.sun.source.tree.IdentifierTree)25 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)23 ReturnTree (com.sun.source.tree.ReturnTree)22 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)22 ArrayList (java.util.ArrayList)22 TypeElement (javax.lang.model.element.TypeElement)21 AssignmentTree (com.sun.source.tree.AssignmentTree)20 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)20