diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/BackendContext.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/BackendContext.kt index c86a051beeb..271319860f8 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/BackendContext.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/BackendContext.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.backend.common -import org.jetbrains.kotlin.backend.common.ir.DeclarationFactory import org.jetbrains.kotlin.backend.common.ir.Ir import org.jetbrains.kotlin.backend.common.ir.SharedVariablesManager import org.jetbrains.kotlin.builtins.KotlinBuiltIns @@ -32,7 +31,6 @@ interface BackendContext { val builtIns: KotlinBuiltIns val irBuiltIns: IrBuiltIns val sharedVariablesManager: SharedVariablesManager - val declarationFactory: DeclarationFactory val internalPackageFqn: FqName val transformedFunction: MutableMap val lateinitNullableFields: MutableMap diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/DeclarationFactory.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/DeclarationFactory.kt deleted file mode 100644 index c3c3c78f5a3..00000000000 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/DeclarationFactory.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. - * 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.backend.common.ir - -import org.jetbrains.kotlin.ir.declarations.* - -interface DeclarationFactory { - object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS", isSynthetic = true) - - fun getOuterThisField(innerClass: IrClass): IrField - fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: IrConstructor): IrConstructor - fun getInnerClassOriginalPrimaryConstructorOrNull(innerClass: IrClass): IrConstructor? -} diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InnerClassesLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InnerClassesLowering.kt index 6270c4f8d1b..d5f9784db56 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InnerClassesLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InnerClassesLowering.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.backend.common.lower import org.jetbrains.kotlin.backend.common.* -import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.builders.irSetField @@ -23,24 +22,30 @@ import org.jetbrains.kotlin.ir.util.patchDeclarationParents import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid -class InnerClassesLowering(val context: BackendContext) : DeclarationTransformer { +interface InnerClassesSupport { + object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS", isSynthetic = true) + fun getOuterThisField(innerClass: IrClass): IrField + fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: IrConstructor): IrConstructor + fun getInnerClassOriginalPrimaryConstructorOrNull(innerClass: IrClass): IrConstructor? +} + +class InnerClassesLowering(val context: BackendContext, private val innerClassesSupport: InnerClassesSupport) : DeclarationTransformer { override fun lower(irFile: IrFile) { runPostfix(true).toFileLoweringPass().lower(irFile) } override fun transformFlat(declaration: IrDeclaration): List? { - if (declaration is IrClass && declaration.isInner) { stageController.unrestrictDeclarationListsAccess { - declaration.declarations += context.declarationFactory.getOuterThisField(declaration) + declaration.declarations += innerClassesSupport.getOuterThisField(declaration) } } else if (declaration is IrConstructor) { val irClass = declaration.parentAsClass if (!irClass.isInner) return null val newConstructor = lowerConstructor(declaration) - val oldConstructorParameterToNew = context.primaryConstructorParameterMap(declaration) + val oldConstructorParameterToNew = innerClassesSupport.primaryConstructorParameterMap(declaration) for ((oldParam, newParam) in oldConstructorParameterToNew.entries) { newParam.defaultValue = oldParam.defaultValue?.let { oldDefault -> IrExpressionBodyImpl(oldDefault.startOffset, oldDefault.endOffset) { @@ -56,11 +61,11 @@ class InnerClassesLowering(val context: BackendContext) : DeclarationTransformer } private fun lowerConstructor(irConstructor: IrConstructor): IrConstructor { - val loweredConstructor = context.declarationFactory.getInnerClassConstructorWithOuterThisParameter(irConstructor) + val loweredConstructor = innerClassesSupport.getInnerClassConstructorWithOuterThisParameter(irConstructor) val outerThisParameter = loweredConstructor.valueParameters[0] val irClass = irConstructor.parentAsClass - val parentThisField = context.declarationFactory.getOuterThisField(irClass) + val parentThisField = innerClassesSupport.getOuterThisField(irClass) val blockBody = irConstructor.body as? IrBlockBody ?: throw AssertionError("Unexpected constructor body: ${irConstructor.body}") @@ -79,7 +84,7 @@ class InnerClassesLowering(val context: BackendContext) : DeclarationTransformer } patchDeclarationParents(loweredConstructor) - val oldConstructorParameterToNew = context.primaryConstructorParameterMap(irConstructor) + val oldConstructorParameterToNew = innerClassesSupport.primaryConstructorParameterMap(irConstructor) transformChildrenVoid(VariableRemapper(oldConstructorParameterToNew)) } @@ -88,10 +93,10 @@ class InnerClassesLowering(val context: BackendContext) : DeclarationTransformer } -private fun BackendContext.primaryConstructorParameterMap(originalConstructor: IrConstructor): Map { +private fun InnerClassesSupport.primaryConstructorParameterMap(originalConstructor: IrConstructor): Map { val oldConstructorParameterToNew = HashMap() - val loweredConstructor = declarationFactory.getInnerClassConstructorWithOuterThisParameter(originalConstructor) + val loweredConstructor = getInnerClassConstructorWithOuterThisParameter(originalConstructor) originalConstructor.valueParameters.forEach { old -> oldConstructorParameterToNew[old] = loweredConstructor.valueParameters[old.index + 1] @@ -101,7 +106,7 @@ private fun BackendContext.primaryConstructorParameterMap(originalConstructor: I } -class InnerClassesMemberBodyLowering(val context: BackendContext) : BodyLoweringPass { +class InnerClassesMemberBodyLowering(val context: BackendContext, private val innerClassesSupport: InnerClassesSupport) : BodyLoweringPass { override fun lower(irFile: IrFile) { runOnFilePostfix(irFile, true) } @@ -123,9 +128,9 @@ class InnerClassesMemberBodyLowering(val context: BackendContext) : BodyLowering if (!irClass.isInner) return if (container is IrField || container is IrAnonymousInitializer || container is IrValueParameter) { - val primaryConstructor = context.declarationFactory.getInnerClassOriginalPrimaryConstructorOrNull(irClass) + val primaryConstructor = innerClassesSupport.getInnerClassOriginalPrimaryConstructorOrNull(irClass) if (primaryConstructor != null) { - val oldConstructorParameterToNew = context.primaryConstructorParameterMap(primaryConstructor) + val oldConstructorParameterToNew = innerClassesSupport.primaryConstructorParameterMap(primaryConstructor) irBody.transformChildrenVoid(VariableRemapper(oldConstructorParameterToNew)) } } @@ -133,7 +138,7 @@ class InnerClassesMemberBodyLowering(val context: BackendContext) : BodyLowering irBody.fixThisReference(irClass, container) } - fun IrBody.fixThisReference(irClass: IrClass, container: IrDeclaration) { + private fun IrBody.fixThisReference(irClass: IrClass, container: IrDeclaration) { val enclosingFunction: IrDeclaration? = run { var current: IrDeclaration? = container while (current != null && current !is IrFunction) { @@ -171,7 +176,7 @@ class InnerClassesMemberBodyLowering(val context: BackendContext) : BodyLowering // an attempt to access the field. Good thing we have a local variable as well. IrGetValueImpl(startOffset, endOffset, function.valueParameters[0].symbol, origin) } else { - val outerThisField = context.declarationFactory.getOuterThisField(innerClass) + val outerThisField = innerClassesSupport.getOuterThisField(innerClass) IrGetFieldImpl(startOffset, endOffset, outerThisField.symbol, outerThisField.type, irThis, origin) } innerClass = innerClass.parentAsClass @@ -182,13 +187,7 @@ class InnerClassesMemberBodyLowering(val context: BackendContext) : BodyLowering } } -val innerClassConstructorCallsPhase = makeIrFilePhase( - ::InnerClassConstructorCallsLowering, - name = "InnerClassConstructorCalls", - description = "Handle constructor calls for inner classes" -) - -class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLoweringPass { +class InnerClassConstructorCallsLowering(val context: BackendContext, val innerClassesSupport: InnerClassesSupport) : BodyLoweringPass { override fun lower(irBody: IrBody, container: IrDeclaration) { irBody.transformChildrenVoid(object : IrElementTransformerVoid() { override fun visitConstructorCall(expression: IrConstructorCall): IrExpression { @@ -199,7 +198,7 @@ class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLowe val parent = callee.owner.parentAsClass if (!parent.isInner) return expression - val newCallee = context.declarationFactory.getInnerClassConstructorWithOuterThisParameter(callee.owner) + val newCallee = innerClassesSupport.getInnerClassConstructorWithOuterThisParameter(callee.owner) val classTypeParametersCount = expression.typeArgumentsCount - expression.constructorTypeArgumentsCount val newCall = IrConstructorCallImpl.fromSymbolOwner( expression.startOffset, expression.endOffset, expression.type, newCallee.symbol, classTypeParametersCount, expression.origin @@ -221,7 +220,7 @@ class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLowe val classConstructor = expression.symbol.owner if (!classConstructor.parentAsClass.isInner) return expression - val newCallee = context.declarationFactory.getInnerClassConstructorWithOuterThisParameter(classConstructor) + val newCallee = innerClassesSupport.getInnerClassConstructorWithOuterThisParameter(classConstructor) val newCall = IrDelegatingConstructorCallImpl( expression.startOffset, expression.endOffset, context.irBuiltIns.unitType, newCallee.symbol, typeArgumentsCount = expression.typeArgumentsCount, @@ -243,10 +242,10 @@ class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLowe val parent = callee.owner.parent as? IrClass ?: return expression if (!parent.isInner) return expression - val newCallee = context.declarationFactory.getInnerClassConstructorWithOuterThisParameter(callee.owner) + val newCallee = innerClassesSupport.getInnerClassConstructorWithOuterThisParameter(callee.owner) val newReflectionTarget = expression.reflectionTarget?.let { reflectionTarget -> if (reflectionTarget is IrConstructorSymbol) { - context.declarationFactory.getInnerClassConstructorWithOuterThisParameter(reflectionTarget.owner) + innerClassesSupport.getInnerClassConstructorWithOuterThisParameter(reflectionTarget.owner) } else { null } @@ -282,4 +281,3 @@ class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLowe }) } } - diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt index 9d3a911d33c..622823e821c 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt @@ -8,7 +8,7 @@ package org.jetbrains.kotlin.ir.backend.js import org.jetbrains.kotlin.backend.common.atMostOne import org.jetbrains.kotlin.backend.common.ir.Ir import org.jetbrains.kotlin.backend.common.ir.Symbols -import org.jetbrains.kotlin.backend.js.JsDeclarationFactory +import org.jetbrains.kotlin.ir.backend.js.lower.JsInnerClassesSupport import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.descriptors.* @@ -134,7 +134,7 @@ class JsIrBackendContext( get() = testContainerFuns override val mapping = JsMapping() - override val declarationFactory = JsDeclarationFactory(mapping) + val innerClassesSupport = JsInnerClassesSupport(mapping) companion object { val KOTLIN_PACKAGE_FQN = FqName.fromSegments(listOf("kotlin")) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt index ebde00d7df1..eb23c81bae4 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt @@ -375,20 +375,20 @@ private val localClassExtractionPhase = makeBodyLoweringPhase( ) private val innerClassesLoweringPhase = makeDeclarationTransformerPhase( - ::InnerClassesLowering, + { context -> InnerClassesLowering(context, context.innerClassesSupport) }, name = "InnerClassesLowering", description = "Capture outer this reference to inner class" ) private val innerClassesMemberBodyLoweringPhase = makeBodyLoweringPhase( - ::InnerClassesMemberBodyLowering, + { context -> InnerClassesMemberBodyLowering(context, context.innerClassesSupport) }, name = "InnerClassesMemberBody", description = "Replace `this` with 'outer this' field references", prerequisite = setOf(innerClassesLoweringPhase) ) private val innerClassConstructorCallsLoweringPhase = makeBodyLoweringPhase( - ::InnerClassConstructorCallsLowering, + { context -> InnerClassConstructorCallsLowering(context, context.innerClassesSupport) }, name = "InnerClassConstructorCallsLowering", description = "Replace inner class constructor invocation" ) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsDeclarationFactory.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsInnerClassesSupport.kt similarity index 93% rename from compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsDeclarationFactory.kt rename to compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsInnerClassesSupport.kt index 3dd607683f6..c5d9ba5d129 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsDeclarationFactory.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsInnerClassesSupport.kt @@ -3,10 +3,10 @@ * 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.backend.js +package org.jetbrains.kotlin.ir.backend.js.lower import org.jetbrains.kotlin.backend.common.getOrPut -import org.jetbrains.kotlin.backend.common.ir.DeclarationFactory +import org.jetbrains.kotlin.backend.common.lower.InnerClassesSupport import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom import org.jetbrains.kotlin.descriptors.Visibilities @@ -23,7 +23,7 @@ import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.name.Name -class JsDeclarationFactory(mapping: JsMapping) : DeclarationFactory { +class JsInnerClassesSupport(mapping: JsMapping) : InnerClassesSupport { private val outerThisFieldSymbols = mapping.outerThisFieldSymbols private val innerClassConstructors = mapping.innerClassConstructors private val originalInnerClassPrimaryConstructorByClass = mapping.originalInnerClassPrimaryConstructorByClass @@ -36,7 +36,7 @@ class JsDeclarationFactory(mapping: JsMapping) : DeclarationFactory { ?: throw AssertionError("No containing class for inner class ${innerClass.dump()}") buildField { - origin = DeclarationFactory.FIELD_FOR_OUTER_THIS + origin = InnerClassesSupport.FIELD_FOR_OUTER_THIS name = Name.identifier("\$this") type = outerClass.defaultType visibility = Visibilities.PROTECTED diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index 3172b37ed77..de06e1e10d3 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDeclarationFactory import org.jetbrains.kotlin.backend.jvm.descriptors.JvmSharedVariablesManager import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods import org.jetbrains.kotlin.backend.jvm.lower.CollectionStubComputer +import org.jetbrains.kotlin.backend.jvm.lower.JvmInnerClassesSupport import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.MemoizedInlineClassReplacements import org.jetbrains.kotlin.codegen.state.GenerationState @@ -67,8 +68,8 @@ class JvmBackendContext( val typeMapper = IrTypeMapper(this) val methodSignatureMapper = MethodSignatureMapper(this) - override val declarationFactory: JvmDeclarationFactory = - JvmDeclarationFactory(this, methodSignatureMapper, state.languageVersionSettings) + internal val innerClassesSupport = JvmInnerClassesSupport() + internal val declarationFactory = JvmDeclarationFactory(this, methodSignatureMapper, state.languageVersionSettings) override val mapping: Mapping = DefaultMapping() 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 0c4939a4e5c..68b5d2b7a4d 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 @@ -190,19 +190,25 @@ private val interfacePhase = makeIrFilePhase( ) private val innerClassesPhase = makeIrFilePhase( - ::InnerClassesLowering, + { context -> InnerClassesLowering(context, context.innerClassesSupport) }, name = "InnerClasses", description = "Add 'outer this' fields to inner classes", prerequisite = setOf(localDeclarationsPhase) ) private val innerClassesMemberBodyPhase = makeIrFilePhase( - ::InnerClassesMemberBodyLowering, + { context -> InnerClassesMemberBodyLowering(context, context.innerClassesSupport) }, name = "InnerClassesMemberBody", description = "Replace `this` with 'outer this' field references", prerequisite = setOf(innerClassesPhase) ) +private val innerClassConstructorCallsPhase = makeIrFilePhase( + { context -> InnerClassConstructorCallsLowering(context, context.innerClassesSupport) }, + name = "InnerClassConstructorCalls", + description = "Handle constructor calls for inner classes" +) + private val staticInitializersPhase = makeIrFilePhase( ::StaticInitializersLowering, name = "StaticInitializers", diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt index 1fd6796bb69..8fad050a720 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt @@ -5,7 +5,9 @@ package org.jetbrains.kotlin.backend.jvm.descriptors -import org.jetbrains.kotlin.backend.common.ir.* +import org.jetbrains.kotlin.backend.common.ir.copyParameterDeclarationsFrom +import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor +import org.jetbrains.kotlin.backend.common.ir.createStaticFunctionWithReceivers import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin @@ -14,12 +16,13 @@ import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface import org.jetbrains.kotlin.backend.jvm.ir.copyCorrespondingPropertyFrom import org.jetbrains.kotlin.backend.jvm.ir.replaceThisByStaticReference import org.jetbrains.kotlin.builtins.CompanionObjectMapping.isMappedIntrinsicCompanionObject -import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities -import org.jetbrains.kotlin.ir.builders.declarations.* +import org.jetbrains.kotlin.ir.builders.declarations.buildClass +import org.jetbrains.kotlin.ir.builders.declarations.buildField +import org.jetbrains.kotlin.ir.builders.declarations.buildFun import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.setSourceRange import org.jetbrains.kotlin.ir.declarations.* @@ -29,18 +32,14 @@ import org.jetbrains.kotlin.load.java.JavaVisibilities import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver -import java.util.* class JvmDeclarationFactory( private val context: JvmBackendContext, private val methodSignatureMapper: MethodSignatureMapper, private val languageVersionSettings: LanguageVersionSettings -) : DeclarationFactory { +) { private val singletonFieldDeclarations = HashMap() private val interfaceCompanionFieldDeclarations = HashMap() - private val outerThisDeclarations = HashMap() - private val innerClassConstructors = HashMap() - private val originalInnerClassPrimaryConstructorByClass = HashMap() private val staticBackingFields = HashMap() private val defaultImplsMethods = HashMap() @@ -61,59 +60,6 @@ class JvmDeclarationFactory( } } - override fun getOuterThisField(innerClass: IrClass): IrField = - outerThisDeclarations.getOrPut(innerClass) { - assert(innerClass.isInner) { "Class is not inner: ${innerClass.dump()}" } - buildField { - name = Name.identifier("this$0") - type = innerClass.parentAsClass.defaultType - origin = DeclarationFactory.FIELD_FOR_OUTER_THIS - visibility = JavaVisibilities.PACKAGE_VISIBILITY - isFinal = true - }.apply { - parent = innerClass - } - } - - override fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: IrConstructor): IrConstructor { - val innerClass = innerClassConstructor.parent as IrClass - assert(innerClass.isInner) { "Class is not inner: ${(innerClassConstructor.parent as IrClass).dump()}" } - - return innerClassConstructors.getOrPut(innerClassConstructor) { - createInnerClassConstructorWithOuterThisParameter(innerClassConstructor) - }.also { - if (innerClassConstructor.isPrimary) { - originalInnerClassPrimaryConstructorByClass[innerClass] = innerClassConstructor - } - } - } - - override fun getInnerClassOriginalPrimaryConstructorOrNull(innerClass: IrClass): IrConstructor? { - assert(innerClass.isInner) { "Class is not inner: $innerClass" } - - return originalInnerClassPrimaryConstructorByClass[innerClass] - } - - private fun createInnerClassConstructorWithOuterThisParameter(oldConstructor: IrConstructor): IrConstructor = - buildConstructor(oldConstructor.descriptor) { - updateFrom(oldConstructor) - returnType = oldConstructor.returnType - }.apply { - annotations = oldConstructor.annotations.map { it.deepCopyWithSymbols(this) } - parent = oldConstructor.parent - returnType = oldConstructor.returnType - copyTypeParametersFrom(oldConstructor) - - val outerThisValueParameter = buildValueParameter(this) { - origin = JvmLoweredDeclarationOrigin.FIELD_FOR_OUTER_THIS - name = Name.identifier(AsmUtil.CAPTURED_THIS_FIELD) - index = 0 - type = oldConstructor.parentAsClass.parentAsClass.defaultType - } - valueParameters = listOf(outerThisValueParameter) + oldConstructor.valueParameters.map { it.copyTo(this, index = it.index + 1) } - metadata = oldConstructor.metadata - } - fun getFieldForObjectInstance(singleton: IrClass): IrField = singletonFieldDeclarations.getOrPut(singleton) { val originalVisibility = singleton.visibility diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt index 28677625734..ec3f0388014 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.* import org.jetbrains.kotlin.backend.common.ir.* +import org.jetbrains.kotlin.backend.common.lower.InnerClassesSupport import org.jetbrains.kotlin.backend.common.lower.LocalDeclarationsLowering import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase @@ -427,7 +428,7 @@ private class AddContinuationLowering(private val context: JvmBackendContext) : addField { name = Name.identifier("this$0") type = it.type - origin = DeclarationFactory.FIELD_FOR_OUTER_THIS + origin = InnerClassesSupport.FIELD_FOR_OUTER_THIS visibility = JavaVisibilities.PACKAGE_VISIBILITY isFinal = true } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInnerClassesSupport.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInnerClassesSupport.kt new file mode 100644 index 00000000000..5674f6ba808 --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInnerClassesSupport.kt @@ -0,0 +1,83 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.backend.jvm.lower + +import org.jetbrains.kotlin.backend.common.ir.copyTo +import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom +import org.jetbrains.kotlin.backend.common.lower.InnerClassesSupport +import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin +import org.jetbrains.kotlin.codegen.AsmUtil +import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor +import org.jetbrains.kotlin.ir.builders.declarations.buildField +import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrConstructor +import org.jetbrains.kotlin.ir.declarations.IrField +import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols +import org.jetbrains.kotlin.ir.util.defaultType +import org.jetbrains.kotlin.ir.util.dump +import org.jetbrains.kotlin.ir.util.parentAsClass +import org.jetbrains.kotlin.load.java.JavaVisibilities +import org.jetbrains.kotlin.name.Name + +class JvmInnerClassesSupport : InnerClassesSupport { + private val outerThisDeclarations = HashMap() + private val innerClassConstructors = HashMap() + private val originalInnerClassPrimaryConstructorByClass = HashMap() + + override fun getOuterThisField(innerClass: IrClass): IrField = + outerThisDeclarations.getOrPut(innerClass) { + assert(innerClass.isInner) { "Class is not inner: ${innerClass.dump()}" } + buildField { + name = Name.identifier("this$0") + type = innerClass.parentAsClass.defaultType + origin = InnerClassesSupport.FIELD_FOR_OUTER_THIS + visibility = JavaVisibilities.PACKAGE_VISIBILITY + isFinal = true + }.apply { + parent = innerClass + } + } + + override fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: IrConstructor): IrConstructor { + val innerClass = innerClassConstructor.parent as IrClass + assert(innerClass.isInner) { "Class is not inner: ${(innerClassConstructor.parent as IrClass).dump()}" } + + return innerClassConstructors.getOrPut(innerClassConstructor) { + createInnerClassConstructorWithOuterThisParameter(innerClassConstructor) + }.also { + if (innerClassConstructor.isPrimary) { + originalInnerClassPrimaryConstructorByClass[innerClass] = innerClassConstructor + } + } + } + + override fun getInnerClassOriginalPrimaryConstructorOrNull(innerClass: IrClass): IrConstructor? { + assert(innerClass.isInner) { "Class is not inner: $innerClass" } + + return originalInnerClassPrimaryConstructorByClass[innerClass] + } + + private fun createInnerClassConstructorWithOuterThisParameter(oldConstructor: IrConstructor): IrConstructor = + buildConstructor(oldConstructor.descriptor) { + updateFrom(oldConstructor) + returnType = oldConstructor.returnType + }.apply { + annotations = oldConstructor.annotations.map { it.deepCopyWithSymbols(this) } + parent = oldConstructor.parent + returnType = oldConstructor.returnType + copyTypeParametersFrom(oldConstructor) + + val outerThisValueParameter = buildValueParameter(this) { + origin = JvmLoweredDeclarationOrigin.FIELD_FOR_OUTER_THIS + name = Name.identifier(AsmUtil.CAPTURED_THIS_FIELD) + index = 0 + type = oldConstructor.parentAsClass.parentAsClass.defaultType + } + valueParameters = listOf(outerThisValueParameter) + oldConstructor.valueParameters.map { it.copyTo(this, index = it.index + 1) } + metadata = oldConstructor.metadata + } +} diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmBackendContext.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmBackendContext.kt index 558019af261..abcb3d4b920 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmBackendContext.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmBackendContext.kt @@ -7,7 +7,7 @@ package org.jetbrains.kotlin.backend.wasm import org.jetbrains.kotlin.backend.common.ir.Ir import org.jetbrains.kotlin.backend.common.ir.Symbols -import org.jetbrains.kotlin.backend.js.JsDeclarationFactory +import org.jetbrains.kotlin.ir.backend.js.lower.JsInnerClassesSupport import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor @@ -52,7 +52,7 @@ class WasmBackendContext( override val mapping = JsMapping() - override val declarationFactory = JsDeclarationFactory(mapping) + val innerClassesSupport = JsInnerClassesSupport(mapping) val objectToGetInstanceFunction = mutableMapOf() override val internalPackageFqn = FqName("kotlin.wasm") @@ -100,6 +100,3 @@ class DescriptorlessExternalPackageFragmentSymbol : IrExternalPackageFragmentSym override val signature: IdSignature get() = error("Operation is unsupported") } - - - diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt index f811273dade..50c16356c6d 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt @@ -149,20 +149,20 @@ private val localClassExtractionPhase = makeWasmModulePhase( ) private val innerClassesLoweringPhase = makeWasmModulePhase( - ::InnerClassesLowering, + { context -> InnerClassesLowering(context, context.innerClassesSupport) }, name = "InnerClassesLowering", description = "Capture outer this reference to inner class" ) private val innerClassesMemberBodyLoweringPhase = makeWasmModulePhase( - ::InnerClassesMemberBodyLowering, + { context -> InnerClassesMemberBodyLowering(context, context.innerClassesSupport) }, name = "InnerClassesMemberBody", description = "Replace `this` with 'outer this' field references", prerequisite = setOf(innerClassesLoweringPhase) ) private val innerClassConstructorCallsLoweringPhase = makeWasmModulePhase( - ::InnerClassConstructorCallsLowering, + { context -> InnerClassConstructorCallsLowering(context, context.innerClassesSupport) }, name = "InnerClassConstructorCallsLowering", description = "Replace inner class constructor invocation" ) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt index ef543b9b37a..0dbb38b335c 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.backend.common.serialization import org.jetbrains.kotlin.backend.common.LoggingContext -import org.jetbrains.kotlin.backend.common.ir.DeclarationFactory +import org.jetbrains.kotlin.backend.common.lower.InnerClassesSupport import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.common.overrides.PlatformFakeOverrideClassFilter import org.jetbrains.kotlin.backend.common.peek @@ -1363,7 +1363,7 @@ abstract class IrFileDeserializer( } private val allKnownDeclarationOrigins = - IrDeclarationOrigin::class.nestedClasses.toList() + DeclarationFactory.FIELD_FOR_OUTER_THIS::class + IrDeclarationOrigin::class.nestedClasses.toList() + InnerClassesSupport.FIELD_FOR_OUTER_THIS::class private val declarationOriginIndex = allKnownDeclarationOrigins.map { it.objectInstance as IrDeclarationOriginImpl }.associateBy { it.name }