Search in sources :

Example 11 with MethodSymbol

use of com.sun.tools.javac.code.Symbol.MethodSymbol in project error-prone by google.

the class ASTHelpers method findMatchingMethods.

/**
   * Finds all methods in any superclass of {@code startClass} with a certain {@code name} that
   * match the given {@code predicate}.
   *
   * @return The (possibly empty) set of methods in any superclass that match {@code predicate} and
   * have the given {@code name}.
   */
public static Set<MethodSymbol> findMatchingMethods(Name name, final Predicate<MethodSymbol> predicate, Type startClass, Types types) {
    Filter<Symbol> matchesMethodPredicate = sym -> sym instanceof MethodSymbol && predicate.apply((MethodSymbol) sym);
    Set<MethodSymbol> matchingMethods = new HashSet<>();
    // Iterate over all classes and interfaces that startClass inherits from.
    for (Type superClass : types.closure(startClass)) {
        // Iterate over all the methods declared in superClass.
        TypeSymbol superClassSymbol = superClass.tsym;
        Scope superClassSymbols = superClassSymbol.members();
        if (superClassSymbols != null) {
            // Can be null if superClass is a type variable
            for (Symbol symbol : superClassSymbols.getSymbolsByName(name, matchesMethodPredicate, NON_RECURSIVE)) {
                // By definition of the filter, we know that the symbol is a MethodSymbol.
                matchingMethods.add((MethodSymbol) symbol);
            }
        }
    }
    return matchingMethods;
}
Also used : Arrays(java.util.Arrays) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassType(com.sun.tools.javac.code.Type.ClassType) Nullness(com.google.errorprone.dataflow.nullnesspropagation.Nullness) JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) PackageTree(com.sun.source.tree.PackageTree) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) TypeVar(com.sun.tools.javac.code.Type.TypeVar) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) TypeTag(com.sun.tools.javac.code.TypeTag) IdentifierTree(com.sun.source.tree.IdentifierTree) Log(com.sun.tools.javac.util.Log) Matcher(com.google.errorprone.matchers.Matcher) URI(java.net.URI) JarURLConnection(java.net.JarURLConnection) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Filter(com.sun.tools.javac.util.Filter) TreePath(com.sun.source.util.TreePath) JCLiteral(com.sun.tools.javac.tree.JCTree.JCLiteral) DeferredDiagnosticHandler(com.sun.tools.javac.util.Log.DeferredDiagnosticHandler) Symbol(com.sun.tools.javac.code.Symbol) Set(java.util.Set) MemberSelectTree(com.sun.source.tree.MemberSelectTree) Collectors(java.util.stream.Collectors) TypeKind(javax.lang.model.type.TypeKind) List(java.util.List) CompletionFailure(com.sun.tools.javac.code.Symbol.CompletionFailure) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) Predicate(com.google.common.base.Predicate) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) Suppliers(com.google.errorprone.suppliers.Suppliers) JCIdent(com.sun.tools.javac.tree.JCTree.JCIdent) Annotation(java.lang.annotation.Annotation) ModifiersTree(com.sun.source.tree.ModifiersTree) MoreObjects.firstNonNull(com.google.common.base.MoreObjects.firstNonNull) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) Flags(com.sun.tools.javac.code.Flags) JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) Name(com.sun.tools.javac.util.Name) Scope(com.sun.tools.javac.code.Scope) Type(com.sun.tools.javac.code.Type) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) BinaryTree(com.sun.source.tree.BinaryTree) VariableTree(com.sun.source.tree.VariableTree) Deque(java.util.Deque) TypeParameterTree(com.sun.source.tree.TypeParameterTree) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) VisitorState(com.google.errorprone.VisitorState) JCPackageDecl(com.sun.tools.javac.tree.JCTree.JCPackageDecl) Kind(com.sun.source.tree.Tree.Kind) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) TreeInfo(com.sun.tools.javac.tree.TreeInfo) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) LinkedHashSet(java.util.LinkedHashSet) Nullable(javax.annotation.Nullable) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) Enter(com.sun.tools.javac.comp.Enter) ElementKind(javax.lang.model.element.ElementKind) ExpressionTree(com.sun.source.tree.ExpressionTree) CharMatcher(com.google.common.base.CharMatcher) IOException(java.io.IOException) JCTree(com.sun.tools.javac.tree.JCTree) AnnotationMirror(javax.lang.model.element.AnnotationMirror) NullnessAnalysis(com.google.errorprone.dataflow.nullnesspropagation.NullnessAnalysis) Types(com.sun.tools.javac.code.Types) JUnitMatchers(com.google.errorprone.matchers.JUnitMatchers) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) ArrayDeque(java.util.ArrayDeque) NON_RECURSIVE(com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE) Resolve(com.sun.tools.javac.comp.Resolve) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) ClassType(com.sun.tools.javac.code.Type.ClassType) Type(com.sun.tools.javac.code.Type) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) Scope(com.sun.tools.javac.code.Scope) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Symbol(com.sun.tools.javac.code.Symbol) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 12 with MethodSymbol

