Search in sources :

Example 26 with ClassSymbol

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

the class FunctionalInterfaceClash method matchClass.

@Override
public Description matchClass(ClassTree tree, VisitorState state) {
    ClassSymbol origin = getSymbol(tree);
    Types types = state.getTypes();
    // collect declared and inherited methods whose signature contains a functional interface
    Multimap<String, MethodSymbol> methods = HashMultimap.create();
    for (Symbol sym : types.membersClosure(getType(tree), /*skipInterface=*/
    false).getSymbols()) {
        if (!(sym instanceof MethodSymbol)) {
            continue;
        }
        if (isBugCheckerSuppressed((MethodSymbol) sym)) {
            continue;
        }
        MethodSymbol msym = (MethodSymbol) sym;
        if (msym.getParameters().stream().noneMatch(p -> maybeFunctionalInterface(p.type, types))) {
            continue;
        }
        if (msym.isConstructor() && !msym.owner.equals(origin)) {
            continue;
        }
        methods.put(functionalInterfaceSignature(state, msym), msym);
    }
    // (don't report clashes between inherited members)
    for (Tree member : tree.getMembers()) {
        if (!(member instanceof MethodTree)) {
            continue;
        }
        MethodSymbol msym = getSymbol((MethodTree) member);
        if (msym.getParameters().stream().noneMatch(p -> maybeFunctionalInterface(p.type, types))) {
            continue;
        }
        Collection<MethodSymbol> clash = new ArrayList<>(methods.removeAll(functionalInterfaceSignature(state, msym)));
        clash.remove(msym);
        // ignore inherited methods that are overridden in the original class
        clash.removeIf(m -> msym.overrides(m, origin, types, false));
        if (!clash.isEmpty()) {
            String message = "When passing lambda arguments to this function, callers will need a cast to" + " disambiguate with: " + clash.stream().map(m -> Signatures.prettyMethodSignature(origin, m)).collect(joining("\n    "));
            state.reportMatch(buildDescription(member).setMessage(message).build());
        }
    }
    return NO_MATCH;
}
Also used : Types(com.sun.tools.javac.code.Types) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodTree(com.sun.source.tree.MethodTree) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ASTHelpers.getSymbol(com.google.errorprone.util.ASTHelpers.getSymbol) Symbol(com.sun.tools.javac.code.Symbol) ArrayList(java.util.ArrayList) MethodTree(com.sun.source.tree.MethodTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree)

Example 27 with ClassSymbol

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

the class LiteralClassName method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    if (!CLASS_NAME.matches(tree, state)) {
        return NO_MATCH;
    }
    String className = constValue(getOnlyElement(tree.getArguments()), String.class);
    if (className == null) {
        return NO_MATCH;
    }
    if (className.startsWith("[")) {
        // TODO(cushon): consider handling arrays
        return NO_MATCH;
    }
    Type type = state.getTypeFromString(className);
    if (type == null) {
        return NO_MATCH;
    }
    ClassSymbol owner = getSymbol(state.findEnclosing(ClassTree.class));
    Enter enter = Enter.instance(state.context);
    if (!Resolve.instance(state.context).isAccessible(enter.getEnv(owner), type.tsym)) {
        return NO_MATCH;
    }
    SuggestedFix.Builder fix = SuggestedFix.builder();
    String replaceWith = String.format("%s.class", qualifyType(state, fix, state.getTypes().erasure(type)));
    if (state.getPath().getParentPath().getLeaf().getKind() == Tree.Kind.EXPRESSION_STATEMENT) {
        fix.addStaticImport("java.util.Objects.requireNonNull");
        replaceWith = String.format("requireNonNull(%s)", replaceWith);
    }
    fix.replace(tree, replaceWith);
    return describeMatch(tree, fix.build());
}
Also used : SuggestedFixes.qualifyType(com.google.errorprone.fixes.SuggestedFixes.qualifyType) Type(com.sun.tools.javac.code.Type) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ClassTree(com.sun.source.tree.ClassTree) Enter(com.sun.tools.javac.comp.Enter)

Example 28 with ClassSymbol

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

the class HeldLockAnalyzer method handleMonitorGuards.

