Search in sources :

Example 1 with VisitorState

use of com.google.errorprone.VisitorState in project error-prone by google.

the class TypeParameterShadowing method renameTypeVariable.

private static SuggestedFix renameTypeVariable(Tree sourceTree, List<? extends TypeParameterTree> typeParameters, Name typeVariable, String typeVarReplacement, VisitorState state) {
    TypeParameterTree matchingTypeParam = typeParameters.stream().filter(t -> t.getName().contentEquals(typeVariable)).collect(MoreCollectors.onlyElement());
    Symbol typeVariableSymbol = ASTHelpers.getSymbol(matchingTypeParam);
    // replace only the type parameter name (and not any upper bounds)
    String name = matchingTypeParam.getName().toString();
    int pos = ((JCTree) matchingTypeParam).getStartPosition();
    SuggestedFix.Builder fixBuilder = SuggestedFix.builder().replace(pos, pos + name.length(), typeVarReplacement);
    ((JCTree) sourceTree).accept(new TreeScanner() {

        @Override
        public void visitIdent(JCTree.JCIdent tree) {
            Symbol identSym = ASTHelpers.getSymbol(tree);
            if (Objects.equal(identSym, typeVariableSymbol)) {
                // }
                if (Objects.equal(state.getSourceForNode(tree), name)) {
                    fixBuilder.replace(tree, typeVarReplacement);
                }
            }
        }
    });
    return fixBuilder.build();
}
Also used : ClassTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher) MethodTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher) MethodTree(com.sun.source.tree.MethodTree) TreeScanner(com.sun.tools.javac.tree.TreeScanner) TypeParameterTree(com.sun.source.tree.TypeParameterTree) ArrayList(java.util.ArrayList) VisitorState(com.google.errorprone.VisitorState) Matcher(java.util.regex.Matcher) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) BugPattern(com.google.errorprone.BugPattern) JDK(com.google.errorprone.BugPattern.Category.JDK) Objects(com.google.common.base.Objects) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) Name(javax.lang.model.element.Name) MoreCollectors(com.google.common.collect.MoreCollectors) Symbol(com.sun.tools.javac.code.Symbol) Set(java.util.Set) Streams(com.google.common.collect.Streams) JCTree(com.sun.tools.javac.tree.JCTree) Collectors(java.util.stream.Collectors) TypeVariableSymbol(com.sun.tools.javac.code.Symbol.TypeVariableSymbol) List(java.util.List) Description(com.google.errorprone.matchers.Description) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) Pattern(java.util.regex.Pattern) ASTHelpers(com.google.errorprone.util.ASTHelpers) TypeParameterTree(com.sun.source.tree.TypeParameterTree) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) TreeScanner(com.sun.tools.javac.tree.TreeScanner) Symbol(com.sun.tools.javac.code.Symbol) TypeVariableSymbol(com.sun.tools.javac.code.Symbol.TypeVariableSymbol) JCTree(com.sun.tools.javac.tree.JCTree)

Example 2 with VisitorState

use of com.google.errorprone.VisitorState in project error-prone by google.

the class AbstractArgumentParameterChecker method findReplacements.

private Description findReplacements(List<? extends ExpressionTree> args, com.sun.tools.javac.util.List<VarSymbol> params, boolean isVarArgs, VisitorState state, Tree tree) {
    if (args.isEmpty()) {
        return Description.NO_MATCH;
    }
    ImmutableSet<PotentialReplacement> potentialReplacements = potentialReplacementsFunction.apply(state.withPath(new TreePath(state.getPath(), args.get(0))));
    SuggestedFix.Builder fix = SuggestedFix.builder();
    // Don't suggest for the varargs parameter.
    // TODO(eaftan): Reconsider this, especially if the argument is of array type or is itself
    // a varargs parameter.
    int maxArg = isVarArgs ? params.size() - 1 : params.size();
    for (int i = 0; i < maxArg; i++) {
        ExpressionTree arg = args.get(i);
        VarSymbol param = params.get(i);
        if (!validKinds.contains(arg.getKind()) || !parameterPredicate.test(param)) {
            continue;
        }
        String extractedArgumentName = extractArgumentName(arg);
        if (extractedArgumentName == null) {
            continue;
        }
        double currSimilarity = similarityMetric.applyAsDouble(extractedArgumentName, param.getSimpleName().toString());
        if (1.0 - currSimilarity < beta) {
            // No way for any replacement to be at least BETA better than the current argument
            continue;
        }
        ReplacementWithSimilarity bestReplacement = potentialReplacements.stream().filter(replacement -> !replacement.sym().equals(ASTHelpers.getSymbol(arg))).filter(replacement -> isSubtypeHandleCompletionFailures(replacement.sym(), param, state)).map(replacement -> ReplacementWithSimilarity.create(replacement, similarityMetric.applyAsDouble(replacement.argumentName(), param.getSimpleName().toString()))).max(Comparator.comparingDouble(ReplacementWithSimilarity::similarity)).orElse(null);
        if ((bestReplacement != null) && (bestReplacement.similarity() - currSimilarity >= beta)) {
            fix.replace(arg, bestReplacement.replacement().replacementString());
        }
    }
    if (fix.isEmpty()) {
        return Description.NO_MATCH;
    } else {
        return describeMatch(tree, fix.build());
    }
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) Function(java.util.function.Function) NewClassTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.NewClassTreeMatcher) VisitorState(com.google.errorprone.VisitorState) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) Kind(com.sun.source.tree.Tree.Kind) NewClassTree(com.sun.source.tree.NewClassTree) IdentifierTree(com.sun.source.tree.IdentifierTree) Tree(com.sun.source.tree.Tree) Nullable(javax.annotation.Nullable) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) MethodInvocationTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher) TreePath(com.sun.source.util.TreePath) ImmutableSet(com.google.common.collect.ImmutableSet) ExpressionTree(com.sun.source.tree.ExpressionTree) Predicate(java.util.function.Predicate) Symbol(com.sun.tools.javac.code.Symbol) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ToDoubleBiFunction(java.util.function.ToDoubleBiFunction) List(java.util.List) CompletionFailure(com.sun.tools.javac.code.Symbol.CompletionFailure) Description(com.google.errorprone.matchers.Description) AutoValue(com.google.auto.value.AutoValue) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) Comparator(java.util.Comparator) ASTHelpers(com.google.errorprone.util.ASTHelpers) Type(com.sun.tools.javac.code.Type) TreePath(com.sun.source.util.TreePath) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) ExpressionTree(com.sun.source.tree.ExpressionTree) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol)

