public static int getNumberOfLines(FunctionTree declaration) {
    Tree body = declaration.body();
    if (!body.is(Kind.BLOCK)) {
      return 0;
    }

    BlockTree block = (BlockTree) body;
    int firstLine = block.openCurlyBraceToken().line();
    int lastLine = block.closeCurlyBraceToken().line();
    return lastLine - firstLine + 1;
  }
 private static boolean endsWithReturn(FunctionTree function) {
   Tree body = function.body();
   if (body.is(Kind.BLOCK)) {
     BlockTree block = (BlockTree) body;
     List<StatementTree> statements = block.statements();
     if (statements.isEmpty()) {
       return false;
     }
     return statements.get(statements.size() - 1).is(Kind.RETURN_STATEMENT);
   }
   return false;
 }
  @Override
  public void visitNode(Tree tree) {
    if (tree.is(Kind.COMPILATION_UNIT)) {
      fileMeasures.setFileComplexity(ComplexityVisitor.complexity(tree));

    } else if (tree.is(CLASS_NODES)) {
      fileMeasures.addClassComplexity(ComplexityVisitor.complexity(tree));

    } else if (tree.is(FUNCTION_NODES)) {
      fileMeasures.addFunctionComplexity(ComplexityVisitor.complexity(tree));
    }
  }
 @Override
 public void visitNode(Tree tree) {
   if (check.isOneSpaceBetweenKeywordAndNextToken) {
     checkSpaceBetweenKeywordAndNextNode(new TokenVisitor(tree), tree);
   }
   if (check.isOneSpaceAfterForLoopSemicolon && tree.is(Kind.FOR_STATEMENT)) {
     checkSpaceForStatement(tree);
   }
   if (check.isSpaceForeachStatement && tree.is(Kind.FOREACH_STATEMENT)) {
     ForEachStatementTree foreachLoop = (ForEachStatementTree) tree;
     checkForeachStatement(
         new TokenVisitor(tree),
         foreachLoop,
         foreachLoop.asToken(),
         foreachLoop.doubleArrowToken());
   }
 }
 @Override
 public void visitNode(Tree tree) {
   if (tree.is(Kind.METHOD_DECLARATION)) {
     checkModifiers(((MethodDeclarationTree) tree).modifiers());
   } else {
     checkModifiers(((ClassPropertyDeclarationTree) tree).modifierTokens());
   }
 }
  private void checkSpaceBetweenKeywordAndNextNode(TokenVisitor tokenVisitor, Tree tree) {
    SyntaxToken keyword = tokenVisitor.tokenByValue(PHPKeyword.getKeywordValues());

    if (tree.is(Kind.TRY_STATEMENT)) {
      TryStatementTree tryStatement = (TryStatementTree) tree;

      if (tryStatement.finallyToken() != null) {
        SyntaxToken finallyKeyword = tryStatement.finallyToken();
        checkSpaceBetweenKeywordAndNextNode(finallyKeyword, tokenVisitor.nextToken(finallyKeyword));
      }
    }

    checkSpaceBetweenKeywordAndNextNode(keyword, tokenVisitor.nextToken(keyword));
  }
 private static boolean isSemicolon(@Nullable Tree tree) {
   return tree != null
       && tree.is(Kind.TOKEN)
       && TokenUtils.isType((SyntaxToken) tree, PHPPunctuator.SEMICOLON);
 }
 public static int complexityWithoutNestedFunctions(Tree tree) {
   ComplexityVisitor visitor = new ShallowComplexityVisitor(tree);
   tree.accept(visitor);
   return visitor.complexity;
 }
 public static int complexity(Tree tree) {
   ComplexityVisitor visitor = new ComplexityVisitor();
   tree.accept(visitor);
   return visitor.complexity;
 }