FIR2IR: support adapted references for constructors
This commit is contained in:
+10
-9
@@ -112,7 +112,7 @@ internal class AdapterGenerator(
|
||||
adapteeSymbol: IrFunctionSymbol,
|
||||
type: IrSimpleType
|
||||
): IrExpression {
|
||||
val firAdaptee = callableReferenceAccess.toResolvedCallableReference()?.resolvedSymbol?.fir as? FirSimpleFunction
|
||||
val firAdaptee = callableReferenceAccess.toResolvedCallableReference()?.resolvedSymbol?.fir as? FirFunction
|
||||
val adaptee = adapteeSymbol.owner
|
||||
val expectedReturnType = type.arguments.last().typeOrNull
|
||||
return callableReferenceAccess.convertWithOffsets { startOffset, endOffset ->
|
||||
@@ -164,7 +164,7 @@ internal class AdapterGenerator(
|
||||
callableReferenceAccess: FirCallableReferenceAccess,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
firAdaptee: FirSimpleFunction,
|
||||
firAdaptee: FirFunction<*>,
|
||||
adaptee: IrFunction,
|
||||
type: IrSimpleType,
|
||||
boundDispatchReceiver: IrExpression?,
|
||||
@@ -172,6 +172,7 @@ internal class AdapterGenerator(
|
||||
): IrSimpleFunction {
|
||||
val returnType = type.arguments.last().typeOrNull!!
|
||||
val parameterTypes = type.arguments.dropLast(1).map { it.typeOrNull!! }
|
||||
val firMemberAdaptee = firAdaptee as FirMemberDeclaration
|
||||
return irFactory.createFunction(
|
||||
startOffset, endOffset,
|
||||
IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE,
|
||||
@@ -180,13 +181,13 @@ internal class AdapterGenerator(
|
||||
DescriptorVisibilities.LOCAL,
|
||||
Modality.FINAL,
|
||||
returnType,
|
||||
isInline = firAdaptee.isInline,
|
||||
isExternal = firAdaptee.isExternal,
|
||||
isTailrec = firAdaptee.isTailRec,
|
||||
isSuspend = firAdaptee.isSuspend || type.isSuspendFunction(),
|
||||
isOperator = firAdaptee.isOperator,
|
||||
isInfix = firAdaptee.isInfix,
|
||||
isExpect = firAdaptee.isExpect,
|
||||
isInline = firMemberAdaptee.isInline,
|
||||
isExternal = firMemberAdaptee.isExternal,
|
||||
isTailrec = firMemberAdaptee.isTailRec,
|
||||
isSuspend = firMemberAdaptee.isSuspend || type.isSuspendFunction(),
|
||||
isOperator = firMemberAdaptee.isOperator,
|
||||
isInfix = firMemberAdaptee.isInfix,
|
||||
isExpect = firMemberAdaptee.isExpect,
|
||||
isFakeOverride = false
|
||||
).also { irAdapterFunction ->
|
||||
irAdapterFunction.metadata = FirMetadataSource.Function(firAdaptee)
|
||||
|
||||
+4
-11
@@ -122,16 +122,6 @@ class CallAndReferenceGenerator(
|
||||
origin
|
||||
)
|
||||
}
|
||||
is IrConstructorSymbol -> {
|
||||
val constructor = symbol.owner
|
||||
val klass = constructor.parent as? IrClass
|
||||
IrFunctionReferenceImpl(
|
||||
startOffset, endOffset, type, symbol,
|
||||
typeArgumentsCount = constructor.typeParameters.size + (klass?.typeParameters?.size ?: 0),
|
||||
valueArgumentsCount = constructor.valueParameters.size,
|
||||
reflectionTarget = symbol
|
||||
)
|
||||
}
|
||||
is IrFunctionSymbol -> {
|
||||
assert(type.isFunctionTypeOrSubtype()) {
|
||||
"Callable reference whose symbol refers to a function should be of functional type."
|
||||
@@ -144,9 +134,12 @@ class CallAndReferenceGenerator(
|
||||
generateAdaptedCallableReference(callableReferenceAccess, explicitReceiverExpression, symbol, adaptedType)
|
||||
}
|
||||
} else {
|
||||
val klass = function.parent as? IrClass
|
||||
val typeArgumentCount = function.typeParameters.size +
|
||||
if (function is IrConstructor) klass?.typeParameters?.size ?: 0 else 0
|
||||
IrFunctionReferenceImpl(
|
||||
startOffset, endOffset, type, symbol,
|
||||
typeArgumentsCount = function.typeParameters.size,
|
||||
typeArgumentsCount = typeArgumentCount,
|
||||
valueArgumentsCount = function.valueParameters.size,
|
||||
reflectionTarget = symbol
|
||||
)
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.reflect.KCallable
|
||||
|
||||
-1
@@ -1,6 +1,5 @@
|
||||
// !LANGUAGE: +SuspendConversion
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.reflect.KCallable
|
||||
|
||||
+19
-3
@@ -30,13 +30,29 @@ class Outer {
|
||||
}
|
||||
|
||||
fun testConstructor(): Any {
|
||||
return use(fn = C::<init>)
|
||||
return use(fn = local fun <init>(p0: Int): C {
|
||||
return C(xs = [p0])
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun testInnerClassConstructor(outer: Outer): Any {
|
||||
return use(fn = outer::<init>)
|
||||
return use(fn = { // BLOCK
|
||||
local fun Outer.<init>(p0: Int): Inner {
|
||||
return receiver.Inner(xs = [p0])
|
||||
}
|
||||
|
||||
outer::<init>
|
||||
})
|
||||
}
|
||||
|
||||
fun testInnerClassConstructorCapturingOuter(): Any {
|
||||
return use(fn = Outer()::<init>)
|
||||
return use(fn = { // BLOCK
|
||||
local fun Outer.<init>(p0: Int): Inner {
|
||||
return receiver.Inner(xs = [p0])
|
||||
}
|
||||
|
||||
Outer()::<init>
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Vendored
+32
-5
@@ -70,17 +70,44 @@ FILE fqName:<root> fileName:/constructorWithAdaptedArguments.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun testConstructor (): kotlin.Any declared in <root>'
|
||||
CALL 'public final fun use (fn: kotlin.Function1<kotlin.Int, kotlin.Any>): kotlin.Any declared in <root>' type=kotlin.Any origin=null
|
||||
fn: FUNCTION_REFERENCE 'public constructor <init> (vararg xs: kotlin.Int) [primary] declared in <root>.C' type=kotlin.reflect.KFunction1<kotlin.Int, <root>.C> origin=null reflectionTarget=<same>
|
||||
fn: FUN_EXPR type=kotlin.Function1<kotlin.Int, <root>.C> origin=ADAPTED_FUNCTION_REFERENCE
|
||||
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:<init> visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:<root>.C
|
||||
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:kotlin.Int
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='local final fun <init> (p0: kotlin.Int): <root>.C declared in <root>.testConstructor'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (vararg xs: kotlin.Int) [primary] declared in <root>.C' type=<root>.C origin=null
|
||||
xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
|
||||
GET_VAR 'p0: kotlin.Int declared in <root>.testConstructor.<init>' type=kotlin.Int origin=null
|
||||
FUN name:testInnerClassConstructor visibility:public modality:FINAL <> (outer:<root>.Outer) returnType:kotlin.Any
|
||||
VALUE_PARAMETER name:outer index:0 type:<root>.Outer
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun testInnerClassConstructor (outer: <root>.Outer): kotlin.Any declared in <root>'
|
||||
CALL 'public final fun use (fn: kotlin.Function1<kotlin.Int, kotlin.Any>): kotlin.Any declared in <root>' type=kotlin.Any origin=null
|
||||
fn: FUNCTION_REFERENCE 'public constructor <init> (vararg xs: kotlin.Int) [primary] declared in <root>.Outer.Inner' type=kotlin.reflect.KFunction1<kotlin.Int, <root>.Outer.Inner> origin=null reflectionTarget=<same>
|
||||
$this: GET_VAR 'outer: <root>.Outer declared in <root>.testInnerClassConstructor' type=<root>.Outer origin=null
|
||||
fn: BLOCK type=kotlin.Function1<kotlin.Int, <root>.Outer.Inner> origin=ADAPTED_FUNCTION_REFERENCE
|
||||
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:<init> visibility:local modality:FINAL <> ($receiver:<root>.Outer, p0:kotlin.Int) returnType:<root>.Outer.Inner
|
||||
$receiver: VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:receiver type:<root>.Outer
|
||||
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:kotlin.Int
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='local final fun <init> (p0: kotlin.Int): <root>.Outer.Inner declared in <root>.testInnerClassConstructor'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (vararg xs: kotlin.Int) [primary] declared in <root>.Outer.Inner' type=<root>.Outer.Inner origin=null
|
||||
$outer: GET_VAR 'receiver: <root>.Outer declared in <root>.testInnerClassConstructor.<init>' type=<root>.Outer origin=ADAPTED_FUNCTION_REFERENCE
|
||||
xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
|
||||
GET_VAR 'p0: kotlin.Int declared in <root>.testInnerClassConstructor.<init>' type=kotlin.Int origin=null
|
||||
FUNCTION_REFERENCE 'local final fun <init> (p0: kotlin.Int): <root>.Outer.Inner declared in <root>.testInnerClassConstructor' type=kotlin.Function1<kotlin.Int, <root>.Outer.Inner> origin=ADAPTED_FUNCTION_REFERENCE reflectionTarget=null
|
||||
$receiver: GET_VAR 'outer: <root>.Outer declared in <root>.testInnerClassConstructor' type=<root>.Outer origin=null
|
||||
FUN name:testInnerClassConstructorCapturingOuter visibility:public modality:FINAL <> () returnType:kotlin.Any
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun testInnerClassConstructorCapturingOuter (): kotlin.Any declared in <root>'
|
||||
CALL 'public final fun use (fn: kotlin.Function1<kotlin.Int, kotlin.Any>): kotlin.Any declared in <root>' type=kotlin.Any origin=null
|
||||
fn: FUNCTION_REFERENCE 'public constructor <init> (vararg xs: kotlin.Int) [primary] declared in <root>.Outer.Inner' type=kotlin.reflect.KFunction1<kotlin.Int, <root>.Outer.Inner> origin=null reflectionTarget=<same>
|
||||
$this: CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.Outer' type=<root>.Outer origin=null
|
||||
fn: BLOCK type=kotlin.Function1<kotlin.Int, <root>.Outer.Inner> origin=ADAPTED_FUNCTION_REFERENCE
|
||||
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:<init> visibility:local modality:FINAL <> ($receiver:<root>.Outer, p0:kotlin.Int) returnType:<root>.Outer.Inner
|
||||
$receiver: VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:receiver type:<root>.Outer
|
||||
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:kotlin.Int
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='local final fun <init> (p0: kotlin.Int): <root>.Outer.Inner declared in <root>.testInnerClassConstructorCapturingOuter'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (vararg xs: kotlin.Int) [primary] declared in <root>.Outer.Inner' type=<root>.Outer.Inner origin=null
|
||||
$outer: GET_VAR 'receiver: <root>.Outer declared in <root>.testInnerClassConstructorCapturingOuter.<init>' type=<root>.Outer origin=ADAPTED_FUNCTION_REFERENCE
|
||||
xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
|
||||
GET_VAR 'p0: kotlin.Int declared in <root>.testInnerClassConstructorCapturingOuter.<init>' type=kotlin.Int origin=null
|
||||
FUNCTION_REFERENCE 'local final fun <init> (p0: kotlin.Int): <root>.Outer.Inner declared in <root>.testInnerClassConstructorCapturingOuter' type=kotlin.Function1<kotlin.Int, <root>.Outer.Inner> origin=ADAPTED_FUNCTION_REFERENCE reflectionTarget=null
|
||||
$receiver: CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.Outer' type=<root>.Outer origin=null
|
||||
|
||||
+4
-1
@@ -27,5 +27,8 @@ fun testFn(): Any {
|
||||
}
|
||||
|
||||
fun testCtor(): Any {
|
||||
return use(fn = C::<init>)
|
||||
return use(fn = local fun <init>(): C {
|
||||
return C()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -58,4 +58,8 @@ FILE fqName:<root> fileName:/kt37131.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun testCtor (): kotlin.Any declared in <root>'
|
||||
CALL 'public final fun use (fn: kotlin.Function0<kotlin.Any>): kotlin.Any declared in <root>' type=kotlin.Any origin=null
|
||||
fn: FUNCTION_REFERENCE 'public constructor <init> (x: kotlin.String) [primary] declared in <root>.C' type=kotlin.reflect.KFunction0<<root>.C> origin=null reflectionTarget=<same>
|
||||
fn: FUN_EXPR type=kotlin.Function0<<root>.C> origin=ADAPTED_FUNCTION_REFERENCE
|
||||
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:<init> visibility:local modality:FINAL <> () returnType:<root>.C
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='local final fun <init> (): <root>.C declared in <root>.testCtor'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (x: kotlin.String) [primary] declared in <root>.C' type=<root>.C origin=null
|
||||
|
||||
Reference in New Issue
Block a user