[K/N] Transform FunctionReference without bound values to ConstantValue
This commit is contained in:
+36
-23
@@ -146,38 +146,33 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
|
|||||||
|
|
||||||
fun transformFunctionReference(expression: IrFunctionReference, samSuperType: IrType? = null): IrExpression {
|
fun transformFunctionReference(expression: IrFunctionReference, samSuperType: IrType? = null): IrExpression {
|
||||||
val parent: IrDeclarationContainer = (currentClass?.irElement as? IrClass) ?: irFile
|
val parent: IrDeclarationContainer = (currentClass?.irElement as? IrClass) ?: irFile
|
||||||
val loweredFunctionReference = FunctionReferenceBuilder(irFile, parent, expression, samSuperType).build()
|
|
||||||
generatedClasses.add(loweredFunctionReference.functionReferenceClass)
|
|
||||||
val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol,
|
val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol,
|
||||||
expression.startOffset, expression.endOffset)
|
expression.startOffset, expression.endOffset)
|
||||||
return irBuilder.irCall(loweredFunctionReference.functionReferenceConstructor.symbol).apply {
|
val (clazz, newExpression) = FunctionReferenceBuilder(irFile, parent, expression, context, irBuilder, samSuperType).build()
|
||||||
expression.getArguments().forEachIndexed { index, argument ->
|
generatedClasses.add(clazz)
|
||||||
putValueArgument(index, argument.second)
|
return newExpression
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, data = null)
|
}, data = null)
|
||||||
|
|
||||||
irFile.declarations += generatedClasses
|
irFile.declarations += generatedClasses
|
||||||
}
|
}
|
||||||
|
|
||||||
private class BuiltFunctionReference(val functionReferenceClass: IrClass,
|
|
||||||
val functionReferenceConstructor: IrConstructor)
|
|
||||||
|
|
||||||
private val VOLATILE_LAMBDA_FQ_NAME = FqName.fromSegments(listOf("kotlin", "native", "internal", "VolatileLambda"))
|
private val VOLATILE_LAMBDA_FQ_NAME = FqName.fromSegments(listOf("kotlin", "native", "internal", "VolatileLambda"))
|
||||||
|
|
||||||
private val symbols = context.ir.symbols
|
|
||||||
private val irBuiltIns = context.irBuiltIns
|
|
||||||
|
|
||||||
private val getContinuationSymbol = symbols.getContinuation
|
class FunctionReferenceBuilder(
|
||||||
private val continuationClassSymbol = getContinuationSymbol.owner.returnType.classifierOrFail as IrClassSymbol
|
|
||||||
|
|
||||||
private inner class FunctionReferenceBuilder(
|
|
||||||
val irFile: IrFile,
|
val irFile: IrFile,
|
||||||
val parent: IrDeclarationParent,
|
val parent: IrDeclarationParent,
|
||||||
val functionReference: IrFunctionReference,
|
val functionReference: IrFunctionReference,
|
||||||
val samSuperType: IrType?
|
val context: Context,
|
||||||
|
val irBuilder: IrBuilderWithScope,
|
||||||
|
val samSuperType: IrType? = null,
|
||||||
) {
|
) {
|
||||||
|
data class BuiltFunctionReference(val functionReferenceClass: IrClass, val functionReferenceExpression: IrExpression)
|
||||||
|
private val irBuiltIns = context.irBuiltIns
|
||||||
|
private val symbols = context.ir.symbols
|
||||||
|
private val getContinuationSymbol = symbols.getContinuation
|
||||||
|
private val continuationClassSymbol = getContinuationSymbol.owner.returnType.classifierOrFail as IrClassSymbol
|
||||||
private val startOffset = functionReference.startOffset
|
private val startOffset = functionReference.startOffset
|
||||||
private val endOffset = functionReference.endOffset
|
private val endOffset = functionReference.endOffset
|
||||||
private val referencedFunction = functionReference.symbol.owner
|
private val referencedFunction = functionReference.symbol.owner
|
||||||
@@ -243,7 +238,7 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
|
|||||||
private val kSuspendFunctionImplSymbol = symbols.kSuspendFunctionImpl
|
private val kSuspendFunctionImplSymbol = symbols.kSuspendFunctionImpl
|
||||||
private val kSuspendFunctionImplConstructorSymbol = kSuspendFunctionImplSymbol.constructors.single()
|
private val kSuspendFunctionImplConstructorSymbol = kSuspendFunctionImplSymbol.constructors.single()
|
||||||
|
|
||||||
fun build(): BuiltFunctionReference {
|
private fun buildClass(): IrClass {
|
||||||
val superClass = when {
|
val superClass = when {
|
||||||
isKSuspendFunction -> kSuspendFunctionImplSymbol.typeWith(referencedFunction.returnType)
|
isKSuspendFunction -> kSuspendFunctionImplSymbol.typeWith(referencedFunction.returnType)
|
||||||
isLambda -> irBuiltIns.anyType
|
isLambda -> irBuiltIns.anyType
|
||||||
@@ -296,11 +291,11 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
|
|||||||
|
|
||||||
functionReferenceClass.addFakeOverrides(context.typeSystem)
|
functionReferenceClass.addFakeOverrides(context.typeSystem)
|
||||||
|
|
||||||
return BuiltFunctionReference(functionReferenceClass, buildConstructor())
|
return functionReferenceClass
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildConstructor(): IrConstructor =
|
private fun buildConstructor(): IrConstructor {
|
||||||
IrConstructorImpl(
|
return IrConstructorImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
|
DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
|
||||||
IrConstructorSymbolImpl(),
|
IrConstructorSymbolImpl(),
|
||||||
@@ -348,6 +343,23 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun build(): BuiltFunctionReference {
|
||||||
|
val clazz = buildClass()
|
||||||
|
val constructor = buildConstructor()
|
||||||
|
val arguments = functionReference.getArguments()
|
||||||
|
val expression = if (arguments.isEmpty()) {
|
||||||
|
irBuilder.irConstantObject(clazz, emptyMap())
|
||||||
|
} else {
|
||||||
|
irBuilder.irCall(constructor).apply {
|
||||||
|
arguments.forEachIndexed { index, argument ->
|
||||||
|
putValueArgument(index, argument.second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return BuiltFunctionReference(clazz, expression)
|
||||||
|
}
|
||||||
|
|
||||||
private fun getFlags() =
|
private fun getFlags() =
|
||||||
(if (referencedFunction.isSuspend) 1 else 0) + getAdaptedCallableReferenceFlags() shl 1
|
(if (referencedFunction.isSuspend) 1 else 0) + getAdaptedCallableReferenceFlags() shl 1
|
||||||
@@ -385,8 +397,8 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildInvokeMethod(superFunction: IrSimpleFunction): IrSimpleFunction =
|
private fun buildInvokeMethod(superFunction: IrSimpleFunction): IrSimpleFunction {
|
||||||
IrFunctionImpl(
|
return IrFunctionImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
|
DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
|
||||||
IrSimpleFunctionSymbolImpl(),
|
IrSimpleFunctionSymbolImpl(),
|
||||||
@@ -452,5 +464,6 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,9 @@ import kotlin.native.concurrent.*
|
|||||||
import kotlin.native.internal.*
|
import kotlin.native.internal.*
|
||||||
|
|
||||||
fun mainLegacyMM() {
|
fun mainLegacyMM() {
|
||||||
|
val wrong = "wrong"
|
||||||
assertFailsWith<InvalidMutabilityException> {
|
assertFailsWith<InvalidMutabilityException> {
|
||||||
setUnhandledExceptionHook { _ -> println("wrong") }
|
setUnhandledExceptionHook { _ -> println(wrong) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val x = 42
|
val x = 42
|
||||||
|
|||||||
@@ -49,14 +49,16 @@ fun withLock(op: () -> Unit) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assertFailsWith<IllegalStateException> {
|
assertFailsWith<IllegalStateException> {
|
||||||
|
val message = "shall not happen"
|
||||||
worker.executeAfter {
|
worker.executeAfter {
|
||||||
println("shall not happen")
|
println(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertFailsWith<IllegalArgumentException> {
|
assertFailsWith<IllegalArgumentException> {
|
||||||
|
val message = "shall not happen"
|
||||||
worker.executeAfter(-1, {
|
worker.executeAfter(-1, {
|
||||||
println("shall not happen")
|
println(message)
|
||||||
}.freeze())
|
}.freeze())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user