use of com.sun.tools.javac.code.Symbol.MethodSymbol in project error-prone by google.

the class AmbiguousMethodReference method matchClass.

@Override
public Description matchClass(ClassTree tree, VisitorState state) {
    ClassSymbol origin = getSymbol(tree);
    Types types = state.getTypes();
    Iterable<Symbol> members = types.membersClosure(getType(tree), /*skipInterface=*/
    false).getSymbols();
    // collect declared and inherited methods, grouped by reference descriptor
    Map<String, List<MethodSymbol>> methods = stream(members.spliterator(), false).filter(MethodSymbol.class::isInstance).map(MethodSymbol.class::cast).filter(m -> m.isConstructor() || m.owner.equals(origin)).collect(groupingBy(m -> methodReferenceDescriptor(types, m), toCollection(ArrayList::new)));
    // look for groups of ambiguous method references
    for (Tree member : tree.getMembers()) {
        if (!(member instanceof MethodTree)) {
            continue;
        }
        MethodSymbol msym = getSymbol((MethodTree) member);
        if (isSuppressed(msym)) {
            continue;
        }
        List<MethodSymbol> clash = methods.remove(methodReferenceDescriptor(types, msym));
        if (clash == null) {
            continue;
        }
        clash.remove(msym);
        // ignore overridden inherited methods and hidden interface methods
        clash.removeIf(m -> types.isSubSignature(msym.type, m.type));
        if (clash.isEmpty()) {
            continue;
        }
        String message = String.format("This method's reference is ambiguous, its name and functional interface type" + " are the same as: %s", clash.stream().map(m -> Signatures.prettyMethodSignature(origin, m)).collect(joining(", ")));
        state.reportMatch(buildDescription(member).setMessage(message).build());
    }
    return NO_MATCH;
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher) MethodTree(com.sun.source.tree.MethodTree) Collectors.groupingBy(java.util.stream.Collectors.groupingBy) ASTHelpers.getSymbol(com.google.errorprone.util.ASTHelpers.getSymbol) Symbol(com.sun.tools.javac.code.Symbol) NO_MATCH(com.google.errorprone.matchers.Description.NO_MATCH) ASTHelpers.getType(com.google.errorprone.util.ASTHelpers.getType) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) Collectors.joining(java.util.stream.Collectors.joining) ArrayList(java.util.ArrayList) Collectors.toCollection(java.util.stream.Collectors.toCollection) VisitorState(com.google.errorprone.VisitorState) List(java.util.List) Types(com.sun.tools.javac.code.Types) StreamSupport.stream(java.util.stream.StreamSupport.stream) Signatures(com.google.errorprone.util.Signatures) Description(com.google.errorprone.matchers.Description) Map(java.util.Map) BugPattern(com.google.errorprone.BugPattern) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) JDK(com.google.errorprone.BugPattern.Category.JDK) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) Types(com.sun.tools.javac.code.Types) MethodTree(com.sun.source.tree.MethodTree) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ASTHelpers.getSymbol(com.google.errorprone.util.ASTHelpers.getSymbol) Symbol(com.sun.tools.javac.code.Symbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ArrayList(java.util.ArrayList) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodTree(com.sun.source.tree.MethodTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ArrayList(java.util.ArrayList) List(java.util.List)

Example 13 with MethodSymbol

use of com.sun.tools.javac.code.Symbol.MethodSymbol in project error-prone by google.

the class BadAnnotationImplementation method matchClass.

@Override
public Description matchClass(ClassTree classTree, final VisitorState state) {
    if (!CLASS_TREE_MATCHER.matches(classTree, state)) {
        return Description.NO_MATCH;
    }
    // If this is an enum that is trying to implement Annotation, give a special error message.
    if (classTree.getKind() == Kind.ENUM) {
        return buildDescription(classTree).setMessage("Enums cannot correctly implement Annotation because their equals and hashCode " + "methods are final. Consider using AutoAnnotation instead of implementing " + "Annotation by hand.").build();
    }
    // Otherwise walk up type hierarchy looking for equals and hashcode methods
    MethodSymbol equals = null;
    MethodSymbol hashCode = null;
    final Types types = state.getTypes();
    Name equalsName = state.getName("equals");
    Predicate<MethodSymbol> equalsPredicate = new Predicate<MethodSymbol>() {

        @Override
        public boolean apply(MethodSymbol methodSymbol) {
            return !methodSymbol.isStatic() && ((methodSymbol.flags() & Flags.SYNTHETIC) == 0) && ((methodSymbol.flags() & Flags.ABSTRACT) == 0) && methodSymbol.getParameters().size() == 1 && types.isSameType(methodSymbol.getParameters().get(0).type, state.getSymtab().objectType);
        }
    };
    Name hashCodeName = state.getName("hashCode");
    Predicate<MethodSymbol> hashCodePredicate = new Predicate<MethodSymbol>() {

        @Override
        public boolean apply(MethodSymbol methodSymbol) {
            return !methodSymbol.isStatic() && ((methodSymbol.flags() & Flags.SYNTHETIC) == 0) && ((methodSymbol.flags() & Flags.ABSTRACT) == 0) && methodSymbol.getParameters().isEmpty();
        }
    };
    for (Type sup : types.closure(ASTHelpers.getSymbol(classTree).type)) {
        if (equals == null) {
            equals = getMatchingMethod(sup, equalsName, equalsPredicate);
        }
        if (hashCode == null) {
            hashCode = getMatchingMethod(sup, hashCodeName, hashCodePredicate);
        }
    }
    Verify.verifyNotNull(equals);
    Verify.verifyNotNull(hashCode);
    Symbol objectSymbol = state.getSymtab().objectType.tsym;
    if (equals.owner.equals(objectSymbol) || hashCode.owner.equals(objectSymbol)) {
        return describeMatch(classTree);
    }
    return Description.NO_MATCH;
}
Also used : Types(com.sun.tools.javac.code.Types) Type(com.sun.tools.javac.code.Type) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) Symbol(com.sun.tools.javac.code.Symbol) Name(com.sun.tools.javac.util.Name) Predicate(com.google.common.base.Predicate)

Example 14 with MethodSymbol

use of com.sun.tools.javac.code.Symbol.MethodSymbol in project error-prone by google.

the class FindIdentifiers method inStaticContext.

/** Returns true iff the leaf node of the {@code path} occurs in a JLS 8.3.1 static context. */
private static boolean inStaticContext(TreePath path) {
    Tree prev = path.getLeaf();
    path = path.getParentPath();
    ClassSymbol enclosingClass = ASTHelpers.getSymbol(ASTHelpers.findEnclosingNode(path, ClassTree.class));
    ClassSymbol directSuperClass = (ClassSymbol) enclosingClass.getSuperclass().tsym;
    for (Tree tree : path) {
        switch(tree.getKind()) {
            case METHOD:
                return ASTHelpers.getSymbol(tree).isStatic();
            case // static initializer
            BLOCK:
                if (((BlockTree) tree).isStatic()) {
                    return true;
                }
                break;
            case // variable initializer of static variable
            VARIABLE:
                VariableTree variableTree = (VariableTree) tree;
                VarSymbol variableSym = ASTHelpers.getSymbol(variableTree);
                if (variableSym.getKind() == ElementKind.FIELD) {
                    return Objects.equals(variableTree.getInitializer(), prev) && variableSym.isStatic();
                }
                break;
            case // JLS 8.8.7.1 explicit constructor invocation
            METHOD_INVOCATION:
                MethodSymbol methodSym = ASTHelpers.getSymbol((MethodInvocationTree) tree);
                if (methodSym == null) {
                    // visibility)
                    return true;
                }
                if (methodSym.isConstructor() && (Objects.equals(methodSym.owner, enclosingClass) || Objects.equals(methodSym.owner, directSuperClass))) {
                    return true;
                }
                break;
            default:
                break;
        }
        prev = tree;
    }
    return false;
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) NewClassTree(com.sun.source.tree.NewClassTree) ClassTree(com.sun.source.tree.ClassTree) VariableTree(com.sun.source.tree.VariableTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) ForLoopTree(com.sun.source.tree.ForLoopTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) BlockTree(com.sun.source.tree.BlockTree) StatementTree(com.sun.source.tree.StatementTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) ImportTree(com.sun.source.tree.ImportTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) TryTree(com.sun.source.tree.TryTree) BlockTree(com.sun.source.tree.BlockTree) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol)

