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);
}
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;
}
}
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;
}
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;
}
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;
}
Aggregations