绑定不能解决eclipse中的AST处理问题

我正在使用eclipse JDT AST解析器来处理一些Java代码,并试图提取字段和方法声明的类型绑定。 这样做的逻辑在我的Visitor类中(见下文)。 不幸的是,我没有任何运气,也没有任何绑定解析(它们始终为空)。 有趣的是,绑定确实与eclipse ASTView插件在相同的代码上工作。 我究竟做错了什么?

这里有一些相关的代码片段,希望能帮助有人弄清楚发生了什么!

ASTParser parser = ASTParser.newParser(AST.JLS3); parser.setKind(ASTParser.K_COMPILATION_UNIT); parser.setSource(source); parser.setResolveBindings(true); CompilationUnit unit = (CompilationUnit) parser.createAST(null); GenericVisitor visitor = new GenericVisitor(outDir + "//" + file.getName() + ".xml"); visitor.process(unit); public class GenericVisitor extends ASTVisitor { public void endVisit(FieldDeclaration node) { String bindingInfo = ""; ITypeBinding binding = node.getType().resolveBinding(); if(binding == null) { System.out.println("field declaration binding = null"); } else { bindingInfo = binding.getQualifiedName(); } endVisitNode(node, bindingInfo); } public void endVisit(MethodInvocation node) { String bindingInfo = ""; IMethodBinding binding = node.resolveMethodBinding(); if(binding == null) { System.out.println("method binding = null"); } else { bindingInfo = binding.toString(); } endVisitNode(node, bindingInfo); } } 

当你使用:parser.setSource(source); 什么是param“source”的类型?

绑定信息从Java模型获得。 这意味着编译单元必须相对于Java模型。 当源代码来自setSource(ICompilationUnit)或setSource(IClassFile)时,会自动发生这种情况。 当source由setSource(char [])提供时,必须通过调用setProject(IJavaProject)和setUnitName(String)显式地创建该位置。

这是来自http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/dom/ASTParser.html我想想也许你只需要使用setSource(char [])而不需要调用setProject(IJavaProject)和setUnitName(String)

可能的原因是您不应该直接调用Visitor实例中的方法。 你应该做的事情如下:

 unit.accept(visitor); 

CompilationUnit的父类ASTNode有一个accept方法,它接受ASTVisitor类型的访问者

您编写的访问者GenericVisitor确实是abstarct类ASTVisitor的子类,并覆盖了您所关注的节点类型的实现。因此,我认为更改代码以上述forms进行调用将解决您的问题。

ASTParser只是解析器:它构建了一个AST,这是编译的第一步。 实际的编译器正在做更多的事情:它运行各种访问者,增强了树的附加信息。 其中之一是绑定解析访问者。

特别是,请查看org.eclipse.jdt.internal.compiler.Compiler类中的public void进程(CompilationUnitDeclaration unit,int i)方法的主体。

好的,这是我在Stack Overflow上的第一个答案。 紧张…

我遇到了同样的问题,因为你这样做了:

 parser.setResolveBindings(true); 

让我们通过检查它看看是否有效:

 if (unit.getAST().hasResolvedBindings()) { System.out.println("Binding activated."); } else { Ststem.out.println("Binding is not activated."); } 

我认为结果是“绑定未激活”。 这就是你一直得到空指针的原因。

然后,我将此语句添加到我的代码中:

 parser.setEnvironment(null, null, null, true); 

神奇的是,问题是解决的! 而且我想你也可以尝试一下。

问题是您的解析器没有提供构建其解析绑定所需的Java模型的必要信息。

如果解析器的源是从setSource(ICompilationUnit)setSource(IClassFile)此信息将自动提供给解析器。

但是,如果使用setSource(char[]) ,则必须为解析器提供此上下文。 这可以通过调用parser.setProject(IJavaProject)setEnvironment(String[], String[], String[], boolean)setUnitName(String)

资料来源: http : //help.eclipse.org/kepler/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/dom/ASTParser.html#setResolveBindings(boolean)

如果您的绑定为空,我不完全确定您的问题是否被其他解释所涵盖。 在我们的代码库中,我们执行以下操作,并且绑定始终存在:

 public static ASTNode getASTNodeFromCompilationUnit(ICompilationUnit compUnit) { ASTParser parser = ASTParser.newParser(AST.JLS3); parser.setResolveBindings(true); parser.setSource(compUnit); return parser.createAST(/* passing in monitor messes up previous monitor state */ null); } 

所以我能看到的唯一区别是解析绑定的调用顺序,以及我们不在解析器上调用setKind的事实。 你有没有机会尝试使用这个代码,看看会发生什么?

有时,如果引用的源文件中存在错误,则不会解析对这些类型的绑定。 例如,确保使用源的正确编码和Java版本。

  ASTParser parser = ASTParser.newParser(AST.JLS3); parser.setKind(ASTParser.K_COMPILATION_UNIT); parser.setResolveBindings(true); parser.setBindingsRecovery(true); Hashtable options = JavaCore.getDefaultOptions(); options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6); parser.setCompilerOptions(options); parser.setEnvironment(classpath, sources, new String[] { "UTF-8", "UTF-8" }, true); parser.setSource(fileContents.toCharArray()); CompilationUnit compilationUnit = (CompilationUnit) parser.createAST(null); IProblem[] problems = compilationUnit.getProblems(); if (problems != null && problems.length > 0) { logger.warn("Got {} problems compiling the source file: ", problems.length); for (IProblem problem : problems) { logger.warn("{}", problem); } } return compilationUnit;