如何在给定行号处获取 org.eclipse.jdt.core.dom.Statement
?
假设我有这个类(class):
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 行 ->
BlockStatement
- 第 4 行 ->
IfStatement
- 第 5 行 ->
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;
}
最佳答案
您可能想使用以下方法将行号转换为(字符)位置
org.eclipse.jdt.core.dom.CompilationUnit.getPosition(int, int)
有了这个偏移量,您可以使用 org.eclipse.jdt.core.dom.NodeFinder
检索ASTNode
在那个位置,s.t.像:
NodeFinder finder= new NodeFinder(cu, offset, 0);
ASTNode node= finder.getCoveringNode();
while (node != null && !(node instanceof Statement)) {
node= node.getParent();
}
return node;
编辑: 然而,这种方法存在空格问题,因为要查找的语句不涵盖前导或尾随空格字符。
我发现有两种可能的策略可以避免此问题:
- 增加
offset
直到您确定它位于该行的重要文本“内”,或者 - 应用下面评论中的技巧:将区域扩展到文件末尾并要求最大的
ASTNode
完全被该区域覆盖(使用getCoveredNode()
而不是getCoveringNode()
)。
策略 (1) 需要通过 IDocument 检索相关行的文本,而 IDocument 可能不容易获得。
策略(2)可能会导致选择跨越多行的语句,不确定这是否违反任何要求。如果需要更高的精度,请计算 getPosition()
的长度参数作为当前行开始和下一行开始之间的差异。
关于java - 如何获取给定行号的所有 JDT AST 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35841083/