如何使用jdt.ast解析多态
How to use jdt.ast to resolve polymorphism
我正在努力通过 eclipse-jdt-ast 获取覆盖方法绑定。
就像我们使用eclipse时,按住Ctrl键,点击方法,就可以跳转到方法实现。
虽然它在 java 中是动态绑定,但以下效果很好:
public class Father{
public void test(){}
}
和儿子:
public class Son extends Father{
@Override
public void test(){}
public static void main (String[] arg){
Father f=new Son();
f.test();
}
}
当我们点击main中的test时,可以正确跳转到Son.java
我想知道该怎么做。找了源码没找到位置,因为代码太多了
现在我的代码是:
public class Main {
static String filep="example/Son.java";
static String[] src={"example/"};
static String[] classfile={"example/"};
public static void main(String[] args) throws IOException,Exception{
ASTParser parser = ASTParser.newParser(AST.JLS8);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(Files.toString(new File(filep), Charsets.UTF_8).toCharArray());
// only setEnvironment can we get bindings from char[]
parser.setEnvironment(classfile, src, null, true);
parser.setUnitName(filep);
parser.setResolveBindings(true);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
CompilationUnit compilationUnit = (CompilationUnit) parser.createAST(null);
if (compilationUnit.getAST().hasResolvedBindings()) {
System.out.println("Binding activated.");
}
else {
System.out.println("Binding is not activated.");
}
ASTNode node=compilationUnit.findDeclaringNode("f");
compilationUnit.accept(new Myvisitor(compilationUnit));
}
}
我的访客是:
public class Myvisitor extends ASTVisitor {
int i=0;
CompilationUnit compilationUnit;
Myvisitor(CompilationUnit compilationUnit){
this.compilationUnit=compilationUnit;
}
@Override
public boolean visit(MethodInvocation node) {
i++;
System.out.println(i);
IMethodBinding binding=node.resolveMethodBinding();
ASTNode astNode=compilationUnit.findDeclaringNode(binding);
System.out.println(astNode);
return true;
}
}
有点长但是很简单,希望你能读到这里。我个人认为
findDeclaringNode 方法可以做到这一点。但是,当我通过绑定时,它 returns null。那么你有什么想法吗?
非常感谢
在查找给定超级方法的所有实现时,AST 几乎没有帮助,因为即使有它的绑定,它也只有从子到超级的引用,而不是相反的方向。
反向搜索使用SearchEngine
。如果您查看 JavaElementImplementationHyperlink
,可以在 line 218 周围找到相关代码部分(截至当前 HEAD)
您必须首先找到代表超级方法的 IMethod
。然后在最终调用 engine.search(..)
之前准备一个 SearchRequestor
、一个 IJavaSearchScope
和一个 SearchPattern
。搜索结果收集在 ArrayList<IJavaElement> links
.
Eclipse 插件开发的一个优良传统是 "monkey see, monkey do",所以我希望通过查看这段代码可以让您开始追求 :)
我正在努力通过 eclipse-jdt-ast 获取覆盖方法绑定。 就像我们使用eclipse时,按住Ctrl键,点击方法,就可以跳转到方法实现。
虽然它在 java 中是动态绑定,但以下效果很好:
public class Father{
public void test(){}
}
和儿子:
public class Son extends Father{
@Override
public void test(){}
public static void main (String[] arg){
Father f=new Son();
f.test();
}
}
当我们点击main中的test时,可以正确跳转到Son.java 我想知道该怎么做。找了源码没找到位置,因为代码太多了
现在我的代码是:
public class Main {
static String filep="example/Son.java";
static String[] src={"example/"};
static String[] classfile={"example/"};
public static void main(String[] args) throws IOException,Exception{
ASTParser parser = ASTParser.newParser(AST.JLS8);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(Files.toString(new File(filep), Charsets.UTF_8).toCharArray());
// only setEnvironment can we get bindings from char[]
parser.setEnvironment(classfile, src, null, true);
parser.setUnitName(filep);
parser.setResolveBindings(true);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
CompilationUnit compilationUnit = (CompilationUnit) parser.createAST(null);
if (compilationUnit.getAST().hasResolvedBindings()) {
System.out.println("Binding activated.");
}
else {
System.out.println("Binding is not activated.");
}
ASTNode node=compilationUnit.findDeclaringNode("f");
compilationUnit.accept(new Myvisitor(compilationUnit));
}
}
我的访客是:
public class Myvisitor extends ASTVisitor {
int i=0;
CompilationUnit compilationUnit;
Myvisitor(CompilationUnit compilationUnit){
this.compilationUnit=compilationUnit;
}
@Override
public boolean visit(MethodInvocation node) {
i++;
System.out.println(i);
IMethodBinding binding=node.resolveMethodBinding();
ASTNode astNode=compilationUnit.findDeclaringNode(binding);
System.out.println(astNode);
return true;
}
}
有点长但是很简单,希望你能读到这里。我个人认为
findDeclaringNode 方法可以做到这一点。但是,当我通过绑定时,它 returns null。那么你有什么想法吗?
非常感谢
在查找给定超级方法的所有实现时,AST 几乎没有帮助,因为即使有它的绑定,它也只有从子到超级的引用,而不是相反的方向。
反向搜索使用SearchEngine
。如果您查看 JavaElementImplementationHyperlink
,可以在 line 218 周围找到相关代码部分(截至当前 HEAD)
您必须首先找到代表超级方法的 IMethod
。然后在最终调用 engine.search(..)
之前准备一个 SearchRequestor
、一个 IJavaSearchScope
和一个 SearchPattern
。搜索结果收集在 ArrayList<IJavaElement> links
.
Eclipse 插件开发的一个优良传统是 "monkey see, monkey do",所以我希望通过查看这段代码可以让您开始追求 :)