首页 > 解决方案 > Javaparser 从内部/嵌套类定义中收集多个孤立的和未附加的注释

问题描述

我正在编写一个用于收集类评论的工具,我想收集开发人员在逻辑上附加到类的所有评论:

public abstract class A {

  private Integer d;



   // comment line
   /**
   * javadoc comment
   */
   class B {
     int c;
   }
 }

或(相反的评论顺序)

public abstract class A {
   /**
   * javadoc comment
   */
   // comment line
   class B {
     int c;
   }
 }

我当前的实现从 CompilationUnit 开始递归遍历到每个子节点(节点),并检查它是否是类(或接口)声明。然后通过 . 从 Node 中提取评论node.getComment()。问题是,位于第一个评论之上的另一个评论没有父评论,因此没有被计算在内。

有没有办法以某种方式收集所有这些?(让我们考虑它们彼此相邻,没有换行)

标签: javainner-classesstatic-classesjavaparser

解决方案


这是一个解决方案。归功于编写此代码的 Waylon Huang 。

  /**
   * This is stolen from JavaParser's PrettyPrintVisitor.printOrphanCommentsBeforeThisChildNode,
   * with light modifications.
   *
   * @param node the node whose orphan comments to collect
   * @param result the list to add orphan comments to. Is side-effected by this method. The
   *     implementation uses this to minimize the diffs against upstream.
   */
  @SuppressWarnings({
    "JdkObsolete", // for LinkedList
    "ReferenceEquality"
  })
  private static void getOrphanCommentsBeforeThisChildNode(final Node node, List<Comment> result) {
    if (node instanceof Comment) {
      return;
    }

    Node parent = node.getParentNode().orElse(null);
    if (parent == null) {
      return;
    }
    List<Node> everything = new LinkedList<>(parent.getChildNodes());
    sortByBeginPosition(everything);
    int positionOfTheChild = -1;
    for (int i = 0; i < everything.size(); i++) {
      if (everything.get(i) == node) positionOfTheChild = i;
    }
    if (positionOfTheChild == -1) {
      throw new AssertionError("I am not a child of my parent.");
    }
    int positionOfPreviousChild = -1;
    for (int i = positionOfTheChild - 1; i >= 0 && positionOfPreviousChild == -1; i--) {
      if (!(everything.get(i) instanceof Comment)) positionOfPreviousChild = i;
    }
    for (int i = positionOfPreviousChild + 1; i < positionOfTheChild; i++) {
      Node nodeToPrint = everything.get(i);
      if (!(nodeToPrint instanceof Comment))
        throw new RuntimeException(
            "Expected comment, instead "
                + nodeToPrint.getClass()
                + ". Position of previous child: "
                + positionOfPreviousChild
                + ", position of child "
                + positionOfTheChild);
      result.add((Comment) nodeToPrint);
    }
  }
}

推荐阅读