对于编译器项目,我必须在Java文件中找到模式。例如,如果我输入“ @x = 3”,则程序必须在每次将3归因于某种情况的情况下返回。

为此,我使用了JDT中的ASTParser。我解析该文件并获得一个CompilationUnit对象,如下所示:

private static CompilationUnit getAST(char[] unit){

    ASTParser parser = ASTParser.newParser(AST.JLS8);
    parser.setKind(ASTParser.K_COMPILATION_UNIT);
    parser.setSource(unit); // set source

    parser.setResolveBindings(true); // we need bindings later on
    parser.setBindingsRecovery(true);

    Map options = JavaCore.getOptions();
    parser.setCompilerOptions(options);

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

    return cu;

}


现在,我正在根据给出的模式构建另一个AST。上面的示例结果如下:

AssignementExpression
 LHS
  Pattern("@x")
 RHS
  Literal("3")


然后,我使用此AST搜索CompilationUnit。问题在于搜索节点的ASTParser API class需要知道我要访问的节点的类。

我需要创建一个新的visitor对象,并定义我要在visit函数中执行的操作:

ASTVisitor visitor = (new ASTVisitor() {

        public boolean visit(VariableDeclarationFragment node) {

            // what I want to do

            return true; // do not continue
        }
}


所以我想做的是,在运行时,将AssignmentExpression与VariableDeclarationFragment关联,并使用VariableDeclarationFragment调用visit函数。就像是:

Class nodeType = getTypeFromGrammar("AssignementExpression");

ASTVisitor visitor = (new ASTVisitor() {

        public boolean visit(nodeType node) { // use the class that was returned above

            // what I want to do

            return true; // do not continue
        }
}

最佳答案

一种方法是使用反射。

您将要使用ASTVisitor的命名子类,而不是匿名类。假设它称为MyAstVisitor。它可以覆盖多个ASTVisitor.visit(T)方法。

您可以使用Class.getMethod()获得适当的方法。例如:

Method visitMethod = MyASTVistor.class.getMethod( "visit", nodeType );


然后可以使用Method.invoke()调用该方法:

visitMethod.invoke( myAstVisitorInstance, myNode );

09-26 15:05