Write inner class attributes
This commit is contained in:
committed by
Dmitry Petrov
parent
0b45655b7b
commit
e40c434c57
@@ -315,6 +315,10 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void writeInnerClass(@NotNull ClassDescriptor innerClass) {
|
private void writeInnerClass(@NotNull ClassDescriptor innerClass) {
|
||||||
|
writeInnerClass(innerClass, typeMapper, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeInnerClass(@NotNull ClassDescriptor innerClass, @NotNull KotlinTypeMapper typeMapper, @NotNull ClassBuilder v) {
|
||||||
DeclarationDescriptor containing = innerClass.getContainingDeclaration();
|
DeclarationDescriptor containing = innerClass.getContainingDeclaration();
|
||||||
String outerClassInternalName = null;
|
String outerClassInternalName = null;
|
||||||
if (containing instanceof ClassDescriptor) {
|
if (containing instanceof ClassDescriptor) {
|
||||||
|
|||||||
+35
-6
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
|||||||
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmSpecialDescriptor
|
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmSpecialDescriptor
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.FileClassDescriptor
|
import org.jetbrains.kotlin.backend.jvm.lower.FileClassDescriptor
|
||||||
import org.jetbrains.kotlin.codegen.*
|
import org.jetbrains.kotlin.codegen.*
|
||||||
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.MemberCodegen.badDescriptor
|
import org.jetbrains.kotlin.codegen.MemberCodegen.badDescriptor
|
||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
@@ -37,7 +38,9 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
|||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import java.lang.RuntimeException
|
import java.lang.RuntimeException
|
||||||
|
|
||||||
class ClassCodegen private constructor(val irClass: IrClass, val context: JvmBackendContext) {
|
class ClassCodegen private constructor(val irClass: IrClass, val context: JvmBackendContext, val parentClassCodegen: ClassCodegen? = null) {
|
||||||
|
|
||||||
|
private val innerClasses = mutableListOf<ClassDescriptor>()
|
||||||
|
|
||||||
val state = context.state
|
val state = context.state
|
||||||
|
|
||||||
@@ -71,6 +74,8 @@ class ClassCodegen private constructor(val irClass: IrClass, val context: JvmBac
|
|||||||
generateDeclaration(it)
|
generateDeclaration(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writeInnerClasses()
|
||||||
|
|
||||||
visitor.done()
|
visitor.done()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,10 +95,6 @@ class ClassCodegen private constructor(val irClass: IrClass, val context: JvmBac
|
|||||||
|
|
||||||
ClassCodegen(irClass, context).generate()
|
ClassCodegen(irClass, context).generate()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateAnonymous(irClass: IrClass, context: JvmBackendContext) {
|
|
||||||
ClassCodegen(irClass, context).generate()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateDeclaration(declaration: IrDeclaration) {
|
fun generateDeclaration(declaration: IrDeclaration) {
|
||||||
@@ -110,7 +111,7 @@ class ClassCodegen private constructor(val irClass: IrClass, val context: JvmBac
|
|||||||
// skip
|
// skip
|
||||||
}
|
}
|
||||||
is IrClass -> {
|
is IrClass -> {
|
||||||
ClassCodegen(declaration, context).generate()
|
ClassCodegen(declaration, context, this).generate()
|
||||||
}
|
}
|
||||||
else -> throw RuntimeException("Unsupported declaration $declaration")
|
else -> throw RuntimeException("Unsupported declaration $declaration")
|
||||||
}
|
}
|
||||||
@@ -128,6 +129,34 @@ class ClassCodegen private constructor(val irClass: IrClass, val context: JvmBac
|
|||||||
FunctionCodegen(method, this).generate()
|
FunctionCodegen(method, this).generate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun writeInnerClasses() {
|
||||||
|
// JVMS7 (4.7.6): a nested class or interface member will have InnerClasses information
|
||||||
|
// for each enclosing class and for each immediate member
|
||||||
|
val classDescriptor = classForInnerClassRecord()
|
||||||
|
if (classDescriptor != null) {
|
||||||
|
if (parentClassCodegen != null) {
|
||||||
|
parentClassCodegen.innerClasses.add(classDescriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
var codegen: ClassCodegen? = this
|
||||||
|
while (codegen != null) {
|
||||||
|
val outerClass = codegen.classForInnerClassRecord()
|
||||||
|
if (outerClass != null) {
|
||||||
|
innerClasses.add(outerClass)
|
||||||
|
}
|
||||||
|
codegen = codegen.parentClassCodegen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (innerClass in innerClasses) {
|
||||||
|
MemberCodegen.writeInnerClass(innerClass, typeMapper, visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun classForInnerClassRecord(): ClassDescriptor? {
|
||||||
|
return if (parentClassCodegen != null) descriptor else null
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ClassDescriptor.calculateClassFlags(): Int {
|
fun ClassDescriptor.calculateClassFlags(): Int {
|
||||||
|
|||||||
+1
-1
@@ -296,7 +296,7 @@ class ExpressionCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitClass(declaration: IrClass, data: BlockInfo): StackValue {
|
override fun visitClass(declaration: IrClass, data: BlockInfo): StackValue {
|
||||||
ClassCodegen.generateAnonymous(declaration, classCodegen.context)
|
classCodegen.generateDeclaration(declaration)
|
||||||
return none()
|
return none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user