/**
   * Converts ParseTree (that is generated by ANTLRv4) to DetailNode tree.
   *
   * @param parseTreeNode root node of ParseTree
   * @return root of DetailNode tree
   */
  private DetailNode convertParseTreeToDetailNode(ParseTree parseTreeNode) {
    final JavadocNodeImpl rootJavadocNode = createRootJavadocNode(parseTreeNode);

    JavadocNodeImpl currentJavadocParent = rootJavadocNode;
    ParseTree parseTreeParent = parseTreeNode;

    while (currentJavadocParent != null) {
      // remove unnecessary children tokens
      if (currentJavadocParent.getType() == JavadocTokenTypes.TEXT) {
        currentJavadocParent.setChildren((DetailNode[]) JavadocNodeImpl.EMPTY_DETAIL_NODE_ARRAY);
      }

      final JavadocNodeImpl[] children = (JavadocNodeImpl[]) currentJavadocParent.getChildren();

      insertChildrenNodes(children, parseTreeParent);

      if (children.length > 0) {
        currentJavadocParent = children[0];
        parseTreeParent = parseTreeParent.getChild(0);
      } else {
        JavadocNodeImpl nextJavadocSibling =
            (JavadocNodeImpl) JavadocUtils.getNextSibling(currentJavadocParent);

        ParseTree nextParseTreeSibling = getNextSibling(parseTreeParent);

        if (nextJavadocSibling == null) {
          JavadocNodeImpl tempJavadocParent = (JavadocNodeImpl) currentJavadocParent.getParent();

          ParseTree tempParseTreeParent = parseTreeParent.getParent();

          while (nextJavadocSibling == null && tempJavadocParent != null) {

            nextJavadocSibling = (JavadocNodeImpl) JavadocUtils.getNextSibling(tempJavadocParent);

            nextParseTreeSibling = getNextSibling(tempParseTreeParent);

            tempJavadocParent = (JavadocNodeImpl) tempJavadocParent.getParent();
            tempParseTreeParent = tempParseTreeParent.getParent();
          }
        }
        currentJavadocParent = nextJavadocSibling;
        parseTreeParent = nextParseTreeSibling;
      }
    }

    return rootJavadocNode;
  }
 /**
  * Finds and returns chars till first dot.
  *
  * @param textNode node with javadoc text.
  * @return String with chars till first dot.
  */
 private static String getCharsTillDot(DetailNode textNode) {
   final StringBuilder result = new StringBuilder();
   for (DetailNode child : textNode.getChildren()) {
     result.append(child.getText());
     if (PERIOD.equals(child.getText())
         && JavadocUtils.getNextSibling(child).getType() == JavadocTokenTypes.WS) {
       break;
     }
   }
   return result.toString();
 }
  /**
   * Gets token type of ParseTree node from JavadocTokenTypes class.
   *
   * @param node ParseTree node.
   * @return token type from JavadocTokenTypes
   */
  private static int getTokenType(ParseTree node) {
    final int tokenType;

    if (node.getChildCount() == 0) {
      tokenType = ((TerminalNode) node).getSymbol().getType();
    } else {
      final String className = getNodeClassNameWithoutContext(node);
      final String typeName = CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, className);
      tokenType = JavadocUtils.getTokenId(typeName);
    }

    return tokenType;
  }
예제 #4
0
 /**
  * Prints full tree (java + comments + javadoc) of the DetailAST.
  *
  * @param ast root DetailAST
  * @return Full tree
  */
 private static String printJavaAndJavadocTree(DetailAST ast) {
   final StringBuilder messageBuilder = new StringBuilder();
   DetailAST node = ast;
   while (node != null) {
     messageBuilder.append(getIndentation(node)).append(getNodeInfo(node)).append(LINE_SEPARATOR);
     if (node.getType() == TokenTypes.COMMENT_CONTENT
         && JavadocUtils.isJavadocComment(node.getParent())) {
       final String javadocTree = parseAndPrintJavadocTree(node);
       messageBuilder.append(javadocTree);
     } else {
       messageBuilder.append(printJavaAndJavadocTree(node.getFirstChild()));
     }
     node = node.getNextSibling();
   }
   return messageBuilder.toString();
 }
  /**
   * Parses Javadoc comment as DetailNode tree.
   *
   * @param javadocCommentAst DetailAST of Javadoc comment
   * @return DetailNode tree of Javadoc comment
   */
  public ParseStatus parseJavadocAsDetailNode(DetailAST javadocCommentAst) {
    blockCommentLineNumber = javadocCommentAst.getLineNo();
    final String javadocComment = JavadocUtils.getJavadocCommentContent(javadocCommentAst);

    // Use a new error listener each time to be able to use
    // one check instance for multiple files to be checked
    // without getting side effects.
    errorListener = new DescriptiveErrorListener();

    // Log messages should have line number in scope of file,
    // not in scope of Javadoc comment.
    // Offset is line number of beginning of Javadoc comment.
    errorListener.setOffset(javadocCommentAst.getLineNo() - 1);

    final ParseStatus result = new ParseStatus();

    try {
      final ParseTree parseTree = parseJavadocAsParseTree(javadocComment);

      final DetailNode tree = convertParseTreeToDetailNode(parseTree);
      result.setTree(tree);
    } catch (ParseCancellationException ex) {
      // If syntax error occurs then message is printed by error listener
      // and parser throws this runtime exception to stop parsing.
      // Just stop processing current Javadoc comment.
      ParseErrorMessage parseErrorMessage = errorListener.getErrorMessage();

      // There are cases when antlr error listener does not handle syntax error
      if (parseErrorMessage == null) {
        parseErrorMessage =
            new ParseErrorMessage(
                javadocCommentAst.getLineNo(),
                MSG_KEY_UNRECOGNIZED_ANTLR_ERROR,
                javadocCommentAst.getColumnNo(),
                ex.getMessage());
      }

      result.setParseErrorMessage(parseErrorMessage);
    }

    return result;
  }