vah*_*eza 5 generics groovy bytecode abstract-syntax-tree groovyc
我想在编译时向某些类添加通用字段。为了这个目标,我按照官方文档实现了我自己的 AST 注释和转换类,并使用 AST 注释来注释所需的类。
但我在编译时收到此错误:
org.codehaus.groovy.control.MultipleCompilationErrorsException:启动失败:/home/.../groovy/Sample.groovy:-1:转换直接使用包含 ClassNode java.util.HashSet 的泛型作为字段 x。你不应该这样做。请参考旧的 ClassNode 创建一个新的 ClassNode,并使用新的 ClassNode 代替旧的 ClassNode。否则,编译器将在 OpenJDK 的 TypeResolver 中创建错误的描述符和潜在的 NullPointerException。如果这不是您自己做的,请将此错误报告给转换的作者。@ 第 -1 行,第 -1 列。
我做错了吗?
示例代码
例如,假设我想向每个通过注释进行注释的类添加一个HashSet<Long>
名为的字段。x
MyAST
我的 AST 注释类:
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
@GroovyASTTransformationClass(classes = [MyASTTransformation.class])
public @interface MyAST {
}
Run Code Online (Sandbox Code Playgroud)
我的 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);
}
}
Run Code Online (Sandbox Code Playgroud)
示例注释类:
@MyAST
public class Sample {
}
Run Code Online (Sandbox Code Playgroud)
笔记
当我消除 line 时longHashSetClass.setGenericsTypes([new GenericsType(new ClassNode(Long.class))] as GenericsType[]);
,一切正常,但 type of x
isHashSet
而不是HashSet<Long>
在运行时。
您应该使用ClassHelper
orGenericUtils
来创建 ClassNode :
import static org.codehaus.groovy.ast.ClassHelper.make
import static org.codehaus.groovy.ast.tools.GenericsUtils.makeClassSafeWithGenerics
...
ClassNode hashSet = makeClassSafeWithGenerics(HashSet, make(Long))
Run Code Online (Sandbox Code Playgroud)