【问题标题】:How to dynamically set the class of a function argument?如何动态设置函数参数的类?
【发布时间】:2017-10-12 02:09:42
【问题描述】:

对于编译器的项目,我必须在 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 需要知道我正在访问的节点的类。

我需要创建一个新的访问者对象,并在访问函数中定义我想做什么:

ASTVisitor visitor = (new ASTVisitor() {

        public boolean visit(VariableDeclarationFragment node) {

            // what I want to do

            return true; // do not continue 
        }
}

所以我想做的是,在运行时,将AssignementExpression与VariableDeclarationFragment关联起来,并用VariableDeclarationFragment调用访问函数。比如:

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 
        }
}

【问题讨论】:

  • 我不确定我是否理解。我如何使用演员表来拜访我想要的班级?

标签: java eclipse dynamic dynamic-programming abstract-syntax-tree


【解决方案1】:

一种方法是使用反射。

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

您可以通过Class.getMethod() 获取相应的方法。例如:

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

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

visitMethod.invoke( myAstVisitorInstance, myNode );

【讨论】:

  • 好的。我没有考虑创建一个我可以控制的新子类。我会尽量按照你说的去做,然后回来反馈。
  • 您的示例显示了匿名子类的创建。如果不想要子类,可以使用ASTVisitor.class.getMethod(...)
  • 是的,我知道。但我不记得创建子类是最好的方法。我终于让它工作了。谢谢!
猜你喜欢
  • 2011-02-28
  • 2020-06-25
  • 2012-01-14
  • 2011-08-11
  • 2023-03-22
  • 2014-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多