Example 15 with MethodSymbol

use of com.sun.tools.javac.code.Symbol.MethodSymbol in project error-prone by google.

the class ChainingConstructorIgnoresParameter method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    MethodSymbol symbol = getSymbol(tree);
    // TODO(cpovirk): determine whether anyone might be calling Foo.this()
    if (!isIdentifierWithName(tree.getMethodSelect(), "this")) {
        return NO_MATCH;
    }
    callersToEvaluate.put(symbol, new Caller(tree, state));
    return evaluateCallers(symbol);
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol)

Aggregations

MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)57 Symbol (com.sun.tools.javac.code.Symbol)24 Type (com.sun.tools.javac.code.Type)22 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)18 MethodTree (com.sun.source.tree.MethodTree)15 Tree (com.sun.source.tree.Tree)11 TypeSymbol (com.sun.tools.javac.code.Symbol.TypeSymbol)11 ExpressionTree (com.sun.source.tree.ExpressionTree)10 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)10 ArrayList (java.util.ArrayList)10 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)9 ClassTree (com.sun.source.tree.ClassTree)7 VariableTree (com.sun.source.tree.VariableTree)7 MethodType (com.sun.tools.javac.code.Type.MethodType)7 Types (com.sun.tools.javac.code.Types)7 IdentifierTree (com.sun.source.tree.IdentifierTree)6 MemberSelectTree (com.sun.source.tree.MemberSelectTree)6 JCTree (com.sun.tools.javac.tree.JCTree)6 VisitorState (com.google.errorprone.VisitorState)5 Description (com.google.errorprone.matchers.Description)5