diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/DescriptorsFactory.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/DescriptorsFactory.kt index 26bd7b25a53..126fa6a3635 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/DescriptorsFactory.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/DescriptorsFactory.kt @@ -9,9 +9,11 @@ import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol +import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol +import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol interface DescriptorsFactory { - fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor + fun getSymbolForEnumEntry(enumEntry: IrEnumEntrySymbol): IrFieldSymbol fun getOuterThisFieldDescriptor(innerClassDescriptor: ClassDescriptor): PropertyDescriptor fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: ClassConstructorDescriptor): IrConstructorSymbol fun getFieldDescriptorForObjectInstance(objectDescriptor: ClassDescriptor): PropertyDescriptor diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsDescriptorsFactory.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsDescriptorsFactory.kt index 6b9be31f2b4..38711afd3d4 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsDescriptorsFactory.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsDescriptorsFactory.kt @@ -24,7 +24,11 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl +import org.jetbrains.kotlin.ir.declarations.IrEnumEntry +import org.jetbrains.kotlin.ir.declarations.IrField import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol +import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol +import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils @@ -37,7 +41,7 @@ class JsDescriptorsFactory( private val outerThisDescriptors = HashMap() private val innerClassConstructors = HashMap() - override fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor = TODO() + override fun getSymbolForEnumEntry(enumEntry: IrEnumEntrySymbol): IrFieldSymbol = TODO() override fun getOuterThisFieldDescriptor(innerClassDescriptor: ClassDescriptor): PropertyDescriptor = if (!innerClassDescriptor.isInner) throw AssertionError("Class is not inner: $innerClassDescriptor") diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index a8f09670a39..3f4867a8554 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.common.runOnFilePostfix import org.jetbrains.kotlin.backend.jvm.lower.* import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor import org.jetbrains.kotlin.ir.visitors.acceptVoid @@ -45,11 +46,16 @@ class JvmLower(val context: JvmBackendContext) { SharedVariablesLowering(context).runOnFilePostfix(irFile) InnerClassesLowering(context).runOnFilePostfix(irFile) InnerClassConstructorCallsLowering(context).runOnFilePostfix(irFile) - LocalDeclarationsLowering(context, - object : LocalNameProvider { - override fun localName(descriptor: DeclarationDescriptor): String = - NameUtils.sanitizeAsJavaIdentifier(super.localName(descriptor)) - }).runOnFilePostfix(irFile) + + LocalDeclarationsLowering( + context, + object : LocalNameProvider { + override fun localName(descriptor: DeclarationDescriptor): String = + NameUtils.sanitizeAsJavaIdentifier(super.localName(descriptor)) + } + ).runOnFilePostfix(irFile) + + irFile.acceptVoid(PatchDeclarationParentsVisitor()) EnumClassLowering(context).runOnFilePostfix(irFile) //Should be before SyntheticAccessorLowering cause of synthetic accessor for companion constructor ObjectClassLowering(context).lower(irFile) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDescriptorsFactory.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDescriptorsFactory.kt index e95d5a70444..67949f1c465 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDescriptorsFactory.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDescriptorsFactory.kt @@ -27,7 +27,10 @@ import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.ir.SourceManager import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol +import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol +import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl +import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl import org.jetbrains.kotlin.load.java.JavaVisibilities import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi2ir.PsiSourceManager @@ -44,10 +47,13 @@ class JvmDescriptorsFactory( private val outerThisDescriptors = HashMap() private val innerClassConstructors = HashMap() - override fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor = - singletonFieldDescriptors.getOrPut(enumEntryDescriptor) { + override fun getSymbolForEnumEntry(enumEntry: IrEnumEntrySymbol): IrFieldSymbol { + val enumEntryDescriptor = enumEntry.descriptor + val fieldDescriptor = singletonFieldDescriptors.getOrPut(enumEntryDescriptor) { createEnumEntryFieldDescriptor(enumEntryDescriptor) } + return IrFieldSymbolImpl(fieldDescriptor) + } fun createFileClassDescriptor(fileEntry: SourceManager.FileEntry, packageFragment: PackageFragmentDescriptor): FileClassDescriptor { val ktFile = psiSourceManager.getKtFile(fileEntry as PsiSourceManager.PsiFileEntry) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/EnumClassLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/EnumClassLowering.kt index b5e4d0c1142..c08929e9320 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/EnumClassLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/EnumClassLowering.kt @@ -33,10 +33,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* -import org.jetbrains.kotlin.ir.util.createParameterDeclarations -import org.jetbrains.kotlin.ir.util.dump -import org.jetbrains.kotlin.ir.util.transform -import org.jetbrains.kotlin.ir.util.transformFlat +import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name @@ -47,8 +44,7 @@ import java.util.* class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass { override fun lower(irClass: IrClass) { - val classDescriptor = irClass.descriptor - if (classDescriptor.kind != ClassKind.ENUM_CLASS) return + if (irClass.kind != ClassKind.ENUM_CLASS) return EnumClassTransformer(irClass).run() } @@ -78,10 +74,11 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass { } private inner class EnumClassTransformer(val irClass: IrClass) { - private val enumEntryOrdinals = TObjectIntHashMap() + private val enumEntryOrdinals = TObjectIntHashMap() + private val enumEntryClassToEntry = HashMap() private val loweredEnumConstructors = HashMap() private val loweredEnumConstructorParameters = HashMap() - private val enumEntriesByField = HashMap() + private val enumEntriesByField = HashMap() private val enumEntryFields = ArrayList() private lateinit var valuesField: IrField @@ -100,7 +97,10 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass { var ordinal = 0 irClass.declarations.forEach { if (it is IrEnumEntry) { - enumEntryOrdinals.put(it.descriptor, ordinal) + enumEntryOrdinals.put(it, ordinal) + it.correspondingClass?.run { + enumEntryClassToEntry.put(this, it) + } ordinal++ } } @@ -109,13 +109,16 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass { private fun lowerEnumConstructors(irClass: IrClass) { irClass.declarations.transform { declaration -> if (declaration is IrConstructor) - transformEnumConstructor(declaration) + transformEnumConstructor(declaration, irClass) else declaration } } - private fun transformEnumConstructor(enumConstructor: IrConstructor): IrConstructor { + private fun transformEnumConstructor( + enumConstructor: IrConstructor, + enumClass: IrClass + ): IrConstructor { val constructorDescriptor = enumConstructor.descriptor val loweredConstructorDescriptor = lowerEnumConstructor(constructorDescriptor) return IrConstructorImpl( @@ -123,6 +126,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass { loweredConstructorDescriptor, enumConstructor.body!! // will be transformed later ).apply { + parent = enumClass createParameterDeclarations() loweredEnumConstructors[constructorDescriptor] = this constructorDescriptor.valueParameters.forEach { @@ -185,16 +189,15 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass { } private fun createFieldForEnumEntry(enumEntry: IrEnumEntry): IrField { - val fieldPropertyDescriptor = context.descriptorsFactory.getFieldDescriptorForEnumEntry(enumEntry.descriptor) - - enumEntriesByField[fieldPropertyDescriptor] = enumEntry.descriptor + val fieldSymbol = context.descriptorsFactory.getSymbolForEnumEntry(enumEntry.symbol) return IrFieldImpl( enumEntry.startOffset, enumEntry.endOffset, JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_ENTRY, - fieldPropertyDescriptor, - IrExpressionBodyImpl(enumEntry.initializerExpression!!) + fieldSymbol ).also { + it.initializer = IrExpressionBodyImpl(enumEntry.initializerExpression!!) enumEntryFields.add(it) + enumEntriesByField[it] = enumEntry } } @@ -230,7 +233,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass { private fun createSyntheticValuesFieldInitializerExpression(): IrExpression = createArrayOfExpression( - irClass.descriptor.defaultType, + irClass.defaultType, enumEntryFields.map { irField -> IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irField.symbol) }) @@ -312,7 +315,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass { } } - private abstract inner class InEnumEntry(private val enumEntry: ClassDescriptor) : EnumConstructorCallTransformer { + private abstract inner class InEnumEntry(private val enumEntry: IrEnumEntry) : EnumConstructorCallTransformer { override fun transform(enumConstructorCall: IrEnumConstructorCall): IrExpression { val name = enumEntry.name.asString() val ordinal = enumEntryOrdinals[enumEntry] @@ -349,7 +352,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass { ): IrMemberAccessExpression } - private inner class InEnumEntryClassConstructor(enumEntry: ClassDescriptor) : InEnumEntry(enumEntry) { + private inner class InEnumEntryClassConstructor(enumEntry: IrEnumEntry) : InEnumEntry(enumEntry) { override fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: IrConstructor) = IrDelegatingConstructorCallImpl( startOffset, @@ -360,7 +363,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass { ) } - private inner class InEnumEntryInitializer(enumEntry: ClassDescriptor) : InEnumEntry(enumEntry) { + private inner class InEnumEntryInitializer(enumEntry: IrEnumEntry) : InEnumEntry(enumEntry) { override fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: IrConstructor) = IrCallImpl( startOffset, @@ -373,7 +376,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass { private var enumConstructorCallTransformer: EnumConstructorCallTransformer? = null override fun visitField(declaration: IrField): IrStatement { - val enumEntry = enumEntriesByField[declaration.descriptor] + val enumEntry = enumEntriesByField[declaration] if (enumEntry == null) { declaration.transformChildrenVoid(this) return declaration @@ -391,15 +394,14 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass { } override fun visitConstructor(declaration: IrConstructor): IrStatement { - val constructorDescriptor = declaration.descriptor - val containingClass = constructorDescriptor.containingDeclaration + val containingClass = declaration.parent as IrClass // TODO local (non-enum) class in enum class constructor? val previous = enumConstructorCallTransformer if (containingClass.kind == ClassKind.ENUM_ENTRY) { assert(enumConstructorCallTransformer == null) { "Nested enum entry initialization:\n${declaration.dump()}" } - enumConstructorCallTransformer = InEnumEntryClassConstructor(containingClass) + enumConstructorCallTransformer = InEnumEntryClassConstructor(enumEntryClassToEntry[containingClass]!!) } else if (containingClass.kind == ClassKind.ENUM_CLASS) { assert(enumConstructorCallTransformer == null) { "Nested enum entry initialization:\n${declaration.dump()}" } enumConstructorCallTransformer = InEnumClassConstructor(declaration) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SingletonReferencesLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SingletonReferencesLowering.kt index 8925a70e758..222dc8046b4 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SingletonReferencesLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SingletonReferencesLowering.kt @@ -32,8 +32,8 @@ class SingletonReferencesLowering(val context: JvmBackendContext) : BodyLowering } override fun visitGetEnumValue(expression: IrGetEnumValue): IrExpression { - val enumValueFieldDescriptor = context.descriptorsFactory.getFieldDescriptorForEnumEntry(expression.descriptor) - return IrGetFieldImpl(expression.startOffset, expression.endOffset, enumValueFieldDescriptor) + val entrySymbol = context.descriptorsFactory.getSymbolForEnumEntry(expression.symbol) + return IrGetFieldImpl(expression.startOffset, expression.endOffset, entrySymbol) } override fun visitGetObjectValue(expression: IrGetObjectValue): IrExpression {