Move out symbols that do not depend on a BackendContext to a separate BuiltinSymbolsBase class.

The goal was to be able to use such symbols before BackendContext is even created – in psi2ir postprocessing step (i.e., IR compiler plugins).

Remove old code from serialization ir plugin.
This commit is contained in:
Leonid Startsev
2019-11-18 16:52:45 +03:00
parent 3e18350a1f
commit 3d2800f99b
7 changed files with 93 additions and 122 deletions
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.backend.common.extensions package org.jetbrains.kotlin.backend.common.extensions
import org.jetbrains.kotlin.backend.common.ir.BuiltinSymbolsBase
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
@@ -21,8 +22,9 @@ class IrPluginContext(
val languageVersionSettings: LanguageVersionSettings, val languageVersionSettings: LanguageVersionSettings,
val symbolTable: SymbolTable, val symbolTable: SymbolTable,
val typeTranslator: TypeTranslator, val typeTranslator: TypeTranslator,
override val irBuiltIns: IrBuiltIns override val irBuiltIns: IrBuiltIns,
): IrGeneratorContext() val symbols: BuiltinSymbolsBase = BuiltinSymbolsBase(irBuiltIns.builtIns, symbolTable)
) : IrGeneratorContext()
interface IrGenerationExtension { interface IrGenerationExtension {
companion object : companion object :
@@ -44,16 +44,14 @@ abstract class Ir<out T : CommonBackendContext>(val context: T, val irModule: Ir
open fun shouldGenerateHandlerParameterForDefaultBodyFun() = false open fun shouldGenerateHandlerParameterForDefaultBodyFun() = false
} }
// Some symbols below are used in kotlin-native, so they can't be private /**
@Suppress("MemberVisibilityCanBePrivate", "PropertyName") * Symbols for builtins that are available without any context and are not specific to any backend
abstract class Symbols<out T : CommonBackendContext>(val context: T, private val symbolTable: ReferenceSymbolTable) { */
open class BuiltinSymbolsBase(protected val builtIns: KotlinBuiltIns, private val symbolTable: ReferenceSymbolTable) {
protected val builtIns
get() = context.builtIns
protected fun builtInsPackage(vararg packageNameSegments: String) = protected fun builtInsPackage(vararg packageNameSegments: String) =
context.builtIns.builtInsModule.getPackage(FqName.fromSegments(listOf(*packageNameSegments))).memberScope builtIns.builtInsModule.getPackage(FqName.fromSegments(listOf(*packageNameSegments))).memberScope
// consider making this public so it can be used to easily locate stdlib functions from any place (in particular, plugins and lowerings)
private fun getSimpleFunction( private fun getSimpleFunction(
name: Name, name: Name,
vararg packageNameSegments: String = arrayOf("kotlin"), vararg packageNameSegments: String = arrayOf("kotlin"),
@@ -75,16 +73,6 @@ abstract class Symbols<out T : CommonBackendContext>(val context: T, private val
open val externalSymbolTable: ReferenceSymbolTable open val externalSymbolTable: ReferenceSymbolTable
get() = symbolTable get() = symbolTable
abstract val ThrowNullPointerException: IrFunctionSymbol
abstract val ThrowNoWhenBranchMatchedException: IrFunctionSymbol
abstract val ThrowTypeCastException: IrFunctionSymbol
abstract val ThrowUninitializedPropertyAccessException: IrSimpleFunctionSymbol
abstract val stringBuilder: IrClassSymbol
abstract val defaultConstructorMarker: IrClassSymbol
val iterator = getClass(Name.identifier("Iterator"), "kotlin", "collections") val iterator = getClass(Name.identifier("Iterator"), "kotlin", "collections")
val charSequence = getClass(Name.identifier("CharSequence"), "kotlin") val charSequence = getClass(Name.identifier("CharSequence"), "kotlin")
@@ -186,22 +174,6 @@ abstract class Symbols<out T : CommonBackendContext>(val context: T, private val
val mutableIterator = symbolTable.referenceClass(builtIns.mutableIterator) val mutableIterator = symbolTable.referenceClass(builtIns.mutableIterator)
val mutableListIterator = symbolTable.referenceClass(builtIns.mutableListIterator) val mutableListIterator = symbolTable.referenceClass(builtIns.mutableListIterator)
abstract val copyRangeTo: Map<ClassDescriptor, IrSimpleFunctionSymbol>
abstract val coroutineImpl: IrClassSymbol
abstract val coroutineSuspendedGetter: IrSimpleFunctionSymbol
abstract val getContinuation: IrSimpleFunctionSymbol
abstract val coroutineContextGetter: IrSimpleFunctionSymbol
abstract val suspendCoroutineUninterceptedOrReturn: IrSimpleFunctionSymbol
abstract val coroutineGetContext: IrSimpleFunctionSymbol
abstract val returnIfSuspended: IrSimpleFunctionSymbol
private val binaryOperatorCache = mutableMapOf<Triple<Name, KotlinType, KotlinType>, IrSimpleFunctionSymbol>() private val binaryOperatorCache = mutableMapOf<Triple<Name, KotlinType, KotlinType>, IrSimpleFunctionSymbol>()
fun getBinaryOperator(name: Name, lhsType: KotlinType, rhsType: KotlinType): IrSimpleFunctionSymbol { fun getBinaryOperator(name: Name, lhsType: KotlinType, rhsType: KotlinType): IrSimpleFunctionSymbol {
@@ -250,6 +222,37 @@ abstract class Symbols<out T : CommonBackendContext>(val context: T, private val
KotlinBuiltIns.isStringOrNullableString(it.extensionReceiverParameter!!.type) && it.valueParameters.size == 1 && KotlinBuiltIns.isStringOrNullableString(it.extensionReceiverParameter!!.type) && it.valueParameters.size == 1 &&
KotlinBuiltIns.isNullableAny(it.valueParameters.first().type) KotlinBuiltIns.isNullableAny(it.valueParameters.first().type)
} }
}
// Some symbols below are used in kotlin-native, so they can't be private
@Suppress("MemberVisibilityCanBePrivate", "PropertyName")
abstract class Symbols<out T : CommonBackendContext>(val context: T, symbolTable: ReferenceSymbolTable) :
BuiltinSymbolsBase(context.builtIns, symbolTable) {
abstract val ThrowNullPointerException: IrFunctionSymbol
abstract val ThrowNoWhenBranchMatchedException: IrFunctionSymbol
abstract val ThrowTypeCastException: IrFunctionSymbol
abstract val ThrowUninitializedPropertyAccessException: IrSimpleFunctionSymbol
abstract val stringBuilder: IrClassSymbol
abstract val defaultConstructorMarker: IrClassSymbol
abstract val copyRangeTo: Map<ClassDescriptor, IrSimpleFunctionSymbol>
abstract val coroutineImpl: IrClassSymbol
abstract val coroutineSuspendedGetter: IrSimpleFunctionSymbol
abstract val getContinuation: IrSimpleFunctionSymbol
abstract val coroutineContextGetter: IrSimpleFunctionSymbol
abstract val suspendCoroutineUninterceptedOrReturn: IrSimpleFunctionSymbol
abstract val coroutineGetContext: IrSimpleFunctionSymbol
abstract val returnIfSuspended: IrSimpleFunctionSymbol
companion object { companion object {
fun isLateinitIsInitializedPropertyGetter(symbol: IrFunctionSymbol): Boolean = fun isLateinitIsInitializedPropertyGetter(symbol: IrFunctionSymbol): Boolean =
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
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.declarations.impl.IrPropertyImpl import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
@@ -26,9 +25,7 @@ import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.ir.types.typeWith import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.components.isVararg
import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
@@ -41,18 +38,14 @@ import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.*
import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
import org.jetbrains.kotlinx.serialization.compiler.resolve.* import org.jetbrains.kotlinx.serialization.compiler.resolve.*
val SerializationPluginContext.externalSymbols: SymbolTable get() = symbolTable // Todo: deprecate and remove
val SerializationPluginContext.localSymbolTable: SymbolTable get() = symbolTable // Todo: deprecate and remove
interface IrBuilderExtension { interface IrBuilderExtension {
val compilerContext: SerializationPluginContext val compilerContext: SerializationPluginContext
val translator: TypeTranslator get() = compilerContext.typeTranslator // Todo: deprecate and remove
private fun IrClass.declareSimpleFunctionWithExternalOverrides(descriptor: FunctionDescriptor): IrSimpleFunction { private fun IrClass.declareSimpleFunctionWithExternalOverrides(descriptor: FunctionDescriptor): IrSimpleFunction {
return compilerContext.localSymbolTable.declareSimpleFunction(startOffset, endOffset, SERIALIZABLE_PLUGIN_ORIGIN, descriptor) return compilerContext.symbolTable.declareSimpleFunction(startOffset, endOffset, SERIALIZABLE_PLUGIN_ORIGIN, descriptor)
.also { f -> .also { f ->
descriptor.overriddenDescriptors.mapTo(f.overriddenSymbols) { descriptor.overriddenDescriptors.mapTo(f.overriddenSymbols) {
compilerContext.externalSymbols.referenceSimpleFunction(it.original) compilerContext.symbolTable.referenceSimpleFunction(it.original)
} }
} }
} }
@@ -64,7 +57,7 @@ interface IrBuilderExtension {
) { ) {
val f: IrSimpleFunction = if (declareNew) declareSimpleFunctionWithExternalOverrides( val f: IrSimpleFunction = if (declareNew) declareSimpleFunctionWithExternalOverrides(
descriptor descriptor
) else compilerContext.externalSymbols.referenceSimpleFunction(descriptor).owner ) else compilerContext.symbolTable.referenceSimpleFunction(descriptor).owner
f.parent = this f.parent = this
f.returnType = descriptor.returnType!!.toIrType() f.returnType = descriptor.returnType!!.toIrType()
if (declareNew) f.createParameterDeclarations(this.thisReceiver!!) if (declareNew) f.createParameterDeclarations(this.thisReceiver!!)
@@ -78,12 +71,12 @@ interface IrBuilderExtension {
overwriteValueParameters: Boolean = false, overwriteValueParameters: Boolean = false,
bodyGen: IrBlockBodyBuilder.(IrConstructor) -> Unit bodyGen: IrBlockBodyBuilder.(IrConstructor) -> Unit
) { ) {
val c = if (declareNew) compilerContext.localSymbolTable.declareConstructor( val c = if (declareNew) compilerContext.symbolTable.declareConstructor(
this.startOffset, this.startOffset,
this.endOffset, this.endOffset,
SERIALIZABLE_PLUGIN_ORIGIN, SERIALIZABLE_PLUGIN_ORIGIN,
descriptor descriptor
) else compilerContext.externalSymbols.referenceConstructor(descriptor).owner ) else compilerContext.symbolTable.referenceConstructor(descriptor).owner
c.parent = this c.parent = this
c.returnType = descriptor.returnType.toIrType() c.returnType = descriptor.returnType.toIrType()
if (declareNew || overwriteValueParameters) c.createParameterDeclarations( if (declareNew || overwriteValueParameters) c.createParameterDeclarations(
@@ -122,44 +115,25 @@ interface IrBuilderExtension {
typeHint = returnTypeHint typeHint = returnTypeHint
).also { call -> typeArguments.forEachIndexed(call::putTypeArgument) } ).also { call -> typeArguments.forEachIndexed(call::putTypeArgument) }
// todo: remove copypasta
private fun SerializationPluginContext.builtInsPackage(vararg packageNameSegments: String) =
builtIns.builtInsModule.getPackage(FqName.fromSegments(listOf(*packageNameSegments))).memberScope
private fun SerializationPluginContext.getSimpleFunction(
name: Name,
vararg packageNameSegments: String = arrayOf("kotlin"),
condition: (SimpleFunctionDescriptor) -> Boolean
): IrSimpleFunctionSymbol =
symbolTable.referenceSimpleFunction(
builtInsPackage(*packageNameSegments).getContributedFunctions(name, NoLookupLocation.FROM_BACKEND)
.first(condition)
)
fun IrBuilderWithScope.createArrayOfExpression( fun IrBuilderWithScope.createArrayOfExpression(
arrayElementType: IrType, arrayElementType: IrType,
arrayElements: List<IrExpression> arrayElements: List<IrExpression>
): IrExpression { ): IrExpression {
val arrayType = context.irBuiltIns.arrayClass.typeWith(arrayElementType) val arrayType = compilerContext.symbols.array.typeWith(arrayElementType)
val arg0 = IrVarargImpl(startOffset, endOffset, arrayType, arrayElementType, arrayElements) val arg0 = IrVarargImpl(startOffset, endOffset, arrayType, arrayElementType, arrayElements)
val typeArguments = listOf(arrayElementType) val typeArguments = listOf(arrayElementType)
val arrayOf = compilerContext.getSimpleFunction(Name.identifier("arrayOf")) { return irCall(compilerContext.symbols.arrayOf, arrayType, typeArguments = typeArguments).apply {
it.extensionReceiverParameter == null && it.dispatchReceiverParameter == null && it.valueParameters.size == 1 &&
it.valueParameters[0].isVararg
}
return irCall(arrayOf, arrayType, typeArguments = typeArguments).apply {
putValueArgument(0, arg0) putValueArgument(0, arg0)
} }
} }
fun IrBuilderWithScope.irBinOp(name: Name, lhs: IrExpression, rhs: IrExpression): IrExpression { fun IrBuilderWithScope.irBinOp(name: Name, lhs: IrExpression, rhs: IrExpression): IrExpression {
val symbol = compilerContext.symbolTable.referenceSimpleFunction( val symbol = compilerContext.symbols.getBinaryOperator(
lhs.type.toKotlinType().memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND) name,
.first { it.valueParameters.size == 1 && it.valueParameters[0].type == rhs.type.toKotlinType() } lhs.type.toKotlinType(),
rhs.type.toKotlinType()
) )
return irInvoke(lhs, symbol, rhs) return irInvoke(lhs, symbol, rhs)
} }
@@ -169,7 +143,7 @@ interface IrBuilderExtension {
startOffset, startOffset,
endOffset, endOffset,
classDescriptor.defaultType.toIrType(), classDescriptor.defaultType.toIrType(),
compilerContext.externalSymbols.referenceClass(classDescriptor) compilerContext.symbolTable.referenceClass(classDescriptor)
) )
fun IrBuilderWithScope.irGetObject(irObject: IrClass) = fun IrBuilderWithScope.irGetObject(irObject: IrClass) =
@@ -182,7 +156,7 @@ interface IrBuilderExtension {
fun <T : IrDeclaration> T.buildWithScope(builder: (T) -> Unit): T = fun <T : IrDeclaration> T.buildWithScope(builder: (T) -> Unit): T =
also { irDeclaration -> also { irDeclaration ->
compilerContext.localSymbolTable.withScope(irDeclaration.descriptor) { compilerContext.symbolTable.withScope(irDeclaration.descriptor) {
builder(irDeclaration) builder(irDeclaration)
} }
} }
@@ -220,13 +194,9 @@ interface IrBuilderExtension {
result result
) )
fun translateType(ktType: KotlinType): IrType = fun KotlinType.toIrType() = compilerContext.typeTranslator.translateType(this)
translator.translateType(ktType)
fun KotlinType.toIrType() = translateType(this) val SerializableProperty.irField: IrField get() = compilerContext.symbolTable.referenceField(this.descriptor).owner
val SerializableProperty.irField: IrField get() = compilerContext.externalSymbols.referenceField(this.descriptor).owner
/* /*
The rest of the file is mainly copied from FunctionGenerator. The rest of the file is mainly copied from FunctionGenerator.
@@ -241,7 +211,7 @@ interface IrBuilderExtension {
+IrDelegatingConstructorCallImpl( +IrDelegatingConstructorCallImpl(
startOffset, endOffset, startOffset, endOffset,
compilerContext.irBuiltIns.unitType, compilerContext.irBuiltIns.unitType,
compilerContext.externalSymbols.referenceConstructor(anyConstructor) compilerContext.symbolTable.referenceConstructor(anyConstructor)
) )
} }
} }
@@ -273,7 +243,7 @@ interface IrBuilderExtension {
propertyDescriptor: PropertyDescriptor, propertyDescriptor: PropertyDescriptor,
originProperty: IrProperty originProperty: IrProperty
): IrField { ): IrField {
return compilerContext.localSymbolTable.declareField( return compilerContext.symbolTable.declareField(
originProperty.startOffset, originProperty.startOffset,
originProperty.endOffset, originProperty.endOffset,
SERIALIZABLE_PLUGIN_ORIGIN, SERIALIZABLE_PLUGIN_ORIGIN,
@@ -286,9 +256,9 @@ interface IrBuilderExtension {
descriptor: PropertyAccessorDescriptor, descriptor: PropertyAccessorDescriptor,
fieldSymbol: IrFieldSymbol fieldSymbol: IrFieldSymbol
): IrSimpleFunction { ): IrSimpleFunction {
val declaration = compilerContext.externalSymbols.declareSimpleFunctionWithOverrides(fieldSymbol.owner.startOffset, val declaration = compilerContext.symbolTable.declareSimpleFunctionWithOverrides(fieldSymbol.owner.startOffset,
fieldSymbol.owner.endOffset, fieldSymbol.owner.endOffset,
SERIALIZABLE_PLUGIN_ORIGIN,descriptor) SERIALIZABLE_PLUGIN_ORIGIN, descriptor)
return declaration.buildWithScope { irAccessor -> return declaration.buildWithScope { irAccessor ->
irAccessor.createParameterDeclarations(receiver = null) irAccessor.createParameterDeclarations(receiver = null)
irAccessor.returnType = irAccessor.descriptor.returnType!!.toIrType() irAccessor.returnType = irAccessor.descriptor.returnType!!.toIrType()
@@ -318,7 +288,7 @@ interface IrBuilderExtension {
irAccessor.symbol, irAccessor.symbol,
IrGetFieldImpl( IrGetFieldImpl(
startOffset, endOffset, startOffset, endOffset,
compilerContext.localSymbolTable.referenceField(property), compilerContext.symbolTable.referenceField(property),
property.type.toIrType(), property.type.toIrType(),
receiver receiver
) )
@@ -343,7 +313,7 @@ interface IrBuilderExtension {
irBody.statements.add( irBody.statements.add(
IrSetFieldImpl( IrSetFieldImpl(
startOffset, endOffset, startOffset, endOffset,
compilerContext.localSymbolTable.referenceField(property), compilerContext.symbolTable.referenceField(property),
receiver, receiver,
IrGetValueImpl(startOffset, endOffset, irValueParameter.type, irValueParameter.symbol), IrGetValueImpl(startOffset, endOffset, irValueParameter.type, irValueParameter.symbol),
compilerContext.irBuiltIns.unitType compilerContext.irBuiltIns.unitType
@@ -361,7 +331,6 @@ interface IrBuilderExtension {
is ClassDescriptor -> is ClassDescriptor ->
IrGetValueImpl( IrGetValueImpl(
ownerSymbol.owner.startOffset, ownerSymbol.owner.endOffset, ownerSymbol.owner.startOffset, ownerSymbol.owner.endOffset,
// symbolTable.referenceValue(containingDeclaration.thisAsReceiverParameter)
ownerSymbol ownerSymbol
) )
else -> throw AssertionError("Property must be in class") else -> throw AssertionError("Property must be in class")
@@ -421,7 +390,7 @@ interface IrBuilderExtension {
startOffset, startOffset,
endOffset, endOffset,
returnType.toIrType(), returnType.toIrType(),
compilerContext.externalSymbols.referenceClassifier(clazz), compilerContext.symbolTable.referenceClassifier(clazz),
classType.toIrType() classType.toIrType()
) )
} }
@@ -449,7 +418,7 @@ interface IrBuilderExtension {
fun findEnumValuesMethod(enumClass: ClassDescriptor): IrFunction { fun findEnumValuesMethod(enumClass: ClassDescriptor): IrFunction {
assert(enumClass.kind == ClassKind.ENUM_CLASS) assert(enumClass.kind == ClassKind.ENUM_CLASS)
return compilerContext.externalSymbols.referenceClass(enumClass).owner.functions return compilerContext.symbolTable.referenceClass(enumClass).owner.functions
.find { it.origin == IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER && it.name == Name.identifier("values") } .find { it.origin == IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER && it.name == Name.identifier("values") }
?: throw AssertionError("Enum class does not have .values() function") ?: throw AssertionError("Enum class does not have .values() function")
} }
@@ -469,7 +438,7 @@ interface IrBuilderExtension {
property: SerializableProperty property: SerializableProperty
): IrExpression? { ): IrExpression? {
val nullableSerClass = val nullableSerClass =
compilerContext.externalSymbols.referenceClass(property.module.getClassFromInternalSerializationPackage(SpecialBuiltins.nullableSerializer)) compilerContext.symbolTable.referenceClass(property.module.getClassFromInternalSerializationPackage(SpecialBuiltins.nullableSerializer))
val serializer = val serializer =
property.serializableWith?.toClassDescriptor property.serializableWith?.toClassDescriptor
?: if (!property.type.isTypeParameter()) generator.findTypeSerializerOrContext( ?: if (!property.type.isTypeParameter()) generator.findTypeSerializerOrContext(
@@ -508,7 +477,7 @@ interface IrBuilderExtension {
fun wrapIrTypeIntoKSerializerIrType(module: ModuleDescriptor, type: IrType, variance: Variance = Variance.INVARIANT): IrType { fun wrapIrTypeIntoKSerializerIrType(module: ModuleDescriptor, type: IrType, variance: Variance = Variance.INVARIANT): IrType {
val kSerClass = val kSerClass =
compilerContext.externalSymbols.referenceClass(module.getClassFromSerializationPackage(SerialEntityNames.KSERIALIZER_CLASS)) compilerContext.symbolTable.referenceClass(module.getClassFromSerializationPackage(SerialEntityNames.KSERIALIZER_CLASS))
return IrSimpleTypeImpl( return IrSimpleTypeImpl(
kSerClass, hasQuestionMark = false, arguments = listOf( kSerClass, hasQuestionMark = false, arguments = listOf(
makeTypeProjection(type, variance) makeTypeProjection(type, variance)
@@ -531,7 +500,7 @@ interface IrBuilderExtension {
genericIndex genericIndex
) { it, _ -> ) { it, _ ->
val prop = enclosingGenerator.localSerializersFieldsDescriptors[it] val prop = enclosingGenerator.localSerializersFieldsDescriptors[it]
irGetField(irGet(dispatchReceiverParameter), compilerContext.localSymbolTable.referenceField(prop).owner) irGetField(irGet(dispatchReceiverParameter), compilerContext.symbolTable.referenceField(prop).owner)
} }
fun IrBuilderWithScope.serializerInstance( fun IrBuilderWithScope.serializerInstance(
@@ -543,7 +512,7 @@ interface IrBuilderExtension {
genericGetter: ((Int, KotlinType) -> IrExpression)? = null genericGetter: ((Int, KotlinType) -> IrExpression)? = null
): IrExpression? { ): IrExpression? {
val nullableSerClass = val nullableSerClass =
compilerContext.externalSymbols.referenceClass(module.getClassFromInternalSerializationPackage(SpecialBuiltins.nullableSerializer)) compilerContext.symbolTable.referenceClass(module.getClassFromInternalSerializationPackage(SpecialBuiltins.nullableSerializer))
if (serializerClassOriginal == null) { if (serializerClassOriginal == null) {
if (genericIndex == null) return null if (genericIndex == null) return null
return genericGetter?.invoke(genericIndex, kType) return genericGetter?.invoke(genericIndex, kType)
@@ -656,9 +625,9 @@ interface IrBuilderExtension {
requireNotNull( requireNotNull(
findSerializerConstructorForTypeArgumentsSerializers(serializerClass) findSerializerConstructorForTypeArgumentsSerializers(serializerClass)
) { "Generated serializer does not have constructor with required number of arguments" } ) { "Generated serializer does not have constructor with required number of arguments" }
.let { compilerContext.externalSymbols.referenceConstructor(it) } .let { compilerContext.symbolTable.referenceConstructor(it) }
} else { } else {
compilerContext.externalSymbols.referenceConstructor(serializerClass.unsubstitutedPrimaryConstructor!!) compilerContext.symbolTable.referenceConstructor(serializerClass.unsubstitutedPrimaryConstructor!!)
} }
val returnType = wrapIrTypeIntoKSerializerIrType(module, thisIrType) val returnType = wrapIrTypeIntoKSerializerIrType(module, thisIrType)
return irInvoke(null, ctor, typeArguments = typeArgs, valueArguments = args, returnTypeHint = returnType) return irInvoke(null, ctor, typeArguments = typeArgs, valueArguments = args, returnTypeHint = returnType)
@@ -57,11 +57,11 @@ class SerializableCompanionIrGenerator(
) )
) ?: return ) ?: return
val annotationCtor = requireNotNull(annotationMarkerClass.unsubstitutedPrimaryConstructor?.let { val annotationCtor = requireNotNull(annotationMarkerClass.unsubstitutedPrimaryConstructor?.let {
compilerContext.externalSymbols.referenceConstructor(it) compilerContext.symbolTable.referenceConstructor(it)
}) })
val annotationType = annotationMarkerClass.defaultType.toIrType() val annotationType = annotationMarkerClass.defaultType.toIrType()
val irSerializableClass = compilerContext.externalSymbols.referenceClass(serializableDescriptor).owner val irSerializableClass = compilerContext.symbolTable.referenceClass(serializableDescriptor).owner
val annotationCtorCall = IrConstructorCallImpl.fromSymbolDescriptor(startOffset, endOffset, annotationType, annotationCtor).apply { val annotationCtorCall = IrConstructorCallImpl.fromSymbolDescriptor(startOffset, endOffset, annotationType, annotationCtor).apply {
val serializerType = serializer.toSimpleType(false) val serializerType = serializer.toSimpleType(false)
putValueArgument( putValueArgument(
@@ -46,7 +46,7 @@ class SerializableIrGenerator(
val exceptionCtor = val exceptionCtor =
serializableDescriptor.getClassFromSerializationPackage(MISSING_FIELD_EXC) serializableDescriptor.getClassFromSerializationPackage(MISSING_FIELD_EXC)
.unsubstitutedPrimaryConstructor!! .unsubstitutedPrimaryConstructor!!
val exceptionCtorRef = compilerContext.externalSymbols.referenceConstructor(exceptionCtor) val exceptionCtorRef = compilerContext.symbolTable.referenceConstructor(exceptionCtor)
val exceptionType = exceptionCtor.returnType.toIrType() val exceptionType = exceptionCtor.returnType.toIrType()
val serializableProperties = properties.serializableProperties val serializableProperties = properties.serializableProperties
@@ -111,7 +111,7 @@ class SerializableIrGenerator(
private fun IrBlockBodyBuilder.generateSuperNonSerializableCall(superClass: ClassDescriptor) { private fun IrBlockBodyBuilder.generateSuperNonSerializableCall(superClass: ClassDescriptor) {
val suitableCtor = superClass.constructors.singleOrNull { it.valueParameters.size == 0 } val suitableCtor = superClass.constructors.singleOrNull { it.valueParameters.size == 0 }
?: throw IllegalArgumentException("Non-serializable parent of serializable $serializableDescriptor must have no arg constructor") ?: throw IllegalArgumentException("Non-serializable parent of serializable $serializableDescriptor must have no arg constructor")
val ctorRef = compilerContext.externalSymbols.referenceConstructor(suitableCtor) val ctorRef = compilerContext.symbolTable.referenceConstructor(suitableCtor)
val call = IrDelegatingConstructorCallImpl( val call = IrDelegatingConstructorCallImpl(
startOffset, startOffset,
endOffset, endOffset,
@@ -138,7 +138,7 @@ class SerializableIrGenerator(
propertiesStart: Int propertiesStart: Int
): Int { ): Int {
check(superClass.isInternalSerializable) check(superClass.isInternalSerializable)
val superCtorRef = compilerContext.externalSymbols.serializableSyntheticConstructor(superClass) val superCtorRef = compilerContext.symbolTable.serializableSyntheticConstructor(superClass)
val superProperties = bindingContext.serializablePropertiesFor(superClass).serializableProperties val superProperties = bindingContext.serializablePropertiesFor(superClass).serializableProperties
val superSlots = superProperties.bitMaskSlotCount() val superSlots = superProperties.bitMaskSlotCount()
val arguments = allValueParameters.subList(0, superSlots) + val arguments = allValueParameters.subList(0, superSlots) +
@@ -35,7 +35,7 @@ class SerializerForEnumsGenerator(
IrGetValueImpl(startOffset, endOffset, saveFunc.dispatchReceiverParameter!!.symbol) IrGetValueImpl(startOffset, endOffset, saveFunc.dispatchReceiverParameter!!.symbol)
val encoderClass = serializerDescriptor.getClassFromSerializationPackage(SerialEntityNames.ENCODER_CLASS) val encoderClass = serializerDescriptor.getClassFromSerializationPackage(SerialEntityNames.ENCODER_CLASS)
val descriptorGetterSymbol = compilerContext.externalSymbols.referenceFunction(anySerialDescProperty?.getter!!) val descriptorGetterSymbol = compilerContext.symbolTable.referenceFunction(anySerialDescProperty?.getter!!)
val encodeEnum = encoderClass.referenceMethod(CallingConventions.encodeEnum) val encodeEnum = encoderClass.referenceMethod(CallingConventions.encodeEnum)
val serialDescGetter = irGet(descriptorGetterSymbol.owner.returnType, irThis(), descriptorGetterSymbol) val serialDescGetter = irGet(descriptorGetterSymbol.owner.returnType, irThis(), descriptorGetterSymbol)
@@ -50,7 +50,7 @@ class SerializerForEnumsGenerator(
IrGetValueImpl(startOffset, endOffset, loadFunc.dispatchReceiverParameter!!.symbol) IrGetValueImpl(startOffset, endOffset, loadFunc.dispatchReceiverParameter!!.symbol)
val decoderClass = serializerDescriptor.getClassFromSerializationPackage(SerialEntityNames.DECODER_CLASS) val decoderClass = serializerDescriptor.getClassFromSerializationPackage(SerialEntityNames.DECODER_CLASS)
val descriptorGetterSymbol = compilerContext.externalSymbols.referenceFunction(anySerialDescProperty?.getter!!) val descriptorGetterSymbol = compilerContext.symbolTable.referenceFunction(anySerialDescProperty?.getter!!)
val decode = decoderClass.referenceMethod(CallingConventions.decodeEnum) val decode = decoderClass.referenceMethod(CallingConventions.decodeEnum)
val serialDescGetter = irGet(descriptorGetterSymbol.owner.returnType, irThis(), descriptorGetterSymbol) val serialDescGetter = irGet(descriptorGetterSymbol.owner.returnType, irThis(), descriptorGetterSymbol)
@@ -58,11 +58,8 @@ class SerializerForEnumsGenerator(
val getValues = irInvoke(dispatchReceiver = null, callee = valuesF.symbol) val getValues = irInvoke(dispatchReceiver = null, callee = valuesF.symbol)
val arrayGet = val arrayGet =
compilerContext.builtIns.array.unsubstitutedMemberScope.getContributedFunctions( compilerContext.builtIns.array.getFuncDesc("get").single()
Name.identifier("get"), val arrayGetSymbol = compilerContext.symbolTable.referenceFunction(arrayGet)
NoLookupLocation.FROM_BACKEND
).single()
val arrayGetSymbol = compilerContext.externalSymbols.referenceFunction(arrayGet)
val getValueByOrdinal = val getValueByOrdinal =
irInvoke(getValues, arrayGetSymbol, irInvoke(irGet(loadFunc.valueParameters[0]), decode, serialDescGetter)) irInvoke(getValues, arrayGetSymbol, irInvoke(irGet(loadFunc.valueParameters[0]), decode, serialDescGetter))
+irReturn(getValueByOrdinal) +irReturn(getValueByOrdinal)
@@ -75,7 +72,7 @@ class SerializerForEnumsGenerator(
val serialDescForEnums = serializerDescriptor val serialDescForEnums = serializerDescriptor
.getClassFromInternalSerializationPackage(SerialEntityNames.SERIAL_DESCRIPTOR_FOR_ENUM) .getClassFromInternalSerializationPackage(SerialEntityNames.SERIAL_DESCRIPTOR_FOR_ENUM)
val ctor = val ctor =
compilerContext.externalSymbols.referenceConstructor(serialDescForEnums.unsubstitutedPrimaryConstructor!!) compilerContext.symbolTable.referenceConstructor(serialDescForEnums.unsubstitutedPrimaryConstructor!!)
return irInvoke( return irInvoke(
null, ctor, null, ctor,
irString(serialName), irString(serialName),
@@ -38,7 +38,7 @@ object SERIALIZABLE_PLUGIN_ORIGIN : IrDeclarationOriginImpl("SERIALIZER")
open class SerializerIrGenerator(val irClass: IrClass, final override val compilerContext: SerializationPluginContext, bindingContext: BindingContext) : open class SerializerIrGenerator(val irClass: IrClass, final override val compilerContext: SerializationPluginContext, bindingContext: BindingContext) :
SerializerCodegen(irClass.descriptor, bindingContext), IrBuilderExtension { SerializerCodegen(irClass.descriptor, bindingContext), IrBuilderExtension {
protected val serializableIrClass = compilerContext.externalSymbols.referenceClass(serializableDescriptor).owner protected val serializableIrClass = compilerContext.symbolTable.referenceClass(serializableDescriptor).owner
override fun generateSerialDesc() { override fun generateSerialDesc() {
val desc: PropertyDescriptor = generatedSerialDescPropertyDescriptor ?: return val desc: PropertyDescriptor = generatedSerialDescPropertyDescriptor ?: return
@@ -51,7 +51,7 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
lateinit var prop: IrProperty lateinit var prop: IrProperty
// how to (auto)create backing field and getter/setter? // how to (auto)create backing field and getter/setter?
compilerContext.localSymbolTable.withScope(irClass.descriptor) { compilerContext.symbolTable.withScope(irClass.descriptor) {
introduceValueParameter(thisAsReceiverParameter) introduceValueParameter(thisAsReceiverParameter)
prop = generateSimplePropertyWithBackingField(thisAsReceiverParameter.symbol, desc, irClass) prop = generateSimplePropertyWithBackingField(thisAsReceiverParameter.symbol, desc, irClass)
@@ -62,13 +62,13 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
} }
} }
compilerContext.localSymbolTable.declareAnonymousInitializer( compilerContext.symbolTable.declareAnonymousInitializer(
irClass.startOffset, irClass.endOffset, SERIALIZABLE_PLUGIN_ORIGIN, irClass.descriptor irClass.startOffset, irClass.endOffset, SERIALIZABLE_PLUGIN_ORIGIN, irClass.descriptor
).buildWithScope { initIrBody -> ).buildWithScope { initIrBody ->
initIrBody.parent = irClass initIrBody.parent = irClass
val ctor = irClass.declarations.filterIsInstance<IrConstructor>().find { it.isPrimary } val ctor = irClass.declarations.filterIsInstance<IrConstructor>().find { it.isPrimary }
?: throw AssertionError("Serializer must have primary constructor") ?: throw AssertionError("Serializer must have primary constructor")
compilerContext.localSymbolTable.withScope(initIrBody.descriptor) { compilerContext.symbolTable.withScope(initIrBody.descriptor) {
initIrBody.body = initIrBody.body =
DeclarationIrBuilder(compilerContext, initIrBody.symbol, initIrBody.startOffset, initIrBody.endOffset).irBlockBody { DeclarationIrBuilder(compilerContext, initIrBody.symbol, initIrBody.startOffset, initIrBody.endOffset).irBlockBody {
val localDesc = irTemporary( val localDesc = irTemporary(
@@ -105,7 +105,7 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
): IrExpression { ): IrExpression {
val serialDescImplConstructor = serialDescImplClass val serialDescImplConstructor = serialDescImplClass
.unsubstitutedPrimaryConstructor!! .unsubstitutedPrimaryConstructor!!
val serialClassDescImplCtor = compilerContext.externalSymbols.referenceConstructor(serialDescImplConstructor) val serialClassDescImplCtor = compilerContext.symbolTable.referenceConstructor(serialDescImplConstructor)
return irInvoke( return irInvoke(
null, serialClassDescImplCtor, null, serialClassDescImplCtor,
irString(serialName), if (isGeneratedSerializer) correctThis else irNull() irString(serialName), if (isGeneratedSerializer) correctThis else irNull()
@@ -167,7 +167,7 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
// store type arguments serializers in fields // store type arguments serializers in fields
val thisAsReceiverParameter = irClass.thisReceiver!! val thisAsReceiverParameter = irClass.thisReceiver!!
ctor.valueParameters.forEachIndexed { index, param -> ctor.valueParameters.forEachIndexed { index, param ->
val localSerial = compilerContext.localSymbolTable.referenceField(localSerializersFieldsDescriptors[index]) val localSerial = compilerContext.symbolTable.referenceField(localSerializersFieldsDescriptors[index])
+irSetField(generateReceiverExpressionForFieldAccess( +irSetField(generateReceiverExpressionForFieldAccess(
thisAsReceiverParameter.symbol, thisAsReceiverParameter.symbol,
localSerializersFieldsDescriptors[index] localSerializersFieldsDescriptors[index]
@@ -194,7 +194,7 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
} }
protected fun ClassDescriptor.referenceMethod(methodName: String) = protected fun ClassDescriptor.referenceMethod(methodName: String) =
getFuncDesc(methodName).single().let { compilerContext.externalSymbols.referenceFunction(it) } getFuncDesc(methodName).single().let { compilerContext.symbolTable.referenceFunction(it) }
override fun generateSave(function: FunctionDescriptor) = irClass.contributeFunction(function) { saveFunc -> override fun generateSave(function: FunctionDescriptor) = irClass.contributeFunction(function) { saveFunc ->
@@ -207,7 +207,7 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
val kOutputClass = serializerDescriptor.getClassFromSerializationPackage(STRUCTURE_ENCODER_CLASS) val kOutputClass = serializerDescriptor.getClassFromSerializationPackage(STRUCTURE_ENCODER_CLASS)
val kOutputSmallClass = serializerDescriptor.getClassFromSerializationPackage(ENCODER_CLASS) val kOutputSmallClass = serializerDescriptor.getClassFromSerializationPackage(ENCODER_CLASS)
val descriptorGetterSymbol = compilerContext.externalSymbols.referenceFunction(anySerialDescProperty?.getter!!) //??? val descriptorGetterSymbol = compilerContext.symbolTable.referenceFunction(anySerialDescProperty?.getter!!) //???
val localSerialDesc = irTemporary(irGet(descriptorGetterSymbol.owner.returnType, irThis(), descriptorGetterSymbol), "desc") val localSerialDesc = irTemporary(irGet(descriptorGetterSymbol.owner.returnType, irThis(), descriptorGetterSymbol), "desc")
@@ -324,7 +324,7 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
val inputClass = serializerDescriptor.getClassFromSerializationPackage(STRUCTURE_DECODER_CLASS) val inputClass = serializerDescriptor.getClassFromSerializationPackage(STRUCTURE_DECODER_CLASS)
val inputSmallClass = serializerDescriptor.getClassFromSerializationPackage(DECODER_CLASS) val inputSmallClass = serializerDescriptor.getClassFromSerializationPackage(DECODER_CLASS)
val descriptorGetterSymbol = compilerContext.externalSymbols.referenceFunction(anySerialDescProperty?.getter!!) //??? val descriptorGetterSymbol = compilerContext.symbolTable.referenceFunction(anySerialDescProperty?.getter!!) //???
val localSerialDesc = irTemporary(irGet(descriptorGetterSymbol.owner.returnType, irThis(), descriptorGetterSymbol), "desc") val localSerialDesc = irTemporary(irGet(descriptorGetterSymbol.owner.returnType, irThis(), descriptorGetterSymbol), "desc")
// workaround due to unavailability of labels (KT-25386) // workaround due to unavailability of labels (KT-25386)
@@ -411,7 +411,7 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
val exceptionCtor = val exceptionCtor =
serializableDescriptor.getClassFromSerializationPackage(UNKNOWN_FIELD_EXC) serializableDescriptor.getClassFromSerializationPackage(UNKNOWN_FIELD_EXC)
.unsubstitutedPrimaryConstructor!! .unsubstitutedPrimaryConstructor!!
val excClassRef = compilerContext.externalSymbols.referenceConstructor(exceptionCtor) val excClassRef = compilerContext.symbolTable.referenceConstructor(exceptionCtor)
+elseBranch( +elseBranch(
irThrow( irThrow(
irInvoke( irInvoke(
@@ -438,9 +438,9 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
val typeArgs = (loadFunc.returnType as IrSimpleType).arguments.map { (it as IrTypeProjection).type } val typeArgs = (loadFunc.returnType as IrSimpleType).arguments.map { (it as IrTypeProjection).type }
val ctor: IrConstructorSymbol = if (serializableDescriptor.isInternalSerializable) { val ctor: IrConstructorSymbol = if (serializableDescriptor.isInternalSerializable) {
args = bitMasks.map { irGet(it) } + args + irNull() args = bitMasks.map { irGet(it) } + args + irNull()
compilerContext.externalSymbols.serializableSyntheticConstructor(serializableDescriptor) compilerContext.symbolTable.serializableSyntheticConstructor(serializableDescriptor)
} else { } else {
compilerContext.externalSymbols.referenceConstructor(serializableDescriptor.unsubstitutedPrimaryConstructor!!) compilerContext.symbolTable.referenceConstructor(serializableDescriptor.unsubstitutedPrimaryConstructor!!)
} }
+irReturn(irInvoke(null, ctor, typeArgs, args)) +irReturn(irInvoke(null, ctor, typeArgs, args))