IrConstructorCall support in JVM_IR, JS_IR, and FIR2IR

This commit is contained in:
Dmitry Petrov
2019-03-26 17:25:00 +03:00
parent 82128800c5
commit b78d1bb2b9
287 changed files with 9008 additions and 8128 deletions
@@ -59,14 +59,19 @@ interface IrBuilderExtension {
val BackendContext.localSymbolTable: SymbolTable
private fun IrClass.declareSimpleFunctionWithExternalOverrides(descriptor: FunctionDescriptor): IrSimpleFunction {
return compilerContext.localSymbolTable.declareSimpleFunction(startOffset, endOffset, SERIALIZABLE_PLUGIN_ORIGIN, descriptor).also {f ->
descriptor.overriddenDescriptors.mapTo(f.overriddenSymbols) {
compilerContext.externalSymbols.referenceSimpleFunction(it.original)
return compilerContext.localSymbolTable.declareSimpleFunction(startOffset, endOffset, SERIALIZABLE_PLUGIN_ORIGIN, descriptor)
.also { f ->
descriptor.overriddenDescriptors.mapTo(f.overriddenSymbols) {
compilerContext.externalSymbols.referenceSimpleFunction(it.original)
}
}
}
}
fun IrClass.contributeFunction(descriptor: FunctionDescriptor, fromStubs: Boolean = false, bodyGen: IrBlockBodyBuilder.(IrFunction) -> Unit) {
fun IrClass.contributeFunction(
descriptor: FunctionDescriptor,
fromStubs: Boolean = false,
bodyGen: IrBlockBodyBuilder.(IrFunction) -> Unit
) {
val f: IrSimpleFunction = if (!fromStubs) declareSimpleFunctionWithExternalOverrides(
descriptor
) else compilerContext.externalSymbols.referenceSimpleFunction(descriptor).owner
@@ -104,7 +109,7 @@ interface IrBuilderExtension {
callee: IrFunctionSymbol,
vararg args: IrExpression,
typeHint: IrType? = null
): IrCall {
): IrMemberAccessExpression {
val call = typeHint?.let { irCall(callee, type = it) } ?: irCall(callee)
call.dispatchReceiver = dispatchReceiver
args.forEachIndexed(call::putValueArgument)
@@ -117,16 +122,17 @@ interface IrBuilderExtension {
typeArguments: List<IrType?>,
valueArguments: List<IrExpression>,
returnTypeHint: IrType? = null
): IrCall = irInvoke(
dispatchReceiver,
callee,
args = *valueArguments.toTypedArray(),
typeHint = returnTypeHint
).also { call -> typeArguments.forEachIndexed(call::putTypeArgument) }
): IrMemberAccessExpression =
irInvoke(
dispatchReceiver,
callee,
args = *valueArguments.toTypedArray(),
typeHint = returnTypeHint
).also { call -> typeArguments.forEachIndexed(call::putTypeArgument) }
fun IrBuilderWithScope.createArrayOfExpression(
arrayElementType: IrType,
arrayElements: List<IrExpression>
arrayElementType: IrType,
arrayElements: List<IrExpression>
): IrExpression {
val arrayType = compilerContext.ir.symbols.array.typeWith(arrayElementType)
@@ -389,7 +395,8 @@ interface IrBuilderExtension {
fun IrBuilderWithScope.classReference(classType: KotlinType): IrClassReference {
val clazz = classType.toClassDescriptor!!
val kClass = clazz.module.findClassAcrossModuleDependencies(ClassId(FqName("kotlin.reflect"), Name.identifier("KClass")))!!
val returnType = KotlinTypeFactory.simpleNotNullType(Annotations.EMPTY, kClass, listOf(TypeProjectionImpl(Variance.INVARIANT, classType)))
val returnType =
KotlinTypeFactory.simpleNotNullType(Annotations.EMPTY, kClass, listOf(TypeProjectionImpl(Variance.INVARIANT, classType)))
return IrClassReferenceImpl(
startOffset,
endOffset,
@@ -432,25 +439,43 @@ interface IrBuilderExtension {
}
// Does not use sti and therefore does not perform encoder calls optimization
fun IrBuilderWithScope.serializerTower(generator: SerializerIrGenerator, dispatchReceiverParameter: IrValueParameter, property: SerializableProperty): IrExpression? {
fun IrBuilderWithScope.serializerTower(
generator: SerializerIrGenerator,
dispatchReceiverParameter: IrValueParameter,
property: SerializableProperty
): IrExpression? {
val nullableSerClass =
compilerContext.externalSymbols.referenceClass(property.module.getClassFromInternalSerializationPackage(SpecialBuiltins.nullableSerializer))
compilerContext.externalSymbols.referenceClass(property.module.getClassFromInternalSerializationPackage(SpecialBuiltins.nullableSerializer))
val serializer =
property.serializableWith?.toClassDescriptor
?: if (!property.type.isTypeParameter()) generator.findTypeSerializerOrContext(
property.module,
property.type,
property.descriptor.annotations,
property.descriptor.findPsi()
) else null
return serializerInstance(generator, dispatchReceiverParameter, generator.serializableDescriptor, serializer, property.module, property.type, genericIndex = property.genericIndex)
?.let { expr -> wrapWithNullableSerializerIfNeeded(property.module, property.type, expr, nullableSerClass) }
property.serializableWith?.toClassDescriptor
?: if (!property.type.isTypeParameter()) generator.findTypeSerializerOrContext(
property.module,
property.type,
property.descriptor.annotations,
property.descriptor.findPsi()
) else null
return serializerInstance(
generator,
dispatchReceiverParameter,
generator.serializableDescriptor,
serializer,
property.module,
property.type,
genericIndex = property.genericIndex
)
?.let { expr -> wrapWithNullableSerializerIfNeeded(property.module, property.type, expr, nullableSerClass) }
}
private fun IrBuilderWithScope.wrapWithNullableSerializerIfNeeded(module: ModuleDescriptor, type: KotlinType, expression: IrExpression, nullableSerializerClass: IrClassSymbol): IrExpression {
private fun IrBuilderWithScope.wrapWithNullableSerializerIfNeeded(
module: ModuleDescriptor,
type: KotlinType,
expression: IrExpression,
nullableSerializerClass: IrClassSymbol
): IrExpression {
return if (type.isMarkedNullable)
irInvoke(null, nullableSerializerClass.constructors.toList()[0],
typeArguments = listOf(type.makeNotNullable().toIrType()),
irInvoke(
null, nullableSerializerClass.constructors.toList()[0],
typeArguments = listOf(type.makeNotNullable().toIrType()),
valueArguments = listOf(expression),
returnTypeHint = wrapIrTypeIntoKSerializerIrType(module, type.toIrType())
)
@@ -513,8 +538,20 @@ interface IrBuilderExtension {
}
else -> {
args = kType.arguments.map {
val argSer = enclosingGenerator.findTypeSerializerOrContext(module, it.type, sourceElement = serializerClassOriginal.findPsi())
val expr = serializerInstance(enclosingGenerator, dispatchReceiverParameter, serializableDescriptor, argSer, module, it.type, it.type.genericIndex)
val argSer = enclosingGenerator.findTypeSerializerOrContext(
module,
it.type,
sourceElement = serializerClassOriginal.findPsi()
)
val expr = serializerInstance(
enclosingGenerator,
dispatchReceiverParameter,
serializableDescriptor,
argSer,
module,
it.type,
it.type.genericIndex
)
?: return null
wrapWithNullableSerializerIfNeeded(module, it.type, expr, nullableSerClass)
}
@@ -132,7 +132,7 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
}
private fun IrBlockBodyBuilder.copySerialInfoAnnotationsToDescriptor(
annotations: List<IrCall>,
annotations: List<IrConstructorCall>,
receiver: IrExpression,
method: IrFunctionSymbol
) {