diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassFileFactory.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassFileFactory.java index 41d1de37e8d..2a35ee065df 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassFileFactory.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassFileFactory.java @@ -151,7 +151,7 @@ public class ClassFileFactory implements OutputFileCollection { ProtoBuf.Annotation.Builder annotation = ProtoBuf.Annotation.newBuilder(); ClassId classId = DescriptorUtilsKt.getClassId(descriptor); if (classId != null) { - annotation.setId(stringTable.getClassIdIndex(classId)); + annotation.setId(stringTable.getQualifiedClassNameIndex(classId.asString(), false)); builder.addAnnotation(annotation); } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt index 419606f0cf5..937133577de 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.ClassBuilder import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.coroutines.COROUTINE_IMPL_ASM_TYPE +import org.jetbrains.kotlin.codegen.serialization.JvmCodegenStringTable import org.jetbrains.kotlin.codegen.serialization.JvmStringTable import org.jetbrains.kotlin.codegen.writeKotlinMetadata import org.jetbrains.kotlin.load.java.JvmAnnotationNames @@ -202,7 +203,7 @@ class AnonymousObjectTransformer( when (header.kind) { KotlinClassHeader.Kind.CLASS -> { val (nameResolver, classProto) = JvmProtoBufUtil.readClassDataFrom(data, strings) - val newStringTable = JvmStringTable(state.typeMapper, nameResolver) + val newStringTable = JvmCodegenStringTable(state.typeMapper, nameResolver) val newProto = classProto.toBuilder().apply { setExtension(JvmProtoBuf.anonymousObjectOriginName, newStringTable.getStringIndex(oldObjectType.internalName)) }.build() @@ -210,7 +211,7 @@ class AnonymousObjectTransformer( } KotlinClassHeader.Kind.SYNTHETIC_CLASS -> { val (nameResolver, functionProto) = JvmProtoBufUtil.readFunctionDataFrom(data, strings) - val newStringTable = JvmStringTable(state.typeMapper, nameResolver) + val newStringTable = JvmCodegenStringTable(state.typeMapper, nameResolver) val newProto = functionProto.toBuilder().apply { setExtension(JvmProtoBuf.lambdaClassOriginName, newStringTable.getStringIndex(oldObjectType.internalName)) }.build() diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmCodegenStringTable.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmCodegenStringTable.kt new file mode 100644 index 00000000000..77d1afa4e21 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmCodegenStringTable.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.codegen.serialization + +import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper +import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters +import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor +import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmNameResolver +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.serialization.DescriptorAwareStringTable + +class JvmCodegenStringTable @JvmOverloads constructor( + private val typeMapper: KotlinTypeMapper, + nameResolver: JvmNameResolver? = null +) : JvmStringTable(nameResolver), DescriptorAwareStringTable { + override fun getLocalClassIdReplacement(descriptor: ClassifierDescriptorWithTypeParameters): ClassId { + val container = descriptor.containingDeclaration + return when (container) { + is ClassifierDescriptorWithTypeParameters -> getLocalClassIdReplacement(container).createNestedClassId(descriptor.name) + is PackageFragmentDescriptor -> { + throw IllegalStateException("getLocalClassIdReplacement should only be called for local classes: $descriptor") + } + else -> { + val fqName = FqName(typeMapper.mapClass(descriptor).internalName.replace('/', '.')) + ClassId(fqName.parent(), FqName.topLevel(fqName.shortName()), true) + } + } + } +} diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java index 37d24682a40..24db145733d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java @@ -43,7 +43,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; import org.jetbrains.kotlin.serialization.AnnotationSerializer; import org.jetbrains.kotlin.serialization.DescriptorSerializer; import org.jetbrains.kotlin.serialization.SerializerExtension; -import org.jetbrains.kotlin.serialization.StringTable; import org.jetbrains.kotlin.types.FlexibleType; import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.org.objectweb.asm.Type; @@ -57,7 +56,7 @@ public class JvmSerializerExtension extends SerializerExtension { private final JvmSerializationBindings bindings; private final BindingContext codegenBinding; private final KotlinTypeMapper typeMapper; - private final StringTable stringTable; + private final JvmCodegenStringTable stringTable; private final AnnotationSerializer annotationSerializer; private final boolean useTypeTable; private final String moduleName; @@ -67,7 +66,7 @@ public class JvmSerializerExtension extends SerializerExtension { this.bindings = bindings; this.codegenBinding = state.getBindingContext(); this.typeMapper = state.getTypeMapper(); - this.stringTable = new JvmStringTable(typeMapper); + this.stringTable = new JvmCodegenStringTable(typeMapper); this.annotationSerializer = new AnnotationSerializer(stringTable); this.useTypeTable = state.getUseTypeTableInSerializer(); this.moduleName = state.getModuleName(); @@ -76,7 +75,7 @@ public class JvmSerializerExtension extends SerializerExtension { @NotNull @Override - public StringTable getStringTable() { + public JvmCodegenStringTable getStringTable() { return stringTable; } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmStringTable.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmStringTable.kt index ac70290f00f..8283e345852 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmStringTable.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmStringTable.kt @@ -16,33 +16,28 @@ package org.jetbrains.kotlin.codegen.serialization -import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters -import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf.StringTableTypes.Record import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmNameResolver -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.serialization.StringTable -import org.jetbrains.kotlin.types.ErrorUtils import java.io.OutputStream // TODO: optimize by reordering records to minimize storage of 'range' fields -class JvmStringTable(private val typeMapper: KotlinTypeMapper) : StringTable { +open class JvmStringTable(nameResolver: JvmNameResolver? = null) : StringTable { val strings = ArrayList() private val records = ArrayList() private val map = HashMap() private val localNames = LinkedHashSet() - constructor(typeMapper: KotlinTypeMapper, nameResolver: JvmNameResolver) : this(typeMapper) { - strings.addAll(nameResolver.strings) - nameResolver.records.mapTo(records, JvmProtoBuf.StringTableTypes.Record::toBuilder) - for (index in strings.indices) { - map[nameResolver.getString(index)] = index + init { + if (nameResolver != null) { + strings.addAll(nameResolver.strings) + nameResolver.records.mapTo(records, JvmProtoBuf.StringTableTypes.Record::toBuilder) + for (index in strings.indices) { + map[nameResolver.getString(index)] = index + } + localNames.addAll(nameResolver.types.localNameList) } - localNames.addAll(nameResolver.types.localNameList) } override fun getStringIndex(string: String): Int = @@ -62,14 +57,6 @@ class JvmStringTable(private val typeMapper: KotlinTypeMapper) : StringTable { return !hasPredefinedIndex() && !hasOperation() && substringIndexCount == 0 && replaceCharCount == 0 } - override fun getFqNameIndex(descriptor: ClassifierDescriptorWithTypeParameters): Int { - if (ErrorUtils.isError(descriptor)) { - throw IllegalStateException("Cannot get FQ name of error class: " + descriptor) - } - - return getClassIdIndex(descriptor.classId) - } - // We use the following format to encode ClassId: "pkg/Outer.Inner". // It represents a unique name, but such names don't usually appear in the constant pool, so we're writing "Lpkg/Outer$Inner;" // instead and an instruction to drop the first and the last character in this string and replace all '$' with '.'. @@ -78,30 +65,28 @@ class JvmStringTable(private val typeMapper: KotlinTypeMapper) : StringTable { // string literally: "pkg/Outer.Inner$with$dollars" // - the class is local or nested in local. In this case we're also storing the literal string, and also storing the fact that // this name represents a local class in a separate list - override fun getClassIdIndex(classId: ClassId): Int { - val string = classId.asString() - - map[string]?.let { recordedIndex -> + override fun getQualifiedClassNameIndex(className: String, isLocal: Boolean): Int { + map[className]?.let { recordedIndex -> // If we already recorded such string, we only return its index if it's local and our name is local // OR it's not local and our name is not local as well - if (classId.isLocal == (recordedIndex in localNames)) { + if (isLocal == (recordedIndex in localNames)) { return recordedIndex } } val index = strings.size - if (classId.isLocal) { + if (isLocal) { localNames.add(index) } val record = Record.newBuilder() // If the class is local or any of its outer class names contains '$', store a literal string - if (classId.isLocal || '$' in string) { - strings.add(string) + if (isLocal || '$' in className) { + strings.add(className) } else { - val predefinedIndex = JvmNameResolver.getPredefinedStringIndex(string) + val predefinedIndex = JvmNameResolver.getPredefinedStringIndex(className) if (predefinedIndex != null) { record.predefinedIndex = predefinedIndex // TODO: move all records with predefined names to the end and do not write associated strings for them (since they are ignored) @@ -109,30 +94,17 @@ class JvmStringTable(private val typeMapper: KotlinTypeMapper) : StringTable { } else { record.operation = Record.Operation.DESC_TO_CLASS_ID - strings.add("L${string.replace('.', '$')};") + strings.add("L${className.replace('.', '$')};") } } records.add(record) - map[string] = index + map[className] = index return index } - private val ClassifierDescriptorWithTypeParameters.classId: ClassId - get() { - val container = containingDeclaration - return when (container) { - is ClassDescriptor -> container.classId.createNestedClassId(name) - is PackageFragmentDescriptor -> ClassId(container.fqName, name) - else -> { - val fqName = FqName(typeMapper.mapClass(this).internalName.replace('/', '.')) - ClassId(fqName.parent(), FqName.topLevel(fqName.shortName()), /* isLocal = */ true) - } - } - } - override fun serializeTo(output: OutputStream) { with(JvmProtoBuf.StringTableTypes.newBuilder()) { addAllRecord(records.map { it.build() }) diff --git a/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializerExtension.kt b/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializerExtension.kt index 2d034a3f388..6479366018e 100644 --- a/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializerExtension.kt +++ b/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializerExtension.kt @@ -18,18 +18,16 @@ package org.jetbrains.kotlin.serialization.builtins import org.jetbrains.kotlin.builtins.BuiltInSerializerProtocol import org.jetbrains.kotlin.metadata.ProtoBuf -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.UnresolvedType class BuiltInsSerializerExtension : KotlinSerializerExtensionBase(BuiltInSerializerProtocol) { private val shortNameToClassId = mapOf( - "IntRange" to "kotlin.ranges.IntRange", - "LongRange" to "kotlin.ranges.LongRange", - "CharRange" to "kotlin.ranges.CharRange" - ).mapValues { (_, value) -> ClassId.topLevel(FqName(value)) } + "IntRange" to "kotlin/ranges/IntRange", + "LongRange" to "kotlin/ranges/LongRange", + "CharRange" to "kotlin/ranges/CharRange" + ) override fun shouldUseTypeTable(): Boolean = true @@ -39,9 +37,9 @@ class BuiltInsSerializerExtension : KotlinSerializerExtensionBase(BuiltInSeriali throw UnsupportedOperationException("Error types which are not UnresolvedType instances are not supported here: $unwrapped") } - val classId = shortNameToClassId[unwrapped.presentableName] - ?: throw UnsupportedOperationException("Unsupported unresolved type: $unwrapped") + val className = shortNameToClassId[unwrapped.presentableName] + ?: throw UnsupportedOperationException("Unsupported unresolved type: $unwrapped") - builder.className = stringTable.getClassIdIndex(classId) + builder.className = stringTable.getQualifiedClassNameIndex(className, false) } } diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/AnnotationSerializer.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/AnnotationSerializer.kt index fcf940b6c02..212b11eada4 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/AnnotationSerializer.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/AnnotationSerializer.kt @@ -26,7 +26,7 @@ import org.jetbrains.kotlin.resolve.constants.* import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass import org.jetbrains.kotlin.types.ErrorUtils -class AnnotationSerializer(private val stringTable: StringTable) { +class AnnotationSerializer(private val stringTable: DescriptorAwareStringTable) { fun serializeAnnotation(annotation: AnnotationDescriptor): ProtoBuf.Annotation = ProtoBuf.Annotation.newBuilder().apply { val annotationClass = annotation.annotationClass ?: error("Annotation type is not a class: ${annotation.type}") if (ErrorUtils.isError(annotationClass)) { @@ -79,7 +79,7 @@ class AnnotationSerializer(private val stringTable: StringTable) { override fun visitEnumValue(value: EnumValue, data: Unit) { type = Type.ENUM - classId = stringTable.getClassIdIndex(value.enumClassId) + classId = stringTable.getQualifiedClassNameIndex(value.enumClassId.asString(), value.enumClassId.isLocal) enumValueId = stringTable.getStringIndex(value.enumEntryName.asString()) } diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt index b0b74ed6297..f7aadaba2a3 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt @@ -48,7 +48,7 @@ class DescriptorSerializer private constructor( DescriptorSerializer(descriptor, Interner(typeParameters), extension, typeTable, versionRequirementTable, serializeTypeTableToFunction = false) - val stringTable: StringTable + val stringTable: DescriptorAwareStringTable get() = extension.stringTable private fun useTypeTable(): Boolean = extension.shouldUseTypeTable() diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.kt index 5fb79657acb..c3ebe20f274 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.kt @@ -23,7 +23,7 @@ import org.jetbrains.kotlin.types.FlexibleType import org.jetbrains.kotlin.types.KotlinType abstract class SerializerExtension { - abstract val stringTable: StringTable + abstract val stringTable: DescriptorAwareStringTable val annotationSerializer by lazy { AnnotationSerializer(stringTable) } diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTable.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTable.kt index 0a289ca4f1e..90c76b24784 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTable.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTable.kt @@ -18,14 +18,33 @@ package org.jetbrains.kotlin.serialization import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.resolve.descriptorUtil.classId +import org.jetbrains.kotlin.types.ErrorUtils import java.io.OutputStream interface StringTable { fun getStringIndex(string: String): Int - fun getFqNameIndex(descriptor: ClassifierDescriptorWithTypeParameters): Int - - fun getClassIdIndex(classId: ClassId): Int + /** + * @param className the fully qualified name of some class in the format: `org/foo/bar/Test.Inner` + */ + fun getQualifiedClassNameIndex(className: String, isLocal: Boolean): Int fun serializeTo(output: OutputStream) } + +interface DescriptorAwareStringTable : StringTable { + fun getFqNameIndex(descriptor: ClassifierDescriptorWithTypeParameters): Int { + if (ErrorUtils.isError(descriptor)) { + throw IllegalStateException("Cannot get FQ name of error class: $descriptor") + } + + val classId = descriptor.classId + ?: getLocalClassIdReplacement(descriptor) + ?: throw IllegalStateException("Cannot get FQ name of local class: $descriptor") + + return getQualifiedClassNameIndex(classId.asString(), classId.isLocal) + } + + fun getLocalClassIdReplacement(descriptor: ClassifierDescriptorWithTypeParameters): ClassId? = null +} diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTableImpl.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTableImpl.kt index 3c172cdef78..3d8a3036a90 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTableImpl.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTableImpl.kt @@ -16,18 +16,14 @@ package org.jetbrains.kotlin.serialization -import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf.QualifiedNameTable.QualifiedName import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.descriptorUtil.classId -import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.utils.Interner import java.io.OutputStream -open class StringTableImpl : StringTable { +open class StringTableImpl : DescriptorAwareStringTable { private class FqNameProto(val fqName: QualifiedName.Builder) { override fun hashCode(): Int { var result = 13 @@ -50,25 +46,17 @@ open class StringTableImpl : StringTable { private val strings = Interner() private val qualifiedNames = Interner() - fun getSimpleNameIndex(name: Name): Int = getStringIndex(name.asString()) - override fun getStringIndex(string: String): Int = strings.intern(string) - override fun getFqNameIndex(descriptor: ClassifierDescriptorWithTypeParameters): Int { - if (ErrorUtils.isError(descriptor)) { - throw IllegalStateException("Cannot get FQ name of error class: $descriptor") - } + override fun getQualifiedClassNameIndex(className: String, isLocal: Boolean): Int = + getQualifiedClassNameIndex(ClassId.fromString(className, isLocal)) - val classId = descriptor.classId ?: return getFqNameIndexOfLocalAnonymousClass(descriptor) - return getClassIdIndex(classId) - } - - override fun getClassIdIndex(classId: ClassId): Int { + private fun getQualifiedClassNameIndex(classId: ClassId): Int { val builder = QualifiedName.newBuilder() builder.kind = QualifiedName.Kind.CLASS builder.parentQualifiedName = - classId.outerClassId?.let(this::getClassIdIndex) + classId.outerClassId?.let(this::getQualifiedClassNameIndex) ?: getPackageFqNameIndex(classId.packageFqName) builder.shortName = getStringIndex(classId.shortClassName.asString()) @@ -76,15 +64,11 @@ open class StringTableImpl : StringTable { return qualifiedNames.intern(FqNameProto(builder)) } - open fun getFqNameIndexOfLocalAnonymousClass(descriptor: ClassifierDescriptorWithTypeParameters): Int { - throw IllegalStateException("Cannot get FQ name of local class: " + descriptor) - } - fun getPackageFqNameIndex(fqName: FqName): Int { var result = -1 for (segment in fqName.pathSegments()) { val builder = QualifiedName.newBuilder() - builder.shortName = getSimpleNameIndex(segment) + builder.shortName = getStringIndex(segment.asString()) if (result != -1) { builder.parentQualifiedName = result } diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/JavaScriptStringTable.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/JavaScriptStringTable.kt index 7bdaa92dc1e..1da58474ec9 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/JavaScriptStringTable.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/JavaScriptStringTable.kt @@ -16,30 +16,32 @@ package org.jetbrains.kotlin.serialization.js +import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers -import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.serialization.StringTableImpl class JavaScriptStringTable : StringTableImpl() { - override fun getFqNameIndexOfLocalAnonymousClass(descriptor: ClassifierDescriptorWithTypeParameters): Int { + override fun getLocalClassIdReplacement(descriptor: ClassifierDescriptorWithTypeParameters): ClassId? { return if (descriptor.containingDeclaration is CallableMemberDescriptor) { val superClassifiers = descriptor.getAllSuperClassifiers() .mapNotNull { it as ClassifierDescriptorWithTypeParameters } .filter { it != descriptor } .toList() if (superClassifiers.size == 1) { - getFqNameIndex(superClassifiers[0]) + superClassifiers[0].classId } else { val superClass = superClassifiers.find { !DescriptorUtils.isInterface(it) } - getFqNameIndex(superClass ?: descriptor.module.builtIns.any) + superClass?.classId ?: ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.any.toSafe()) } } else { - super.getFqNameIndexOfLocalAnonymousClass(descriptor) + super.getLocalClassIdReplacement(descriptor) } } }