コンパイル時にいくつかのクラスに汎用フィールドを追加したいと思います。この目的のために、私はdocumentationという公式に従って独自のASTアノテーションとトランスフォーメーションクラスを実装し、ASTアノテーションで目的のクラスにアノテーションを付けました。GroovyASTコンパイル時に汎用フィールドを追加する
org.codehaus.groovy.control.MultipleCompilationErrorsException:起動に失敗しました: /home/.../groovy/Sample.groovy:-1
しかし、私はコンパイル時にこのエラーを取得しています:変換では、フィールドxに対して直接ClassNode java.util.HashSetを含むジェネリックを使用しました。あなたはこれをするべきではありません。古いClassNodeを参照する新しいClassNodeを作成し、古いClassNodeの代わりに新しいClassNodeを使用してください。そうしないと、コンパイラは誤った記述子を作成し、OpenJDKのTypeResolverでNullPointerExceptionが発生する可能性があります。これが自分自身でない場合は、このバグを変換の作者に報告してください。 @行-1、列-1
私は間違いをしましたか?例えば
サンプルコード
、私はMyAST
アノテーションで注釈され、すべてのクラスに、x
という名前HashSet<Long>
フィールドを追加するとします。
マイAST注釈クラス:
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
@GroovyASTTransformationClass(classes = [MyASTTransformation.class])
public @interface MyAST {
}
マイAST変換クラス:
@CompileStatic
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
public class MyASTTransformation implements ASTTransformation {
@Override
public void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
ClassNode clazz = (ClassNode) nodes[1];
ClassNode longHashSetClass = new ClassNode(HashSet.class);
longHashSetClass.setGenericsTypes([new GenericsType(new ClassNode(Long.class))] as GenericsType[]);
FieldNode field = new FieldNode("x", FieldNode.ACC_PRIVATE, longHashSetClass, clazz, new ConstantExpression(null));
clazz.addField(field);
}
}
サンプル注釈付きクラス:
@MyAST
public class Sample {
}
注
longHashSetClass.setGenericsTypes([new GenericsType(new ClassNode(Long.class))] as GenericsType[]);
行を削除すると、すべてがOKですが、x
のタイプは、実行時にHashSet<Long>
の代わりにHashSet
になります。
ありがとうございました。それは動作しますが、 'make(HashSet)'を 'new ClassNode(HashSet)'に変更するとエラーになります。彼らの違いは何ですか? – vahidreza
正直なところ、わかりませんが、ClassNodeを直接インスタンス化するべきではありません。これらのメソッドは、バイトコードを生成するときに必要なキャッシング、エイリアシングなどを処理します。 –