use of com.sun.tools.javac.code.Symbol in project error-prone by google.
the class SelfAssignment method matchVariable.
@Override
public Description matchVariable(VariableTree tree, VisitorState state) {
ExpressionTree initializer = stripCheckNotNull(tree.getInitializer(), state);
Tree parent = state.getPath().getParentPath().getLeaf();
// must be a static class variable with member select initializer
if (initializer == null || initializer.getKind() != MEMBER_SELECT || parent.getKind() != CLASS || !tree.getModifiers().getFlags().contains(STATIC)) {
return Description.NO_MATCH;
}
MemberSelectTree rhs = (MemberSelectTree) initializer;
Symbol rhsClass = ASTHelpers.getSymbol(rhs.getExpression());
Symbol lhsClass = ASTHelpers.getSymbol(parent);
if (rhsClass != null && lhsClass != null && rhsClass.equals(lhsClass) && rhs.getIdentifier().contentEquals(tree.getName())) {
return describeForVarDecl(tree, state);
}
return Description.NO_MATCH;
}
use of com.sun.tools.javac.code.Symbol in project error-prone by google.
the class MissingOverride method matchMethod.
@Override
public Description matchMethod(MethodTree tree, VisitorState state) {
Symbol sym = ASTHelpers.getSymbol(tree);
if (sym.isStatic()) {
return Description.NO_MATCH;
}
if (ASTHelpers.hasAnnotation(sym, Override.class, state)) {
return Description.NO_MATCH;
}
MethodSymbol override = getFirstOverride(sym, state.getTypes());
if (override == null) {
return Description.NO_MATCH;
}
if (ASTHelpers.hasAnnotation(override, Deprecated.class, state)) {
// @Deprecated to skip the annotation
return Description.NO_MATCH;
}
return buildDescription(tree).addFix(SuggestedFix.prefixWith(tree, "@Override ")).setMessage(String.format("%s %s method in %s; expected @Override", sym.getSimpleName(), override.enclClass().isInterface() || override.getModifiers().contains(Modifier.ABSTRACT) ? "implements" : "overrides", override.enclClass().getSimpleName())).build();
}
use of com.sun.tools.javac.code.Symbol in project error-prone by google.
the class RedundantThrows method matchMethod.
@Override
public Description matchMethod(MethodTree tree, VisitorState state) {
List<? extends ExpressionTree> thrown = tree.getThrows();
if (thrown.isEmpty()) {
return NO_MATCH;
}
SetMultimap<Symbol, ExpressionTree> exceptionsBySuper = LinkedHashMultimap.create();
for (ExpressionTree exception : thrown) {
Type type = getType(exception);
do {
type = state.getTypes().supertype(type);
exceptionsBySuper.put(type.tsym, exception);
} while (!state.getTypes().isSameType(type, state.getSymtab().objectType));
}
Set<ExpressionTree> toRemove = new HashSet<>();
List<String> messages = new ArrayList<>();
for (ExpressionTree exception : thrown) {
Symbol sym = getSymbol(exception);
if (exceptionsBySuper.containsKey(sym)) {
Set<ExpressionTree> sub = exceptionsBySuper.get(sym);
messages.add(String.format("%s %s of %s", oxfordJoin(", ", sub), sub.size() == 1 ? "is a subtype" : "are subtypes", sym.getSimpleName()));
toRemove.addAll(sub);
}
}
if (toRemove.isEmpty()) {
return NO_MATCH;
}
// sort by order in input
List<ExpressionTree> delete = ImmutableList.<ExpressionTree>copyOf(Iterables.filter(tree.getThrows(), Predicates.in(toRemove)));
return buildDescription(delete.get(0)).setMessage("Redundant throws clause: " + oxfordJoin("; ", messages)).addFix(SuggestedFixes.deleteExceptions(tree, state, delete)).build();
}
use of com.sun.tools.javac.code.Symbol 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 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;
}
Aggregations