当前位置: 首页 > 知识库问答 >
问题:

在Groovy中疲惫地走过AST树

吕鹏
2023-03-14

这与我的问题有关,即拦截给定类中对字段的所有访问,而不仅仅是以与Groovy“属性”样式访问一致的方式进行的访问。您可以在这里查看:在groovy中拦截LOCAL属性访问。

我发现的一种肯定会解决我的问题的方法是在编译时使用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树行者助手,但没有找到一个。我真的需要为此处的所有 38 种表达式类型实现表达式 walker http://groovy.codehaus.org/api/org/codehaus/groovy/ast/expr/package-summary.html 此处的所有 18 种语句类型 http://groovy.codehaus.org/api/org/codehaus/groovy/ast/stmt/package-summary.html?这似乎是某人已经写过的东西(因为它首先是构建AST树不可或缺的一部分),但我似乎找不到它。

共有1个答案

越安翔
2023-03-14

格伦

您正在寻找某种类型的访问者。Groovy定义了一些(记录不充分的)访问者,您可以使用这些访问者。对于您的问题,我没有确切的答案,但我可以为您提供一些方向。

下面的代码片段显示了如何遍历一个类的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)

参观者会替你横穿这棵树。它们有访问*方法,您可以覆盖这些方法并对其执行任何操作。我认为适合您的问题的访问者是CodeVisitorSupport,它有一个visitVariableExpression方法。

我建议您阅读groovyConsole附带的AST浏览器代码,以获得更多关于如何使用Groovy AST访问者的示例。另外,看看CodeVisitorSupport的api文档。

 类似资料:
  • 我正在寻找Groovy AST转换,它可以在我的类中生成构建器模式代码。 我知道有一些类似于< code>@Canonnical或< code>@ToString或< code>@EqualsAndHashCode的增强器可以自动生成有用的方法,希望有@GenerateBuilder。我想这样使用它:

  • 在我可以进一步回答之前,原始问题已被删除,因此我将问题与答案重新发布如下: 我无法使用AST转换修改我的方法,因为我无法在修改后执行前面的方法语句。我从方法中提取语句,将其保存在某个临时变量中,但在修改之后,当我尝试执行它时,得到MissingPropertyException:No such property:code for class:Calculator,就像我试图使用类中的属性,而不是方

  • 一面0809(做的是汽车控制相关的,车门控制等软件开发) 简单聊一下生活还有技术,没有问技术相关的。(英语对话就很疲惫:)) 类似HR面试。 二面0823 面试官:先用英文介绍一下自己的项目 下面是用中文来说的 你对嵌入式来说,自己的优势是在哪里? Autosar的架构方面来说,了解多少 获取Linux的根目录如何操作? 字符串拼接思路? 反问: 团队规模? 校招对于Autosar的学习程度? 总

  • 我想知道我们是否可以使用Antlr版本4构建一个AST。我找不到任何关于使用ANTLR4构建它的参考。一个答案是,使用antlr4会很容易,它只产生解析树,但我的问题是效率如何? 它迫使我们只能爬取整个解析树而不是抽象的语法树,这对于遍历整个解析树和使用访问者执行任务是不有效的。

  • 我得到了这个Java web应用程序,它使用Struts 2和Hibernate。最上层由Struts 2 action类组成。然后是我的业务逻辑类,它们负责应用程序的逻辑。最后还有一个DAO层(称为数据库桥),负责与数据库通信。 目前,我在DAO层打开会话并执行如下事务: 这种方法似乎有一些问题: > 逻辑上,我的事务是我的Struts 2操作(控制器),应该提交或回滚。Struts 2操作可能

  • 问题内容: 我对在groovy中使用排序的映射感兴趣(使用gremlin,这是用于图形数据库的DSL)。 我在这里按排序的地图查看了此博客文章,但我仍然有些困惑。 排序的地图如何声明?它与地图的标准方式有何不同? 使用排序映射时,插入列表中的项目是否会按照插入顺序进行?还是在对已排序的地图中的项目进行排序之前必须先运行? 问题答案: 如果您只是这样声明地图: 然后,您可以看到Groovy默认情况下