Removed KProperty creation from each call of delegated property.
This commit is contained in:
+58
@@ -1,10 +1,21 @@
|
||||
package org.jetbrains.kotlin.backend.konan.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import java.io.StringWriter
|
||||
|
||||
|
||||
@@ -76,3 +87,50 @@ fun ir2stringWhole(ir: IrElement?): String {
|
||||
return strWriter.toString()
|
||||
}
|
||||
|
||||
internal fun ClassDescriptor.createSimpleDelegatingConstructor(superConstructorDescriptor: ClassConstructorDescriptor)
|
||||
: Pair<ClassConstructorDescriptor, IrConstructor> {
|
||||
val constructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
|
||||
this,
|
||||
Annotations.EMPTY,
|
||||
superConstructorDescriptor.isPrimary,
|
||||
SourceElement.NO_SOURCE)
|
||||
val valueParameters = superConstructorDescriptor.valueParameters.map {
|
||||
it.copy(constructorDescriptor, it.name, it.index)
|
||||
}
|
||||
constructorDescriptor.initialize(valueParameters, superConstructorDescriptor.visibility)
|
||||
constructorDescriptor.returnType = superConstructorDescriptor.returnType
|
||||
|
||||
val body = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
listOf(
|
||||
IrDelegatingConstructorCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, superConstructorDescriptor).apply {
|
||||
valueParameters.forEachIndexed { idx, parameter ->
|
||||
putValueArgument(idx, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, parameter))
|
||||
}
|
||||
},
|
||||
IrInstanceInitializerCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, this)
|
||||
)
|
||||
)
|
||||
val constructor = IrConstructorImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.DEFINED, constructorDescriptor, body)
|
||||
|
||||
return Pair(constructorDescriptor, constructor)
|
||||
}
|
||||
|
||||
internal fun Context.createArrayOfExpression(arrayElementType: KotlinType,
|
||||
arrayElements: List<IrExpression>): IrExpression {
|
||||
val kotlinPackage = irModule!!.descriptor.getPackage(FqName("kotlin"))
|
||||
val genericArrayOfFun = kotlinPackage.memberScope.getContributedFunctions(Name.identifier("arrayOf"), NoLookupLocation.FROM_BACKEND).first()
|
||||
val typeParameter0 = genericArrayOfFun.typeParameters[0]
|
||||
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameter0.typeConstructor to TypeProjectionImpl(arrayElementType)))
|
||||
val substitutedArrayOfFun = genericArrayOfFun.substitute(typeSubstitutor)!!
|
||||
|
||||
val typeArguments = mapOf(typeParameter0 to arrayElementType)
|
||||
|
||||
val valueParameter0 = substitutedArrayOfFun.valueParameters[0]
|
||||
val arg0VarargType = valueParameter0.type
|
||||
val arg0VarargElementType = valueParameter0.varargElementType!!
|
||||
val arg0 = IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, arg0VarargType, arg0VarargElementType, arrayElements)
|
||||
|
||||
return IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, substitutedArrayOfFun, typeArguments).apply {
|
||||
putValueArgument(0, arg0)
|
||||
}
|
||||
}
|
||||
+63
-13
@@ -2,13 +2,20 @@ package org.jetbrains.kotlin.backend.konan.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.jvm.descriptors.initialize
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.OverriddenFunctionDescriptor
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
|
||||
import org.jetbrains.kotlin.backend.konan.ir.createArrayOfExpression
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
@@ -18,9 +25,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.*
|
||||
|
||||
internal class ClassDelegationLowering(val context: Context) : DeclarationContainerLoweringPass {
|
||||
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
|
||||
@@ -89,7 +94,35 @@ internal class ClassDelegationLowering(val context: Context) : DeclarationContai
|
||||
}
|
||||
|
||||
internal class PropertyDelegationLowering(val context: Context) : FileLoweringPass {
|
||||
private val kotlinReflectPackage = context.irModule!!.descriptor.getPackage(FqName.fromSegments(listOf("kotlin", "reflect")))
|
||||
private val genericKPropertyImplType = kotlinReflectPackage.memberScope.getContributedClassifier(Name.identifier("KPropertyImpl"),
|
||||
NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
||||
|
||||
private val kotlinPackage = context.irModule!!.descriptor.getPackage(FqName("kotlin"))
|
||||
private val genericArrayType = kotlinPackage.memberScope.getContributedClassifier(Name.identifier("Array"), NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
||||
|
||||
fun getKPropertyImplConstructorDescriptorWithProjection(type: KotlinType): ClassConstructorDescriptor {
|
||||
val typeParameterT = genericKPropertyImplType.declaredTypeParameters[0]
|
||||
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameterT.typeConstructor to TypeProjectionImpl(type)))
|
||||
return genericKPropertyImplType.unsubstitutedPrimaryConstructor!!.substitute(typeSubstitutor)!!
|
||||
}
|
||||
|
||||
fun ClassDescriptor.replace(vararg type: KotlinType): SimpleType {
|
||||
return this.defaultType.replace(type.map(::TypeProjectionImpl))
|
||||
}
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
val kProperties = mutableListOf<IrExpression>()
|
||||
|
||||
val getter = genericArrayType.unsubstitutedMemberScope.getContributedFunctions(Name.identifier("get"), NoLookupLocation.FROM_BACKEND).single()
|
||||
val typeParameterT = genericArrayType.declaredTypeParameters[0]
|
||||
val kPropertyImplType = genericKPropertyImplType.replace(context.builtIns.anyType)
|
||||
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameterT.typeConstructor to TypeProjectionImpl(kPropertyImplType)))
|
||||
val substitutedGetter = getter.substitute(typeSubstitutor)!!
|
||||
|
||||
val kPropertiesField = createKPropertiesFieldDescriptor(irFile.packageFragmentDescriptor, genericArrayType.replace(kPropertyImplType))
|
||||
|
||||
|
||||
irFile.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||
return super.visitFunction(declaration)
|
||||
@@ -124,26 +157,43 @@ internal class PropertyDelegationLowering(val context: Context) : FileLoweringPa
|
||||
return declaration
|
||||
}
|
||||
|
||||
private val kotlinPackage = context.irModule!!.descriptor.getPackage(FqName.fromSegments(listOf("kotlin", "reflect")))
|
||||
private val genericKPropertyImplType = kotlinPackage.memberScope.getContributedClassifier(Name.identifier("KPropertyImpl"),
|
||||
NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
||||
|
||||
private fun transformBridgeToDelegate(name: String, type: KotlinType, irFunction: IrFunction?): IrFunction? {
|
||||
irFunction?.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
override fun visitCallableReference(expression: IrCallableReference): IrExpression {
|
||||
val typeParameterT = genericKPropertyImplType.declaredTypeParameters[0]
|
||||
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameterT.typeConstructor to TypeProjectionImpl(type)))
|
||||
val kPropertyImplType = genericKPropertyImplType.substitute(typeSubstitutor)
|
||||
return IrCallImpl(expression.startOffset, expression.endOffset,
|
||||
kPropertyImplType.defaultType, kPropertyImplType.unsubstitutedPrimaryConstructor!!, null).apply {
|
||||
putValueArgument(0, IrConstImpl<String>(expression.startOffset, expression.endOffset,
|
||||
val fieldInitializer = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
getKPropertyImplConstructorDescriptorWithProjection(type)).apply {
|
||||
putValueArgument(0, IrConstImpl<String>(UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
context.builtIns.stringType, IrConstKind.String, name))
|
||||
}
|
||||
|
||||
val index = kProperties.size
|
||||
kProperties.add(fieldInitializer)
|
||||
|
||||
return IrCallImpl(expression.startOffset, expression.endOffset, substitutedGetter).apply {
|
||||
dispatchReceiver = IrGetFieldImpl(expression.startOffset, expression.endOffset, kPropertiesField)
|
||||
putValueArgument(0, IrConstImpl.int(startOffset, endOffset, context.builtIns.intType, index))
|
||||
}
|
||||
}
|
||||
})
|
||||
return irFunction
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
irFile.declarations.add(0, IrFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION,
|
||||
kPropertiesField,
|
||||
IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
context.createArrayOfExpression(kPropertyImplType, kProperties))))
|
||||
}
|
||||
|
||||
private object DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION :
|
||||
IrDeclarationOriginImpl("KPROPERTIES_FOR_DELEGATION")
|
||||
|
||||
private fun createKPropertiesFieldDescriptor(containingDeclaration: DeclarationDescriptor, fieldType: SimpleType): PropertyDescriptorImpl {
|
||||
return PropertyDescriptorImpl.create(containingDeclaration, Annotations.EMPTY, Modality.FINAL, Visibilities.PRIVATE,
|
||||
false, "KPROPERTIES".synthesizedName, CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE,
|
||||
false, false, false, false, false, false).initialize(fieldType)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-50
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.backend.konan.KonanPlatform
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.getKonanInternalFunctions
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
|
||||
import org.jetbrains.kotlin.backend.konan.ir.createArrayOfExpression
|
||||
import org.jetbrains.kotlin.backend.konan.ir.createSimpleDelegatingConstructor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||
@@ -171,7 +173,7 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
|
||||
descriptor.constructors.forEach {
|
||||
val loweredEnumConstructor = loweredEnumConstructors[it]!!
|
||||
val (constructorDescriptor, constructor) = createSimpleDelegatingConstructor(defaultClassDescriptor, loweredEnumConstructor)
|
||||
val (constructorDescriptor, constructor) = defaultClassDescriptor.createSimpleDelegatingConstructor(loweredEnumConstructor)
|
||||
constructors.add(constructorDescriptor)
|
||||
defaultClass.declarations.add(constructor)
|
||||
defaultEnumEntryConstructors.put(loweredEnumConstructor, constructorDescriptor)
|
||||
@@ -233,7 +235,7 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
val memberScope = MemberScope.Empty
|
||||
|
||||
val constructorOfAny = irClass.descriptor.module.builtIns.any.constructors.first()
|
||||
val (constructorDescriptor, constructor) = createSimpleDelegatingConstructor(implObjectDescriptor, constructorOfAny)
|
||||
val (constructorDescriptor, constructor) = implObjectDescriptor.createSimpleDelegatingConstructor(constructorOfAny)
|
||||
|
||||
implObjectDescriptor.initialize(memberScope, setOf(constructorDescriptor), constructorDescriptor)
|
||||
|
||||
@@ -260,34 +262,6 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
return newDescriptor
|
||||
}
|
||||
|
||||
private fun createSimpleDelegatingConstructor(classDescriptor: ClassDescriptor,
|
||||
superConstructorDescriptor: ClassConstructorDescriptor)
|
||||
: Pair<ClassConstructorDescriptor, IrConstructor> {
|
||||
val constructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
|
||||
classDescriptor,
|
||||
Annotations.EMPTY,
|
||||
superConstructorDescriptor.isPrimary,
|
||||
SourceElement.NO_SOURCE)
|
||||
val valueParameters = superConstructorDescriptor.valueParameters.map {
|
||||
it.copy(constructorDescriptor, it.name, it.index)
|
||||
}
|
||||
constructorDescriptor.initialize(valueParameters, superConstructorDescriptor.visibility)
|
||||
constructorDescriptor.returnType = superConstructorDescriptor.returnType
|
||||
|
||||
val body = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
listOf(
|
||||
IrDelegatingConstructorCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, superConstructorDescriptor).apply {
|
||||
valueParameters.forEachIndexed { idx, parameter ->
|
||||
putValueArgument(idx, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, parameter))
|
||||
}
|
||||
},
|
||||
IrInstanceInitializerCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, classDescriptor)
|
||||
)
|
||||
)
|
||||
val constructor = IrConstructorImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.DEFINED, constructorDescriptor, body)
|
||||
return Pair(constructorDescriptor, constructor)
|
||||
}
|
||||
|
||||
private fun createSyntheticValuesFieldDeclaration(implObjectDescriptor: ClassDescriptor,
|
||||
enumEntries: List<IrEnumEntry>): IrFieldImpl {
|
||||
val valuesArrayType = context.builtIns.getArrayType(Variance.INVARIANT, irClass.descriptor.defaultType)
|
||||
@@ -304,7 +278,7 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
val loweredEnumEntry = LoweredEnumEntry(implObjectDescriptor, valuesFieldDescriptor, substitutedValueOf, entriesMap)
|
||||
loweredEnumEntries.put(irClass.descriptor, loweredEnumEntry)
|
||||
|
||||
val irValuesInitializer = createArrayOfExpression(irClass.descriptor.defaultType, enumEntries.map { it.initializerExpression })
|
||||
val irValuesInitializer = context.createArrayOfExpression(irClass.descriptor.defaultType, enumEntries.map { it.initializerExpression })
|
||||
|
||||
val irField = IrFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.DEFINED,
|
||||
valuesFieldDescriptor,
|
||||
@@ -321,31 +295,12 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
|
||||
private val kotlinPackage = context.irModule!!.descriptor.getPackage(FqName("kotlin"))
|
||||
|
||||
private val genericArrayOfFun = kotlinPackage.memberScope.getContributedFunctions(Name.identifier("arrayOf"), NoLookupLocation.FROM_BACKEND).first()
|
||||
|
||||
private val genericValueOfFun = context.builtIns.getKonanInternalFunctions("valueOfForEnum").single()
|
||||
|
||||
private val genericValuesFun = context.builtIns.getKonanInternalFunctions("valuesForEnum").single()
|
||||
|
||||
private val genericArrayType = kotlinPackage.memberScope.getContributedClassifier(Name.identifier("Array"), NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
||||
|
||||
private fun createArrayOfExpression(arrayElementType: KotlinType, arrayElements: List<IrExpression>): IrExpression {
|
||||
val typeParameter0 = genericArrayOfFun.typeParameters[0]
|
||||
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameter0.typeConstructor to TypeProjectionImpl(arrayElementType)))
|
||||
val substitutedArrayOfFun = genericArrayOfFun.substitute(typeSubstitutor)!!
|
||||
|
||||
val typeArguments = mapOf(typeParameter0 to arrayElementType)
|
||||
|
||||
val valueParameter0 = substitutedArrayOfFun.valueParameters[0]
|
||||
val arg0VarargType = valueParameter0.type
|
||||
val arg0VarargElementType = valueParameter0.varargElementType!!
|
||||
val arg0 = IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, arg0VarargType, arg0VarargElementType, arrayElements)
|
||||
|
||||
return IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, substitutedArrayOfFun, typeArguments).apply {
|
||||
putValueArgument(0, arg0)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createSyntheticValuesMethodDeclaration(companionObjectDescriptor: ClassDescriptor): IrFunction {
|
||||
val typeParameterT = genericValuesFun.typeParameters[0]
|
||||
val enumClassType = irClass.descriptor.defaultType
|
||||
|
||||
Reference in New Issue
Block a user