Search in sources :

Example 6 with MethodSymbol

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

the class IsInstanceOfClass method classify.

static Operand classify(JCTree tree, VisitorState state) {
    CharSequence source = state.getSourceForNode(tree);
    if (tree instanceof MethodInvocationTree) {
        // expr.getClass() -> "expr"
        MethodInvocationTree receiverInvocation = (MethodInvocationTree) tree;
        MethodSymbol sym = ASTHelpers.getSymbol(receiverInvocation);
        if (sym != null) {
            if (sym.getSimpleName().contentEquals("getClass") && sym.params().isEmpty()) {
                if (receiverInvocation.getMethodSelect() instanceof IdentifierTree) {
                    // unqualified `getClass()`
                    return Operand.create(Kind.EXPR, state.getSourceForNode(tree), source);
                }
                return Operand.create(Kind.GET_CLASS, state.getSourceForNode((JCTree) ASTHelpers.getReceiver(receiverInvocation)), source);
            }
        }
    } else if (tree instanceof MemberSelectTree) {
        // Foo.class -> "Foo"
        MemberSelectTree select = (MemberSelectTree) tree;
        if (select.getIdentifier().contentEquals("class")) {
            return Operand.create(Kind.LITERAL, state.getSourceForNode((JCTree) select.getExpression()), source);
        }
    }
    return Operand.create(Kind.EXPR, source, source);
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) IdentifierTree(com.sun.source.tree.IdentifierTree) JCTree(com.sun.tools.javac.tree.JCTree)

Example 7 with MethodSymbol

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

the class ProtoFieldNullComparison method createReplacement.

/**
   * Creates replacements for the following comparisons:
   * <pre>
   * proto.getField() == null --> !proto.hasField()
   * proto.getField() != null --> proto.hasField()
   * proto.getList() == null  --> proto.getList().isEmpty()
   * proto.getList() != null  --> !proto.getList().isEmpty()
   * <pre>
   * Also creates replacements for the Yoda style version of them.
   */
@Nullable
private static String createReplacement(BinaryTree tree, VisitorState state) {
    ExpressionTree leftOperand = tree.getLeftOperand();
    ExpressionTree rightOperand = tree.getRightOperand();
    ExpressionTree methodInvocation;
    if (isNull(leftOperand)) {
        methodInvocation = rightOperand;
    } else {
        methodInvocation = leftOperand;
    }
    if (isGetMethodInvocation(methodInvocation, state)) {
        String methodName = getMethodName(methodInvocation);
        String hasMethod = methodName.replaceFirst("get", "has");
        // proto3 does not generate has methods for scalar types, e.g. ByteString and String.
        // Do not provide a replacement in these cases.
        Set<MethodSymbol> hasMethods = ASTHelpers.findMatchingMethods(state.getName(hasMethod), NO_ARGS, ASTHelpers.getType(ASTHelpers.getReceiver(methodInvocation)), state.getTypes());
        if (hasMethods.isEmpty()) {
            return null;
        }
        String replacement = replaceLast(methodInvocation.toString(), methodName, hasMethod);
        replacement = tree.getKind() == Kind.EQUAL_TO ? "!" + replacement : replacement;
        return replacement;
    } else {
        String replacement = methodInvocation + ".isEmpty()";
        return tree.getKind() == Kind.EQUAL_TO ? replacement : "!" + replacement;
    }
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ExpressionTree(com.sun.source.tree.ExpressionTree) Nullable(javax.annotation.Nullable)

Example 8 with MethodSymbol

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

the class ForOverrideChecker method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    MethodSymbol method = ASTHelpers.getSymbol(tree);
    if (method == null) {
        return Description.NO_MATCH;
    }
    Type currentClass = getOutermostClass(state);
    if (method.isStatic() || method.isConstructor() || currentClass == null) {
        return Description.NO_MATCH;
    }
    // allow super.foo() calls to @ForOverride methods from overriding methods
    if (isSuperCall(currentClass, tree, state)) {
        MethodTree currentMethod = findDirectMethod(state.getPath());
        // currentMethod might be null if we are in a field initializer
        if (currentMethod != null) {
            // MethodSymbol.overrides doesn't check that names match, so we need to do that first.
            if (currentMethod.getName().equals(method.name)) {
                MethodSymbol currentMethodSymbol = ASTHelpers.getSymbol(currentMethod);
                if (currentMethodSymbol.overrides(method, (TypeSymbol) method.owner, state.getTypes(), true)) {
                    return Description.NO_MATCH;
                }
            }
        }
    }
    List<MethodSymbol> overriddenMethods = getOverriddenMethods(state, method);
    for (Symbol overriddenMethod : overriddenMethods) {
        Type declaringClass = overriddenMethod.outermostClass().asType();
        if (!declaringClass.equals(currentClass)) {
            String customMessage = MESSAGE_BASE + "must not be invoked directly " + "(except by the declaring class, " + declaringClass + ")";
            return buildDescription(tree).setMessage(customMessage).build();
        }
    }
    return Description.NO_MATCH;
}
Also used : Type(com.sun.tools.javac.code.Type) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodTree(com.sun.source.tree.MethodTree) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Symbol(com.sun.tools.javac.code.Symbol)