Example 3 with VisitorState

use of com.google.errorprone.VisitorState 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 4 with VisitorState

use of com.google.errorprone.VisitorState in project error-prone by google.

the class CompileTimeConstantExpressionMatcherTest method assertCompilerMatchesOnAssignment.

// Helper methods.
private void assertCompilerMatchesOnAssignment(final Map<String, Boolean> expectedMatches, String... lines) {
    final Matcher<ExpressionTree> matcher = new CompileTimeConstantExpressionMatcher();
    final Scanner scanner = new Scanner() {

        @Override
        public Void visitAssignment(AssignmentTree t, VisitorState state) {
            ExpressionTree lhs = t.getVariable();
            if (expectedMatches.containsKey(lhs.toString())) {
                boolean matches = matcher.matches(t.getExpression(), state);
                if (expectedMatches.get(lhs.toString())) {
                    assertTrue("Matcher should match expression" + t.getExpression(), matches);
                } else {
                    assertFalse("Matcher should not match expression" + t.getExpression(), matches);
                }
            }
            return super.visitAssignment(t, state);
        }
    };
    CompilationTestHelper.newInstance(ScannerSupplier.fromScanner(scanner), getClass()).expectResult(Result.OK).addSourceLines("test/CompileTimeConstantExpressionMatcherTestCase.java", lines).doTest();
}
Also used : Scanner(com.google.errorprone.scanner.Scanner) VisitorState(com.google.errorprone.VisitorState) ExpressionTree(com.sun.source.tree.ExpressionTree) AssignmentTree(com.sun.source.tree.AssignmentTree)

Example 5 with VisitorState

use of com.google.errorprone.VisitorState in project error-prone by google.

the class ThreadSafety method getAnnotation.

