【问题标题】:Exhaustively walking the AST tree in Groovy在 Groovy 中详尽地遍历 AST 树
【发布时间】:2012-07-14 22:54:21
【问题描述】:

这与我关于拦截对给定类中的字段的所有访问的问题有关,而不仅仅是那些以与 Groovy 'property' 样式访问一致的方式完成的访问。你可以在这里查看:intercepting LOCAL property access in groovy。

我发现肯定会解决我的问题的一种方法是在编译时使用 AST 用属性访问重写任何非属性访问。例如,如果一个类看起来像这样:

class Foo {
  def x = 1
  def getter() {
    x
  }
  def getProperty(String name) {
    this."$name" ++
  }
}

foo = new Foo()
assert foo.getter() == 1
assert foo.x == 2

这些断言语句将起作用,因为 getter 方法直接访问 x,而 foo.x 通过 getProperty("x") 在返回之前递增 x。

经过反复试验后,我可以使用 AST 转换来更改代码的行为,以便“getter”方法中的表达式“x”实际上作为属性而不是本地字段进行访问。到目前为止一切顺利!

现在,如何访问给定类中本地字段的所有访问权限?我一直在互联网上寻找某种 AST tree walker helper,但还没有找到。我真的需要为http://groovy.codehaus.org/api/org/codehaus/groovy/ast/expr/package-summary.html 的所有 38 种表达式类型和http://groovy.codehaus.org/api/org/codehaus/groovy/ast/stmt/package-summary.html 的所有 18 种语句类型实现一个表达式步行器吗?这似乎是某人一定已经写过的东西(因为它首先是构建 AST 树的组成部分),但我似乎找不到它。

【问题讨论】:

    标签: groovy abstract-syntax-tree


    【解决方案1】:

    格伦

    您正在寻找某种访客。 Groovy 定义了一些您可以使用的访问者(文档薄弱)。对于您的问题,我没有确切的答案,但我可以为您提供一些指导。

    下面的 sn-p 显示了如何遍历一个类的 AST 并打印所有方法名:

    class TypeSystemUsageVisitor extends ClassCodeVisitorSupport {
    
    @Override
    public void visitExpression(MethodNode node) {
        super.visitMethod(node)
        println node.name
    }
    
    @Override
    protected SourceUnit getSourceUnit() {
        // I don't know ho I should implement this, but it makes no difference
        return null;
    } 
    }
    

    这就是我使用上面定义的访问者的方式

    def visitor = new TypeSystemUsageVisitor()
    def sourceFile = new File("path/to/Class.groovy")
    def ast = new AstBuilder().buildFromString(CompilePhase.CONVERSION, false, sourceFile.text).find { it.class == ClassNode.class }
    ast.visitContents(visitor)
    

    访客会为您负责穿越树木。他们有 visit* 方法,您可以覆盖这些方法并使用它们做任何您想做的事情。我相信您的问题的合适访问者是 CodeVisitorSupport,它有一个 visitVariableExpression 方法。

    我建议您阅读 groovyConsole 随附的 code of the AST Browser,以获取有关如何使用 Groovy AST 访问者的更多示例。另外,请查看 api doc 以获得 CodeVisitorSupport。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-19
      • 1970-01-01
      • 2014-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多