Search in sources :

Example 11 with Types

use of com.sun.tools.javac.code.Types 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 : CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) Arrays(java.util.Arrays) ClassType(com.sun.tools.javac.code.Type.ClassType) Nullness(com.google.errorprone.dataflow.nullnesspropagation.Nullness) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) Log(com.sun.tools.javac.util.Log) Matcher(com.google.errorprone.matchers.Matcher) JarURLConnection(java.net.JarURLConnection) ForLoopTree(com.sun.source.tree.ForLoopTree) EnumSet(java.util.EnumSet) ParenthesizedTree(com.sun.source.tree.ParenthesizedTree) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Filter(com.sun.tools.javac.util.Filter) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) TreePath(com.sun.source.util.TreePath) JCLiteral(com.sun.tools.javac.tree.JCTree.JCLiteral) Compound(com.sun.tools.javac.code.Attribute.Compound) Symbol(com.sun.tools.javac.code.Symbol) Set(java.util.Set) MemberSelectTree(com.sun.source.tree.MemberSelectTree) TreeScanner(com.sun.source.util.TreeScanner) Stream(java.util.stream.Stream) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) Predicate(com.google.common.base.Predicate) Attribute(com.sun.tools.javac.code.Attribute) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) AutoValue(com.google.auto.value.AutoValue) JCIdent(com.sun.tools.javac.tree.JCTree.JCIdent) AnnotationValue(javax.lang.model.element.AnnotationValue) Flags(com.sun.tools.javac.code.Flags) JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) Scope(com.sun.tools.javac.code.Scope) ReturnTree(com.sun.source.tree.ReturnTree) UnaryTree(com.sun.source.tree.UnaryTree) VariableTree(com.sun.source.tree.VariableTree) TypeParameterTree(com.sun.source.tree.TypeParameterTree) ArrayList(java.util.ArrayList) VisitorState(com.google.errorprone.VisitorState) Kind(com.sun.source.tree.Tree.Kind) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) Tree(com.sun.source.tree.Tree) LinkedHashSet(java.util.LinkedHashSet) Nullable(javax.annotation.Nullable) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) SimpleAnnotationValueVisitor8(javax.lang.model.util.SimpleAnnotationValueVisitor8) Enter(com.sun.tools.javac.comp.Enter) ExpressionTree(com.sun.source.tree.ExpressionTree) CharMatcher(com.google.common.base.CharMatcher) IOException(java.io.IOException) AnnotationMirror(javax.lang.model.element.AnnotationMirror) Types(com.sun.tools.javac.code.Types) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) ArrayDeque(java.util.ArrayDeque) NON_RECURSIVE(com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE) ArrayAccessTree(com.sun.source.tree.ArrayAccessTree) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) PackageTree(com.sun.source.tree.PackageTree) JCAnnotatedType(com.sun.tools.javac.tree.JCTree.JCAnnotatedType) TypeVar(com.sun.tools.javac.code.Type.TypeVar) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) TypeTag(com.sun.tools.javac.code.TypeTag) JCMemberReference(com.sun.tools.javac.tree.JCTree.JCMemberReference) IdentifierTree(com.sun.source.tree.IdentifierTree) URI(java.net.URI) ImmutableSet(com.google.common.collect.ImmutableSet) DeferredDiagnosticHandler(com.sun.tools.javac.util.Log.DeferredDiagnosticHandler) SwitchTree(com.sun.source.tree.SwitchTree) Collectors(java.util.stream.Collectors) Preconditions.checkState(com.google.common.base.Preconditions.checkState) TypeKind(javax.lang.model.type.TypeKind) Objects(java.util.Objects) JavacTrees(com.sun.tools.javac.api.JavacTrees) List(java.util.List) CompletionFailure(com.sun.tools.javac.code.Symbol.CompletionFailure) Suppliers(com.google.errorprone.suppliers.Suppliers) Annotation(java.lang.annotation.Annotation) ModifiersTree(com.sun.source.tree.ModifiersTree) Optional(java.util.Optional) WhileLoopTree(com.sun.source.tree.WhileLoopTree) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) Name(com.sun.tools.javac.util.Name) 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) Deque(java.util.Deque) HashSet(java.util.HashSet) JCPackageDecl(com.sun.tools.javac.tree.JCTree.JCPackageDecl) JUNIT4_RUN_WITH_ANNOTATION(com.google.errorprone.matchers.JUnitMatchers.JUNIT4_RUN_WITH_ANNOTATION) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) ClassTree(com.sun.source.tree.ClassTree) IfTree(com.sun.source.tree.IfTree) ElementKind(javax.lang.model.element.ElementKind) MemberReferenceTree(com.sun.source.tree.MemberReferenceTree) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) JCTree(com.sun.tools.javac.tree.JCTree) NullnessAnalysis(com.google.errorprone.dataflow.nullnesspropagation.NullnessAnalysis) JUnitMatchers(com.google.errorprone.matchers.JUnitMatchers) DoWhileLoopTree(com.sun.source.tree.DoWhileLoopTree) Resolve(com.sun.tools.javac.comp.Resolve) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) ClassType(com.sun.tools.javac.code.Type.ClassType) JCAnnotatedType(com.sun.tools.javac.tree.JCTree.JCAnnotatedType) Type(com.sun.tools.javac.code.Type) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) Scope(com.sun.tools.javac.code.Scope) 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) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet)

