如何从所有节点从EclipseJDT解析器解析的java源代码中获取行和/或列?

如何从所有节点从EclipseJDT解析器解析的java源代码中获取行和/或列?,java,eclipse,parsing,abstract-syntax-tree,eclipse-jdt,Java,Eclipse,Parsing,Abstract Syntax Tree,Eclipse Jdt,我已经使用ASTs玩了很长一段时间,并试图从eclipse中获取与在该插件上解析的给定节点相关联的行和列信息。根据记录在案的api,我发现方法getStartPosition()可以给出解析文件字符的位置,但这不是我想要的 我继续寻找方法getLineNumber(int-position)和getColumnNumber(int-position),据我所知,这两种方法都可以做到这一点。position参数等于getStartPosition()方法通过执行node.getStartPosit

我已经使用ASTs玩了很长一段时间,并试图从eclipse中获取与在该插件上解析的给定节点相关联的行和列信息。根据记录在案的api,我发现方法
getStartPosition()
可以给出解析文件字符的位置,但这不是我想要的

我继续寻找方法
getLineNumber(int-position)
getColumnNumber(int-position)
,据我所知,这两种方法都可以做到这一点。
position
参数等于
getStartPosition()
方法通过执行
node.getStartPosition()
返回的值

现在的问题是,在源文件上获取行和列的两种方法似乎并不适用于所有节点。例如,他们没有他们

我怎样才能得到所有树上的这些信息?我知道这不是不可能的,因为我能够为其他语言使用解析器,对于每个ast节点都有一行和一列与其关联。事实上,我相信java就是其中之一,因为该类包含硬编码的行和列的属性。看到EclipseJDT在我看来更加健壮,并且在那里呆了很长一段时间,我会惊讶地发现这样的信息不可能获得

编辑:同样,问题是从只出现在根目录上的编译单元的不同内容中获取行号:

<type 'org.eclipse.jdt.core.dom.CompilationUnit'>
1
<type 'org.eclipse.jdt.core.dom.TypeDeclaration'>
<type 'org.eclipse.jdt.core.dom.Javadoc'>
<type 'org.eclipse.jdt.core.dom.TagElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>

1.

谢谢。

我面前没有正在运行的程序,但是根据您上面链接的文档和Eclipse上的源代码,您似乎可以通过调用
getRoot()
并将其强制转换为
CompilationUnit
来获取
ASTNode
CompilationUnit
。或者,从
ASTParser
和的示例中可以看出,
ASTParser.createAST(IProgressMonitor)
几乎总是返回一个
compileationunit
,它表示您正在解析的源代码

拥有名为
root
compilementunit
后,您应该能够使用
root.getLineNumber(node.getStartPosition())
root.getColumnNumber(node.getStartPosition())
方法

final ASTParser p = ASTParser.newParser(AST.JLS3);
p.setSource(source);
final CompilationUnit root = (CompilationUnit) p.createAST(null);
// stuff happens
final ASTNode node = //get a node

final int line = root.getLineNumber(node.getStartPosition());
final int column = root.getColumnNumber(node.getStartPosition());
System.out.println("Node started at (" + line + ", " + column + ")";

我面前没有一个正在运行的程序,但根据您上面链接的文档和Eclipse上的源代码,您似乎可以通过调用
getRoot()
并将其强制转换为
CompilationUnit
来获取
ASTNode
CompilationUnit
。或者,从
ASTParser
和的示例中可以看出,
ASTParser.createAST(IProgressMonitor)
几乎总是返回一个
compileationunit
,它表示您正在解析的源代码

拥有名为
root
compilementunit
后,您应该能够使用
root.getLineNumber(node.getStartPosition())
root.getColumnNumber(node.getStartPosition())
方法

final ASTParser p = ASTParser.newParser(AST.JLS3);
p.setSource(source);
final CompilationUnit root = (CompilationUnit) p.createAST(null);
// stuff happens
final ASTNode node = //get a node

final int line = root.getLineNumber(node.getStartPosition());
final int column = root.getColumnNumber(node.getStartPosition());
System.out.println("Node started at (" + line + ", " + column + ")";

为了子孙后代,我将重新发布我在jdt核心开发人员邮件列表上发布的答案。(我的回答与上面Ryan的建议没有太大区别)

你好,卡洛斯

关于CompilationUnit.getLineNumber(int)方法,您是正确的。您可以按如下方式使用它:

int lineNumber=compilationUnit.getLineNumber(node.getStartPosition())-1

然而,我不明白你被困在哪里了。为什么需要为MethodDeclaration定义getLineNumber(..)?您所要做的就是找到方法声明节点,然后使用下面的代码找到它对应的编译单元,然后使用上面的代码行找到行号。我是不是遗漏了什么

ASTParser parser = ASTParser.newParser(AST.JLS3); // or JLS_4 for java 7 and above

parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(source); // give your java source here as char array
parser.setResolveBindings(true);

CompilationUnit compilationUnit = parser.createAST(null);
干杯!
Ayush

为了子孙后代,我重新发布了我在jdt核心开发邮件列表上发布的答案。(我的回答与上面Ryan的建议没有太大区别)

你好,卡洛斯

关于CompilationUnit.getLineNumber(int)方法,您是正确的。您可以按如下方式使用它:

int lineNumber=compilationUnit.getLineNumber(node.getStartPosition())-1

然而,我不明白你被困在哪里了。为什么需要为MethodDeclaration定义getLineNumber(..)?您所要做的就是找到方法声明节点,然后使用下面的代码找到它对应的编译单元,然后使用上面的代码行找到行号。我是不是遗漏了什么

ASTParser parser = ASTParser.newParser(AST.JLS3); // or JLS_4 for java 7 and above

parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(source); // give your java source here as char array
parser.setResolveBindings(true);

CompilationUnit compilationUnit = parser.createAST(null);
干杯!
Ayush

谢谢,我没有意识到CU与给定的java文件相关联,因此它拥有与该文件相关的ast节点的行位置信息是合理的。我更习惯于心理模型,每个节点都有它所属的相关行和列,因为这是我见过的唯一的模型。这一切都归结为设定班级责任的方式,而这个新的方式是没有意义的。现在一切都运转正常。由于我是从你的答案中意识到这一点的,所以我设置了投票并将你的设置为已回答。谢谢你,我没有意识到CU与给定的java文件关联,因此它拥有与该文件相关的ast节点的行位置信息是合理的。我更习惯于心理模型,每个节点都有它所属的相关行和列,因为这是我见过的唯一的模型。这一切都归结为设定班级责任的方式,而这个新的方式是没有意义的。现在一切都运转正常。因为我从你的回答中意识到了这一点,所以我投了你的一票,并将你的答案设为答案。谢谢你,我投了一票,因为答案也很连贯。投票选择另一个作为最终答案,因为它帮助我认识到m的不同