Use recorded into descriptor inferred callable reference input/output types, to prevent leaking raw type parameter's types of reflectionCandidateType into the back-end

This commit is contained in:
Victor Petukhov
2021-05-21 15:32:41 +03:00
parent 84bd580f92
commit 31ed1ad5d9
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.resolve.calls.tower
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.createFunctionType
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ReceiverParameterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
@@ -14,10 +15,7 @@ import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.MissingSupertypesResolver
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator
import org.jetbrains.kotlin.resolve.calls.callUtil.toOldSubstitution
@@ -403,7 +401,7 @@ class ResolvedAtomCompleter(
private fun extractCallableReferenceResultTypeInfoFromDescriptor(
callableCandidate: CallableReferenceCandidate,
recorderDescriptor: CallableDescriptor
recordedDescriptor: CallableDescriptor
): CallableReferenceResultTypeInfo {
val explicitCallableReceiver = when (callableCandidate.explicitReceiverKind) {
ExplicitReceiverKind.DISPATCH_RECEIVER -> callableCandidate.dispatchReceiver
@@ -411,14 +409,31 @@ class ResolvedAtomCompleter(
else -> null
}
return CallableReferenceResultTypeInfo(
recorderDescriptor.dispatchReceiverParameter?.value,
recorderDescriptor.extensionReceiverParameter?.value,
recordedDescriptor.dispatchReceiverParameter?.value,
recordedDescriptor.extensionReceiverParameter?.value,
explicitCallableReceiver?.receiver?.receiverValue,
TypeSubstitutor.EMPTY,
callableCandidate.reflectionCandidateType
callableCandidate.reflectionCandidateType.replaceFunctionTypeArgumentsByDescriptor(recordedDescriptor)
)
}
@OptIn(ExperimentalStdlibApi::class)
private fun KotlinType.replaceFunctionTypeArgumentsByDescriptor(descriptor: CallableDescriptor) =
when (descriptor) {
is CallableMemberDescriptor -> {
val newArgumentTypes = buildList {
descriptor.extensionReceiverParameter?.let { add(it.type) }
addAll(descriptor.valueParameters.map { it.type })
add(descriptor.returnType)
}
if (newArgumentTypes.size == arguments.size) {
replace(arguments.mapIndexed { i, type -> newArgumentTypes[i]?.let { type.replaceType(it) } ?: type })
} else this
}
is ValueDescriptor -> replace(descriptor.type.arguments)
else -> this
}
private fun completeCallableReference(resolvedAtom: ResolvedCallableReferenceAtom) {
val psiCallArgument = resolvedAtom.atom.psiCallArgument as CallableReferenceKotlinCallArgumentImpl
val callableReferenceExpression = psiCallArgument.ktCallableReferenceExpression