Search in sources :

Example 21 with MethodSymbol

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

the class StrictFormatStringValidation method isFormatStringParameter.

/**
   * Returns whether an input {@link Symbol} is a format string in a {@link FormatMethod}. This is
   * true if the {@link Symbol} is a {@link String} parameter in a {@link FormatMethod} and is
   * either:
   *
   * <ol>
   * <li>Annotated with {@link FormatString}
   * <li>The first {@link String} parameter in the method with no other parameters annotated {@link
   *     FormatString}.
   * </ol>
   */
private static boolean isFormatStringParameter(Symbol formatString, VisitorState state) {
    Type stringType = state.getSymtab().stringType;
    // The input symbol must be a String and a parameter of a @FormatMethod to be a @FormatString.
    if (!ASTHelpers.isSameType(formatString.type, stringType, state) || !(formatString.owner instanceof MethodSymbol) || !ASTHelpers.hasAnnotation(formatString.owner, FormatMethod.class, state)) {
        return false;
    }
    // If the format string is annotated @FormatString in a @FormatMethod, it is a format string.
    if (ASTHelpers.hasAnnotation(formatString, FormatString.class, state)) {
        return true;
    }
    // Check if format string is the first string with no @FormatString params in the @FormatMethod.
    MethodSymbol owner = (MethodSymbol) formatString.owner;
    boolean formatStringFound = false;
    for (Symbol param : owner.getParameters()) {
        if (param == formatString) {
            formatStringFound = true;
        }
        if (ASTHelpers.isSameType(param.type, stringType, state)) {
            // format string since it wasn't annotated @FormatString.
            if (!formatStringFound) {
                return false;
            } else if (ASTHelpers.hasAnnotation(param, FormatString.class, state)) {
                return false;
            }
        }
    }
    return true;
}
Also used : 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) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) FormatString(com.google.errorprone.annotations.FormatString)

Example 22 with MethodSymbol

use of com.sun.tools.javac.code.Symbol.MethodSymbol 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)

Example 23 with MethodSymbol

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

the class StaticQualifiedUsingExpression method matchMemberSelect.

@Override
public Description matchMemberSelect(MemberSelectTree tree, VisitorState state) {
    if (!staticAccessedFromInstanceMatcher.matches(tree, state)) {
        return Description.NO_MATCH;
    }
    // Is the static member being accessed a method or a variable?
    Symbol staticMemberSym = ASTHelpers.getSymbol(tree);
    if (staticMemberSym == null) {
        return Description.NO_MATCH;
    }
    boolean isMethod = staticMemberSym instanceof MethodSymbol;
    // Is the static member defined in this class?
    Symbol ownerSym = staticMemberSym.owner;
    Symbol whereAccessedSym = ASTHelpers.getSymbol(ASTHelpers.findEnclosingNode(state.getPath().getParentPath(), ClassTree.class));
    if (!(ownerSym instanceof ClassSymbol && whereAccessedSym instanceof ClassSymbol)) {
        return Description.NO_MATCH;
    }
    boolean staticMemberDefinedHere = whereAccessedSym.equals(ownerSym);
    SuggestedFix.Builder fix = SuggestedFix.builder();
    String replacement;
    if (staticMemberDefinedHere && isMethod) {
        // If the static member is defined in the enclosing class and the member is a method, then
        // just use the bare method name. Don't do this for fields, because they may share a simple
        // name with a local in the same scope.
        // TODO(eaftan): If we had access to name resolution info, we could do this in all applicable
        // cases.  Investigate Scope.Entry for this.
        replacement = tree.getIdentifier().toString();
    } else {
        // Replace the operand of the field access expression with the simple name of the class.
        replacement = ownerSym.getSimpleName() + "." + tree.getIdentifier();
        // Don't import implicitly imported packages (java.lang.* and current package).
        // TODO(cushon): move this logic into addImport?
        Symbol packageSym = ownerSym.packge();
        if (!packageSym.toString().equals("java.lang") && !packageSym.equals(whereAccessedSym.packge())) {
            fix.addImport(ownerSym.toString());
        }
    }
    fix.replace(tree, replacement);
    // Compute strings to interpolate into diagnostic message.
    String memberName = staticMemberSym.getSimpleName().toString();
    String methodOrVariable = isMethod ? "method" : "variable";
    String customDiagnosticMessage = String.format(MESSAGE_TEMPLATE, methodOrVariable, memberName, replacement);
    return buildDescription(tree).setMessage(customDiagnosticMessage).addFix(fix.build()).build();
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) Symbol(com.sun.tools.javac.code.Symbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ClassTree(com.sun.source.tree.ClassTree)

Example 24 with MethodSymbol

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

the class TryFailThrowable method getMessageSnippet.

private static String getMessageSnippet(StatementTree failStatement, VisitorState state, HasOtherParameters hasOtherParameters) {
    ExpressionTree expression = ((ExpressionStatementTree) failStatement).getExpression();
    MethodSymbol sym = (MethodSymbol) getSymbol(expression);
    String tail = hasOtherParameters == HasOtherParameters.TRUE ? ", " : "";
    // The above casts were checked earlier by failOrAssert.
    return hasInitialStringParameter(sym, state) ? state.getSourceForNode(((MethodInvocationTree) expression).getArguments().get(0)) + tail : "";
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) ExpressionTree(com.sun.source.tree.ExpressionTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree)

Example 25 with MethodSymbol

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

the class WrongParameterPackage method matchMethod.

@Override
public Description matchMethod(MethodTree tree, VisitorState state) {
    MethodSymbol method = ASTHelpers.getSymbol(tree);
    if (method == null) {
        return Description.NO_MATCH;
    }
    ClassSymbol classSym = method.enclClass();
    if (classSym == null) {
        return Description.NO_MATCH;
    }
    TypeSymbol superClass = classSym.getSuperclass().tsym;
    if (superClass == null) {
        return Description.NO_MATCH;
    }
    for (Symbol s : superClass.members().getSymbols()) {
        if (s.name.contentEquals(method.name) && s.getKind() == ElementKind.METHOD) {
            MethodSymbol supermethod = (MethodSymbol) s;
            // if this method actually overrides the supermethod, then it's correct and not a match.
            if (method.overrides(supermethod, superClass, state.getTypes(), true)) {
                return Description.NO_MATCH;
            }
            // if this doesn't have the right number of parameters, look at other ones.
            if (supermethod.params().size() != method.params().size()) {
                continue;
            }
            for (int x = 0; x < method.params().size(); x++) {
                Type methodParamType = method.params().get(x).type;
                Type supermethodParamType = supermethod.params().get(x).type;
                if (methodParamType.tsym.name.contentEquals(supermethodParamType.tsym.name) && !state.getTypes().isSameType(methodParamType, supermethodParamType)) {
                    this.supermethod = supermethod;
                    return describe(tree, state);
                }
            }
        }
    }
    return Description.NO_MATCH;
}
Also used : Type(com.sun.tools.javac.code.Type) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) Symbol(com.sun.tools.javac.code.Symbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol)

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