Example 12 with Types

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

the class CollectionToArraySafeParameter method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree methodInvocationTree, VisitorState visitorState) {
    if (!TO_ARRAY_MATCHER.matches(methodInvocationTree, visitorState)) {
        return NO_MATCH;
    }
    Types types = visitorState.getTypes();
    Type variableType = types.elemtype(getType(getOnlyElement(methodInvocationTree.getArguments())));
    if (variableType == null) {
        return NO_MATCH;
    }
    Type collectionType = types.asSuper(ASTHelpers.getReceiverType(methodInvocationTree), visitorState.getSymbolFromString("java.util.Collection"));
    List<Type> typeArguments = collectionType.getTypeArguments();
    if (!typeArguments.isEmpty() && !types.isCastable(types.erasure(variableType), types.erasure(getOnlyElement(typeArguments)))) {
        return describeMatch(methodInvocationTree);
    }
    return NO_MATCH;
}
Also used : Types(com.sun.tools.javac.code.Types) ASTHelpers.getType(com.google.errorprone.util.ASTHelpers.getType) Type(com.sun.tools.javac.code.Type)

Example 13 with Types

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

the class ArrayHashCode method matchMethodInvocation.

/**
 * Wraps identity hashcode computations in calls to {@link java.util.Arrays#hashCode} if the array
 * is single dimensional or {@link java.util.Arrays#deepHashCode} if the array is
 * multidimensional.
 *
 * <p>If there is only one argument to the hashcode method or the instance hashcode method is
 * used, replaces the whole method invocation. If there are multiple arguments, wraps any that are
 * of array type with the appropriate {@link java.util.Arrays} hashcode method.
 */
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    SuggestedFix.Builder fix = null;
    Types types = state.getTypes();
    if (jdk7HashCodeMethodMatcher.matches(tree, state)) {
        // java.util.Objects#hashCode takes a single argument, so rewrite the whole method call
        // to use Arrays.hashCode/deepHashCode instead.
        fix = SuggestedFix.builder().replace(tree, rewriteArrayArgument(tree.getArguments().get(0), types));
    } else if (instanceHashCodeMethodMatcher.matches(tree, state)) {
        // Rewrite call to instance hashCode method to use Arrays.hashCode/deepHashCode instead.
        fix = SuggestedFix.builder().replace(tree, rewriteArrayArgument(((JCFieldAccess) tree.getMethodSelect()).getExpression(), types));
    } else if (varargsHashCodeMethodMatcher.matches(tree, state)) {
        // com.google.common.base.Objects#hashCode
        if (tree.getArguments().size() == 1) {
            // If only one argument, type must be either primitive array or multidimensional array.
            // Types like Object[], String[], etc. are not an error because they don't get boxed
            // in this single-argument varargs call.
            ExpressionTree arg = tree.getArguments().get(0);
            Type elemType = types.elemtype(ASTHelpers.getType(arg));
            if (elemType.isPrimitive() || types.isArray(elemType)) {
                fix = SuggestedFix.builder().replace(tree, rewriteArrayArgument(arg, types));
            }
        } else {
            // If more than one argument, wrap each argument in a call to Arrays#hashCode/deepHashCode.
            fix = SuggestedFix.builder();
            for (ExpressionTree arg : tree.getArguments()) {
                if (types.isArray(ASTHelpers.getType(arg))) {
                    fix.replace(arg, rewriteArrayArgument(arg, types));
                }
            }
        }
    }
    if (fix != null) {
        fix.addImport("java.util.Arrays");
        return describeMatch(tree, fix.build());
    }
    return Description.NO_MATCH;
}
Also used : Types(com.sun.tools.javac.code.Types) MatchType(com.google.errorprone.matchers.ChildMultiMatcher.MatchType) Type(com.sun.tools.javac.code.Type) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) ExpressionTree(com.sun.source.tree.ExpressionTree)

