Ich möchte einige Klassen zur Kompilierzeit ein generisches Feld hinzufügen. Zu diesem Zweck implementierte ich meine eigenen AST-Annotations- und Transformationsklassen, indem ich die offizielle documentation befolgte und gewünschte Klassen mit AST-Annotationen annotierte.GroovyAST generisches Feld zur Kompilierzeit hinzufügen
Aber ich erhalte diesen Fehler bei der Kompilierung:
org.codehaus.groovy.control.MultipleCompilationErrorsException: Start nicht gestartet: /home/.../groovy/Sample.groovy: -1: Eine Transformation verwendete eine Generika, die ClassNode java.util.HashSet für das Feld x direkt enthielt. Du solltest das nicht tun. Bitte erstellen Sie einen neuen ClassNode, der sich auf den alten ClassNode bezieht, und verwenden Sie den neuen ClassNode anstelle des alten. Andernfalls erstellt der Compiler in TypeResolver in OpenJDK falsche Deskriptoren und eine mögliche NullPointerException. Wenn dies nicht Ihre eigene Aufgabe ist, melden Sie diesen Fehler bitte dem Verfasser der Transformation. @ Zeile -1, Spalte -1.
Habe ich einen Fehler gemacht?
Beispielcodes
Zum Beispiel nehme ich an x
, durch MyAST
Anmerkung kommentiert zu jeder Klasse ein HashSet<Long>
Feld, mit dem Namen hinzufügen möchten.
Meine AST Annotation-Klasse:
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
@GroovyASTTransformationClass(classes = [MyASTTransformation.class])
public @interface MyAST {
}
Meine AST Transformationsklasse:
@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);
}
}
Beispiel kommentierte Klasse:
@MyAST
public class Sample {
}
Hinweis
Wenn ich die Zeile longHashSetClass.setGenericsTypes([new GenericsType(new ClassNode(Long.class))] as GenericsType[]);
eliminiere, ist alles in Ordnung, aber der Typ x
ist HashSet
statt HashSet<Long>
zur Laufzeit.
Danke. Es funktioniert, aber wenn ich 'make (HashSet)' zu 'new ClassNode (HashSet)' 'ändere, erhalte ich einen Fehler. Was ist zwischen ihnen anders? – vahidreza
Ehrlich gesagt, ich weiß es nicht, aber ClassNode sollte nicht direkt instanziiert werden. Diese Methoden verarbeiten Caching, Aliasing und andere Dinge, die beim Generieren von Bytecodes notwendig sind. –