From c7f9dc1c408c1ff15162ab3292111bf9345fdc13 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 8 Jul 2020 18:40:23 +0200 Subject: [PATCH] IR: rename DeclarationFactory to InnerClassesSupport, move out of context Methods of the common interface DeclarationFactory were only used in lowerings in InnerClassesLowering, which were used in JVM and JS, not Native. Therefore, it makes sense to have this as a separate interface and pass its implementation to these lowerings directly, instead of declaring it in the common context (which is not going to be implemented in Native). --- .../kotlin/backend/common/BackendContext.kt | 2 - .../backend/common/ir/DeclarationFactory.kt | 16 ---- .../common/lower/InnerClassesLowering.kt | 52 ++++++------ .../ir/backend/js/JsIrBackendContext.kt | 4 +- .../kotlin/ir/backend/js/JsLoweringPhases.kt | 6 +- .../JsInnerClassesSupport.kt} | 8 +- .../kotlin/backend/jvm/JvmBackendContext.kt | 5 +- .../jetbrains/kotlin/backend/jvm/JvmLower.kt | 10 ++- .../jvm/descriptors/JvmDeclarationFactory.kt | 68 ++------------- .../jvm/lower/AddContinuationLowering.kt | 3 +- .../jvm/lower/JvmInnerClassesSupport.kt | 83 +++++++++++++++++++ .../kotlin/backend/wasm/WasmBackendContext.kt | 7 +- .../kotlin/backend/wasm/WasmLoweringPhases.kt | 6 +- .../serialization/IrFileDeserializer.kt | 4 +- 14 files changed, 144 insertions(+), 130 deletions(-) delete mode 100644 compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/DeclarationFactory.kt rename compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/{JsDeclarationFactory.kt => lower/JsInnerClassesSupport.kt} (93%) create mode 100644 compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInnerClassesSupport.kt 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 }