我使用org.eclipse.jdt.core.dom生成某些给定Java源代码的AST。 生成AST后,我有根节点。
如何使用ASTVisitor
以便我可以解析我的AST以获取所有叶节点?
答案 0 :(得分:2)
如果您还不熟悉特定的设计模式,我建议您先从Visitor Pattern开始阅读。
基本上,它归结为使用double dispatch在Visitor
类上调用适当的方法,将访问对象作为参数传递。通常,它以与以下(YMMV)类似的方式实现:
public interface Node {
void acceptVisitor(Visitor v);
Collection<Node> getChildren();
}
// Incomplete implementation, for demonstration only
public class SubNode implements Node {
@Override
public void acceptVisitor(Visitor v) {
if(v.preVisit(this)) {
v.visit(this);
v.postVisit(this);
}
getChildren().forEach(child -> child.accept(v));
}
}
public interface Visitor {
boolean preVisit(Node node);
void visit(Node node);
void visit(SubNode node);
void postVisit(Node node);
}
然后实现Visitor
接口,并将其传递到acceptVisitor
的{{1}}方法(通常但不总是树的根节点)。
要更全面地了解如何实施Node
,您可以查看this tutorial
在您的特定情况下,您需要扩展org.eclipse.jdt.core.dom.ASTVisitor
类,覆盖您关注的org.eclipse.jdt.core.dom.ASTNode
实现的ASTVisitor
方法。然后将此visit
的实例传递给AST根节点的accept
方法。
由于您正在寻找叶节点(定义为没有子节点的AST节点),您可以执行the following之类的操作来检索ASTVisitor
的子节点:
ASTNode
通过调用此方法并传递您检查的每个节点,您可以确定该节点是否没有子节点(返回的数组的public Object[] getChildren(ASTNode node) {
List list= node.structuralPropertiesForType();
for (int i= 0; i < list.size(); i++) {
StructuralPropertyDescriptor curr= (StructuralPropertyDescriptor) list.get(i);
Object child= node.getStructuralProperty(curr);
if (child instanceof List) {
return ((List) child).toArray();
} else if (child instanceof ASTNode) {
return new Object[] { child };
}
return new Object[0];
}
}
将为0)并将其添加到您的length
中Collection
要跟踪它们。
答案 1 :(得分:1)
这可能不是正确的方法,但这可以获取所有叶节点。
1)维护两组节点,让我们说S1
和S2
。
2)遍历所有节点并将每个节点添加到S1
3)如果node.getParent() != null
,则将node.getParent()
添加到S2
4)这意味着S1
跟踪所有节点,而S2
具有所有内部节点。叶子节点是S1 - S2
。
希望它有所帮助。
答案 2 :(得分:0)
一个例子是:
package de.vogella.jdt.astsimple.handler;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.MethodDeclaration;
public class MethodVisitor extends ASTVisitor {
List<MethodDeclaration> methods = new ArrayList<MethodDeclaration>();
@Override
public boolean visit(MethodDeclaration node) {
methods.add(node);
return super.visit(node);
}
public List<MethodDeclaration> getMethods() {
return methods;
}
}