diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.kt index 3e17220f8e7..428e6882145 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.kt @@ -38,6 +38,7 @@ import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.Method class JvmSerializerExtension(private val bindings: JvmSerializationBindings, state: GenerationState) : SerializerExtension() { + private val globalBindings = state.globalSerializationBindings private val codegenBinding = state.bindingContext private val typeMapper = state.typeMapper override val stringTable = JvmCodegenStringTable(typeMapper) @@ -151,10 +152,10 @@ class JvmSerializerExtension(private val bindings: JvmSerializationBindings, sta } } - override fun serializeConstructor(descriptor: ConstructorDescriptor, - proto: ProtoBuf.Constructor.Builder, - childSerializer: DescriptorSerializer) { - val method = bindings.get(METHOD_FOR_FUNCTION, descriptor) + override fun serializeConstructor( + descriptor: ConstructorDescriptor, proto: ProtoBuf.Constructor.Builder, childSerializer: DescriptorSerializer + ) { + val method = getBinding(METHOD_FOR_FUNCTION, descriptor) if (method != null) { val signature = SignatureSerializer().methodSignature(descriptor, method) if (signature != null) { @@ -163,10 +164,10 @@ class JvmSerializerExtension(private val bindings: JvmSerializationBindings, sta } } - override fun serializeFunction(descriptor: FunctionDescriptor, - proto: ProtoBuf.Function.Builder, - childSerializer: DescriptorSerializer) { - val method = bindings.get(METHOD_FOR_FUNCTION, descriptor) + override fun serializeFunction( + descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder, childSerializer: DescriptorSerializer + ) { + val method = getBinding(METHOD_FOR_FUNCTION, descriptor) if (method != null) { val signature = SignatureSerializer().methodSignature(descriptor, method) if (signature != null) { @@ -176,20 +177,20 @@ class JvmSerializerExtension(private val bindings: JvmSerializationBindings, sta } override fun serializeProperty( - descriptor: PropertyDescriptor, - proto: ProtoBuf.Property.Builder, - versionRequirementTable: MutableVersionRequirementTable?, - childSerializer: DescriptorSerializer + descriptor: PropertyDescriptor, + proto: ProtoBuf.Property.Builder, + versionRequirementTable: MutableVersionRequirementTable?, + childSerializer: DescriptorSerializer ) { val signatureSerializer = SignatureSerializer() val getter = descriptor.getter val setter = descriptor.setter - val getterMethod = if (getter == null) null else bindings.get(METHOD_FOR_FUNCTION, getter) - val setterMethod = if (setter == null) null else bindings.get(METHOD_FOR_FUNCTION, setter) + val getterMethod = if (getter == null) null else getBinding(METHOD_FOR_FUNCTION, getter) + val setterMethod = if (setter == null) null else getBinding(METHOD_FOR_FUNCTION, setter) - val field = bindings.get(FIELD_FOR_PROPERTY, descriptor) - val syntheticMethod = bindings.get(SYNTHETIC_METHOD_FOR_PROPERTY, descriptor) + val field = getBinding(FIELD_FOR_PROPERTY, descriptor) + val syntheticMethod = getBinding(SYNTHETIC_METHOD_FOR_PROPERTY, descriptor) val signature = signatureSerializer.propertySignature( descriptor, @@ -232,6 +233,9 @@ class JvmSerializerExtension(private val bindings: JvmSerializationBindings, sta super.serializeErrorType(type, builder) } + private fun getBinding(slice: SerializationMappingSlice, key: K): V? = + bindings.get(slice, key) ?: globalBindings.get(slice, key) + private inner class SignatureSerializer { fun methodSignature(descriptor: FunctionDescriptor?, method: Method): JvmProtoBuf.JvmMethodSignature? { val builder = JvmProtoBuf.JvmMethodSignature.newBuilder() diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt index 5f2ff365599..35a6036e078 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.codegen.inline.GlobalInlineContext import org.jetbrains.kotlin.codegen.inline.InlineCache import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods import org.jetbrains.kotlin.codegen.optimization.OptimizationClassBuilderFactory +import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ScriptDescriptor @@ -256,6 +257,8 @@ class GenerationState private constructor( val metadataVersion = configuration.get(CommonConfigurationKeys.METADATA_VERSION) ?: JvmMetadataVersion.INSTANCE + val globalSerializationBindings = JvmSerializationBindings() + init { this.interceptedBuilderFactory = builderFactory .wrapWith( diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index a9086a6099b..0dbbc101c16 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.backend.jvm.codegen import org.jetbrains.kotlin.backend.jvm.JvmBackendContext -import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.lower.constantValue import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.binding.CodegenBinding @@ -24,7 +23,6 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.name.SpecialNames -import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_SYNTHETIC_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.resolve.jvm.annotations.TRANSIENT_ANNOTATION_FQ_NAME @@ -103,10 +101,8 @@ open class ClassCodegen protected constructor( val shortName = File(fileEntry.name).name visitor.visitSource(shortName, null) - val companionObjectCodegen = nestedClasses.firstOrNull { it.irClass.isCompanion } - for (declaration in irClass.declarations) { - generateDeclaration(declaration, companionObjectCodegen) + generateDeclaration(declaration) } // Generate nested classes at the end, to ensure that codegen for companion object will have the necessary JVM signatures in its @@ -186,10 +182,10 @@ open class ClassCodegen protected constructor( } } - private fun generateDeclaration(declaration: IrDeclaration, companionObjectCodegen: ClassCodegen?) { + private fun generateDeclaration(declaration: IrDeclaration) { when (declaration) { is IrField -> - generateField(declaration, companionObjectCodegen) + generateField(declaration) is IrFunction -> { generateMethod(declaration) } @@ -207,7 +203,7 @@ open class ClassCodegen protected constructor( ClassCodegen(klass, context, this).generate() } - private fun generateField(field: IrField, companionObjectCodegen: ClassCodegen?) { + private fun generateField(field: IrField) { if (field.origin == IrDeclarationOrigin.FAKE_OVERRIDE) return val fieldType = typeMapper.mapType(field) @@ -228,10 +224,7 @@ open class ClassCodegen protected constructor( val descriptor = field.metadata?.descriptor if (descriptor != null) { - val codegen = if (field.origin != IrDeclarationOrigin.DELEGATE && JvmAbi.isPropertyWithBackingFieldInOuterClass(descriptor)) { - companionObjectCodegen ?: error("Class with a property moved from the companion must have a companion:\n${irClass.dump()}") - } else this - codegen.visitor.serializationBindings.put(JvmSerializationBindings.FIELD_FOR_PROPERTY, descriptor, fieldType to fieldName) + state.globalSerializationBindings.put(JvmSerializationBindings.FIELD_FOR_PROPERTY, descriptor, fieldType to fieldName) } } @@ -240,21 +233,14 @@ open class ClassCodegen protected constructor( val signature = FunctionCodegen(method, this).generate().asmMethod - val metadata = method.metadata - when (metadata) { + when (val metadata = method.metadata) { is MetadataSource.Property -> { // We can't check for JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS because for interface methods // moved to DefaultImpls, origin is changed to DEFAULT_IMPLS // TODO: fix origin somehow, because otherwise $annotations methods in interfaces also don't have ACC_SYNTHETIC assert(method.name.asString().endsWith(JvmAbi.ANNOTATED_PROPERTY_METHOD_NAME_SUFFIX)) { method.dump() } - val codegen = if (DescriptorUtils.isInterface(metadata.descriptor.containingDeclaration)) { - assert(irClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) { irClass.dump() } - parentClassCodegen!! - } else { - this - } - codegen.visitor.serializationBindings.put( + state.globalSerializationBindings.put( JvmSerializationBindings.SYNTHETIC_METHOD_FOR_PROPERTY, metadata.descriptor, signature ) }