Example 14 with Types

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

the class FormatStringValidation method validate.

@Nullable
public static ValidationResult validate(Collection<? extends ExpressionTree> arguments, final VisitorState state) {
    Deque<ExpressionTree> args = new ArrayDeque<>(arguments);
    Stream<String> formatStrings = constValues(args.removeFirst());
    if (formatStrings == null) {
        return null;
    }
    // Bail out, since we don't know what the actual argument types are.
    if (args.size() == 1) {
        Type type = ASTHelpers.getType(Iterables.getOnlyElement(args));
        if (type instanceof Type.ArrayType && ASTHelpers.isSameType(((Type.ArrayType) type).elemtype, state.getSymtab().objectType, state)) {
            return null;
        }
    }
    Iterable<Object> instances = Iterables.transform(args, new Function<ExpressionTree, Object>() {

        @Override
        public Object apply(ExpressionTree input) {
            try {
                return getInstance(input, state);
            } catch (Throwable t) {
                // ignore symbol completion failures
                return null;
            }
        }
    });
    return formatStrings.map(formatString -> validate(formatString, instances)).filter(x -> x != null).findFirst().orElse(null);
}
Also used : Formatter(edu.umd.cs.findbugs.formatStringChecker.Formatter) Iterables(com.google.common.collect.Iterables) Date(java.util.Date) LocalDateTime(java.time.LocalDateTime) FormatFlagsConversionMismatchException(java.util.FormatFlagsConversionMismatchException) Deque(java.util.Deque) MissingFormatArgumentException(java.util.MissingFormatArgumentException) TemporalAccessor(java.time.temporal.TemporalAccessor) VisitorState(com.google.errorprone.VisitorState) BigDecimal(java.math.BigDecimal) IllegalFormatPrecisionException(java.util.IllegalFormatPrecisionException) Calendar(java.util.Calendar) IllegalFormatWidthException(java.util.IllegalFormatWidthException) BigInteger(java.math.BigInteger) Tree(com.sun.source.tree.Tree) Nullable(javax.annotation.Nullable) DuplicateFormatFlagsException(java.util.DuplicateFormatFlagsException) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) Function(com.google.common.base.Function) GregorianCalendar(java.util.GregorianCalendar) UnknownFormatFlagsException(java.util.UnknownFormatFlagsException) ExpressionTree(com.sun.source.tree.ExpressionTree) IllegalFormatFlagsException(java.util.IllegalFormatFlagsException) MissingFormatWidthException(java.util.MissingFormatWidthException) Collection(java.util.Collection) UnknownFormatConversionException(java.util.UnknownFormatConversionException) Iterables.getOnlyElement(com.google.common.collect.Iterables.getOnlyElement) IllegalFormatConversionException(java.util.IllegalFormatConversionException) Instant(java.time.Instant) ZoneId(java.time.ZoneId) TypeKind(javax.lang.model.type.TypeKind) ExtraFormatArgumentsException(edu.umd.cs.findbugs.formatStringChecker.ExtraFormatArgumentsException) Types(com.sun.tools.javac.code.Types) Stream(java.util.stream.Stream) IllegalFormatCodePointException(java.util.IllegalFormatCodePointException) AutoValue(com.google.auto.value.AutoValue) ArrayDeque(java.util.ArrayDeque) Collections(java.util.Collections) ASTHelpers(com.google.errorprone.util.ASTHelpers) Type(com.sun.tools.javac.code.Type) ArrayDeque(java.util.ArrayDeque) Type(com.sun.tools.javac.code.Type) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree) Nullable(javax.annotation.Nullable)

