JVM IR: Fix types in LateInitLowering
On the JVM backend the throwUninitializedPropertyAccessException function is implemented in Java and has a return type of Unit instead of Nothing. In order to make the types match up we have to wrap its call in a block with an additional IrThrow.
This commit is contained in:
committed by
max-kammerer
parent
3ee013aac6
commit
7c9578116b
+6
-15
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
|||||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedVariableDescriptor
|
import org.jetbrains.kotlin.backend.common.descriptors.WrappedVariableDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.buildField
|
import org.jetbrains.kotlin.ir.builders.declarations.buildField
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
@@ -36,7 +35,7 @@ import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
|
||||||
class LateinitLowering(val context: CommonBackendContext) : FileLoweringPass {
|
open class LateinitLowering(val context: CommonBackendContext) : FileLoweringPass {
|
||||||
|
|
||||||
private val nullableFields = context.lateinitNullableFields
|
private val nullableFields = context.lateinitNullableFields
|
||||||
private fun buildOrGetNullableField(originalField: IrField): IrField {
|
private fun buildOrGetNullableField(originalField: IrField): IrField {
|
||||||
@@ -117,7 +116,7 @@ class LateinitLowering(val context: CommonBackendContext) : FileLoweringPass {
|
|||||||
context.irBuiltIns.nothingType,
|
context.irBuiltIns.nothingType,
|
||||||
irNotEquals(irGet(resultVar), irNull()),
|
irNotEquals(irGet(resultVar), irNull()),
|
||||||
irReturn(irGet(resultVar)),
|
irReturn(irGet(resultVar)),
|
||||||
throwUninitializedPropertyAccessException(backingField.name.asString())
|
throwUninitializedPropertyAccessException(this, backingField.name.asString())
|
||||||
)
|
)
|
||||||
body.statements.add(throwIfNull)
|
body.statements.add(throwIfNull)
|
||||||
getter.body = body
|
getter.body = body
|
||||||
@@ -136,7 +135,7 @@ class LateinitLowering(val context: CommonBackendContext) : FileLoweringPass {
|
|||||||
return irBuilder.run {
|
return irBuilder.run {
|
||||||
irIfThenElse(
|
irIfThenElse(
|
||||||
expression.type, irEqualsNull(irGet(irVar)),
|
expression.type, irEqualsNull(irGet(irVar)),
|
||||||
throwUninitializedPropertyAccessException(irVar.name.asString()),
|
throwUninitializedPropertyAccessException(this, irVar.name.asString()),
|
||||||
irGet(irVar)
|
irGet(irVar)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -185,17 +184,9 @@ class LateinitLowering(val context: CommonBackendContext) : FileLoweringPass {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrBuilderWithScope.throwUninitializedPropertyAccessException(name: String) =
|
open fun throwUninitializedPropertyAccessException(builder: IrBuilderWithScope, name: String): IrExpression =
|
||||||
irCall(throwErrorFunction).apply {
|
builder.irCall(throwErrorFunction).apply {
|
||||||
putValueArgument(
|
putValueArgument(0, builder.irString(name))
|
||||||
0,
|
|
||||||
IrConstImpl.string(
|
|
||||||
UNDEFINED_OFFSET,
|
|
||||||
UNDEFINED_OFFSET,
|
|
||||||
context.irBuiltIns.stringType,
|
|
||||||
name
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val throwErrorFunction by lazy { context.ir.symbols.ThrowUninitializedPropertyAccessException.owner }
|
private val throwErrorFunction by lazy { context.ir.symbols.ThrowUninitializedPropertyAccessException.owner }
|
||||||
|
|||||||
@@ -13,7 +13,11 @@ import org.jetbrains.kotlin.backend.jvm.lower.*
|
|||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
|
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
||||||
|
import org.jetbrains.kotlin.ir.builders.irBlock
|
||||||
|
import org.jetbrains.kotlin.ir.builders.irNull
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor
|
import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||||
@@ -75,7 +79,15 @@ private val expectDeclarationsRemovingPhase = makeIrModulePhase(
|
|||||||
)
|
)
|
||||||
|
|
||||||
private val lateinitPhase = makeIrFilePhase(
|
private val lateinitPhase = makeIrFilePhase(
|
||||||
::LateinitLowering,
|
{ backend: JvmBackendContext ->
|
||||||
|
object : LateinitLowering(backend) {
|
||||||
|
override fun throwUninitializedPropertyAccessException(builder: IrBuilderWithScope, name: String): IrExpression =
|
||||||
|
builder.irBlock {
|
||||||
|
+super.throwUninitializedPropertyAccessException(builder, name)
|
||||||
|
+irThrow(irNull())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
name = "Lateinit",
|
name = "Lateinit",
|
||||||
description = "Insert checks for lateinit field references"
|
description = "Insert checks for lateinit field references"
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user