From c1a4aeb67f83a27bb2481c4a361eafd851088caf Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Wed, 18 Apr 2018 22:25:23 +0300 Subject: [PATCH] Lift InnerClassesLowering from JVM to common since it is used by every backend in the same way --- .../kotlin/backend/common/BackendContext.kt | 2 + .../common/descriptors/DescriptorsFactory.kt | 17 ++ .../common}/lower/InnerClassesLowering.kt | 57 ++++--- .../kotlin/backend/common/lower/LowerUtils.kt | 19 ++- .../ir/backend/js/JsIrBackendContext.kt | 23 +-- .../backend/js/JsSpecialDescriptorsFactory.kt | 160 ++++++++++++++++++ .../kotlin/backend/jvm/JvmBackendContext.kt | 5 +- ...ory.kt => JvmSpecialDescriptorsFactory.kt} | 13 +- .../backend/jvm/lower/EnumClassLowering.kt | 2 +- .../backend/jvm/lower/FileClassLowering.kt | 2 +- .../backend/jvm/lower/ObjectClassLowering.kt | 2 +- .../jvm/lower/SingletonReferencesLowering.kt | 4 +- 12 files changed, 247 insertions(+), 59 deletions(-) create mode 100644 compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/DescriptorsFactory.kt rename compiler/ir/{backend.jvm/src/org/jetbrains/kotlin/backend/jvm => backend.common/src/org/jetbrains/kotlin/backend/common}/lower/InnerClassesLowering.kt (81%) create mode 100644 compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSpecialDescriptorsFactory.kt rename compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/{SpecialDescriptorsFactory.kt => JvmSpecialDescriptorsFactory.kt} (91%) 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 84de73794cb..2aec18c30e8 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,6 +16,7 @@ package org.jetbrains.kotlin.backend.common +import org.jetbrains.kotlin.backend.common.descriptors.DescriptorsFactory import org.jetbrains.kotlin.backend.common.descriptors.SharedVariablesManager import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns @@ -24,4 +25,5 @@ interface BackendContext { val builtIns: KotlinBuiltIns val irBuiltIns: IrBuiltIns val sharedVariablesManager: SharedVariablesManager + val descriptorsFactory: DescriptorsFactory } 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 new file mode 100644 index 00000000000..2b07ae6fce2 --- /dev/null +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/DescriptorsFactory.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2010-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.backend.common.descriptors + +import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor + +interface DescriptorsFactory { + fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor + fun getOuterThisFieldDescriptor(classDescriptor: ClassDescriptor): PropertyDescriptor + fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: ClassConstructorDescriptor): ClassConstructorDescriptor + fun getFieldDescriptorForObjectInstance(objectDescriptor: ClassDescriptor): PropertyDescriptor +} \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InnerClassesLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InnerClassesLowering.kt similarity index 81% rename from compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InnerClassesLowering.kt rename to compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InnerClassesLowering.kt index 9d5427d4c18..c70a036bc5d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InnerClassesLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InnerClassesLowering.kt @@ -1,31 +1,22 @@ /* - * Copyright 2010-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-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.backend.jvm.lower +package org.jetbrains.kotlin.backend.common.lower +import org.jetbrains.kotlin.backend.common.BackendContext import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.ClassLoweringPass -import org.jetbrains.kotlin.backend.jvm.JvmBackendContext -import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrConstructor +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.util.dump @@ -35,7 +26,9 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver import java.util.* -class InnerClassesLowering(val context: JvmBackendContext) : ClassLoweringPass { +class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass { + object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS") + override fun lower(irClass: IrClass) { InnerClassTransformer(irClass).lowerInnerClass() } @@ -57,12 +50,12 @@ class InnerClassesLowering(val context: JvmBackendContext) : ClassLoweringPass { } private fun createOuterThisField() { - outerThisFieldDescriptor = context.specialDescriptorsFactory.getOuterThisFieldDescriptor(irClass.descriptor) + outerThisFieldDescriptor = context.descriptorsFactory.getOuterThisFieldDescriptor(irClass.descriptor) irClass.declarations.add(IrFieldImpl( - irClass.startOffset, irClass.endOffset, - JvmLoweredDeclarationOrigin.FIELD_FOR_OUTER_THIS, - outerThisFieldDescriptor + irClass.startOffset, irClass.endOffset, + FIELD_FOR_OUTER_THIS, + outerThisFieldDescriptor )) } @@ -80,7 +73,7 @@ class InnerClassesLowering(val context: JvmBackendContext) : ClassLoweringPass { val startOffset = irConstructor.startOffset val endOffset = irConstructor.endOffset - val newDescriptor = context.specialDescriptorsFactory.getInnerClassConstructorWithOuterThisParameter(oldDescriptor) + val newDescriptor = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(oldDescriptor) val outerThisValueParameter = newDescriptor.valueParameters[0] oldDescriptor.valueParameters.forEach { oldValueParameter -> @@ -116,7 +109,17 @@ class InnerClassesLowering(val context: JvmBackendContext) : ClassLoweringPass { irConstructor.origin, // TODO special origin for lowered inner class constructors? newDescriptor, blockBody - ) + ).apply { + newDescriptor.valueParameters.forEachIndexed { i, desc -> + val valueParameter = if (i == 0) { + IrValueParameterImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, FIELD_FOR_OUTER_THIS, desc, null) + } else { + val origParam = irConstructor.valueParameters[i - 1] + IrValueParameterImpl(origParam.startOffset, origParam.endOffset, origParam.origin, desc, origParam.defaultValue) + } + valueParameters.add(valueParameter) + } + } } private fun lowerConstructorParameterUsages() { @@ -153,7 +156,7 @@ class InnerClassesLowering(val context: JvmBackendContext) : ClassLoweringPass { return expression } - val outerThisField = context.specialDescriptorsFactory.getOuterThisFieldDescriptor(innerClass) + val outerThisField = context.descriptorsFactory.getOuterThisFieldDescriptor(innerClass) irThis = IrGetFieldImpl(startOffset, endOffset, outerThisField, irThis, origin) val outer = classDescriptor.containingDeclaration @@ -178,7 +181,7 @@ class InnerClassesLowering(val context: JvmBackendContext) : ClassLoweringPass { } } -class InnerClassConstructorCallsLowering(val context: JvmBackendContext) : BodyLoweringPass { +class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLoweringPass { override fun lower(irBody: IrBody) { irBody.transformChildrenVoid(object : IrElementTransformerVoid() { override fun visitCall(expression: IrCall): IrExpression { @@ -188,7 +191,7 @@ class InnerClassConstructorCallsLowering(val context: JvmBackendContext) : BodyL val callee = expression.descriptor as? ClassConstructorDescriptor ?: return expression if (!callee.constructedClass.isInner) return expression - val newCallee = context.specialDescriptorsFactory.getInnerClassConstructorWithOuterThisParameter(callee) + val newCallee = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(callee) val newCall = IrCallImpl( expression.startOffset, expression.endOffset, newCallee, null, // TODO type arguments map @@ -210,7 +213,7 @@ class InnerClassConstructorCallsLowering(val context: JvmBackendContext) : BodyL val callee = expression.descriptor if (!callee.constructedClass.isInner) return expression - val newCallee = context.specialDescriptorsFactory.getInnerClassConstructorWithOuterThisParameter(callee) + val newCallee = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(callee) val newCall = IrDelegatingConstructorCallImpl( expression.startOffset, expression.endOffset, newCallee, null // TODO type arguments map diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LowerUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LowerUtils.kt index de849c39836..10f6f918eb2 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LowerUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LowerUtils.kt @@ -26,10 +26,7 @@ import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall -import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin -import org.jetbrains.kotlin.ir.expressions.IrTypeOperator +import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol @@ -58,6 +55,20 @@ class DeclarationIrBuilder( endOffset ) +abstract class AbstractVariableRemapper : IrElementTransformerVoid() { + protected abstract fun remapVariable(value: ValueDescriptor): ValueDescriptor? + + override fun visitGetValue(expression: IrGetValue): IrExpression = + remapVariable(expression.descriptor)?.let { + IrGetValueImpl(expression.startOffset, expression.endOffset, it, expression.origin) + } ?: expression +} + +class VariableRemapper(val mapping: Map) : AbstractVariableRemapper() { + override fun remapVariable(value: ValueDescriptor): ValueDescriptor? = + mapping[value] +} + fun BackendContext.createIrBuilder(symbol: IrSymbol, startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET) = 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 6ccf6073ab0..d9ebaca9dce 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 @@ -10,28 +10,23 @@ import org.jetbrains.kotlin.backend.common.ReflectionTypes import org.jetbrains.kotlin.backend.common.descriptors.KnownPackageFragmentDescriptor import org.jetbrains.kotlin.backend.common.ir.Ir import org.jetbrains.kotlin.backend.common.ir.Symbols -import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.annotations.Annotations -import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl -import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl -import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl +import org.jetbrains.kotlin.backend.js.JsSpecialDescriptorsFactory +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET -import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol -import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.scopes.MemberScope -import org.jetbrains.kotlin.types.KotlinTypeFactory -import org.jetbrains.kotlin.types.Variance class JsIrBackendContext( val module: ModuleDescriptor, @@ -45,6 +40,7 @@ class JsIrBackendContext( override val builtIns = module.builtIns override val sharedVariablesManager = JsSharedVariablesManager(builtIns, KnownPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.js.internal"))) + override val descriptorsFactory = JsSpecialDescriptorsFactory(builtIns) override val reflectionTypes: ReflectionTypes by lazy(LazyThreadSafetyMode.PUBLICATION) { // TODO @@ -129,5 +125,4 @@ class JsIrBackendContext( /*TODO*/ print(message) } - -} +} \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSpecialDescriptorsFactory.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSpecialDescriptorsFactory.kt new file mode 100644 index 00000000000..1c0d35d0f0d --- /dev/null +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSpecialDescriptorsFactory.kt @@ -0,0 +1,160 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.backend.js + +import org.jetbrains.kotlin.backend.common.descriptors.DescriptorsFactory +import org.jetbrains.kotlin.builtins.CompanionObjectMapping.isMappedIntrinsicCompanionObject +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.* +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.name.Name +import org.jetbrains.kotlin.resolve.DescriptorUtils +import java.util.* + +class JsSpecialDescriptorsFactory( + private val builtIns: KotlinBuiltIns +) : DescriptorsFactory { + private val singletonFieldDescriptors = HashMap() + private val outerThisDescriptors = HashMap() + private val innerClassConstructors = HashMap() + + override fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor = TODO() +// singletonFieldDescriptors.getOrPut(enumEntryDescriptor) { +// createEnumEntryFieldDescriptor(enumEntryDescriptor) +// } + + override fun getOuterThisFieldDescriptor(innerClassDescriptor: ClassDescriptor): PropertyDescriptor = + if (!innerClassDescriptor.isInner) throw AssertionError("Class is not inner: $innerClassDescriptor") + else outerThisDescriptors.getOrPut(innerClassDescriptor) { + val outerClassDescriptor = DescriptorUtils.getContainingClass(innerClassDescriptor) + ?: throw AssertionError("No containing class for inner class $innerClassDescriptor") + +// PropertyDescriptorImpl.create(innerClassDescriptor, Annotations.EMPTY. Mo +// Name.identifier("this$0"), outerClassDescriptor.defaultType, innerClassDescriptor, +// Annotations.EMPTY, JavaVisibilities.PACKAGE_VISIBILITY, Opcodes.ACC_SYNTHETIC, SourceElement.NO_SOURCE +// ) + PropertyDescriptorImpl.create( + innerClassDescriptor, + Annotations.EMPTY, + Modality.FINAL, + Visibilities.PROTECTED, + false, + Name.identifier("\$this"), + CallableMemberDescriptor.Kind.SYNTHESIZED, + SourceElement.NO_SOURCE, + false, + true, + false, + false, + false, + false + ).apply { + setType( + outerClassDescriptor.defaultType, + emptyList(), + innerClassDescriptor.thisAsReceiverParameter, + null as? ReceiverParameterDescriptor + ) + initialize(null, null) + } + } + + override fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: ClassConstructorDescriptor): ClassConstructorDescriptor { + val innerClass = innerClassConstructor.containingDeclaration + assert(innerClass.isInner) { "Class is not inner: $innerClass" } + + return innerClassConstructors.getOrPut(innerClassConstructor) { + createInnerClassConstructorWithOuterThisParameter(innerClassConstructor) + } + } + + private fun createInnerClassConstructorWithOuterThisParameter(oldDescriptor: ClassConstructorDescriptor): ClassConstructorDescriptor { + val classDescriptor = oldDescriptor.containingDeclaration + val outerThisType = (classDescriptor.containingDeclaration as ClassDescriptor).defaultType + + val newDescriptor = ClassConstructorDescriptorImpl.createSynthesized( + classDescriptor, oldDescriptor.annotations, oldDescriptor.isPrimary, oldDescriptor.source + ) + +// val outerThisValueParameter = newDescriptor.createValueParameter(0, "\$outer", outerThisType) + val outerThisValueParameter = ValueParameterDescriptorImpl( + newDescriptor, + null, + 0, + Annotations.EMPTY, + Name.identifier("\$outer"), + outerThisType, + false, + false, + false, + null, + SourceElement.NO_SOURCE + ) + + val newValueParameters = + listOf(outerThisValueParameter) + + oldDescriptor.valueParameters.map { it.copy(newDescriptor, it.name, it.index + 1) } + newDescriptor.initialize(newValueParameters, oldDescriptor.visibility) + newDescriptor.returnType = oldDescriptor.returnType + return newDescriptor + } + + +// private fun createEnumEntryFieldDescriptor(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor { +// assert(enumEntryDescriptor.kind == ClassKind.ENUM_ENTRY) { "Should be enum entry: $enumEntryDescriptor" } +// +// val enumClassDescriptor = enumEntryDescriptor.containingDeclaration as ClassDescriptor +// assert(enumClassDescriptor.kind == ClassKind.ENUM_CLASS) { "Should be enum class: $enumClassDescriptor" } +// +// return JvmPropertyDescriptorImpl.createStaticVal( +// enumEntryDescriptor.name, +// enumClassDescriptor.defaultType, +// enumClassDescriptor, +// enumEntryDescriptor.annotations, +// Modality.FINAL, +// Visibilities.PUBLIC, +// Opcodes.ACC_ENUM, +// enumEntryDescriptor.source +// ) +// } + + override fun getFieldDescriptorForObjectInstance(objectDescriptor: ClassDescriptor): PropertyDescriptor = + singletonFieldDescriptors.getOrPut(objectDescriptor) { + createObjectInstanceFieldDescriptor(objectDescriptor) + } + + private fun createObjectInstanceFieldDescriptor(objectDescriptor: ClassDescriptor): PropertyDescriptor { + assert(objectDescriptor.kind == ClassKind.OBJECT) { "Should be an object: $objectDescriptor" } + + val isNotMappedCompanion = objectDescriptor.isCompanionObject && !isMappedIntrinsicCompanionObject(objectDescriptor) + val name = if (isNotMappedCompanion) objectDescriptor.name else Name.identifier("INSTANCE") + val containingDeclaration = if (isNotMappedCompanion) objectDescriptor.containingDeclaration else objectDescriptor + return PropertyDescriptorImpl.create( + containingDeclaration, + Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, false, + name, + CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE, /* lateInit = */ false, /* isConst = */ false, + /* isExpect = */ false, /* isActual = */ false, /* isExternal = */ false, /* isDelegated = */ false + ).apply { + setType(objectDescriptor.defaultType, emptyList(), null, null as ReceiverParameterDescriptor) + initialize(null, null) + } + } +} 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 937f299df74..943f958fbd2 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 @@ -21,7 +21,7 @@ import org.jetbrains.kotlin.backend.common.ReflectionTypes import org.jetbrains.kotlin.backend.common.ir.Ir import org.jetbrains.kotlin.backend.common.ir.Symbols import org.jetbrains.kotlin.backend.jvm.descriptors.JvmSharedVariablesManager -import org.jetbrains.kotlin.backend.jvm.descriptors.SpecialDescriptorsFactory +import org.jetbrains.kotlin.backend.jvm.descriptors.JvmSpecialDescriptorsFactory import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor @@ -31,7 +31,6 @@ import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.IrClassSymbol -import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.name.FqName @@ -46,7 +45,7 @@ class JvmBackendContext( irModuleFragment: IrModuleFragment, symbolTable: SymbolTable ) : CommonBackendContext { override val builtIns = state.module.builtIns - val specialDescriptorsFactory = SpecialDescriptorsFactory(psiSourceManager, builtIns) + override val descriptorsFactory: JvmSpecialDescriptorsFactory = JvmSpecialDescriptorsFactory(psiSourceManager, builtIns) override val sharedVariablesManager = JvmSharedVariablesManager(builtIns) override val reflectionTypes: ReflectionTypes by lazy(LazyThreadSafetyMode.PUBLICATION) { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SpecialDescriptorsFactory.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmSpecialDescriptorsFactory.kt similarity index 91% rename from compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SpecialDescriptorsFactory.kt rename to compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmSpecialDescriptorsFactory.kt index 524eb74178e..746442bd885 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SpecialDescriptorsFactory.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmSpecialDescriptorsFactory.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.backend.jvm.descriptors +import org.jetbrains.kotlin.backend.common.descriptors.DescriptorsFactory import org.jetbrains.kotlin.builtins.CompanionObjectMapping.isMappedIntrinsicCompanionObject import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.codegen.descriptors.FileClassDescriptor @@ -33,15 +34,15 @@ import org.jetbrains.kotlin.resolve.source.KotlinSourceElement import org.jetbrains.org.objectweb.asm.Opcodes import java.util.* -class SpecialDescriptorsFactory( +class JvmSpecialDescriptorsFactory( private val psiSourceManager: PsiSourceManager, private val builtIns: KotlinBuiltIns -) { +) : DescriptorsFactory { private val singletonFieldDescriptors = HashMap() private val outerThisDescriptors = HashMap() private val innerClassConstructors = HashMap() - fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor = + override fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor = singletonFieldDescriptors.getOrPut(enumEntryDescriptor) { createEnumEntryFieldDescriptor(enumEntryDescriptor) } @@ -59,7 +60,7 @@ class SpecialDescriptorsFactory( ) } - fun getOuterThisFieldDescriptor(innerClassDescriptor: ClassDescriptor): PropertyDescriptor = + override fun getOuterThisFieldDescriptor(innerClassDescriptor: ClassDescriptor): PropertyDescriptor = if (!innerClassDescriptor.isInner) throw AssertionError("Class is not inner: $innerClassDescriptor") else outerThisDescriptors.getOrPut(innerClassDescriptor) { val outerClassDescriptor = DescriptorUtils.getContainingClass(innerClassDescriptor) ?: @@ -71,7 +72,7 @@ class SpecialDescriptorsFactory( ) } - fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: ClassConstructorDescriptor): ClassConstructorDescriptor { + override fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: ClassConstructorDescriptor): ClassConstructorDescriptor { val innerClass = innerClassConstructor.containingDeclaration assert(innerClass.isInner) { "Class is not inner: $innerClass" } @@ -118,7 +119,7 @@ class SpecialDescriptorsFactory( ) } - fun getFieldDescriptorForObjectInstance(objectDescriptor: ClassDescriptor): PropertyDescriptor = + override fun getFieldDescriptorForObjectInstance(objectDescriptor: ClassDescriptor): PropertyDescriptor = singletonFieldDescriptors.getOrPut(objectDescriptor) { createObjectInstanceFieldDescriptor(objectDescriptor) } 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 ecd95435778..5a15d91ce5b 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 @@ -181,7 +181,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass { } private fun createFieldForEnumEntry(enumEntry: IrEnumEntry): IrField { - val fieldPropertyDescriptor = context.specialDescriptorsFactory.getFieldDescriptorForEnumEntry(enumEntry.descriptor) + val fieldPropertyDescriptor = context.descriptorsFactory.getFieldDescriptorForEnumEntry(enumEntry.descriptor) enumEntriesByField[fieldPropertyDescriptor] = enumEntry.descriptor enumEntryFields.add(fieldPropertyDescriptor) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt index 0b28d136a96..83d7a1c1e79 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt @@ -39,7 +39,7 @@ class FileClassLowering(val context: JvmBackendContext) : FileLoweringPass { if (fileClassMembers.isEmpty()) return - val fileClassDescriptor = context.specialDescriptorsFactory.createFileClassDescriptor(irFile.fileEntry, irFile.packageFragmentDescriptor) + val fileClassDescriptor = context.descriptorsFactory.createFileClassDescriptor(irFile.fileEntry, irFile.packageFragmentDescriptor) val irFileClass = IrClassImpl(0, irFile.fileEntry.maxOffset, IrDeclarationOrigin.DEFINED, fileClassDescriptor, fileClassMembers) classes.add(irFileClass) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ObjectClassLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ObjectClassLowering.kt index 1cac5da3eed..3366d61b003 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ObjectClassLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ObjectClassLowering.kt @@ -53,7 +53,7 @@ class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformer private fun process(irClass: IrClass) { if (irClass.descriptor.kind != ClassKind.OBJECT) return - val publicInstanceDescriptor = context.specialDescriptorsFactory.getFieldDescriptorForObjectInstance(irClass.descriptor) + val publicInstanceDescriptor = context.descriptorsFactory.getFieldDescriptorForObjectInstance(irClass.descriptor) val constructor = irClass.descriptor.unsubstitutedPrimaryConstructor ?: throw AssertionError("Object should have a primary constructor: ${irClass.descriptor}") 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 4a74b63ce10..8925a70e758 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,12 +32,12 @@ class SingletonReferencesLowering(val context: JvmBackendContext) : BodyLowering } override fun visitGetEnumValue(expression: IrGetEnumValue): IrExpression { - val enumValueFieldDescriptor = context.specialDescriptorsFactory.getFieldDescriptorForEnumEntry(expression.descriptor) + val enumValueFieldDescriptor = context.descriptorsFactory.getFieldDescriptorForEnumEntry(expression.descriptor) return IrGetFieldImpl(expression.startOffset, expression.endOffset, enumValueFieldDescriptor) } override fun visitGetObjectValue(expression: IrGetObjectValue): IrExpression { - val instanceFieldDescriptor = context.specialDescriptorsFactory.getFieldDescriptorForObjectInstance(expression.descriptor) + val instanceFieldDescriptor = context.descriptorsFactory.getFieldDescriptorForObjectInstance(expression.descriptor) return IrGetFieldImpl(expression.startOffset, expression.endOffset, instanceFieldDescriptor) } } \ No newline at end of file