如何获取给定行号处的所有 JDT AST 语句?
How to get all JDT AST Statement's at a given line number?
如何在给定的行号处获得 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
此代码有效,但有点笨重,因为在最坏的情况下必须访问每个主体和语句。有 better/simpler 的方法吗?
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
在该位置 s.t 检索 ASTNode
。喜欢:
NodeFinder finder= new NodeFinder(cu, offset, 0);
ASTNode node= finder.getCoveringNode();
while (node != null && !(node instanceof Statement)) {
node= node.getParent();
}
return node;
编辑:
但是,这种方法对于白色 space 有问题,因为前导或尾随的白色 space 字符未包含在所查找的语句中。
我看到了两种可能的策略来避免这个问题:
- 增加
offset
直到您确定它是 "within" 该行的重要文本,或者
- 应用下面评论中的技巧:将区域扩展到文件末尾并要求最大的
ASTNode
完全被该区域覆盖(使用 getCoveredNode()
而不是 getCoveringNode()
).
策略 (1) 需要通过 IDocument 检索相关行的文本,这可能不容易获得。
策略 (2) 可能会产生这样的效果,即可以选择跨越多行的语句,但不确定这是否违反任何要求。如果需要更高的精度,计算 getPosition()
的长度参数作为当前行开始和下一行开始之间的差异。
如何在给定的行号处获得 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
此代码有效,但有点笨重,因为在最坏的情况下必须访问每个主体和语句。有 better/simpler 的方法吗?
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
在该位置 s.t 检索 ASTNode
。喜欢:
NodeFinder finder= new NodeFinder(cu, offset, 0);
ASTNode node= finder.getCoveringNode();
while (node != null && !(node instanceof Statement)) {
node= node.getParent();
}
return node;
编辑: 但是,这种方法对于白色 space 有问题,因为前导或尾随的白色 space 字符未包含在所查找的语句中。
我看到了两种可能的策略来避免这个问题:
- 增加
offset
直到您确定它是 "within" 该行的重要文本,或者 - 应用下面评论中的技巧:将区域扩展到文件末尾并要求最大的
ASTNode
完全被该区域覆盖(使用getCoveredNode()
而不是getCoveringNode()
).
策略 (1) 需要通过 IDocument 检索相关行的文本,这可能不容易获得。
策略 (2) 可能会产生这样的效果,即可以选择跨越多行的语句,但不确定这是否违反任何要求。如果需要更高的精度,计算 getPosition()
的长度参数作为当前行开始和下一行开始之间的差异。