private AnnotationInfo getAnnotation(Symbol sym, VisitorState state, String annotation, @Nullable Class<? extends Annotation> elementAnnotation) {
    if (sym == null) {
        return null;
    }
    Symbol annosym = state.getSymbolFromString(annotation);
    Optional<Compound> attr = sym.getAnnotationMirrors().stream().filter(a -> a.getAnnotationType().asElement().equals(annosym)).findAny();
    if (attr.isPresent()) {
        ImmutableList<String> containerElements = containerOf(state, attr.get());
        if (elementAnnotation != null && containerElements.isEmpty()) {
            containerElements = sym.getTypeParameters().stream().filter(p -> p.getAnnotation(elementAnnotation) != null).map(p -> p.getSimpleName().toString()).collect(toImmutableList());
        }
        return AnnotationInfo.create(sym.getQualifiedName().toString(), containerElements);
    }
    // @ThreadSafe is inherited from supertypes
    if (!(sym instanceof ClassSymbol)) {
        return null;
    }
    Type superClass = ((ClassSymbol) sym).getSuperclass();
    AnnotationInfo superAnnotation = getInheritedAnnotation(superClass.asElement(), state);
    if (superAnnotation == null) {
        return null;
    }
    // If an annotated super-type was found, look for any type arguments to the super-type that
    // are in the super-type's containerOf spec, and where the arguments are type parameters
    // of the current class.
    // E.g. for `Foo<X> extends Super<X>` if `Super<Y>` is annotated
    // `@ThreadSafeContainerAnnotation Y`
    // then `Foo<X>` is has X implicitly annotated `@ThreadSafeContainerAnnotation X`
    ImmutableList.Builder<String> containerOf = ImmutableList.builder();
    for (int i = 0; i < superClass.getTypeArguments().size(); i++) {
        Type arg = superClass.getTypeArguments().get(i);
        TypeVariableSymbol formal = superClass.asElement().getTypeParameters().get(i);
        if (!arg.hasTag(TypeTag.TYPEVAR)) {
            continue;
        }
        TypeSymbol argSym = arg.asElement();
        if (argSym.owner == sym && superAnnotation.containerOf().contains(formal.getSimpleName().toString())) {
            containerOf.add(argSym.getSimpleName().toString());
        }
    }
    return AnnotationInfo.create(superAnnotation.typeName(), containerOf.build());
}
Also used : Iterables(com.google.common.collect.Iterables) Arrays(java.util.Arrays) ClassType(com.sun.tools.javac.code.Type.ClassType) ArrayType(com.sun.tools.javac.code.Type.ArrayType) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) TypeVar(com.sun.tools.javac.code.Type.TypeVar) ArrayList(java.util.ArrayList) VisitorState(com.google.errorprone.VisitorState) ConsPStack(org.pcollections.ConsPStack) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) ImmutableList(com.google.common.collect.ImmutableList) TypeTag(com.sun.tools.javac.code.TypeTag) Map(java.util.Map) ClassTree(com.sun.source.tree.ClassTree) Nullable(javax.annotation.Nullable) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) SimpleAnnotationValueVisitor8(javax.lang.model.util.SimpleAnnotationValueVisitor8) ImmutableSet(com.google.common.collect.ImmutableSet) ElementKind(javax.lang.model.element.ElementKind) ImmutableMap(com.google.common.collect.ImmutableMap) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Collection(java.util.Collection) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) Compound(com.sun.tools.javac.code.Attribute.Compound) Symbol(com.sun.tools.javac.code.Symbol) Set(java.util.Set) Target(java.lang.annotation.Target) Streams(com.google.common.collect.Streams) ElementType(java.lang.annotation.ElementType) Field(java.lang.reflect.Field) WildcardType(com.sun.tools.javac.code.Type.WildcardType) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) Violation(com.google.errorprone.bugpatterns.threadsafety.ThreadSafety.Violation) CanBeStaticAnalyzer(com.google.errorprone.bugpatterns.CanBeStaticAnalyzer) TypeVariableSymbol(com.sun.tools.javac.code.Symbol.TypeVariableSymbol) List(java.util.List) Types(com.sun.tools.javac.code.Types) Attribute(com.sun.tools.javac.code.Attribute) AutoValue(com.google.auto.value.AutoValue) Annotation(java.lang.annotation.Annotation) Optional(java.util.Optional) AnnotationValue(javax.lang.model.element.AnnotationValue) ASTHelpers(com.google.errorprone.util.ASTHelpers) Type(com.sun.tools.javac.code.Type) Joiner(com.google.common.base.Joiner) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Symbol(com.sun.tools.javac.code.Symbol) TypeVariableSymbol(com.sun.tools.javac.code.Symbol.TypeVariableSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ImmutableList(com.google.common.collect.ImmutableList) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Compound(com.sun.tools.javac.code.Attribute.Compound) ClassType(com.sun.tools.javac.code.Type.ClassType) ArrayType(com.sun.tools.javac.code.Type.ArrayType) ElementType(java.lang.annotation.ElementType) WildcardType(com.sun.tools.javac.code.Type.WildcardType) Type(com.sun.tools.javac.code.Type) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) TypeVariableSymbol(com.sun.tools.javac.code.Symbol.TypeVariableSymbol)

Aggregations

VisitorState (com.google.errorprone.VisitorState)52 Tree (com.sun.source.tree.Tree)31 ASTHelpers (com.google.errorprone.util.ASTHelpers)29 Description (com.google.errorprone.matchers.Description)28 BugPattern (com.google.errorprone.BugPattern)27 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)23 Symbol (com.sun.tools.javac.code.Symbol)23 ClassTree (com.sun.source.tree.ClassTree)22 Type (com.sun.tools.javac.code.Type)22 WARNING (com.google.errorprone.BugPattern.SeverityLevel.WARNING)21 ExpressionTree (com.sun.source.tree.ExpressionTree)21 MethodTree (com.sun.source.tree.MethodTree)21 JDK (com.google.errorprone.BugPattern.Category.JDK)19 SuggestedFix (com.google.errorprone.fixes.SuggestedFix)18 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)16 List (java.util.List)16 NO_MATCH (com.google.errorprone.matchers.Description.NO_MATCH)14 Optional (java.util.Optional)14 VariableTree (com.sun.source.tree.VariableTree)13 ArrayList (java.util.ArrayList)13