@Override public void visitVariable(VariableTree tree) { Symbol symbol = tree.symbol(); if (symbol != null && !symbol.isStatic()) { super.visitVariable(tree); } }
private static Multimap<String, Symbol> sortByName(List<Symbol> members) { Multimap<String, Symbol> membersByName = LinkedListMultimap.create(); for (Symbol member : members) { membersByName.put(member.name(), member); } return membersByName; }
private static boolean isVariableToExtract(Symbol symbol) { String name = symbol.name(); return !symbol.isEnum() && symbol.isVariableSymbol() && !"this".equals(name) && !"super".equals(name); }
private void checkForIssue(Symbol symbol, Multimap<String, Symbol> membersByName) { String name = symbol.name(); for (String knownMemberName : membersByName.keySet()) { if (name.equalsIgnoreCase(knownMemberName)) { for (Symbol knownMemberSymbol : membersByName.get(knownMemberName)) { if (!symbol.equals(knownMemberSymbol) && isValidIssueLocation(symbol, knownMemberSymbol) && isInvalidMember(symbol, knownMemberSymbol)) { addIssue( symbol.declaration(), "Rename " + getSymbolTypeName(symbol) + " \"" + name + "\" " + "to prevent any misunderstanding/clash with " + getSymbolTypeName(knownMemberSymbol) + " \"" + knownMemberName + "\" " + "defined " + getDefinitionPlace(symbol, knownMemberSymbol) + "."); break; } } } } }
@Override public void visitNode(Tree tree) { if (hasSemantic()) { TypeParameters typeParameters; String messageEnd; if (tree.is(Tree.Kind.METHOD)) { typeParameters = ((MethodTree) tree).typeParameters(); messageEnd = "method."; } else { typeParameters = ((ClassTree) tree).typeParameters(); messageEnd = "class."; if (tree.is(Tree.Kind.INTERFACE)) { messageEnd = "interface."; } } for (TypeParameterTree typeParameter : typeParameters) { Symbol symbol = getSemanticModel().getSymbol(typeParameter); if (symbol.usages().isEmpty()) { String message = new StringBuilder(typeParameter.identifier().name()) .append(" is not used in the ") .append(messageEnd) .toString(); addIssue(typeParameter, message); } } } }
private static Collection<MethodSymbol> filterMethods(Collection<Symbol> symbols) { List<MethodSymbol> methods = Lists.newArrayList(); for (Symbol symbol : symbols) { if (symbol.isMethodSymbol() && !isConstructor(symbol)) { methods.add((MethodSymbol) symbol); } } return methods; }
private static String getDefinitionPlace(Symbol symbol, Symbol knownMemberSymbol) { if (sameOwner(symbol, knownMemberSymbol)) { return "on line " + getDeclarationLine(knownMemberSymbol); } return "in " + (knownMemberSymbol.owner().isInterface() ? "interface" : "superclass") + " \"" + knownMemberSymbol.owner().type().fullyQualifiedName() + "\""; }
private static List<Symbol> extractMembers(Symbol.TypeSymbol classSymbol, boolean ignorePrivate) { List<Symbol> results = Lists.newLinkedList(); for (Symbol symbol : classSymbol.memberSymbols()) { if ((isVariableToExtract(symbol) || isMethodToExtract(symbol)) && !(symbol.isPrivate() && ignorePrivate)) { results.add(symbol); } } return results; }
private static boolean isFirstParentStatic(Deque<Symbol> outerClasses) { if (outerClasses.size() == 1) { return true; } for (Symbol outerClass : outerClasses) { if (outerClass.isStatic()) { return true; } } return false; }
public void checkIfUnused(VariableTree tree) { if (tree.modifiers().annotations().isEmpty()) { Symbol symbol = tree.symbol(); String name = symbol.name(); if (symbol.isPrivate() && !"serialVersionUID".equals(name) && symbol.usages().size() == assignments.get(symbol).size()) { addIssue(tree, "Remove this unused \"" + name + "\" private field."); } } }
@Override public void visitCatch(CatchTree tree) { if (!isExcludedType(tree.parameter().type())) { Symbol exception = tree.parameter().symbol(); validUsagesStack.addFirst(exception.usages()); super.visitCatch(tree); Collection<IdentifierTree> usages = validUsagesStack.pop(); if (usages.isEmpty()) { context.reportIssue(this, tree.parameter(), "Either log or rethrow this exception."); } } }
private int fromInstance(Symbol symbol, Symbol owner) { int i = -1; Type ownerType = owner.type(); for (Symbol outerClass : outerClasses) { i++; if (symbol.equals(outerClass) || (ownerType != null && owner.isTypeSymbol() && outerClass.type().isSubtypeOf(ownerType))) { return i; } } return -1; }
private void addBoxingIssue(Tree tree, Symbol classSymbol, Tree boxingArg) { if (boxingArg.is(Tree.Kind.IDENTIFIER)) { IdentifierTree identifier = (IdentifierTree) boxingArg; reportIssue(tree, "Remove the boxing of \"" + identifier.name() + "\"."); } else { reportIssue(tree, "Remove the boxing to \"" + classSymbol.name() + "\"."); } }
private void visitMethodInvocationTree(MethodInvocationTree methodInvocationTree) { if (isValueOfInvocation(methodInvocationTree)) { checkForUnboxing(methodInvocationTree.arguments().get(0)); } else if (isUnboxingMethodInvocation(methodInvocationTree)) { ExpressionTree methodSelect = methodInvocationTree.methodSelect(); if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) { MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) methodSelect; checkForBoxing(memberSelectExpressionTree.expression()); } } else { Symbol symbol = methodInvocationTree.symbol(); if (symbol.isMethodSymbol()) { List<Type> parametersTypes = ((Symbol.MethodSymbol) symbol).parameterTypes(); checkMethodInvocationArguments(methodInvocationTree, parametersTypes); } } }
private int referenceInstance(Symbol symbol) { Symbol owner = symbol.owner(); if (owner != null && owner.isMethodSymbol()) { // local variable, use owner of the method owner = owner.owner(); } int result = -1; if (owner != null && !outerClasses.peek().equals(owner)) { if (symbol.isUnknown()) { result = atLeastOneReference.size() - 1; } else if (!symbol.isStatic()) { result = fromInstance(symbol, owner); } } return result; }
private static boolean bothProtected(Symbol s1, Symbol s2) { return s1.isProtected() && s2.isProtected(); }
private static boolean isMethodToExtract(Symbol symbol) { return symbol.isMethodSymbol() && !"<init>".equals(symbol.name()); }
private static boolean isMethodMatchingName(Symbol symbol, String matchName) { return symbol.isMethodSymbol() && matchName.equals(symbol.name()); }
private static boolean isConstructor(Symbol symbol) { return "<init>".equals(symbol.name()); }
private static String getSymbolTypeName(Symbol symbol) { return symbol.isMethodSymbol() ? "method" : "field"; }
private static int getDeclarationLine(Symbol symbol) { if (symbol.isVariableSymbol()) { return ((Symbol.VariableSymbol) symbol).declaration().simpleName().identifierToken().line(); } return ((Symbol.MethodSymbol) symbol).declaration().simpleName().identifierToken().line(); }
private static boolean variableAndMethod(Symbol s1, Symbol s2) { return s1.isVariableSymbol() && s2.isMethodSymbol(); }
private static boolean sameName(Symbol currentMember, Symbol knownMember) { return currentMember.name().equals(knownMember.name()); }
private static boolean sameOwner(Symbol currentMember, Symbol knownMember) { return currentMember.owner().equals(knownMember.owner()); }
private static boolean isObjectsMethod(Symbol symbol, String methodName) { return symbol.isMethodSymbol() && symbol.owner().type().is("java.util.Objects") && methodName.equals(symbol.name()); }
private static boolean bothPackageVisibility(Symbol s1, Symbol s2) { return s1.isPackageVisibility() && s2.isPackageVisibility(); }
private static boolean isOverriding(Symbol symbol) { return symbol.isMethodSymbol() && BooleanUtils.isTrue(((MethodTreeImpl) symbol.declaration()).isOverriding()); }
private void addAssignment(IdentifierTree identifier) { Symbol reference = identifier.symbol(); if (!reference.isUnknown()) { assignments.put(reference, identifier); } }
private static boolean bothPublic(Symbol s1, Symbol s2) { return s1.isPublic() && s2.isPublic(); }