1

これは、Groovy の「プロパティ」スタイルのアクセスと一致する方法で行われたものだけでなく、特定のクラスのフィールドへのすべてのアクセスをインターセプトすることに関する私の質問に関連しています。ここで確認できます: groovy で LOCAL プロパティ アクセスをインターセプトします

私の問題を確実に解決することがわかった1つの方法は、コンパイル時にASTを使用して、プロパティアクセスで非プロパティアクセスを書き直すことです。たとえば、 if クラスは次のようになります。

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 をインクリメントしてから戻るため、これらの assert ステートメントは機能します。

試行錯誤の末、AST 変換を使用してコードの動作を変更し、「getter」メソッドの式「x」が実際にはローカル フィールドではなくプロパティとしてアクセスされるようにすることができます。ここまでは順調ですね!

では、特定のクラスのローカル フィールドへのすべてのアクセスを取得するにはどうすればよいでしょうか。私はある種の AST ツリー ウォーカー ヘルパーを探してインターネットをくまなく調べてきましたが、見つかりませんでした。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 ? それは誰かがすでに書いたに違いないもののように思えますが (最初に AST ツリーを構築するのに不可欠であるため)、私はそれを見つけることができないようです。

4

1 に答える 1

2

グレン

あなたはある種の訪問者を探しています。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)

訪問者はあなたのために木を横断する世話をします。それらには、オーバーライドして、必要なことを何でも実行できる visit* メソッドがあります。あなたの問題に適切な訪問者は、visitVariableExpression メソッドを持つ CodeVisitorSupport だと思います。

Groovy AST ビジターの使用方法に関するその他の例については、groovyConsole に付属するAST ブラウザーのコードを読むことをお勧めします。また、CodeVisitorSupportのapi docも参照してください。

于 2012-12-09T22:40:58.617 に答える