Introduce NewCallableReferenceResolvedCall and commonize other logic under NewAbstractResolvedCall
This commit is contained in:
+6
-5
@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.CallUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.NewAbstractResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl;
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.NewVariableAsFunctionResolvedCallImpl;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
@@ -776,21 +777,21 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
}
|
||||
|
||||
private void recordSamValuesForNewInference(@NotNull ResolvedCall<?> call) {
|
||||
NewResolvedCallImpl<?> newResolvedCall = getNewResolvedCallForCallWithPossibleSamConversions(call);
|
||||
if (newResolvedCall == null) return;
|
||||
NewAbstractResolvedCall<?> newResolvedCall = getNewResolvedCallForCallWithPossibleSamConversions(call);
|
||||
if (!(newResolvedCall instanceof NewResolvedCallImpl<?>)) return;
|
||||
|
||||
Map<ValueParameterDescriptor, ResolvedValueArgument> arguments = newResolvedCall.getValueArguments();
|
||||
for (ValueParameterDescriptor valueParameter : arguments.keySet()) {
|
||||
ResolvedValueArgument argument = arguments.get(valueParameter);
|
||||
if (argument instanceof ExpressionValueArgument) {
|
||||
ValueArgument valueArgument = ((ExpressionValueArgument) argument).getValueArgument();
|
||||
if (valueArgument != null && newResolvedCall.getExpectedTypeForSamConvertedArgument(valueArgument) != null) {
|
||||
if (valueArgument != null && ((NewResolvedCallImpl<?>)newResolvedCall).getExpectedTypeForSamConvertedArgument(valueArgument) != null) {
|
||||
recordSamTypeOnArgumentExpression(valueParameter, valueArgument);
|
||||
}
|
||||
} else if (argument instanceof VarargValueArgument) {
|
||||
VarargValueArgument varargValueArgument = (VarargValueArgument) argument;
|
||||
for (ValueArgument valueArgument : varargValueArgument.getArguments()) {
|
||||
if (valueArgument != null && newResolvedCall.getExpectedTypeForSamConvertedArgument(valueArgument) != null) {
|
||||
if (valueArgument != null && ((NewResolvedCallImpl<?>)newResolvedCall).getExpectedTypeForSamConvertedArgument(valueArgument) != null) {
|
||||
recordSamTypeOnArgumentExpression(valueParameter, valueArgument);
|
||||
}
|
||||
}
|
||||
@@ -799,7 +800,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static NewResolvedCallImpl<?> getNewResolvedCallForCallWithPossibleSamConversions(@NotNull ResolvedCall<?> call) {
|
||||
private static NewAbstractResolvedCall<?> getNewResolvedCallForCallWithPossibleSamConversions(@NotNull ResolvedCall<?> call) {
|
||||
if (call instanceof NewVariableAsFunctionResolvedCallImpl) {
|
||||
return ((NewVariableAsFunctionResolvedCallImpl) call).getFunctionCall();
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.resolve.calls.context.CallPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.isCaptured
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.wrapWithCapturingSubstitution
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeConstructorSubstitution
|
||||
|
||||
+3
-3
@@ -447,11 +447,11 @@ class BuilderInferenceSession(
|
||||
return commonSystem.notFixedTypeVariables.all { it.value.constraints.isEmpty() }
|
||||
}
|
||||
|
||||
private fun reportErrors(completedCall: CallInfo, resolvedCall: ResolvedCall<*>, errors: List<ConstraintSystemError>) {
|
||||
private fun reportErrors(completedCall: CallInfo, resolvedCall: NewAbstractResolvedCall<*>, errors: List<ConstraintSystemError>) {
|
||||
kotlinToResolvedCallTransformer.reportCallDiagnostic(
|
||||
completedCall.context,
|
||||
trace,
|
||||
completedCall.callResolutionResult.resultCallAtom,
|
||||
resolvedCall,
|
||||
resolvedCall.resultingDescriptor,
|
||||
errors.asDiagnostics()
|
||||
)
|
||||
@@ -528,7 +528,7 @@ class BuilderInferenceSession(
|
||||
private fun completeCall(
|
||||
callInfo: CallInfo,
|
||||
atomCompleter: ResolvedAtomCompleter
|
||||
): ResolvedCall<*>? {
|
||||
): NewAbstractResolvedCall<*>? {
|
||||
val resultCallAtom = callInfo.callResolutionResult.resultCallAtom
|
||||
resultCallAtom.subResolvedAtoms?.forEach { subResolvedAtom ->
|
||||
atomCompleter.completeAll(subResolvedAtom)
|
||||
|
||||
+4
-6
@@ -24,9 +24,7 @@ import org.jetbrains.kotlin.resolve.calls.context.ContextDependency;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.KotlinToResolvedCallTransformerKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl;
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.NewVariableAsFunctionResolvedCallImpl;
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.*;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.ResolvedCallUtilKt;
|
||||
|
||||
@@ -58,12 +56,12 @@ public class OverloadResolutionResultsUtil {
|
||||
) {
|
||||
if (results.isSingleResult() && context.contextDependency == ContextDependency.INDEPENDENT) {
|
||||
ResolvedCall<D> resultingCall = results.getResultingCall();
|
||||
NewResolvedCallImpl<?> newResolvedCall;
|
||||
NewAbstractResolvedCall<?> newResolvedCall;
|
||||
if (resultingCall instanceof NewVariableAsFunctionResolvedCallImpl) {
|
||||
newResolvedCall = ((NewVariableAsFunctionResolvedCallImpl) resultingCall).getFunctionCall();
|
||||
}
|
||||
else if (resultingCall instanceof NewResolvedCallImpl) {
|
||||
newResolvedCall = (NewResolvedCallImpl<?>) resultingCall;
|
||||
else if (resultingCall instanceof NewAbstractResolvedCall<?>) {
|
||||
newResolvedCall = (NewAbstractResolvedCall<?>) resultingCall;
|
||||
} else {
|
||||
newResolvedCall = null;
|
||||
}
|
||||
|
||||
+44
-33
@@ -101,13 +101,13 @@ class KotlinToResolvedCallTransformer(
|
||||
fun <D : CallableDescriptor> onlyTransform(
|
||||
resolvedCallAtom: ResolvedCallAtom,
|
||||
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||
): ResolvedCall<D> = transformToResolvedCall(resolvedCallAtom, null, null, diagnostics)
|
||||
): NewAbstractResolvedCall<D> = transformToResolvedCall(resolvedCallAtom, null, null, diagnostics)
|
||||
|
||||
fun <D : CallableDescriptor> transformAndReport(
|
||||
baseResolvedCall: CallResolutionResult,
|
||||
context: BasicCallResolutionContext,
|
||||
tracingStrategy: TracingStrategy,
|
||||
): ResolvedCall<D> {
|
||||
): NewAbstractResolvedCall<D> {
|
||||
return when (baseResolvedCall) {
|
||||
is PartialCallResolutionResult -> {
|
||||
val candidate = baseResolvedCall.resultCallAtom
|
||||
@@ -123,7 +123,7 @@ class KotlinToResolvedCallTransformer(
|
||||
)
|
||||
}
|
||||
|
||||
createStubResolvedCallAndWriteItToTrace(candidate, context.trace, baseResolvedCall.diagnostics, substitutor = null)
|
||||
createStubResolvedCallAndWriteItToTrace<D>(candidate, context.trace, baseResolvedCall.diagnostics, substitutor = null)
|
||||
}
|
||||
|
||||
is CompletedCallResolutionResult, is ErrorCallResolutionResult -> {
|
||||
@@ -141,7 +141,7 @@ class KotlinToResolvedCallTransformer(
|
||||
forwardCallToInferenceSession(baseResolvedCall, context, stub, tracingStrategy)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return stub as ResolvedCall<D>
|
||||
return stub as NewAbstractResolvedCall<D>
|
||||
}
|
||||
|
||||
val ktPrimitiveCompleter = ResolvedAtomCompleter(
|
||||
@@ -159,7 +159,7 @@ class KotlinToResolvedCallTransformer(
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val resolvedCall = ktPrimitiveCompleter.completeResolvedCall(
|
||||
candidate, baseResolvedCall.completedDiagnostic(resultSubstitutor),
|
||||
) as ResolvedCall<D>
|
||||
) as NewAbstractResolvedCall<D>
|
||||
|
||||
forwardCallToInferenceSession(baseResolvedCall, context, resolvedCall, tracingStrategy)
|
||||
|
||||
@@ -174,7 +174,7 @@ class KotlinToResolvedCallTransformer(
|
||||
private fun forwardCallToInferenceSession(
|
||||
baseResolvedCall: CallResolutionResult,
|
||||
context: BasicCallResolutionContext,
|
||||
resolvedCall: ResolvedCall<*>,
|
||||
resolvedCall: NewAbstractResolvedCall<*>,
|
||||
tracingStrategy: TracingStrategy,
|
||||
) {
|
||||
if (baseResolvedCall is CompletedCallResolutionResult) {
|
||||
@@ -187,7 +187,7 @@ class KotlinToResolvedCallTransformer(
|
||||
trace: BindingTrace,
|
||||
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||
substitutor: NewTypeSubstitutor?,
|
||||
): ResolvedCall<D> {
|
||||
): NewAbstractResolvedCall<D> {
|
||||
val result = transformToResolvedCall<D>(candidate, trace, substitutor, diagnostics)
|
||||
val psiKotlinCall = candidate.atom.psiKotlinCall
|
||||
val tracing = psiKotlinCall.safeAs<PSIKotlinCallForInvoke>()?.baseCall?.tracingStrategy ?: psiKotlinCall.tracingStrategy
|
||||
@@ -202,7 +202,7 @@ class KotlinToResolvedCallTransformer(
|
||||
trace: BindingTrace?,
|
||||
resultSubstitutor: NewTypeSubstitutor? = null, // if substitutor is not null, it means that this call is completed
|
||||
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||
): ResolvedCall<D> {
|
||||
): NewAbstractResolvedCall<D> {
|
||||
val psiKotlinCall = completedCallAtom.atom.psiKotlinCall
|
||||
return if (psiKotlinCall is PSIKotlinCallForInvoke) {
|
||||
val diagnosticsForVariableCall = if (completedCallAtom.candidateDescriptor is FunctionDescriptor) emptyList() else diagnostics
|
||||
@@ -211,7 +211,7 @@ class KotlinToResolvedCallTransformer(
|
||||
NewVariableAsFunctionResolvedCallImpl(
|
||||
createOrGet(psiKotlinCall.variableCall.resolvedCall, trace, resultSubstitutor, diagnosticsForVariableCall),
|
||||
createOrGet(completedCallAtom, trace, resultSubstitutor, diagnosticsForFunctionCall),
|
||||
) as ResolvedCall<D>
|
||||
) as NewAbstractResolvedCall<D>
|
||||
} else {
|
||||
createOrGet(completedCallAtom, trace, resultSubstitutor, diagnostics)
|
||||
}
|
||||
@@ -222,7 +222,7 @@ class KotlinToResolvedCallTransformer(
|
||||
trace: BindingTrace?,
|
||||
resultSubstitutor: NewTypeSubstitutor?,
|
||||
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||
): NewResolvedCallImpl<D> {
|
||||
): NewAbstractResolvedCall<D> {
|
||||
if (trace != null) {
|
||||
val storedResolvedCall = completedSimpleAtom.atom.psiKotlinCall.getResolvedPsiKotlinCall<D>(trace)
|
||||
if (storedResolvedCall != null) {
|
||||
@@ -231,13 +231,16 @@ class KotlinToResolvedCallTransformer(
|
||||
return storedResolvedCall
|
||||
}
|
||||
}
|
||||
return NewResolvedCallImpl(
|
||||
completedSimpleAtom,
|
||||
resultSubstitutor,
|
||||
diagnostics,
|
||||
typeApproximator,
|
||||
expressionTypingServices.languageVersionSettings
|
||||
)
|
||||
|
||||
return if (completedSimpleAtom.atom.callKind == KotlinCallKind.CALLABLE_REFERENCE) {
|
||||
NewCallableReferenceResolvedCall(
|
||||
completedSimpleAtom as ResolvedCallableReferenceCallAtom, typeApproximator, resultSubstitutor
|
||||
)
|
||||
} else {
|
||||
NewResolvedCallImpl(
|
||||
completedSimpleAtom, resultSubstitutor, diagnostics, typeApproximator, expressionTypingServices.languageVersionSettings
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun runCallCheckers(resolvedCall: ResolvedCall<*>, callCheckerContext: CallCheckerContext) {
|
||||
@@ -289,7 +292,9 @@ class KotlinToResolvedCallTransformer(
|
||||
}
|
||||
|
||||
// todo very beginning code
|
||||
fun runArgumentsChecks(context: BasicCallResolutionContext, resolvedCall: NewResolvedCallImpl<*>) {
|
||||
fun runArgumentsChecks(context: BasicCallResolutionContext, resolvedCall: NewAbstractResolvedCall<*>) {
|
||||
if (resolvedCall !is NewResolvedCallImpl<*>) return
|
||||
|
||||
for (valueArgument in resolvedCall.call.valueArguments) {
|
||||
val argumentMapping = resolvedCall.getArgumentMapping(valueArgument!!)
|
||||
val parameter: ValueParameterDescriptor?
|
||||
@@ -404,7 +409,7 @@ class KotlinToResolvedCallTransformer(
|
||||
if (!ExpressionTypingUtils.dependsOnExpectedType(expression))
|
||||
null
|
||||
else
|
||||
expression.getResolvedCall(context.trace.bindingContext)
|
||||
expression.getResolvedCall(context.trace.bindingContext) as? NewAbstractResolvedCall<*>
|
||||
|
||||
// See CallCompleter#updateRecordedTypeForArgument
|
||||
private fun updateRecordedTypeForArgument(
|
||||
@@ -461,32 +466,35 @@ class KotlinToResolvedCallTransformer(
|
||||
}
|
||||
|
||||
internal fun bind(trace: BindingTrace, resolvedCall: ResolvedCall<*>) {
|
||||
resolvedCall.safeAs<NewResolvedCallImpl<*>>()?.let { bind(trace, it) }
|
||||
resolvedCall.safeAs<NewAbstractResolvedCall<*>>()?.let { bind(trace, it) }
|
||||
resolvedCall.safeAs<NewVariableAsFunctionResolvedCallImpl>()?.let { bind(trace, it) }
|
||||
}
|
||||
|
||||
fun reportDiagnostics(
|
||||
context: BasicCallResolutionContext,
|
||||
trace: BindingTrace,
|
||||
resolvedCall: ResolvedCall<*>,
|
||||
resolvedCall: NewAbstractResolvedCall<*>,
|
||||
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||
) {
|
||||
when (resolvedCall) {
|
||||
is NewResolvedCallImpl ->
|
||||
reportCallDiagnostic(context, trace, resolvedCall.resolvedCallAtom, resolvedCall.resultingDescriptor, diagnostics)
|
||||
|
||||
is NewVariableAsFunctionResolvedCallImpl -> {
|
||||
val variableCall = resolvedCall.variableCall
|
||||
val functionCall = resolvedCall.functionCall
|
||||
|
||||
reportCallDiagnostic(context, trace, variableCall.resolvedCallAtom, variableCall.resultingDescriptor, diagnostics)
|
||||
reportCallDiagnostic(context, trace, functionCall.resolvedCallAtom, functionCall.resultingDescriptor, emptyList())
|
||||
reportCallDiagnostic(context, trace, variableCall, variableCall.resultingDescriptor, diagnostics)
|
||||
reportCallDiagnostic(context, trace, functionCall, functionCall.resultingDescriptor, emptyList())
|
||||
}
|
||||
else -> {
|
||||
val resolvedCallAtom = resolvedCall.resolvedCallAtom
|
||||
if (resolvedCallAtom != null) {
|
||||
reportCallDiagnostic(context, trace, resolvedCall, resolvedCall.resultingDescriptor, diagnostics)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun bind(trace: BindingTrace, simpleResolvedCall: NewResolvedCallImpl<*>) {
|
||||
val tracing = simpleResolvedCall.resolvedCallAtom.atom.psiKotlinCall.tracingStrategy
|
||||
private fun bind(trace: BindingTrace, simpleResolvedCall: NewAbstractResolvedCall<*>) {
|
||||
val tracing = simpleResolvedCall.psiKotlinCall.tracingStrategy
|
||||
|
||||
tracing.bindReference(trace, simpleResolvedCall)
|
||||
tracing.bindResolvedCall(trace, simpleResolvedCall)
|
||||
@@ -505,7 +513,7 @@ class KotlinToResolvedCallTransformer(
|
||||
fun reportCallDiagnostic(
|
||||
context: BasicCallResolutionContext,
|
||||
trace: BindingTrace,
|
||||
completedCallAtom: ResolvedCallAtom,
|
||||
resolvedCall: NewAbstractResolvedCall<*>,
|
||||
resultingDescriptor: CallableDescriptor,
|
||||
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||
) {
|
||||
@@ -513,14 +521,18 @@ class KotlinToResolvedCallTransformer(
|
||||
val newContext = context.replaceBindingTrace(trackingTrace)
|
||||
|
||||
val diagnosticHolder = KotlinDiagnosticsHolder.SimpleHolder()
|
||||
additionalDiagnosticReporter.reportAdditionalDiagnostics(completedCallAtom, resultingDescriptor, diagnosticHolder, diagnostics)
|
||||
val resolvedCallAtom = resolvedCall.resolvedCallAtom
|
||||
|
||||
if (resolvedCallAtom != null) {
|
||||
additionalDiagnosticReporter.reportAdditionalDiagnostics(resolvedCallAtom, resultingDescriptor, diagnosticHolder, diagnostics)
|
||||
}
|
||||
|
||||
val allDiagnostics = diagnostics + diagnosticHolder.getDiagnostics()
|
||||
|
||||
val diagnosticReporter = DiagnosticReporterByTrackingStrategy(
|
||||
constantExpressionEvaluator,
|
||||
newContext,
|
||||
completedCallAtom.atom.psiKotlinCall,
|
||||
resolvedCall.psiKotlinCall,
|
||||
context.dataFlowValueFactory,
|
||||
allDiagnostics,
|
||||
smartCastManager,
|
||||
@@ -533,8 +545,7 @@ class KotlinToResolvedCallTransformer(
|
||||
|
||||
if (diagnostic is ResolvedUsingDeprecatedVisibility) {
|
||||
reportResolvedUsingDeprecatedVisibility(
|
||||
completedCallAtom.atom.psiKotlinCall.psiCall, completedCallAtom.candidateDescriptor,
|
||||
resultingDescriptor, diagnostic, trace,
|
||||
resolvedCall.psiKotlinCall.psiCall, resolvedCall.candidateDescriptor, resultingDescriptor, diagnostic, trace,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -202,7 +202,7 @@ class PSIPartialCallInfo(
|
||||
class PSICompletedCallInfo(
|
||||
override val callResolutionResult: CompletedCallResolutionResult,
|
||||
context: BasicCallResolutionContext,
|
||||
val resolvedCall: ResolvedCall<*>,
|
||||
val resolvedCall: NewAbstractResolvedCall<*>,
|
||||
tracingStrategy: TracingStrategy
|
||||
) : CallInfo(callResolutionResult, context, tracingStrategy), CompletedCallInfo
|
||||
|
||||
|
||||
+13
-5
@@ -18,10 +18,13 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.compactIfPossible
|
||||
|
||||
sealed class NewAbstractResolvedCall<D : CallableDescriptor>() : ResolvedCall<D> {
|
||||
sealed class NewAbstractResolvedCall<D : CallableDescriptor> : ResolvedCall<D> {
|
||||
abstract val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
||||
abstract val kotlinCall: KotlinCall
|
||||
protected abstract val languageVersionSettings: LanguageVersionSettings
|
||||
abstract val languageVersionSettings: LanguageVersionSettings
|
||||
abstract val resolvedCallAtom: ResolvedCallAtom?
|
||||
abstract val psiKotlinCall: PSIKotlinCall
|
||||
abstract val isCompleted: Boolean
|
||||
|
||||
protected var argumentToParameterMap: Map<ValueArgument, ArgumentMatchImpl>? = null
|
||||
protected var _valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>? = null
|
||||
@@ -39,9 +42,15 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>() : ResolvedCall<D>
|
||||
return _valueArguments!!
|
||||
}
|
||||
|
||||
fun setValueArguments(m: Map<ValueParameterDescriptor, ResolvedValueArgument>) {
|
||||
_valueArguments = m
|
||||
}
|
||||
|
||||
open fun setResultingSubstitutor(substitutor: NewTypeSubstitutor?) {}
|
||||
|
||||
override fun getValueArgumentsByIndex(): List<ResolvedValueArgument>? {
|
||||
val arguments = ArrayList<ResolvedValueArgument?>(candidateDescriptor.valueParameters.size)
|
||||
for (i in 0..candidateDescriptor.valueParameters.size - 1) {
|
||||
for (i in 0 until candidateDescriptor.valueParameters.size) {
|
||||
arguments.add(null)
|
||||
}
|
||||
|
||||
@@ -86,7 +95,7 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>() : ResolvedCall<D>
|
||||
nonTrivialUpdatedResultInfo = dataFlowInfo.and(kotlinCall.psiKotlinCall.resultDataFlowInfo)
|
||||
}
|
||||
|
||||
protected abstract fun argumentToParameterMap(
|
||||
abstract fun argumentToParameterMap(
|
||||
resultingDescriptor: CallableDescriptor,
|
||||
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>,
|
||||
): Map<ValueArgument, ArgumentMatchImpl>
|
||||
@@ -130,5 +139,4 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>() : ResolvedCall<D>
|
||||
}
|
||||
}
|
||||
}.compactIfPossible()
|
||||
|
||||
}
|
||||
+257
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.tower
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
|
||||
import org.jetbrains.kotlin.psi.ValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.substitute
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateTypes
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.resolve.calls.util.isNotSimpleCall
|
||||
import org.jetbrains.kotlin.resolve.calls.util.toResolutionStatus
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
|
||||
class NewCallableReferenceResolvedCall<D : CallableDescriptor>(
|
||||
val resolvedAtom: ResolvedCallableReferenceAtom,
|
||||
val typeApproximator: TypeApproximator,
|
||||
substitutor: NewTypeSubstitutor?,
|
||||
) : NewAbstractResolvedCall<D>() {
|
||||
override var isCompleted = false
|
||||
private set
|
||||
|
||||
override val resolvedCallAtom: MutableResolvedCallAtom? = when (resolvedAtom) {
|
||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom
|
||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate?.resolvedCall
|
||||
}
|
||||
|
||||
override val psiKotlinCall: PSIKotlinCall = when (resolvedAtom) {
|
||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.atom.psiKotlinCall
|
||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.atom.call.psiKotlinCall
|
||||
}
|
||||
|
||||
init {
|
||||
setResultingSubstitutor(substitutor)
|
||||
}
|
||||
|
||||
var diagnostics: Collection<KotlinCallDiagnostic> = mutableListOf()
|
||||
private lateinit var resultingDescriptor: D
|
||||
|
||||
override fun getStatus(): ResolutionStatus {
|
||||
return getResultApplicability(diagnostics).toResolutionStatus()
|
||||
}
|
||||
|
||||
override fun getCandidateDescriptor(): D = when (resolvedAtom) {
|
||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.candidateDescriptor as D
|
||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate?.candidate as D
|
||||
}
|
||||
|
||||
override fun getResultingDescriptor(): D = resultingDescriptor
|
||||
|
||||
private var extensionReceiver = when (resolvedAtom) {
|
||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.extensionReceiverArgument?.receiverValue
|
||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate?.extensionReceiver?.receiver?.receiverValue
|
||||
}
|
||||
|
||||
private var dispatchReceiver = when (resolvedAtom) {
|
||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.dispatchReceiverArgument?.receiverValue
|
||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate?.dispatchReceiver?.receiver?.receiverValue
|
||||
}
|
||||
|
||||
override fun getExtensionReceiver(): ReceiverValue? = extensionReceiver
|
||||
|
||||
override fun getDispatchReceiver(): ReceiverValue? = dispatchReceiver
|
||||
|
||||
override fun getExplicitReceiverKind(): ExplicitReceiverKind = when (resolvedAtom) {
|
||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate!!.explicitReceiverKind
|
||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.explicitReceiverKind
|
||||
}
|
||||
|
||||
override fun getValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> = _valueArguments ?: emptyMap()
|
||||
|
||||
override fun getValueArgumentsByIndex(): List<ResolvedValueArgument>? {
|
||||
val arguments = ArrayList<ResolvedValueArgument?>(candidateDescriptor.valueParameters.size)
|
||||
for (i in 0 until candidateDescriptor.valueParameters.size) {
|
||||
arguments.add(null)
|
||||
}
|
||||
|
||||
for ((parameterDescriptor, value) in valueArguments) {
|
||||
val oldValue = arguments.set(parameterDescriptor.index, value)
|
||||
if (oldValue != null) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.any { it == null }) return null
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return arguments as List<ResolvedValueArgument>
|
||||
}
|
||||
|
||||
override fun getArgumentMapping(valueArgument: ValueArgument): ArgumentMapping = ArgumentUnmapped
|
||||
|
||||
override fun getTypeArguments(): Map<TypeParameterDescriptor, KotlinType> {
|
||||
val typeParameters = candidateDescriptor.typeParameters.takeIf { it.isNotEmpty() } ?: return emptyMap()
|
||||
return typeParameters.zip(typeArguments).toMap()
|
||||
}
|
||||
|
||||
private lateinit var typeArguments: List<UnwrappedType>
|
||||
|
||||
override fun getDataFlowInfoForArguments(): DataFlowInfoForArguments =
|
||||
MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY)
|
||||
|
||||
override fun getSmartCastDispatchReceiverType(): KotlinType? = null
|
||||
|
||||
|
||||
private fun updateDispatchReceiverType(newType: KotlinType) {
|
||||
if (dispatchReceiver?.type == newType) return
|
||||
dispatchReceiver = dispatchReceiver?.replaceType(newType)
|
||||
}
|
||||
|
||||
private fun updateExtensionReceiverType(newType: KotlinType) {
|
||||
if (extensionReceiver?.type == newType) return
|
||||
extensionReceiver = extensionReceiver?.replaceType(newType)
|
||||
}
|
||||
|
||||
override fun setResultingSubstitutor(substitutor: NewTypeSubstitutor?) {
|
||||
//clear cached values
|
||||
if (substitutor != null) {
|
||||
isCompleted = true
|
||||
dispatchReceiver?.type?.let {
|
||||
val newType = substitutor.safeSubstitute(it.unwrap())
|
||||
updateDispatchReceiverType(newType)
|
||||
}
|
||||
|
||||
extensionReceiver?.type?.let {
|
||||
val newType = substitutor.safeSubstitute(it.unwrap())
|
||||
updateExtensionReceiverType(newType)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
resultingDescriptor = substitutedResultingDescriptor(substitutor) as D
|
||||
|
||||
val sub = when (resolvedAtom) {
|
||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.freshVariablesSubstitutor
|
||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate!!.freshVariablesSubstitutor!!
|
||||
}
|
||||
|
||||
typeArguments = sub.freshVariables.map {
|
||||
val substituted = (substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType)
|
||||
typeApproximator
|
||||
.approximateToSuperType(substituted, TypeApproximatorConfiguration.IntegerLiteralsTypesApproximation)
|
||||
?: substituted
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSubstitutorWithoutFlexibleTypes(
|
||||
currentSubstitutor: NewTypeSubstitutor?,
|
||||
explicitTypeArguments: List<SimpleTypeArgument>,
|
||||
): NewTypeSubstitutor? {
|
||||
if (currentSubstitutor !is NewTypeSubstitutorByConstructorMap || explicitTypeArguments.isEmpty()) return currentSubstitutor
|
||||
if (!currentSubstitutor.map.any { (_, value) -> value.isFlexible() }) return currentSubstitutor
|
||||
|
||||
val sub = when (resolvedAtom) {
|
||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.freshVariablesSubstitutor
|
||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate!!.freshVariablesSubstitutor!!
|
||||
}
|
||||
|
||||
val typeVariables = sub.freshVariables
|
||||
val newSubstitutorMap = currentSubstitutor.map.toMutableMap()
|
||||
|
||||
explicitTypeArguments.forEachIndexed { index, typeArgument ->
|
||||
val typeVariableConstructor = typeVariables.getOrNull(index)?.freshTypeConstructor ?: return@forEachIndexed
|
||||
|
||||
newSubstitutorMap[typeVariableConstructor] =
|
||||
newSubstitutorMap[typeVariableConstructor]?.withNullabilityFromExplicitTypeArgument(typeArgument)
|
||||
?: return@forEachIndexed
|
||||
}
|
||||
|
||||
return NewTypeSubstitutorByConstructorMap(newSubstitutorMap)
|
||||
}
|
||||
|
||||
private fun KotlinType.withNullabilityFromExplicitTypeArgument(typeArgument: SimpleTypeArgument) =
|
||||
(if (typeArgument.type.isMarkedNullable) makeNullable() else makeNotNullable()).unwrap()
|
||||
|
||||
private fun substitutedResultingDescriptor(substitutor: NewTypeSubstitutor?): CallableDescriptor {
|
||||
val candidateDescriptor = when (resolvedAtom) {
|
||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.candidateDescriptor
|
||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate!!.candidate
|
||||
}
|
||||
|
||||
return when (candidateDescriptor) {
|
||||
is ClassConstructorDescriptor, is SyntheticMemberDescriptor<*> -> {
|
||||
val explicitTypeArguments = emptyList<SimpleTypeArgument>()
|
||||
|
||||
candidateDescriptor.substituteInferredVariablesAndApproximate(
|
||||
getSubstitutorWithoutFlexibleTypes(substitutor, explicitTypeArguments),
|
||||
)
|
||||
}
|
||||
is FunctionDescriptor -> {
|
||||
candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor, candidateDescriptor.isNotSimpleCall())
|
||||
}
|
||||
is PropertyDescriptor -> {
|
||||
if (candidateDescriptor.isNotSimpleCall()) {
|
||||
candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor)
|
||||
} else {
|
||||
candidateDescriptor
|
||||
}
|
||||
}
|
||||
else -> candidateDescriptor
|
||||
}
|
||||
}
|
||||
|
||||
private fun CallableDescriptor.substituteInferredVariablesAndApproximate(
|
||||
substitutor: NewTypeSubstitutor?,
|
||||
shouldApproximate: Boolean = true
|
||||
): CallableDescriptor {
|
||||
val sub = when (resolvedAtom) {
|
||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate!!.freshVariablesSubstitutor!!
|
||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.freshVariablesSubstitutor
|
||||
}
|
||||
|
||||
val inferredTypeVariablesSubstitutor = substitutor ?: FreshVariableNewTypeSubstitutor.Empty
|
||||
|
||||
return substitute(sub).substituteAndApproximateTypes(
|
||||
inferredTypeVariablesSubstitutor,
|
||||
typeApproximator = if (shouldApproximate) typeApproximator else null,
|
||||
positionDependentApproximation = true
|
||||
)
|
||||
}
|
||||
|
||||
override val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override val kotlinCall: KotlinCall
|
||||
get() = when (resolvedAtom) {
|
||||
is ResolvedCallableReferenceArgumentAtom ->
|
||||
(resolvedAtom.candidate?.kotlinCall as CallableReferenceKotlinCallArgument).call
|
||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.atom
|
||||
}
|
||||
override val languageVersionSettings: LanguageVersionSettings
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override fun containsOnlyOnlyInputTypesErrors(): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun argumentToParameterMap(
|
||||
resultingDescriptor: CallableDescriptor,
|
||||
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>
|
||||
): Map<ValueArgument, ArgumentMatchImpl> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
+11
-6
@@ -30,15 +30,16 @@ import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
|
||||
class NewResolvedCallImpl<D : CallableDescriptor>(
|
||||
val resolvedCallAtom: ResolvedCallAtom,
|
||||
override val resolvedCallAtom: ResolvedCallAtom,
|
||||
substitutor: NewTypeSubstitutor?,
|
||||
private var diagnostics: Collection<KotlinCallDiagnostic>,
|
||||
private val typeApproximator: TypeApproximator,
|
||||
override val languageVersionSettings: LanguageVersionSettings,
|
||||
) : NewAbstractResolvedCall<D>() {
|
||||
var isCompleted = false
|
||||
override val psiKotlinCall: PSIKotlinCall = resolvedCallAtom.atom.psiKotlinCall
|
||||
|
||||
override var isCompleted = false
|
||||
private set
|
||||
private lateinit var resultingDescriptor: D
|
||||
|
||||
@@ -104,7 +105,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
||||
dispatchReceiver = dispatchReceiver?.replaceType(newType)
|
||||
}
|
||||
|
||||
fun setResultingSubstitutor(substitutor: NewTypeSubstitutor?) {
|
||||
override fun setResultingSubstitutor(substitutor: NewTypeSubstitutor?) {
|
||||
//clear cached values
|
||||
argumentToParameterMap = null
|
||||
_valueArguments = null
|
||||
@@ -192,8 +193,12 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
||||
val inferredTypeVariablesSubstitutor = substitutor ?: FreshVariableNewTypeSubstitutor.Empty
|
||||
|
||||
// TODO: merge last two substitutors to avoid redundant descriptor substitutions
|
||||
return substitute(resolvedCallAtom.freshVariablesSubstitutor).substitute(resolvedCallAtom.knownParametersSubstitutor)
|
||||
.substituteAndApproximateTypes(inferredTypeVariablesSubstitutor, if (shouldApproximate) typeApproximator else null)
|
||||
return substitute(resolvedCallAtom.freshVariablesSubstitutor)
|
||||
.substitute(resolvedCallAtom.knownParametersSubstitutor)
|
||||
.substituteAndApproximateTypes(
|
||||
inferredTypeVariablesSubstitutor,
|
||||
typeApproximator.takeIf { shouldApproximate }
|
||||
)
|
||||
}
|
||||
|
||||
fun getArgumentTypeForConstantConvertedArgument(valueArgument: ValueArgument): IntegerValueTypeConstant? {
|
||||
|
||||
+23
-5
@@ -9,14 +9,32 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
|
||||
class NewVariableAsFunctionResolvedCallImpl(
|
||||
override val variableCall: NewResolvedCallImpl<VariableDescriptor>,
|
||||
override val functionCall: NewResolvedCallImpl<FunctionDescriptor>,
|
||||
) : VariableAsFunctionResolvedCall, ResolvedCall<FunctionDescriptor> by functionCall {
|
||||
val baseCall get() = functionCall.resolvedCallAtom.atom.psiKotlinCall.cast<PSIKotlinCallForInvoke>().baseCall
|
||||
override val variableCall: NewAbstractResolvedCall<VariableDescriptor>,
|
||||
override val functionCall: NewAbstractResolvedCall<FunctionDescriptor>,
|
||||
) : VariableAsFunctionResolvedCall, NewAbstractResolvedCall<FunctionDescriptor>() {
|
||||
override val resolvedCallAtom = functionCall.resolvedCallAtom
|
||||
override val psiKotlinCall: PSIKotlinCall = functionCall.psiKotlinCall
|
||||
val baseCall get() = functionCall.psiKotlinCall.cast<PSIKotlinCallForInvoke>().baseCall
|
||||
override fun getStatus() = functionCall.status
|
||||
override fun getCandidateDescriptor() = functionCall.candidateDescriptor
|
||||
override fun getResultingDescriptor() = functionCall.resultingDescriptor
|
||||
override fun getExtensionReceiver() = functionCall.extensionReceiver
|
||||
override fun getDispatchReceiver() = functionCall.dispatchReceiver
|
||||
override fun getExplicitReceiverKind() = functionCall.explicitReceiverKind
|
||||
override fun getTypeArguments() = functionCall.typeArguments
|
||||
override fun getSmartCastDispatchReceiverType() = functionCall.smartCastDispatchReceiverType
|
||||
override val argumentMappingByOriginal = functionCall.argumentMappingByOriginal
|
||||
override val kotlinCall = functionCall.kotlinCall
|
||||
override val languageVersionSettings = functionCall.languageVersionSettings
|
||||
override fun containsOnlyOnlyInputTypesErrors() = functionCall.containsOnlyOnlyInputTypesErrors()
|
||||
override fun argumentToParameterMap(
|
||||
resultingDescriptor: CallableDescriptor,
|
||||
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>
|
||||
) = functionCall.argumentToParameterMap(resultingDescriptor, valueArguments)
|
||||
override val isCompleted: Boolean = functionCall.isCompleted
|
||||
}
|
||||
Reference in New Issue
Block a user