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;
 }
示例#4
0
  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);
      }
    }
  }
示例#5
0
 @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();
     }
   }
 }