Example 9 with MethodSymbol

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

the class ForOverrideChecker method getOverriddenMethods.

/**
   * Get overridden @ForOverride methods.
   *
   * @param state the VisitorState
   * @param method the method to find overrides for
   * @return a list of methods annotated @ForOverride that the method overrides, including the
   *     method itself if it has the annotation
   */
private List<MethodSymbol> getOverriddenMethods(VisitorState state, MethodSymbol method) {
    // Static methods cannot override, only overload.
    if (method.isStatic()) {
        throw new IllegalArgumentException("getOverriddenMethods may not be called on a static method");
    }
    List<MethodSymbol> list = new LinkedList<MethodSymbol>();
    list.add(method);
    // Iterate over supertypes of the type that owns this method, collecting a list of all method
    // symbols with the same name.  We intentionally exclude interface methods because interface
    // methods cannot be annotated @ForOverride.  @ForOverride methods must have protected or
    // package-private visibility, but interface methods have implicit public visibility.
    Type currType = state.getTypes().supertype(method.owner.type);
    while (currType != null && !currType.equals(state.getSymtab().objectType) && !currType.equals(Type.noType)) {
        Symbol sym = currType.tsym.members().findFirst(method.name);
        if (sym instanceof MethodSymbol) {
            list.add((MethodSymbol) sym);
        }
        currType = state.getTypes().supertype(currType);
    }
    // Remove methods that either don't have the @ForOverride annotation or don't override the
    // method in question.
    Iterator<MethodSymbol> iter = list.iterator();
    while (iter.hasNext()) {
        MethodSymbol member = iter.next();
        if (!hasAnnotation(FOR_OVERRIDE, member) || // already checked that this method is not static.
        !method.overrides(member, (TypeSymbol) member.owner, state.getTypes(), true)) {
            iter.remove();
        }
    }
    return list;
}
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) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Symbol(com.sun.tools.javac.code.Symbol) LinkedList(java.util.LinkedList)

Example 10 with MethodSymbol

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

the class ConstructorMatcherImpl method getConstructor.

private static MethodSymbol getConstructor(ExpressionTree tree) {
    switch(tree.getKind()) {
        case NEW_CLASS:
        case METHOD_INVOCATION:
            break;
        default:
            return null;
    }
    Symbol sym = ASTHelpers.getSymbol(tree);
    if (!(sym instanceof MethodSymbol)) {
        return null;
    }
    MethodSymbol method = (MethodSymbol) sym;
    if (!method.isConstructor()) {
        return null;
    }
    return method;
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) Symbol(com.sun.tools.javac.code.Symbol)

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