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