in src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java [304:414]
public void visitClass(final ClassNode classNode) {
referencedClasses.clear();
WriterControllerFactory factory = classNode.getNodeMetaData(WriterControllerFactory.class);
controller = new WriterController();
if (factory != null) {
controller = factory.makeController(controller);
}
controller.init(this, context, classVisitor, classNode);
if (controller.shouldOptimizeForInt() || factory != null) {
OptimizingStatementWriter.setNodeMeta(controller.getTypeChooser(), classNode);
}
classVisitor = controller.getClassVisitor();
try {
int bytecodeVersion = controller.getBytecodeVersion();
Object min = classNode.getNodeMetaData(MINIMUM_BYTECODE_VERSION);
if (min instanceof Integer) {
int minVersion = (int) min;
if ((bytecodeVersion ^ V_PREVIEW) < minVersion) {
bytecodeVersion = minVersion;
}
}
classVisitor.visit(
bytecodeVersion,
adjustedClassModifiersForClassWriting(classNode),
controller.getInternalClassName(),
BytecodeHelper.getGenericsSignature(classNode),
controller.getInternalBaseClassName(),
BytecodeHelper.getClassInternalNames(classNode.getInterfaces())
);
classVisitor.visitSource(sourceFile, null);
if (classNode instanceof InnerClassNode && !(classNode instanceof InterfaceHelperClassNode)) {
makeInnerClassEntry(classNode); // GROOVY-4649, et al.
ClassNode nestHost = getNestHost(classNode); // GROOVY-10687
classVisitor.visitNestHost(BytecodeHelper.getClassInternalName(nestHost));
MethodNode enclosingMethod = classNode.getEnclosingMethod();
if (enclosingMethod != null) {
classVisitor.visitOuterClass(
BytecodeHelper.getClassInternalName(classNode.getOuterClass()),
enclosingMethod.getName(), BytecodeHelper.getMethodDescriptor(enclosingMethod));
}
}
if (classNode.getName().endsWith("package-info")) {
PackageNode packageNode = classNode.getPackage();
if (packageNode != null) {
// pull them out of package node but treat them like they were on class node
visitAnnotations(classNode, packageNode, classVisitor);
}
} else {
visitAnnotations(classNode, classVisitor);
visitTypeParameters(classNode, classVisitor);
visitType(classNode.getUnresolvedSuperClass(), classVisitor, newSuperTypeReference(-1), "", true);
ClassNode[] interfaces = classNode.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
visitType(interfaces[i], classVisitor, newSuperTypeReference(i), "", true);
}
if (classNode.isInterface()) {
String outerClassName = classNode.getName();
String name = outerClassName + "$" + context.getNextInnerClassIdx();
controller.setInterfaceClassLoadingClass(
new InterfaceHelperClassNode(
Optional.ofNullable(classNode.getOuterClass()).orElse(classNode),
name, ACC_SUPER | ACC_STATIC | ACC_SYNTHETIC, ClassHelper.OBJECT_TYPE,
controller.getCallSiteWriter().getCallSites()
)
);
super.visitClass(classNode);
createInterfaceSyntheticStaticFields();
} else {
super.visitClass(classNode);
MopWriter.Factory mopWriterFactory = classNode.getNodeMetaData(MopWriter.Factory.class);
if (mopWriterFactory == null) {
mopWriterFactory = MopWriter.FACTORY;
}
MopWriter mopWriter = mopWriterFactory.create(controller);
mopWriter.createMopMethods();
controller.getCallSiteWriter().generateCallSiteArray();
createSyntheticStaticFields();
}
}
// GROOVY-10687
if (classNode.getOuterClass() == null && classNode.getInnerClasses().hasNext()) {
makeNestmateEntries(classNode);
moreNestmateEntries(classNode);
}
// GROOVY-4649, GROOVY-6750, GROOVY-6808
for (Iterator<InnerClassNode> it = classNode.getInnerClasses(); it.hasNext(); ) {
makeInnerClassEntry(it.next());
}
if (sealedNative(classNode)) {
for (ClassNode sub : classNode.getPermittedSubclasses()) {
classVisitor.visitPermittedSubclass(BytecodeHelper.getClassInternalName(sub));
}
}
if (classNode.isRecord()) {
visitRecordComponents(classNode);
}
classVisitor.visitEnd();
} catch (GroovyRuntimeException e) {
e.setModule(classNode.getModule());
throw e;
} catch (NullPointerException | NegativeArraySizeException e) {
String m = e.getClass().getSimpleName() + " while processing " + sourceFile;
GroovyRuntimeException gre = new GroovyRuntimeException(m, e);
gre.setModule(classNode.getModule());
throw gre;
}
}