Fix lateinit isInitialized check in multi-file case

This commit is contained in:
Roman Artemev
2019-10-28 16:38:50 +03:00
committed by romanart
parent d75b938089
commit 78b29349c9
11 changed files with 100 additions and 12 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.backend.common.ir.DeclarationFactory
import org.jetbrains.kotlin.backend.common.ir.Ir
import org.jetbrains.kotlin.backend.common.ir.SharedVariablesManager
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
@@ -33,4 +34,5 @@ interface BackendContext {
val declarationFactory: DeclarationFactory
val internalPackageFqn: FqName
val transformedFunction: MutableMap<IrFunctionSymbol, IrSimpleFunctionSymbol>
val lateinitNullableFields: MutableMap<IrField, IrField>
}
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
import org.jetbrains.kotlin.ir.types.isMarkedNullable
import org.jetbrains.kotlin.ir.types.isPrimitiveType
import org.jetbrains.kotlin.ir.types.makeNullable
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
@@ -36,8 +37,24 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
class LateinitLowering(val context: CommonBackendContext) : FileLoweringPass {
private val nullableFields = context.lateinitNullableFields
private fun buildOrGetNullableField(originalField: IrField): IrField {
if (originalField.type.isMarkedNullable()) return originalField
return nullableFields.getOrPut(originalField) {
buildField {
updateFrom(originalField)
type = originalField.type.makeNullable()
name = originalField.name
}.apply {
parent = originalField.parent
correspondingPropertySymbol = originalField.correspondingPropertySymbol
}
}
}
override fun lower(irFile: IrFile) {
val nullableFields = mutableMapOf<IrField, IrField>()
val nullableVariables = mutableMapOf<IrVariable, IrVariable>()
// Transform declarations
@@ -46,17 +63,9 @@ class LateinitLowering(val context: CommonBackendContext) : FileLoweringPass {
declaration.transformChildrenVoid(this)
if (declaration.isLateinit && declaration.origin != IrDeclarationOrigin.FAKE_OVERRIDE) {
val oldField = declaration.backingField!!
val newField = buildField {
updateFrom(oldField)
type = oldField.type.makeNullable()
name = oldField.name
}.also { newField ->
newField.parent = oldField.parent
newField.correspondingPropertySymbol = declaration.symbol
declaration.backingField = newField
}
val newField = buildOrGetNullableField(oldField)
nullableFields[oldField] = newField
declaration.backingField = newField
transformGetter(newField, declaration.getter!!)
}
@@ -166,8 +175,11 @@ class LateinitLowering(val context: CommonBackendContext) : FileLoweringPass {
val property = receiver.getter?.owner?.resolveFakeOverride()?.correspondingProperty!!.also { assert(it.isLateinit) }
val nullableField =
buildOrGetNullableField(property.backingField ?: error("Lateinit property is supposed to have backing field"))
return expression.run { context.createIrBuilder(symbol, startOffset, endOffset) }.run {
irNotEquals(irGetField(receiver.dispatchReceiver, property.backingField!!), irNull())
irNotEquals(irGetField(receiver.dispatchReceiver, nullableField), irNull())
}
}
})
@@ -48,6 +48,7 @@ class JsIrBackendContext(
override val scriptMode: Boolean = false
) : CommonBackendContext {
override val transformedFunction = mutableMapOf<IrFunctionSymbol, IrSimpleFunctionSymbol>()
override val lateinitNullableFields = mutableMapOf<IrField, IrField>()
override val builtIns = module.builtIns
@@ -53,6 +53,7 @@ class JvmBackendContext(
override val transformedFunction: MutableMap<IrFunctionSymbol, IrSimpleFunctionSymbol>
get() = TODO("not implemented")
override val scriptMode: Boolean = false
override val lateinitNullableFields = mutableMapOf<IrField, IrField>()
override val builtIns = state.module.builtIns
val typeMapper = IrTypeMapper(this)
@@ -38,6 +38,7 @@ class WasmBackendContext(
override var inVerbosePhase: Boolean = false
override val scriptMode = false
override val transformedFunction = mutableMapOf<IrFunctionSymbol, IrSimpleFunctionSymbol>()
override val lateinitNullableFields = mutableMapOf<IrField, IrField>()
// Place to store declarations excluded from code generation
val excludedDeclarations: IrPackageFragment by lazy {