如何获取给定行号的所有JDT AST语句?

时间:2016-03-07 10:17:51

标签: java abstract-syntax-tree eclipse-jdt

如何在给定的行号中获得org.eclipse.jdt.core.dom.Statement

假设我有这门课程:

 1 package foo;
 2 public class Operations {
 3  public static int calc(int a, int b) {
 4      if (a >= b)
 5          return a - b;
 6      if (a<b || b==2)
 7          return -1;
 8      return 0;
 9  }
10 }

这就是我的期望:

  • 第3行 - &gt; BlockStatement
  • 第4行 - &gt; IfStatement
  • 第5行 - &gt; ReturnStatement

此代码有效,但有点笨重,因为在恶化的情况下必须访问每个正文和声明。有更好/更简单的方法吗?

List<Statement> getStatementsAtLine(final CompilationUnit cu, final int lineNumber) {
        final List<Statement> result = new ArrayList<Statement>();
        cu.accept(new ASTVisitor() {
            @Override
            public boolean visit(MethodDeclaration node) {
                Block body = node.getBody();

                for (Statement s : (List<Statement>) body.statements()) {
                    int l=cu.getLineNumber(s.getStartPosition());
                    if (l==lineNumber){
                        result.add(s);
                    }
                }
                return true;
            }
        });

        return result;
    }

1 个答案:

答案 0 :(得分:0)

您可能希望使用

将行号转换为(字符)位置
org.eclipse.jdt.core.dom.NodeFinder

使用该偏移量,您可以使用ASTNode检索该位置的NodeFinder finder= new NodeFinder(cu, offset, 0); ASTNode node= finder.getCoveringNode(); while (node != null && !(node instanceof Statement)) { node= node.getParent(); } return node; ,s。像:

offset

编辑: 但是,这种方法存在空白问题,因为正在搜索的语句不包括前导或尾随空白字符。

我看到两种可能的策略来避免这个问题:

  1. 增加ASTNode,直到您确定它在该行的重要文本“内”,或
  2. 应用以下评论中的技巧:将区域扩展到文件结尾,并要求该区域完全涵盖的最大getCoveredNode()(使用getCoveringNode()代替{{1 }})。
  3. 策略(1)要求通过IDocument检索相关行的文本,这可能不是现成的。 策略(2)可能会导致跨越多行的语句可能被选中,不确定这是否违反任何要求。如果需要更高的精度,请计算getPosition()的长度参数,作为当前行开始和下一行开始之间的差异。