private static HeldLockSet handleMonitorGuards(VisitorState state, HeldLockSet locks) {
    JCNewClass newClassTree = ASTHelpers.findEnclosingNode(state.getPath(), JCNewClass.class);
    if (newClassTree == null) {
        return locks;
    }
    Symbol clazzSym = ASTHelpers.getSymbol(newClassTree.clazz);
    if (!(clazzSym instanceof ClassSymbol)) {
        return locks;
    }
    if (!((ClassSymbol) clazzSym).fullname.contentEquals(MONITOR_GUARD_CLASS)) {
        return locks;
    }
    Optional<GuardedByExpression> lockExpression = GuardedByBinder.bindExpression(Iterables.getOnlyElement(newClassTree.getArguments()), state);
    if (!lockExpression.isPresent()) {
        return locks;
    }
    return locks.plus(lockExpression.get());
}
Also used : ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) Symbol(com.sun.tools.javac.code.Symbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass)

Example 29 with ClassSymbol

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

the class ImmutableAnnotationChecker method matchClass.

@Override
public Description matchClass(ClassTree tree, VisitorState state) {
    ClassSymbol symbol = getSymbol(tree);
    if (symbol == null || symbol.isAnnotationType() || !WellKnownMutability.isAnnotation(state, symbol.type)) {
        return NO_MATCH;
    }
    if (ASTHelpers.hasAnnotation(symbol, Immutable.class, state)) {
        AnnotationTree annotation = ASTHelpers.getAnnotationWithSimpleName(tree.getModifiers().getAnnotations(), "Immutable");
        if (annotation != null) {
            state.reportMatch(buildDescription(annotation).setMessage(ANNOTATED_ANNOTATION_MESSAGE).addFix(SuggestedFix.delete(annotation)).build());
        } else {
            state.reportMatch(buildDescription(tree).setMessage(ANNOTATED_ANNOTATION_MESSAGE).build());
        }
    }
    Violation info = new ImmutableAnalysis(this, state, "annotations should be immutable, and cannot have non-final fields", "annotations should be immutable").checkForImmutability(Optional.of(tree), ImmutableSet.of(), getType(tree));
    if (!info.isPresent()) {
        return NO_MATCH;
    }
    String message = "annotations should be immutable: " + info.message();
    return buildDescription(tree).setMessage(message).build();
}
Also used : Violation(com.google.errorprone.bugpatterns.threadsafety.ImmutableAnalysis.Violation) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) AnnotationTree(com.sun.source.tree.AnnotationTree)

Example 30 with ClassSymbol

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

the class ImmutableChecker method checkSubtype.

// Strong behavioural subtyping
/** Check for classes without {@code @Immutable} that have immutable supertypes. */
private Description checkSubtype(ClassTree tree, VisitorState state) {
    ClassSymbol sym = ASTHelpers.getSymbol(tree);
    if (sym == null) {
        return Description.NO_MATCH;
    }
    Type superType = immutableSupertype(sym, state);
    if (superType == null) {
        return Description.NO_MATCH;
    }
    String message = String.format("Class extends @Immutable type %s, but is not annotated as immutable", superType);
    Fix fix = SuggestedFix.builder().prefixWith(tree, "@Immutable ").addImport(Immutable.class.getName()).build();
    return buildDescription(tree).setMessage(message).addFix(fix).build();
}
Also used : Type(com.sun.tools.javac.code.Type) Fix(com.google.errorprone.fixes.Fix) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol)

Aggregations

ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)49 Symbol (com.sun.tools.javac.code.Symbol)20 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)20 Type (com.sun.tools.javac.code.Type)17 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)10 PackageSymbol (com.sun.tools.javac.code.Symbol.PackageSymbol)9 ClassType (com.sun.tools.javac.code.Type.ClassType)9 ClassTree (com.sun.source.tree.ClassTree)8 TypeSymbol (com.sun.tools.javac.code.Symbol.TypeSymbol)8 MethodTree (com.sun.source.tree.MethodTree)6 Tree (com.sun.source.tree.Tree)6 ArrayType (com.sun.tools.javac.code.Type.ArrayType)5 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)4 VariableTree (com.sun.source.tree.VariableTree)4 Name (com.sun.tools.javac.util.Name)4 ArrayList (java.util.ArrayList)4 Violation (com.google.errorprone.bugpatterns.threadsafety.ImmutableAnalysis.Violation)3 BlockTree (com.sun.source.tree.BlockTree)3 EnhancedForLoopTree (com.sun.source.tree.EnhancedForLoopTree)3 ForLoopTree (com.sun.source.tree.ForLoopTree)3