PSI2IR: support NewInference + SamConversionPerArgument
except for SAM conversions of varargs (which aren't implemented in the non-IR JVM backend either btw)
This commit is contained in:
+15
-6
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
|
||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
@@ -39,6 +40,7 @@ import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getSuperCallExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
@@ -399,11 +401,12 @@ private fun StatementGenerator.pregenerateValueArguments(call: CallBuilder, reso
|
||||
generateExpression(it)
|
||||
}
|
||||
|
||||
generateSamConversionForValueArgumentsIfRequired(call, resolvedCall.resultingDescriptor)
|
||||
generateSamConversionForValueArgumentsIfRequired(call, resolvedCall)
|
||||
}
|
||||
|
||||
fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: CallBuilder, originalDescriptor: CallableDescriptor) {
|
||||
val underlyingDescriptor = context.extensions.samConversion.getOriginalForSamAdapter(originalDescriptor) ?: return
|
||||
fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: CallBuilder, resolvedCall: ResolvedCall<*>) {
|
||||
val originalDescriptor = resolvedCall.resultingDescriptor
|
||||
val underlyingDescriptor = context.extensions.samConversion.getOriginalForSamAdapter(originalDescriptor) ?: originalDescriptor
|
||||
|
||||
val originalValueParameters = originalDescriptor.valueParameters
|
||||
val underlyingValueParameters = underlyingDescriptor.valueParameters
|
||||
@@ -422,17 +425,23 @@ fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: Ca
|
||||
"$originalDescriptor has ${originalDescriptor.typeParameters}"
|
||||
}
|
||||
|
||||
val partialSamConversionIsSupported = context.languageVersionSettings.supportsFeature(LanguageFeature.SamConversionPerArgument)
|
||||
val substitutionContext = call.original.typeArguments.entries.associate { (typeParameterDescriptor, typeArgument) ->
|
||||
underlyingDescriptor.typeParameters[typeParameterDescriptor.index].typeConstructor to TypeProjectionImpl(typeArgument)
|
||||
}
|
||||
val typeSubstitutor = TypeSubstitutor.create(substitutionContext)
|
||||
|
||||
for (i in underlyingValueParameters.indices) {
|
||||
val originalParameterType = originalValueParameters[i].type
|
||||
val underlyingParameterType = underlyingValueParameters[i].type
|
||||
|
||||
if (!context.extensions.samConversion.isSamType(underlyingParameterType)) continue
|
||||
if (!originalParameterType.isFunctionTypeOrSubtype) continue
|
||||
if (partialSamConversionIsSupported && resolvedCall is NewResolvedCallImpl<*>) {
|
||||
// TODO support SAM conversion of varargs
|
||||
val argument = resolvedCall.valueArguments[originalValueParameters[i]]?.arguments?.singleOrNull() ?: continue
|
||||
if (resolvedCall.getExpectedTypeForSamConvertedArgument(argument) == null) continue
|
||||
} else {
|
||||
if (!context.extensions.samConversion.isSamType(underlyingParameterType)) continue
|
||||
if (!originalValueParameters[i].type.isFunctionTypeOrSubtype) continue
|
||||
}
|
||||
|
||||
val originalArgument = call.irValueArgumentsByIndex[i] ?: continue
|
||||
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
||||
val opCall = statementGenerator.pregenerateCallReceivers(opResolvedCall)
|
||||
opCall.setExplicitReceiverValue(irLValue)
|
||||
opCall.irValueArgumentsByIndex[0] = ktRight.genExpr()
|
||||
statementGenerator.generateSamConversionForValueArgumentsIfRequired(opCall, opResolvedCall.resultingDescriptor)
|
||||
statementGenerator.generateSamConversionForValueArgumentsIfRequired(opCall, opResolvedCall)
|
||||
val irOpCall = CallGenerator(statementGenerator).generateCall(ktExpression, opCall, origin)
|
||||
|
||||
if (isSimpleAssignment) {
|
||||
|
||||
+1
-1
@@ -124,6 +124,6 @@ class ArrayAccessAssignmentReceiver(
|
||||
ktExpressionToIrIndexValue[ktExpression]?.load()
|
||||
}
|
||||
value?.let { lastArgument = it }
|
||||
callGenerator.statementGenerator.generateSamConversionForValueArgumentsIfRequired(this, resolvedCall.resultingDescriptor)
|
||||
callGenerator.statementGenerator.generateSamConversionForValueArgumentsIfRequired(this, resolvedCall)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// !LANGUAGE: +NewInference +SamConversionPerArgument
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
// FILE: Fn.java
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// !LANGUAGE: +NewInference +SamConversionForKotlinFunctions +SamConversionPerArgument
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
// FILE: Fn.java
|
||||
|
||||
+4
-3
@@ -5,7 +5,7 @@ FILE fqName:<root> fileName:/samConversionInGenericConstructorCall.kt
|
||||
RETURN type=kotlin.Nothing from='public final fun test1 (f: kotlin.Function1<kotlin.String, kotlin.String>): <root>.C<kotlin.String> declared in <root>'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (jxx: <root>.J<X of <root>.C?, X of <root>.C?>?) declared in <root>.C' type=<root>.C<kotlin.String> origin=null
|
||||
<class: X>: kotlin.String
|
||||
jxx: TYPE_OP type=<root>.J<kotlin.String?, kotlin.String?> origin=IMPLICIT_CAST typeOperand=<root>.J<kotlin.String?, kotlin.String?>
|
||||
jxx: TYPE_OP type=<root>.J<kotlin.String?, kotlin.String?>? origin=SAM_CONVERSION typeOperand=<root>.J<kotlin.String?, kotlin.String?>?
|
||||
GET_VAR 'f: kotlin.Function1<kotlin.String, kotlin.String> declared in <root>.test1' type=kotlin.Function1<kotlin.String, kotlin.String> origin=null
|
||||
FUN name:test2 visibility:public modality:FINAL <> (x:kotlin.Any) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:x index:0 type:kotlin.Any
|
||||
@@ -16,5 +16,6 @@ FILE fqName:<root> fileName:/samConversionInGenericConstructorCall.kt
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (jxx: <root>.J<X of <root>.C?, X of <root>.C?>?) declared in <root>.C' type=<root>.C<kotlin.String> origin=null
|
||||
<class: X>: kotlin.String
|
||||
jxx: TYPE_OP type=<root>.J<kotlin.String?, kotlin.String?> origin=IMPLICIT_CAST typeOperand=<root>.J<kotlin.String?, kotlin.String?>
|
||||
GET_VAR 'x: kotlin.Any declared in <root>.test2' type=kotlin.Any origin=null
|
||||
jxx: TYPE_OP type=<root>.J<kotlin.String?, kotlin.String?>? origin=SAM_CONVERSION typeOperand=<root>.J<kotlin.String?, kotlin.String?>?
|
||||
TYPE_OP type=kotlin.Function1<@[ParameterName(name = 'x')] kotlin.String?, kotlin.String?> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<@[ParameterName(name = 'x')] kotlin.String?, kotlin.String?>
|
||||
GET_VAR 'x: kotlin.Any declared in <root>.test2' type=kotlin.Any origin=null
|
||||
|
||||
+8
-7
@@ -8,9 +8,9 @@ FILE fqName:<root> fileName:/samConversionInGenericConstructorCall_NI.kt
|
||||
<class: Y>: kotlin.Int
|
||||
$outer: CONSTRUCTOR_CALL 'public constructor <init> (jxx: <root>.J<X of <root>.C?, X of <root>.C?>?) declared in <root>.C' type=<root>.C<kotlin.String> origin=null
|
||||
<class: X>: kotlin.String
|
||||
jxx: TYPE_OP type=<root>.J<kotlin.String?, kotlin.String?> origin=IMPLICIT_CAST typeOperand=<root>.J<kotlin.String?, kotlin.String?>
|
||||
jxx: TYPE_OP type=<root>.J<kotlin.String?, kotlin.String?>? origin=SAM_CONVERSION typeOperand=<root>.J<kotlin.String?, kotlin.String?>?
|
||||
GET_VAR 'f1: kotlin.Function1<kotlin.String, kotlin.String> declared in <root>.test3' type=kotlin.Function1<kotlin.String, kotlin.String> origin=null
|
||||
jxy: TYPE_OP type=<root>.J<kotlin.String?, kotlin.Int?> origin=IMPLICIT_CAST typeOperand=<root>.J<kotlin.String?, kotlin.Int?>
|
||||
jxy: TYPE_OP type=<root>.J<kotlin.String?, kotlin.Int?>? origin=SAM_CONVERSION typeOperand=<root>.J<kotlin.String?, kotlin.Int?>?
|
||||
GET_VAR 'f2: kotlin.Function1<kotlin.Int, kotlin.String> declared in <root>.test3' type=kotlin.Function1<kotlin.Int, kotlin.String> origin=null
|
||||
CLASS CLASS name:Outer modality:FINAL visibility:public superTypes:[kotlin.Any]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Outer<T1 of <root>.Outer>
|
||||
@@ -86,9 +86,9 @@ FILE fqName:<root> fileName:/samConversionInGenericConstructorCall_NI.kt
|
||||
<class: T2>: kotlin.Any
|
||||
$outer: CONSTRUCTOR_CALL 'public constructor <init> (j11: <root>.J<T1 of <root>.Outer, T1 of <root>.Outer>) [primary] declared in <root>.Outer' type=<root>.Outer<kotlin.String> origin=null
|
||||
<class: T1>: kotlin.String
|
||||
j11: TYPE_OP type=<root>.J<kotlin.String, kotlin.String> origin=IMPLICIT_CAST typeOperand=<root>.J<kotlin.String, kotlin.String>
|
||||
j11: TYPE_OP type=<root>.J<kotlin.String, kotlin.String> origin=SAM_CONVERSION typeOperand=<root>.J<kotlin.String, kotlin.String>
|
||||
GET_VAR 'f: kotlin.Function1<kotlin.String, kotlin.String> declared in <root>.test4' type=kotlin.Function1<kotlin.String, kotlin.String> origin=null
|
||||
j12: TYPE_OP type=<root>.J<kotlin.String, kotlin.Any> origin=IMPLICIT_CAST typeOperand=<root>.J<kotlin.String, kotlin.Any>
|
||||
j12: TYPE_OP type=<root>.J<kotlin.String, kotlin.Any> origin=SAM_CONVERSION typeOperand=<root>.J<kotlin.String, kotlin.Any>
|
||||
GET_VAR 'g: kotlin.Function1<kotlin.Any, kotlin.String> declared in <root>.test4' type=kotlin.Function1<kotlin.Any, kotlin.String> origin=null
|
||||
FUN name:testGenericJavaCtor1 visibility:public modality:FINAL <> (f:kotlin.Function1<kotlin.String, kotlin.Int>) returnType:<root>.G<kotlin.String>
|
||||
VALUE_PARAMETER name:f index:0 type:kotlin.Function1<kotlin.String, kotlin.Int>
|
||||
@@ -97,7 +97,7 @@ FILE fqName:<root> fileName:/samConversionInGenericConstructorCall_NI.kt
|
||||
CONSTRUCTOR_CALL 'public constructor <init> <TCtor> (x: <root>.J<TCtor of <root>.G.<init>?, TClass of <root>.G?>?) declared in <root>.G' type=<root>.G<kotlin.String> origin=null
|
||||
<class: TClass>: kotlin.String
|
||||
<TCtor>: kotlin.Int
|
||||
x: TYPE_OP type=<root>.J<kotlin.Int?, kotlin.String?> origin=IMPLICIT_CAST typeOperand=<root>.J<kotlin.Int?, kotlin.String?>
|
||||
x: TYPE_OP type=<root>.J<kotlin.Int?, kotlin.String?>? origin=SAM_CONVERSION typeOperand=<root>.J<kotlin.Int?, kotlin.String?>?
|
||||
GET_VAR 'f: kotlin.Function1<kotlin.String, kotlin.Int> declared in <root>.testGenericJavaCtor1' type=kotlin.Function1<kotlin.String, kotlin.Int> origin=null
|
||||
FUN name:testGenericJavaCtor2 visibility:public modality:FINAL <> (x:kotlin.Any) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:x index:0 type:kotlin.Any
|
||||
@@ -109,5 +109,6 @@ FILE fqName:<root> fileName:/samConversionInGenericConstructorCall_NI.kt
|
||||
CONSTRUCTOR_CALL 'public constructor <init> <TCtor> (x: <root>.J<TCtor of <root>.G.<init>?, TClass of <root>.G?>?) declared in <root>.G' type=<root>.G<kotlin.String> origin=null
|
||||
<class: TClass>: kotlin.String
|
||||
<TCtor>: kotlin.Int
|
||||
x: TYPE_OP type=<root>.J<kotlin.Int?, kotlin.String?> origin=IMPLICIT_CAST typeOperand=<root>.J<kotlin.Int?, kotlin.String?>
|
||||
GET_VAR 'x: kotlin.Any declared in <root>.testGenericJavaCtor2' type=kotlin.Any origin=null
|
||||
x: TYPE_OP type=<root>.J<kotlin.Int?, kotlin.String?>? origin=SAM_CONVERSION typeOperand=<root>.J<kotlin.Int?, kotlin.String?>?
|
||||
TYPE_OP type=kotlin.Function1<@[ParameterName(name = 'x')] kotlin.String?, kotlin.Int?> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<@[ParameterName(name = 'x')] kotlin.String?, kotlin.Int?>
|
||||
GET_VAR 'x: kotlin.Any declared in <root>.testGenericJavaCtor2' type=kotlin.Any origin=null
|
||||
|
||||
Reference in New Issue
Block a user