Example 15 with Types

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

the class StrictFormatStringValidation method validateFormatStringParamter.

/**
 * Helps {@code validate()} validate a format string that is declared as a method parameter.
 */
private static ValidationResult validateFormatStringParamter(ExpressionTree formatStringTree, Symbol formatStringSymbol, List<? extends ExpressionTree> args, VisitorState state) {
    if (!isFormatStringParameter(formatStringSymbol, state)) {
        return ValidationResult.create(null, String.format("Format strings must be compile time constant or parameters annotated " + "@FormatString: %s", formatStringTree));
    }
    List<VarSymbol> ownerParams = ((MethodSymbol) formatStringSymbol.owner).getParameters();
    int ownerFormatStringIndex = ownerParams.indexOf(formatStringSymbol);
    ImmutableList.Builder<Type> ownerFormatArgTypesBuilder = ImmutableList.builder();
    for (VarSymbol paramSymbol : ownerParams.subList(ownerFormatStringIndex + 1, ownerParams.size())) {
        ownerFormatArgTypesBuilder.add(paramSymbol.type);
    }
    ImmutableList<Type> ownerFormatArgTypes = ownerFormatArgTypesBuilder.build();
    Types types = state.getTypes();
    ImmutableList.Builder<Type> calleeFormatArgTypesBuilder = ImmutableList.builder();
    for (ExpressionTree formatArgExpression : args) {
        calleeFormatArgTypesBuilder.add(types.erasure(((JCExpression) formatArgExpression).type));
    }
    ImmutableList<Type> calleeFormatArgTypes = calleeFormatArgTypesBuilder.build();
    if (ownerFormatArgTypes.size() != calleeFormatArgTypes.size()) {
        return ValidationResult.create(null, String.format("The number of format arguments passed " + "with an @FormatString must match the number of format arguments in the " + "@FormatMethod header where the format string was declared.\n\t" + "Format args passed: %d\n\tFormat args expected: %d", calleeFormatArgTypes.size(), ownerFormatArgTypes.size()));
    } else {
        for (int i = 0; i < calleeFormatArgTypes.size(); i++) {
            if (!ASTHelpers.isSameType(ownerFormatArgTypes.get(i), calleeFormatArgTypes.get(i), state)) {
                return ValidationResult.create(null, String.format("The format argument types passed " + "with an @FormatString must match the types of the format arguments in " + "the @FormatMethod header where the format string was declared.\n\t" + "Format arg types passed: %s\n\tFormat arg types expected: %s", calleeFormatArgTypes.toArray(), ownerFormatArgTypes.toArray()));
            }
        }
    }
    // Format string usage was valid.
    return null;
}
Also used : Types(com.sun.tools.javac.code.Types) Type(com.sun.tools.javac.code.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ImmutableList(com.google.common.collect.ImmutableList) ExpressionTree(com.sun.source.tree.ExpressionTree) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol)

Aggregations

Types (com.sun.tools.javac.code.Types)39 Type (com.sun.tools.javac.code.Type)29 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)10 Tree (com.sun.source.tree.Tree)9 Symbol (com.sun.tools.javac.code.Symbol)9 VisitorState (com.google.errorprone.VisitorState)8 ASTHelpers.getType (com.google.errorprone.util.ASTHelpers.getType)7 ExpressionTree (com.sun.source.tree.ExpressionTree)6 Symtab (com.sun.tools.javac.code.Symtab)6 SuggestedFix (com.google.errorprone.fixes.SuggestedFix)5 Description (com.google.errorprone.matchers.Description)5 ClassTree (com.sun.source.tree.ClassTree)5 MethodTree (com.sun.source.tree.MethodTree)5 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)5 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)5 JavacProcessingEnvironment (com.sun.tools.javac.processing.JavacProcessingEnvironment)5 ArrayList (java.util.ArrayList)5 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)4 List (java.util.List)4 BugPattern (com.google.errorprone.BugPattern)3