private static MethodTree getParentMethod(Tree tree) { Tree result = tree; while (!result.is(Tree.Kind.METHOD)) { result = result.parent(); } return (MethodTree) result; }
@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 boolean isWithinTryHeader(Tree syntaxNode) { final Tree parent = syntaxNode.parent(); if (parent.is(Tree.Kind.VARIABLE)) { return isTryStatementResource((VariableTree) parent); } return false; }
private CFG(BlockTree tree, Symbol.MethodSymbol symbol) { methodSymbol = symbol; exitBlock = createBlock(); currentBlock = createBlock(exitBlock); for (StatementTree statementTree : Lists.reverse(tree.body())) { build(statementTree); } for (Block b : gotos) { assert b.successors.isEmpty(); Tree s = b.terminator; assert s != null; String label; if (s.is(Tree.Kind.BREAK_STATEMENT)) { label = ((BreakStatementTree) s).label().name(); } else { label = ((ContinueStatementTree) s).label().name(); } Block target = labels.get(label); if (target == null) { throw new IllegalStateException("Undeclared label: " + label); } b.successors.add(target); } for (Block b : blocks) { for (Block successor : b.successors) { successor.predecessors.add(b); } } }
@Override public void visitNode(Tree tree) { if (isClassTree(tree)) { classes++; classTrees.push((ClassTree) tree); } if (tree.is(Tree.Kind.NEW_CLASS) && ((NewClassTree) tree).classBody() != null) { classes--; } if (tree.is(Tree.Kind.METHOD, Tree.Kind.CONSTRUCTOR) && classTrees.peek().simpleName() != null) { // don't count methods in anonymous classes. MethodTree methodTree = (MethodTree) tree; if (separateAccessorsFromMethods && AccessorsUtils.isAccessor(classTrees.peek(), methodTree)) { accessors++; } else { methods++; int methodComplexity = context.getMethodComplexityNodes(classTrees.peek(), methodTree).size(); methodComplexityDistribution.add(methodComplexity); complexityInMethods += methodComplexity; } } }
private MethodTree extractMethod(ClassTree classTree) { for (Tree tree : classTree.members()) { if (tree.is(Tree.Kind.METHOD) || tree.is(Tree.Kind.CONSTRUCTOR)) { return (MethodTree) tree; } } return null; }
private void checkClassFields(ClassTree classTree) { if (!hasExcludedAnnotation(classTree)) { for (Tree member : classTree.members()) { if (member.is(Tree.Kind.VARIABLE)) { checkIfUnused((VariableTree) member); } } } }
private static boolean hasOverrideAnnotation(MethodTree method) { for (AnnotationTree annotationTree : method.modifiers().annotations()) { Tree annotationType = annotationTree.annotationType(); if (annotationType.is(Tree.Kind.IDENTIFIER) && "Override".equals(((IdentifierTree) annotationType).name())) { return true; } } return false; }
private static boolean isAnnotated(ClassTree tree) { for (AnnotationTree annotationTree : tree.modifiers().annotations()) { Tree annotationType = annotationTree.annotationType(); if (annotationType.is(Tree.Kind.IDENTIFIER) && "FunctionalInterface".equals(((IdentifierTree) annotationType).name())) { return true; } } return false; }
private static TryStatementTree getEnclosingTryStatement(Tree syntaxNode) { Tree parent = syntaxNode.parent(); while (parent != null) { if (parent.is(Tree.Kind.TRY_STATEMENT)) { return (TryStatementTree) parent; } parent = parent.parent(); } return null; }
private static boolean classHasNoFieldAndProtectedMethod(ClassTree tree) { for (Tree member : tree.members()) { if (member.is(Tree.Kind.VARIABLE) || (member.is(Tree.Kind.METHOD) && ModifiersUtils.hasModifier( ((MethodTree) member).modifiers(), Modifier.PROTECTED))) { return false; } } return true; }
public boolean isPublicApi(Tree currentParent, Tree tree) { if (tree.is(CLASS_KINDS) && (currentParent == null || currentParent.is(PublicApiChecker.CLASS_KINDS))) { return isPublicApi((ClassTree) currentParent, (ClassTree) tree); } else if (tree.is(METHOD_KINDS)) { return isPublicApi((ClassTree) currentParent, (MethodTree) tree); } else if (tree.is(Tree.Kind.VARIABLE) && !currentParent.is(METHOD_KINDS)) { return isPublicApi((ClassTree) currentParent, (VariableTree) tree); } return false; }
private static ModifiersTree getModifierTrees(Tree tree) { ModifiersTree modifiersTree = null; if (tree.is(CLASS_KINDS)) { modifiersTree = ((ClassTree) tree).modifiers(); } else if (tree.is(METHOD_KINDS)) { modifiersTree = ((MethodTree) tree).modifiers(); } else if (tree.is(Kind.VARIABLE)) { modifiersTree = ((VariableTree) tree).modifiers(); } return modifiersTree; }
@Nullable private static String getNewClassName(Tree tree) { if (tree.is(Kind.IDENTIFIER)) { return ((IdentifierTree) tree).name(); } else if (tree.is(Kind.MEMBER_SELECT)) { return ((MemberSelectExpressionTree) tree).identifier().name(); } else if (tree.is(Kind.PARAMETERIZED_TYPE)) { return getNewClassName(((ParameterizedTypeTree) tree).type()); } return null; }
@Override protected void onMethodInvocationFound(MethodInvocationTree mit) { Tree parent = mit.parent(); while (parent != null && !parent.is(Tree.Kind.METHOD)) { parent = parent.parent(); } if (parent != null && THREAD_RUN_METHOD_MATCHER.matches((MethodTree) parent)) { return; } reportIssue( MethodsHelper.methodName(mit), "Call the method Thread.start() to execute the content of the run() method in a dedicated thread."); }
@Override public void visitNode(Tree tree) { ClassTree classTree = (ClassTree) tree; for (Tree member : classTree.members()) { if (member.is(Tree.Kind.VARIABLE) && hasNoVisibilityModifier((VariableTree) member)) { addIssue( member, "Explicitly declare the visibility for \"" + ((VariableTree) member).simpleName().name() + "\"."); } } }
@CheckForNull private static TypeTree getTypeFromExpression(Tree expression) { if (expression.is( Tree.Kind.VARIABLE, Tree.Kind.TYPE_CAST, Tree.Kind.RETURN_STATEMENT, Tree.Kind.ASSIGNMENT, Tree.Kind.CONDITIONAL_EXPRESSION)) { TypeTreeLocator visitor = new TypeTreeLocator(); expression.accept(visitor); return visitor.type; } return null; }
private boolean isQualifiedExcludedType(Tree tree) { if (!tree.is(Kind.MEMBER_SELECT)) { return false; } return Iterables.contains( exceptions, ExpressionsHelper.concatenate((MemberSelectExpressionTree) tree)); }
@Override public void visitClass(ClassTree tree) { if (tree.is(Tree.Kind.CLASS) || tree.is(Tree.Kind.ENUM)) { for (Tree member : tree.members()) { if (member.is(Tree.Kind.VARIABLE) && isPublicStaticNotFinal((VariableTree) member)) { context.addIssue( member, this, "Make this \"public static " + ((VariableTree) member).simpleName() + "\" field final"); } } } super.visitClass(tree); }
@Override public void leaveNode(Tree tree) { if (tree.is(Tree.Kind.CATCH)) { CatchTree catchTree = (CatchTree) tree; caughtVariables.remove(catchTree.parameter().simpleName().name()); } }
@Override public void visitNode(Tree tree) { if (!hasSemantic()) { return; } ClassTree classTree = (ClassTree) tree; List<Symbol> allMembers = retrieveMembers(classTree.symbol()); Multimap<String, Symbol> membersByName = sortByName(allMembers); for (Tree member : classTree.members()) { if (member.is(Tree.Kind.METHOD)) { checkForIssue(((MethodTree) member).symbol(), membersByName); } else if (member.is(Tree.Kind.VARIABLE)) { checkForIssue(((VariableTree) member).symbol(), membersByName); } } }
private void visitNode(Tree tree) { Tree currentParent = currentParents.peek(); if (tree.is(PublicApiChecker.CLASS_KINDS)) { classTrees.push((ClassTree) tree); currentParents.push(tree); } else if (tree.is(PublicApiChecker.METHOD_KINDS)) { currentParents.push(tree); } if (isPublicApi(currentParent, tree)) { publicApi++; if (getApiJavadoc(tree) != null) { documentedPublicApi++; } } }
private static boolean isBlockWithOneStatement(Tree tree) { boolean result = false; if (tree.is(Tree.Kind.BLOCK)) { List<StatementTree> blockBody = ((BlockTree) tree).body(); result = blockBody.size() == 1 && isRefactorizable(blockBody.get(0)); } return result; }
@Override public void visitNode(Tree tree) { if (tree.is(Tree.Kind.RETURN_STATEMENT)) { returnStatementCounter.add(methods.peek()); } else { methods.push(tree); } }
@Override public void checkEndOfExecutionPath(CheckerContext context, ConstraintManager constraintManager) { final List<ObjectConstraint> constraints = context.getState().getFieldConstraints(Status.OPENED); for (ObjectConstraint constraint : constraints) { Tree syntaxNode = constraint.syntaxNode(); String name = null; if (syntaxNode.is(Tree.Kind.NEW_CLASS)) { name = ((NewClassTree) syntaxNode).identifier().symbolType().name(); } else if (syntaxNode.is(Tree.Kind.METHOD_INVOCATION)) { name = ((MethodInvocationTree) syntaxNode).symbolType().name(); } if (name != null) { context.reportIssue(syntaxNode, this, "Close this \"" + name + "\"."); } } }
@Nullable public static String getApiJavadoc(Tree tree) { if (!tree.is(API_KINDS)) { return null; } ModifiersTree modifiersTree = getModifierTrees(tree); // FIXME token should be retrieved in a much simpler way. if (modifiersTree != null && !(modifiersTree.modifiers().isEmpty() && modifiersTree.annotations().isEmpty())) { return getCommentFromTree(modifiersTree); } if (tree.is(Tree.Kind.METHOD)) { MethodTree methodTree = (MethodTree) tree; return getCommentFromMethod(methodTree); } return getCommentFromTree(tree); }
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 static String getCommentFromMethod(MethodTree methodTree) { if (methodTree.typeParameters().isEmpty()) { Tree tokenTree = methodTree.returnType(); while (tokenTree != null && tokenTree.is(Kind.ARRAY_TYPE, Kind.PARAMETERIZED_TYPE, Kind.MEMBER_SELECT)) { if (tokenTree.is(Kind.ARRAY_TYPE)) { tokenTree = ((ArrayTypeTree) tokenTree).type(); } else if (tokenTree.is(Kind.MEMBER_SELECT)) { tokenTree = ((MemberSelectExpressionTree) tokenTree).expression(); } else if (tokenTree.is(Kind.PARAMETERIZED_TYPE)) { tokenTree = ((ParameterizedTypeTree) tokenTree).type(); } } return getCommentFromTree(tokenTree); } else { return getCommentFromSyntaxToken(methodTree.typeParameters().openBracketToken()); } }
public SymbolicValue createSymbolicValue(Tree syntaxNode) { SymbolicValue result; switch (syntaxNode.kind()) { case EQUAL_TO: result = new RelationalSymbolicValue(counter, RelationalSymbolicValue.Kind.EQUAL); break; case NOT_EQUAL_TO: result = new RelationalSymbolicValue(counter, RelationalSymbolicValue.Kind.NOT_EQUAL); break; case LESS_THAN: result = new RelationalSymbolicValue(counter, RelationalSymbolicValue.Kind.LESS_THAN); break; case LESS_THAN_OR_EQUAL_TO: result = new RelationalSymbolicValue(counter, RelationalSymbolicValue.Kind.LESS_THAN_OR_EQUAL); break; case GREATER_THAN: result = new RelationalSymbolicValue(counter, RelationalSymbolicValue.Kind.GREATER_THAN); break; case GREATER_THAN_OR_EQUAL_TO: result = new RelationalSymbolicValue( counter, RelationalSymbolicValue.Kind.GREATER_THAN_OR_EQUAL); break; case LOGICAL_COMPLEMENT: result = new SymbolicValue.NotSymbolicValue(counter); break; case AND: case AND_ASSIGNMENT: result = new SymbolicValue.AndSymbolicValue(counter); break; case OR: case OR_ASSIGNMENT: result = new SymbolicValue.OrSymbolicValue(counter); break; case XOR: case XOR_ASSIGNMENT: result = new SymbolicValue.XorSymbolicValue(counter); break; case INSTANCE_OF: result = new SymbolicValue.InstanceOfSymbolicValue(counter); break; case MEMBER_SELECT: result = createIdentifierSymbolicValue(((MemberSelectExpressionTree) syntaxNode).identifier()); break; case IDENTIFIER: result = createIdentifierSymbolicValue((IdentifierTree) syntaxNode); break; default: result = createDefaultSymbolicValue(); } counter++; return result; }
@Override public void leaveNode(Tree tree) { if (hasSemantic()) { if (tree.is(Tree.Kind.METHOD)) { MethodTree method = (MethodTree) tree; if (ModifiersUtils.hasModifier(method.modifiers(), Modifier.NATIVE)) { hasNativeMethod = true; } } else if (tree.is(Tree.Kind.CLASS)) { classes.add((ClassTree) tree); } else if (tree.is(Tree.Kind.EXPRESSION_STATEMENT)) { ExpressionTree expression = ((ExpressionStatementTree) tree).expression(); if (expression.is(ASSIGNMENT_KINDS)) { addAssignment(((AssignmentExpressionTree) expression).variable()); } } else { leaveCompilationUnit(); } } }