从 Eclipse 的 JDT 访问者模式中提取数据

Extracting data from Eclipse's JDT visitor pattern

所以我正在使用 Eclipse 的 JDT API 并尝试构建一个小应用程序。但是,我在从访问的节点中提取数据时遇到了困难,因为我只能打印它们。

例如,我希望能够 return 或将 getSuperclassType() 的值添加到 List 或 HashMap。但是,由于新的 ASTVisitor 是内部 class,Java 不允许我在没有 final 关键字的情况下声明在 ASTVisitor 内部使用的对象。

private static void get(String src) {
    ASTParser parser = ASTParser.newParser(AST.JLS3);
    parser.setSource(src.toCharArray());
    parser.setKind(ASTParser.K_COMPILATION_UNIT);
    parser.setResolveBindings(true);
    parser.setBindingsRecovery(true);

    final CompilationUnit cu = (CompilationUnit) parser.createAST(null);

    cu.accept(new ASTVisitor() {
        Set names = new HashSet();

        public boolean visit(TypeDeclaration typeDecNode) {
            if(!typeDecNode.isInterface()) {
                System.out.println(typeDecNode.getName().toString());
                System.out.println(typeDecNode.getSuperclassType());
                System.out.println(typeDecNode.superInterfaceTypes().toString());

                return true;
            }
...

是否可以通过这样的一段代码将每个访问节点的所需数据存储到数据结构中?或者另一种不使用访问者模式从 AST 遍历节点的方法?

只需使用扩展 ASTVisitor 的普通 class 作为访问者,而不是您当前使用的匿名 class,并在 class 中存储您喜欢的任何内容。

例如对于超级类型是这样的:

class MyVisitor extends ASTVisitor
{
  private List<Type> superTypes = new ArrayList<>();

  @Override
  public boolean visit(TypeDeclaration typeDecNode) {
       if(!typeDecNode.isInterface()) {
            superTypes.add(typeDecNode.getSuperclassType());
            return true;
       }
  }

  List<Type> getSuperTypes() {
     return superTypes;
  }
}

并用于:

MyVisitor myVisitor = new MyVisitor();

cu.accept(myVisitor);

List<Type> superTypes = myVisitor.getSuperTypes();

或者,您可以像这样在匿名 class 中访问 final 列表:

final List<Type> superTypes = new ArrayList<>();

cu.accept(new ASTVisitor() {
     public boolean visit(TypeDeclaration typeDecNode) {
        if(!typeDecNode.isInterface()) {
            superTypes.add(typeDecNode.getSuperclassType());

            return true;
        }