[JS IR BE] Support local delegated properties
This commit is contained in:
+24
-5
@@ -8,14 +8,11 @@ package org.jetbrains.kotlin.backend.common.lower
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.util.*
|
||||
|
||||
@@ -48,3 +45,25 @@ class PropertiesLowering : IrElementTransformerVoid(), FileLoweringPass {
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
class LocalDelegatedPropertiesLowering : IrElementTransformerVoid(), FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.accept(this, null)
|
||||
}
|
||||
|
||||
override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty): IrStatement {
|
||||
declaration.transformChildrenVoid(this)
|
||||
|
||||
val initializer = declaration.delegate.initializer!!
|
||||
declaration.delegate.initializer = IrBlockImpl(
|
||||
initializer.startOffset, initializer.endOffset, initializer.type, null,
|
||||
listOfNotNull(
|
||||
declaration.getter,
|
||||
declaration.setter,
|
||||
initializer
|
||||
)
|
||||
)
|
||||
|
||||
return declaration.delegate
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ private fun JsIrBackendContext.lower(moduleFragment: IrModuleFragment) {
|
||||
moduleFragment.files.forEach(EnumClassLowering(this)::runOnFilePostfix)
|
||||
moduleFragment.files.forEach(EnumUsageLowering(this)::lower)
|
||||
moduleFragment.files.forEach(ReturnableBlockLowering(this)::lower)
|
||||
moduleFragment.files.forEach(LocalDelegatedPropertiesLowering()::lower)
|
||||
moduleFragment.files.forEach(LocalDeclarationsLowering(this)::runOnFilePostfix)
|
||||
moduleFragment.files.forEach(InnerClassesLowering(this)::runOnFilePostfix)
|
||||
moduleFragment.files.forEach(InnerClassConstructorCallsLowering(this)::runOnFilePostfix)
|
||||
|
||||
+64
@@ -82,6 +82,10 @@ class CallableReferenceLowering(val context: JsIrBackendContext) {
|
||||
collectedReferenceMap[makeCallableKey(expression.getter!!.owner, expression)] = expression
|
||||
}
|
||||
|
||||
override fun visitLocalDelegatedPropertyReference(expression: IrLocalDelegatedPropertyReference) {
|
||||
collectedReferenceMap[makeCallableKey(expression.getter!!.owner, expression)] = expression
|
||||
}
|
||||
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
@@ -111,6 +115,11 @@ class CallableReferenceLowering(val context: JsIrBackendContext) {
|
||||
expression.getter!!.owner,
|
||||
expression
|
||||
) else emptyList()
|
||||
|
||||
override fun visitLocalDelegatedPropertyReference(
|
||||
expression: IrLocalDelegatedPropertyReference,
|
||||
data: Nothing?
|
||||
) = lowerLocalKPropertyReference(expression)
|
||||
}, null)
|
||||
}
|
||||
}
|
||||
@@ -128,6 +137,12 @@ class CallableReferenceLowering(val context: JsIrBackendContext) {
|
||||
} ?: expression
|
||||
}
|
||||
|
||||
override fun visitLocalDelegatedPropertyReference(expression: IrLocalDelegatedPropertyReference): IrExpression {
|
||||
return callableToGetterFunction[makeCallableKey(expression.getter!!.owner, expression)]!!.let {
|
||||
redirectToFunction(expression, it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun redirectToFunction(callable: IrCallableReference, newTarget: IrFunction) =
|
||||
IrCallImpl(
|
||||
callable.startOffset, callable.endOffset,
|
||||
@@ -278,6 +293,55 @@ class CallableReferenceLowering(val context: JsIrBackendContext) {
|
||||
return additionalDeclarations + listOf(refGetFunction)
|
||||
}
|
||||
|
||||
private fun lowerLocalKPropertyReference(propertyReference: IrLocalDelegatedPropertyReference): List<IrDeclaration> {
|
||||
// transform
|
||||
// ::bar ->
|
||||
// Foo_bar_KreferenceGet() : KPropertyN<Foo, PType> {
|
||||
// if ($cache$ == null) {
|
||||
// val x = fun Foo_bar_KreferenceClosure_get(): PType {
|
||||
// throw IllegalStateException()
|
||||
// }
|
||||
// x.get = x
|
||||
// x.callableName = "bar"
|
||||
// $cache$ = x
|
||||
// }
|
||||
// return $cache$
|
||||
// }
|
||||
|
||||
val getterName = createPropertyClosureGetterName(propertyReference.descriptor)
|
||||
val refGetFunction = buildGetFunction(propertyReference.getter.owner, propertyReference, getterName)
|
||||
val getterFunction = buildClosureFunction(context.irBuiltIns.throwIseFun, refGetFunction, propertyReference)
|
||||
|
||||
val additionalDeclarations = generateGetterBodyWithGuard(refGetFunction) {
|
||||
val statements = mutableListOf<IrStatement>()
|
||||
|
||||
val getterFunctionType = context.builtIns.getFunction(getterFunction.valueParameters.size + 1)
|
||||
val type = getterFunctionType.toIrType()
|
||||
val irGetReference = JsIrBuilder.buildFunctionReference(type, getterFunction.symbol)
|
||||
val irVarSymbol = JsSymbolBuilder.buildTempVar(refGetFunction.symbol, type)
|
||||
|
||||
statements += JsIrBuilder.buildVar(irVarSymbol, irGetReference, type = type)
|
||||
|
||||
statements += JsIrBuilder.buildCall(context.intrinsics.jsSetJSField.symbol).apply {
|
||||
putValueArgument(0, JsIrBuilder.buildGetValue(irVarSymbol))
|
||||
putValueArgument(1, getterConst)
|
||||
putValueArgument(2, JsIrBuilder.buildGetValue(irVarSymbol))
|
||||
}
|
||||
|
||||
statements += JsIrBuilder.buildCall(context.intrinsics.jsSetJSField.symbol).apply {
|
||||
putValueArgument(0, JsIrBuilder.buildGetValue(irVarSymbol))
|
||||
putValueArgument(1, callableNameConst)
|
||||
putValueArgument(2, JsIrBuilder.buildString(context.irBuiltIns.stringType, getReferenceName(propertyReference.descriptor)))
|
||||
}
|
||||
|
||||
Pair(statements, irVarSymbol)
|
||||
}
|
||||
|
||||
callableToGetterFunction[makeCallableKey(propertyReference.getter.owner, propertyReference)] = refGetFunction
|
||||
|
||||
return additionalDeclarations + listOf(refGetFunction)
|
||||
}
|
||||
|
||||
private fun generateGetterBodyWithGuard(
|
||||
getterFunction: IrSimpleFunction,
|
||||
builder: () -> Pair<List<IrStatement>, IrValueSymbol>
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// WITH_RUNTIME
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
package foo
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
package foo
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
package foo
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
package foo
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
package foo
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
package foo
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
|
||||
object Whatever {
|
||||
operator fun getValue(thisRef: Any?, prop: Any?) = "OK"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
package foo
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
package foo
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
package foo
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
package foo
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// Enable when KT-14833 is fixed.
|
||||
// IGNORE_BACKEND: JVM
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1114
|
||||
//TODO: reuse same tests from JVM backend
|
||||
package foo
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1116
|
||||
//TODO: reuse same tests from JVM backend
|
||||
package foo
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1115
|
||||
//TODO: reuse same tests from JVM backend
|
||||
package foo
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1118
|
||||
//TODO: reuse same tests from JVM backend
|
||||
package foo
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1114
|
||||
//TODO: reuse same tests from JVM backend
|
||||
package foo
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1115
|
||||
//TODO: reuse same tests from JVM backend
|
||||
package foo
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1115
|
||||
//TODO: reuse same tests from JVM backend
|
||||
package foo
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1115
|
||||
//TODO: reuse same tests from JVM backend
|
||||
package foo
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1131
|
||||
// PROPERTY_NOT_USED: PropertyMetadata
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
Reference in New Issue
Block a user