[JS IR BE] lateinit support
* Functions with IrExpressionBody are lowered to IrBlockBody * Implemented throwUninitializedPropertyAccessException function
This commit is contained in:
+5
-4
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlock
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
||||
@@ -50,19 +51,19 @@ class LateinitLowering(
|
||||
val endOffset = getter.endOffset
|
||||
val irBuilder = context.createIrBuilder(getter.symbol, startOffset, endOffset)
|
||||
irBuilder.run {
|
||||
val block = irBlock(type)
|
||||
val body = IrBlockBodyImpl(startOffset, endOffset)
|
||||
val resultVar = scope.createTemporaryVariable(
|
||||
irGetField(getter.dispatchReceiverParameter?.let { irGet(it) }, backingField)
|
||||
)
|
||||
block.statements.add(resultVar)
|
||||
body.statements.add(resultVar)
|
||||
val throwIfNull = irIfThenElse(
|
||||
context.irBuiltIns.nothingType,
|
||||
irNotEquals(irGet(resultVar), irNull()),
|
||||
irReturn(irGet(resultVar)),
|
||||
throwUninitializedPropertyAccessException(backingField)
|
||||
)
|
||||
block.statements.add(throwIfNull)
|
||||
getter.body = IrExpressionBodyImpl(startOffset, endOffset, block)
|
||||
body.statements.add(throwIfNull)
|
||||
getter.body = body
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -193,13 +193,8 @@ class JsIrBackendContext(
|
||||
override val ThrowTypeCastException
|
||||
get () = irBuiltIns.throwCceSymbol
|
||||
|
||||
override val ThrowUninitializedPropertyAccessException = symbolTable.referenceSimpleFunction(
|
||||
irBuiltIns.defineOperator(
|
||||
"throwUninitializedPropertyAccessException",
|
||||
builtIns.nothingType,
|
||||
listOf(builtIns.stringType)
|
||||
).descriptor
|
||||
)
|
||||
override val ThrowUninitializedPropertyAccessException=
|
||||
symbolTable.referenceSimpleFunction(getFunctions(FqName("kotlin.throwUninitializedPropertyAccessException")).single())
|
||||
|
||||
override val stringBuilder
|
||||
get() = TODO("not implemented")
|
||||
|
||||
+12
-5
@@ -38,9 +38,19 @@ class BlockDecomposerLowering(context: JsIrBackendContext) : DeclarationContaine
|
||||
}
|
||||
|
||||
fun lower(irFunction: IrFunction) {
|
||||
(irFunction.body as? IrExpressionBody)?.apply {
|
||||
irFunction.body = toBlockBody(irFunction)
|
||||
}
|
||||
irFunction.accept(decomposerTransformer, null)
|
||||
}
|
||||
|
||||
private fun IrExpressionBody.toBlockBody(containingFunction: IrFunction): IrBlockBody {
|
||||
val returnStatement = JsIrBuilder.buildReturn(containingFunction.symbol, expression, nothingType)
|
||||
return IrBlockBodyImpl(expression.startOffset, expression.endOffset).apply {
|
||||
statements += returnStatement
|
||||
}
|
||||
}
|
||||
|
||||
fun lower(irField: IrField, container: IrDeclarationContainer): List<IrDeclaration> {
|
||||
irField.initializer?.apply {
|
||||
val initFunction = JsIrBuilder.buildFunction(irField.name.asString() + "\$init\$", irField.visibility).also {
|
||||
@@ -48,17 +58,14 @@ class BlockDecomposerLowering(context: JsIrBackendContext) : DeclarationContaine
|
||||
it.returnType = expression.type
|
||||
}
|
||||
|
||||
val returnStatement = JsIrBuilder.buildReturn(initFunction.symbol, expression, nothingType)
|
||||
val newBody = IrBlockBodyImpl(expression.startOffset, expression.endOffset).apply {
|
||||
statements += returnStatement
|
||||
}
|
||||
val newBody = toBlockBody(initFunction)
|
||||
|
||||
initFunction.body = newBody
|
||||
|
||||
lower(initFunction)
|
||||
|
||||
val lastStatement = newBody.statements.last()
|
||||
if (lastStatement != returnStatement || (lastStatement as IrReturn).value != expression) {
|
||||
if (newBody.statements.size > 1 || lastStatement !is IrReturn || lastStatement.value != expression) {
|
||||
expression = JsIrBuilder.buildCall(initFunction.symbol, expression.type)
|
||||
return listOf(initFunction, irField)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
public class A {
|
||||
|
||||
fun setMyStr() {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
public class A {
|
||||
|
||||
fun getMyStr(): String {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
class A {
|
||||
private lateinit var str: String
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
class A {
|
||||
public lateinit var str: String
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
interface Intf {
|
||||
val str: String
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
interface Intf {
|
||||
val str: String
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
class My {
|
||||
lateinit var x: String
|
||||
private set
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
class My {
|
||||
lateinit var x: String
|
||||
private set
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
open class A {
|
||||
lateinit var x: String
|
||||
private set
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
class A {
|
||||
public lateinit var str: String
|
||||
}
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// LANGUAGE_VERSION: 1.2
|
||||
// WITH_RUNTIME
|
||||
// FILE: lateinit.kt
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// LANGUAGE_VERSION: 1.2
|
||||
|
||||
// FILE: lateinit.kt
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// LANGUAGE_VERSION: 1.2
|
||||
|
||||
lateinit var ok: String
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// LANGUAGE_VERSION: 1.2
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// LANGUAGE_VERSION: 1.2
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1233
|
||||
class Greeting {
|
||||
val noon = xrun {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
|
||||
// EXPECTED_REACHABLE_NODES: 1336
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
|
||||
@@ -98,4 +98,8 @@ fun THROW_NPE() {
|
||||
throw NullPointerException()
|
||||
}
|
||||
|
||||
fun error(s: String): Nothing = throw IllegalStateException(s, null)
|
||||
fun error(s: String): Nothing = throw IllegalStateException(s, null)
|
||||
|
||||
@PublishedApi
|
||||
internal fun throwUninitializedPropertyAccessException(name: String): Nothing =
|
||||
throw UninitializedPropertyAccessException("lateinit property $name has not been initialized")
|
||||
Reference in New Issue
Block a user