Lift InnerClassesLowering from JVM to common since it is used by every backend in the same way

This commit is contained in:
Roman Artemev
2018-04-18 22:25:23 +03:00
parent ed0c26ef07
commit c1a4aeb67f
12 changed files with 247 additions and 59 deletions
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.backend.common 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.backend.common.descriptors.SharedVariablesManager
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
@@ -24,4 +25,5 @@ interface BackendContext {
val builtIns: KotlinBuiltIns val builtIns: KotlinBuiltIns
val irBuiltIns: IrBuiltIns val irBuiltIns: IrBuiltIns
val sharedVariablesManager: SharedVariablesManager val sharedVariablesManager: SharedVariablesManager
val descriptorsFactory: DescriptorsFactory
} }
@@ -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
}
@@ -1,31 +1,22 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * 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.
* 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.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.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.ClassLoweringPass 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.descriptors.*
import org.jetbrains.kotlin.ir.IrStatement 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.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor 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.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl 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.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.util.dump 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 org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
import java.util.* 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) { override fun lower(irClass: IrClass) {
InnerClassTransformer(irClass).lowerInnerClass() InnerClassTransformer(irClass).lowerInnerClass()
} }
@@ -57,12 +50,12 @@ class InnerClassesLowering(val context: JvmBackendContext) : ClassLoweringPass {
} }
private fun createOuterThisField() { private fun createOuterThisField() {
outerThisFieldDescriptor = context.specialDescriptorsFactory.getOuterThisFieldDescriptor(irClass.descriptor) outerThisFieldDescriptor = context.descriptorsFactory.getOuterThisFieldDescriptor(irClass.descriptor)
irClass.declarations.add(IrFieldImpl( irClass.declarations.add(IrFieldImpl(
irClass.startOffset, irClass.endOffset, irClass.startOffset, irClass.endOffset,
JvmLoweredDeclarationOrigin.FIELD_FOR_OUTER_THIS, FIELD_FOR_OUTER_THIS,
outerThisFieldDescriptor outerThisFieldDescriptor
)) ))
} }
@@ -80,7 +73,7 @@ class InnerClassesLowering(val context: JvmBackendContext) : ClassLoweringPass {
val startOffset = irConstructor.startOffset val startOffset = irConstructor.startOffset
val endOffset = irConstructor.endOffset val endOffset = irConstructor.endOffset
val newDescriptor = context.specialDescriptorsFactory.getInnerClassConstructorWithOuterThisParameter(oldDescriptor) val newDescriptor = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(oldDescriptor)
val outerThisValueParameter = newDescriptor.valueParameters[0] val outerThisValueParameter = newDescriptor.valueParameters[0]
oldDescriptor.valueParameters.forEach { oldValueParameter -> oldDescriptor.valueParameters.forEach { oldValueParameter ->
@@ -116,7 +109,17 @@ class InnerClassesLowering(val context: JvmBackendContext) : ClassLoweringPass {
irConstructor.origin, // TODO special origin for lowered inner class constructors? irConstructor.origin, // TODO special origin for lowered inner class constructors?
newDescriptor, newDescriptor,
blockBody 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() { private fun lowerConstructorParameterUsages() {
@@ -153,7 +156,7 @@ class InnerClassesLowering(val context: JvmBackendContext) : ClassLoweringPass {
return expression return expression
} }
val outerThisField = context.specialDescriptorsFactory.getOuterThisFieldDescriptor(innerClass) val outerThisField = context.descriptorsFactory.getOuterThisFieldDescriptor(innerClass)
irThis = IrGetFieldImpl(startOffset, endOffset, outerThisField, irThis, origin) irThis = IrGetFieldImpl(startOffset, endOffset, outerThisField, irThis, origin)
val outer = classDescriptor.containingDeclaration 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) { override fun lower(irBody: IrBody) {
irBody.transformChildrenVoid(object : IrElementTransformerVoid() { irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitCall(expression: IrCall): IrExpression { override fun visitCall(expression: IrCall): IrExpression {
@@ -188,7 +191,7 @@ class InnerClassConstructorCallsLowering(val context: JvmBackendContext) : BodyL
val callee = expression.descriptor as? ClassConstructorDescriptor ?: return expression val callee = expression.descriptor as? ClassConstructorDescriptor ?: return expression
if (!callee.constructedClass.isInner) return expression if (!callee.constructedClass.isInner) return expression
val newCallee = context.specialDescriptorsFactory.getInnerClassConstructorWithOuterThisParameter(callee) val newCallee = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(callee)
val newCall = IrCallImpl( val newCall = IrCallImpl(
expression.startOffset, expression.endOffset, newCallee, expression.startOffset, expression.endOffset, newCallee,
null, // TODO type arguments map null, // TODO type arguments map
@@ -210,7 +213,7 @@ class InnerClassConstructorCallsLowering(val context: JvmBackendContext) : BodyL
val callee = expression.descriptor val callee = expression.descriptor
if (!callee.constructedClass.isInner) return expression if (!callee.constructedClass.isInner) return expression
val newCallee = context.specialDescriptorsFactory.getInnerClassConstructorWithOuterThisParameter(callee) val newCallee = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(callee)
val newCall = IrDelegatingConstructorCallImpl( val newCall = IrDelegatingConstructorCallImpl(
expression.startOffset, expression.endOffset, newCallee, expression.startOffset, expression.endOffset, newCallee,
null // TODO type arguments map null // TODO type arguments map
@@ -26,10 +26,7 @@ import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall import org.jetbrains.kotlin.ir.expressions.*
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.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
@@ -58,6 +55,20 @@ class DeclarationIrBuilder(
endOffset 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<ValueDescriptor, ValueDescriptor>) : AbstractVariableRemapper() {
override fun remapVariable(value: ValueDescriptor): ValueDescriptor? =
mapping[value]
}
fun BackendContext.createIrBuilder(symbol: IrSymbol, fun BackendContext.createIrBuilder(symbol: IrSymbol,
startOffset: Int = UNDEFINED_OFFSET, startOffset: Int = UNDEFINED_OFFSET,
endOffset: Int = UNDEFINED_OFFSET) = endOffset: Int = UNDEFINED_OFFSET) =
@@ -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.descriptors.KnownPackageFragmentDescriptor
import org.jetbrains.kotlin.backend.common.ir.Ir import org.jetbrains.kotlin.backend.common.ir.Ir
import org.jetbrains.kotlin.backend.common.ir.Symbols import org.jetbrains.kotlin.backend.common.ir.Symbols
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.backend.js.JsSpecialDescriptorsFactory
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol 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.ir.util.SymbolTable
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.KotlinTypeFactory
import org.jetbrains.kotlin.types.Variance
class JsIrBackendContext( class JsIrBackendContext(
val module: ModuleDescriptor, val module: ModuleDescriptor,
@@ -45,6 +40,7 @@ class JsIrBackendContext(
override val builtIns = module.builtIns override val builtIns = module.builtIns
override val sharedVariablesManager = override val sharedVariablesManager =
JsSharedVariablesManager(builtIns, KnownPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.js.internal"))) JsSharedVariablesManager(builtIns, KnownPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.js.internal")))
override val descriptorsFactory = JsSpecialDescriptorsFactory(builtIns)
override val reflectionTypes: ReflectionTypes by lazy(LazyThreadSafetyMode.PUBLICATION) { override val reflectionTypes: ReflectionTypes by lazy(LazyThreadSafetyMode.PUBLICATION) {
// TODO // TODO
@@ -129,5 +125,4 @@ class JsIrBackendContext(
/*TODO*/ /*TODO*/
print(message) print(message)
} }
}
}
@@ -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<ClassDescriptor, PropertyDescriptor>()
private val outerThisDescriptors = HashMap<ClassDescriptor, PropertyDescriptor>()
private val innerClassConstructors = HashMap<ClassConstructorDescriptor, ClassConstructorDescriptor>()
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)
}
}
}
@@ -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.Ir
import org.jetbrains.kotlin.backend.common.ir.Symbols import org.jetbrains.kotlin.backend.common.ir.Symbols
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmSharedVariablesManager 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.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor 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.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol 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.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -46,7 +45,7 @@ class JvmBackendContext(
irModuleFragment: IrModuleFragment, symbolTable: SymbolTable irModuleFragment: IrModuleFragment, symbolTable: SymbolTable
) : CommonBackendContext { ) : CommonBackendContext {
override val builtIns = state.module.builtIns 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 sharedVariablesManager = JvmSharedVariablesManager(builtIns)
override val reflectionTypes: ReflectionTypes by lazy(LazyThreadSafetyMode.PUBLICATION) { override val reflectionTypes: ReflectionTypes by lazy(LazyThreadSafetyMode.PUBLICATION) {
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.backend.jvm.descriptors 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.CompanionObjectMapping.isMappedIntrinsicCompanionObject
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.codegen.descriptors.FileClassDescriptor 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 org.jetbrains.org.objectweb.asm.Opcodes
import java.util.* import java.util.*
class SpecialDescriptorsFactory( class JvmSpecialDescriptorsFactory(
private val psiSourceManager: PsiSourceManager, private val psiSourceManager: PsiSourceManager,
private val builtIns: KotlinBuiltIns private val builtIns: KotlinBuiltIns
) { ) : DescriptorsFactory {
private val singletonFieldDescriptors = HashMap<ClassDescriptor, PropertyDescriptor>() private val singletonFieldDescriptors = HashMap<ClassDescriptor, PropertyDescriptor>()
private val outerThisDescriptors = HashMap<ClassDescriptor, PropertyDescriptor>() private val outerThisDescriptors = HashMap<ClassDescriptor, PropertyDescriptor>()
private val innerClassConstructors = HashMap<ClassConstructorDescriptor, ClassConstructorDescriptor>() private val innerClassConstructors = HashMap<ClassConstructorDescriptor, ClassConstructorDescriptor>()
fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor = override fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor =
singletonFieldDescriptors.getOrPut(enumEntryDescriptor) { singletonFieldDescriptors.getOrPut(enumEntryDescriptor) {
createEnumEntryFieldDescriptor(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") if (!innerClassDescriptor.isInner) throw AssertionError("Class is not inner: $innerClassDescriptor")
else outerThisDescriptors.getOrPut(innerClassDescriptor) { else outerThisDescriptors.getOrPut(innerClassDescriptor) {
val outerClassDescriptor = DescriptorUtils.getContainingClass(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 val innerClass = innerClassConstructor.containingDeclaration
assert(innerClass.isInner) { "Class is not inner: $innerClass" } 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) { singletonFieldDescriptors.getOrPut(objectDescriptor) {
createObjectInstanceFieldDescriptor(objectDescriptor) createObjectInstanceFieldDescriptor(objectDescriptor)
} }
@@ -181,7 +181,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
} }
private fun createFieldForEnumEntry(enumEntry: IrEnumEntry): IrField { private fun createFieldForEnumEntry(enumEntry: IrEnumEntry): IrField {
val fieldPropertyDescriptor = context.specialDescriptorsFactory.getFieldDescriptorForEnumEntry(enumEntry.descriptor) val fieldPropertyDescriptor = context.descriptorsFactory.getFieldDescriptorForEnumEntry(enumEntry.descriptor)
enumEntriesByField[fieldPropertyDescriptor] = enumEntry.descriptor enumEntriesByField[fieldPropertyDescriptor] = enumEntry.descriptor
enumEntryFields.add(fieldPropertyDescriptor) enumEntryFields.add(fieldPropertyDescriptor)
@@ -39,7 +39,7 @@ class FileClassLowering(val context: JvmBackendContext) : FileLoweringPass {
if (fileClassMembers.isEmpty()) return 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) val irFileClass = IrClassImpl(0, irFile.fileEntry.maxOffset, IrDeclarationOrigin.DEFINED, fileClassDescriptor, fileClassMembers)
classes.add(irFileClass) classes.add(irFileClass)
@@ -53,7 +53,7 @@ class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformer
private fun process(irClass: IrClass) { private fun process(irClass: IrClass) {
if (irClass.descriptor.kind != ClassKind.OBJECT) return 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 ?: val constructor = irClass.descriptor.unsubstitutedPrimaryConstructor ?:
throw AssertionError("Object should have a primary constructor: ${irClass.descriptor}") throw AssertionError("Object should have a primary constructor: ${irClass.descriptor}")
@@ -32,12 +32,12 @@ class SingletonReferencesLowering(val context: JvmBackendContext) : BodyLowering
} }
override fun visitGetEnumValue(expression: IrGetEnumValue): IrExpression { 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) return IrGetFieldImpl(expression.startOffset, expression.endOffset, enumValueFieldDescriptor)
} }
override fun visitGetObjectValue(expression: IrGetObjectValue): IrExpression { 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) return IrGetFieldImpl(expression.startOffset, expression.endOffset, instanceFieldDescriptor)
} }
} }