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.DescriptorUtils;
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.CallUtilKt;
|
import org.jetbrains.kotlin.resolve.calls.util.CallUtilKt;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*;
|
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.NewResolvedCallImpl;
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.NewVariableAsFunctionResolvedCallImpl;
|
import org.jetbrains.kotlin.resolve.calls.tower.NewVariableAsFunctionResolvedCallImpl;
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||||
@@ -776,21 +777,21 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void recordSamValuesForNewInference(@NotNull ResolvedCall<?> call) {
|
private void recordSamValuesForNewInference(@NotNull ResolvedCall<?> call) {
|
||||||
NewResolvedCallImpl<?> newResolvedCall = getNewResolvedCallForCallWithPossibleSamConversions(call);
|
NewAbstractResolvedCall<?> newResolvedCall = getNewResolvedCallForCallWithPossibleSamConversions(call);
|
||||||
if (newResolvedCall == null) return;
|
if (!(newResolvedCall instanceof NewResolvedCallImpl<?>)) return;
|
||||||
|
|
||||||
Map<ValueParameterDescriptor, ResolvedValueArgument> arguments = newResolvedCall.getValueArguments();
|
Map<ValueParameterDescriptor, ResolvedValueArgument> arguments = newResolvedCall.getValueArguments();
|
||||||
for (ValueParameterDescriptor valueParameter : arguments.keySet()) {
|
for (ValueParameterDescriptor valueParameter : arguments.keySet()) {
|
||||||
ResolvedValueArgument argument = arguments.get(valueParameter);
|
ResolvedValueArgument argument = arguments.get(valueParameter);
|
||||||
if (argument instanceof ExpressionValueArgument) {
|
if (argument instanceof ExpressionValueArgument) {
|
||||||
ValueArgument valueArgument = ((ExpressionValueArgument) argument).getValueArgument();
|
ValueArgument valueArgument = ((ExpressionValueArgument) argument).getValueArgument();
|
||||||
if (valueArgument != null && newResolvedCall.getExpectedTypeForSamConvertedArgument(valueArgument) != null) {
|
if (valueArgument != null && ((NewResolvedCallImpl<?>)newResolvedCall).getExpectedTypeForSamConvertedArgument(valueArgument) != null) {
|
||||||
recordSamTypeOnArgumentExpression(valueParameter, valueArgument);
|
recordSamTypeOnArgumentExpression(valueParameter, valueArgument);
|
||||||
}
|
}
|
||||||
} else if (argument instanceof VarargValueArgument) {
|
} else if (argument instanceof VarargValueArgument) {
|
||||||
VarargValueArgument varargValueArgument = (VarargValueArgument) argument;
|
VarargValueArgument varargValueArgument = (VarargValueArgument) argument;
|
||||||
for (ValueArgument valueArgument : varargValueArgument.getArguments()) {
|
for (ValueArgument valueArgument : varargValueArgument.getArguments()) {
|
||||||
if (valueArgument != null && newResolvedCall.getExpectedTypeForSamConvertedArgument(valueArgument) != null) {
|
if (valueArgument != null && ((NewResolvedCallImpl<?>)newResolvedCall).getExpectedTypeForSamConvertedArgument(valueArgument) != null) {
|
||||||
recordSamTypeOnArgumentExpression(valueParameter, valueArgument);
|
recordSamTypeOnArgumentExpression(valueParameter, valueArgument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -799,7 +800,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static NewResolvedCallImpl<?> getNewResolvedCallForCallWithPossibleSamConversions(@NotNull ResolvedCall<?> call) {
|
private static NewAbstractResolvedCall<?> getNewResolvedCallForCallWithPossibleSamConversions(@NotNull ResolvedCall<?> call) {
|
||||||
if (call instanceof NewVariableAsFunctionResolvedCallImpl) {
|
if (call instanceof NewVariableAsFunctionResolvedCallImpl) {
|
||||||
return ((NewVariableAsFunctionResolvedCallImpl) call).getFunctionCall();
|
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.context.ResolutionContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.isCaptured
|
import org.jetbrains.kotlin.resolve.calls.inference.isCaptured
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.wrapWithCapturingSubstitution
|
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.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeConstructorSubstitution
|
import org.jetbrains.kotlin.types.TypeConstructorSubstitution
|
||||||
|
|||||||
+3
-3
@@ -447,11 +447,11 @@ class BuilderInferenceSession(
|
|||||||
return commonSystem.notFixedTypeVariables.all { it.value.constraints.isEmpty() }
|
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(
|
kotlinToResolvedCallTransformer.reportCallDiagnostic(
|
||||||
completedCall.context,
|
completedCall.context,
|
||||||
trace,
|
trace,
|
||||||
completedCall.callResolutionResult.resultCallAtom,
|
resolvedCall,
|
||||||
resolvedCall.resultingDescriptor,
|
resolvedCall.resultingDescriptor,
|
||||||
errors.asDiagnostics()
|
errors.asDiagnostics()
|
||||||
)
|
)
|
||||||
@@ -528,7 +528,7 @@ class BuilderInferenceSession(
|
|||||||
private fun completeCall(
|
private fun completeCall(
|
||||||
callInfo: CallInfo,
|
callInfo: CallInfo,
|
||||||
atomCompleter: ResolvedAtomCompleter
|
atomCompleter: ResolvedAtomCompleter
|
||||||
): ResolvedCall<*>? {
|
): NewAbstractResolvedCall<*>? {
|
||||||
val resultCallAtom = callInfo.callResolutionResult.resultCallAtom
|
val resultCallAtom = callInfo.callResolutionResult.resultCallAtom
|
||||||
resultCallAtom.subResolvedAtoms?.forEach { subResolvedAtom ->
|
resultCallAtom.subResolvedAtoms?.forEach { subResolvedAtom ->
|
||||||
atomCompleter.completeAll(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.context.ResolutionContext;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.KotlinToResolvedCallTransformerKt;
|
import org.jetbrains.kotlin.resolve.calls.tower.*;
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl;
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.NewVariableAsFunctionResolvedCallImpl;
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.ResolvedCallUtilKt;
|
import org.jetbrains.kotlin.resolve.calls.util.ResolvedCallUtilKt;
|
||||||
|
|
||||||
@@ -58,12 +56,12 @@ public class OverloadResolutionResultsUtil {
|
|||||||
) {
|
) {
|
||||||
if (results.isSingleResult() && context.contextDependency == ContextDependency.INDEPENDENT) {
|
if (results.isSingleResult() && context.contextDependency == ContextDependency.INDEPENDENT) {
|
||||||
ResolvedCall<D> resultingCall = results.getResultingCall();
|
ResolvedCall<D> resultingCall = results.getResultingCall();
|
||||||
NewResolvedCallImpl<?> newResolvedCall;
|
NewAbstractResolvedCall<?> newResolvedCall;
|
||||||
if (resultingCall instanceof NewVariableAsFunctionResolvedCallImpl) {
|
if (resultingCall instanceof NewVariableAsFunctionResolvedCallImpl) {
|
||||||
newResolvedCall = ((NewVariableAsFunctionResolvedCallImpl) resultingCall).getFunctionCall();
|
newResolvedCall = ((NewVariableAsFunctionResolvedCallImpl) resultingCall).getFunctionCall();
|
||||||
}
|
}
|
||||||
else if (resultingCall instanceof NewResolvedCallImpl) {
|
else if (resultingCall instanceof NewAbstractResolvedCall<?>) {
|
||||||
newResolvedCall = (NewResolvedCallImpl<?>) resultingCall;
|
newResolvedCall = (NewAbstractResolvedCall<?>) resultingCall;
|
||||||
} else {
|
} else {
|
||||||
newResolvedCall = null;
|
newResolvedCall = null;
|
||||||
}
|
}
|
||||||
|
|||||||
+44
-33
@@ -101,13 +101,13 @@ class KotlinToResolvedCallTransformer(
|
|||||||
fun <D : CallableDescriptor> onlyTransform(
|
fun <D : CallableDescriptor> onlyTransform(
|
||||||
resolvedCallAtom: ResolvedCallAtom,
|
resolvedCallAtom: ResolvedCallAtom,
|
||||||
diagnostics: Collection<KotlinCallDiagnostic>,
|
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||||
): ResolvedCall<D> = transformToResolvedCall(resolvedCallAtom, null, null, diagnostics)
|
): NewAbstractResolvedCall<D> = transformToResolvedCall(resolvedCallAtom, null, null, diagnostics)
|
||||||
|
|
||||||
fun <D : CallableDescriptor> transformAndReport(
|
fun <D : CallableDescriptor> transformAndReport(
|
||||||
baseResolvedCall: CallResolutionResult,
|
baseResolvedCall: CallResolutionResult,
|
||||||
context: BasicCallResolutionContext,
|
context: BasicCallResolutionContext,
|
||||||
tracingStrategy: TracingStrategy,
|
tracingStrategy: TracingStrategy,
|
||||||
): ResolvedCall<D> {
|
): NewAbstractResolvedCall<D> {
|
||||||
return when (baseResolvedCall) {
|
return when (baseResolvedCall) {
|
||||||
is PartialCallResolutionResult -> {
|
is PartialCallResolutionResult -> {
|
||||||
val candidate = baseResolvedCall.resultCallAtom
|
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 -> {
|
is CompletedCallResolutionResult, is ErrorCallResolutionResult -> {
|
||||||
@@ -141,7 +141,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
forwardCallToInferenceSession(baseResolvedCall, context, stub, tracingStrategy)
|
forwardCallToInferenceSession(baseResolvedCall, context, stub, tracingStrategy)
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return stub as ResolvedCall<D>
|
return stub as NewAbstractResolvedCall<D>
|
||||||
}
|
}
|
||||||
|
|
||||||
val ktPrimitiveCompleter = ResolvedAtomCompleter(
|
val ktPrimitiveCompleter = ResolvedAtomCompleter(
|
||||||
@@ -159,7 +159,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val resolvedCall = ktPrimitiveCompleter.completeResolvedCall(
|
val resolvedCall = ktPrimitiveCompleter.completeResolvedCall(
|
||||||
candidate, baseResolvedCall.completedDiagnostic(resultSubstitutor),
|
candidate, baseResolvedCall.completedDiagnostic(resultSubstitutor),
|
||||||
) as ResolvedCall<D>
|
) as NewAbstractResolvedCall<D>
|
||||||
|
|
||||||
forwardCallToInferenceSession(baseResolvedCall, context, resolvedCall, tracingStrategy)
|
forwardCallToInferenceSession(baseResolvedCall, context, resolvedCall, tracingStrategy)
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
private fun forwardCallToInferenceSession(
|
private fun forwardCallToInferenceSession(
|
||||||
baseResolvedCall: CallResolutionResult,
|
baseResolvedCall: CallResolutionResult,
|
||||||
context: BasicCallResolutionContext,
|
context: BasicCallResolutionContext,
|
||||||
resolvedCall: ResolvedCall<*>,
|
resolvedCall: NewAbstractResolvedCall<*>,
|
||||||
tracingStrategy: TracingStrategy,
|
tracingStrategy: TracingStrategy,
|
||||||
) {
|
) {
|
||||||
if (baseResolvedCall is CompletedCallResolutionResult) {
|
if (baseResolvedCall is CompletedCallResolutionResult) {
|
||||||
@@ -187,7 +187,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
diagnostics: Collection<KotlinCallDiagnostic>,
|
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||||
substitutor: NewTypeSubstitutor?,
|
substitutor: NewTypeSubstitutor?,
|
||||||
): ResolvedCall<D> {
|
): NewAbstractResolvedCall<D> {
|
||||||
val result = transformToResolvedCall<D>(candidate, trace, substitutor, diagnostics)
|
val result = transformToResolvedCall<D>(candidate, trace, substitutor, diagnostics)
|
||||||
val psiKotlinCall = candidate.atom.psiKotlinCall
|
val psiKotlinCall = candidate.atom.psiKotlinCall
|
||||||
val tracing = psiKotlinCall.safeAs<PSIKotlinCallForInvoke>()?.baseCall?.tracingStrategy ?: psiKotlinCall.tracingStrategy
|
val tracing = psiKotlinCall.safeAs<PSIKotlinCallForInvoke>()?.baseCall?.tracingStrategy ?: psiKotlinCall.tracingStrategy
|
||||||
@@ -202,7 +202,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
trace: BindingTrace?,
|
trace: BindingTrace?,
|
||||||
resultSubstitutor: NewTypeSubstitutor? = null, // if substitutor is not null, it means that this call is completed
|
resultSubstitutor: NewTypeSubstitutor? = null, // if substitutor is not null, it means that this call is completed
|
||||||
diagnostics: Collection<KotlinCallDiagnostic>,
|
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||||
): ResolvedCall<D> {
|
): NewAbstractResolvedCall<D> {
|
||||||
val psiKotlinCall = completedCallAtom.atom.psiKotlinCall
|
val psiKotlinCall = completedCallAtom.atom.psiKotlinCall
|
||||||
return if (psiKotlinCall is PSIKotlinCallForInvoke) {
|
return if (psiKotlinCall is PSIKotlinCallForInvoke) {
|
||||||
val diagnosticsForVariableCall = if (completedCallAtom.candidateDescriptor is FunctionDescriptor) emptyList() else diagnostics
|
val diagnosticsForVariableCall = if (completedCallAtom.candidateDescriptor is FunctionDescriptor) emptyList() else diagnostics
|
||||||
@@ -211,7 +211,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
NewVariableAsFunctionResolvedCallImpl(
|
NewVariableAsFunctionResolvedCallImpl(
|
||||||
createOrGet(psiKotlinCall.variableCall.resolvedCall, trace, resultSubstitutor, diagnosticsForVariableCall),
|
createOrGet(psiKotlinCall.variableCall.resolvedCall, trace, resultSubstitutor, diagnosticsForVariableCall),
|
||||||
createOrGet(completedCallAtom, trace, resultSubstitutor, diagnosticsForFunctionCall),
|
createOrGet(completedCallAtom, trace, resultSubstitutor, diagnosticsForFunctionCall),
|
||||||
) as ResolvedCall<D>
|
) as NewAbstractResolvedCall<D>
|
||||||
} else {
|
} else {
|
||||||
createOrGet(completedCallAtom, trace, resultSubstitutor, diagnostics)
|
createOrGet(completedCallAtom, trace, resultSubstitutor, diagnostics)
|
||||||
}
|
}
|
||||||
@@ -222,7 +222,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
trace: BindingTrace?,
|
trace: BindingTrace?,
|
||||||
resultSubstitutor: NewTypeSubstitutor?,
|
resultSubstitutor: NewTypeSubstitutor?,
|
||||||
diagnostics: Collection<KotlinCallDiagnostic>,
|
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||||
): NewResolvedCallImpl<D> {
|
): NewAbstractResolvedCall<D> {
|
||||||
if (trace != null) {
|
if (trace != null) {
|
||||||
val storedResolvedCall = completedSimpleAtom.atom.psiKotlinCall.getResolvedPsiKotlinCall<D>(trace)
|
val storedResolvedCall = completedSimpleAtom.atom.psiKotlinCall.getResolvedPsiKotlinCall<D>(trace)
|
||||||
if (storedResolvedCall != null) {
|
if (storedResolvedCall != null) {
|
||||||
@@ -231,13 +231,16 @@ class KotlinToResolvedCallTransformer(
|
|||||||
return storedResolvedCall
|
return storedResolvedCall
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NewResolvedCallImpl(
|
|
||||||
completedSimpleAtom,
|
return if (completedSimpleAtom.atom.callKind == KotlinCallKind.CALLABLE_REFERENCE) {
|
||||||
resultSubstitutor,
|
NewCallableReferenceResolvedCall(
|
||||||
diagnostics,
|
completedSimpleAtom as ResolvedCallableReferenceCallAtom, typeApproximator, resultSubstitutor
|
||||||
typeApproximator,
|
)
|
||||||
expressionTypingServices.languageVersionSettings
|
} else {
|
||||||
)
|
NewResolvedCallImpl(
|
||||||
|
completedSimpleAtom, resultSubstitutor, diagnostics, typeApproximator, expressionTypingServices.languageVersionSettings
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun runCallCheckers(resolvedCall: ResolvedCall<*>, callCheckerContext: CallCheckerContext) {
|
fun runCallCheckers(resolvedCall: ResolvedCall<*>, callCheckerContext: CallCheckerContext) {
|
||||||
@@ -289,7 +292,9 @@ class KotlinToResolvedCallTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// todo very beginning code
|
// 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) {
|
for (valueArgument in resolvedCall.call.valueArguments) {
|
||||||
val argumentMapping = resolvedCall.getArgumentMapping(valueArgument!!)
|
val argumentMapping = resolvedCall.getArgumentMapping(valueArgument!!)
|
||||||
val parameter: ValueParameterDescriptor?
|
val parameter: ValueParameterDescriptor?
|
||||||
@@ -404,7 +409,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
if (!ExpressionTypingUtils.dependsOnExpectedType(expression))
|
if (!ExpressionTypingUtils.dependsOnExpectedType(expression))
|
||||||
null
|
null
|
||||||
else
|
else
|
||||||
expression.getResolvedCall(context.trace.bindingContext)
|
expression.getResolvedCall(context.trace.bindingContext) as? NewAbstractResolvedCall<*>
|
||||||
|
|
||||||
// See CallCompleter#updateRecordedTypeForArgument
|
// See CallCompleter#updateRecordedTypeForArgument
|
||||||
private fun updateRecordedTypeForArgument(
|
private fun updateRecordedTypeForArgument(
|
||||||
@@ -461,32 +466,35 @@ class KotlinToResolvedCallTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun bind(trace: BindingTrace, resolvedCall: ResolvedCall<*>) {
|
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) }
|
resolvedCall.safeAs<NewVariableAsFunctionResolvedCallImpl>()?.let { bind(trace, it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reportDiagnostics(
|
fun reportDiagnostics(
|
||||||
context: BasicCallResolutionContext,
|
context: BasicCallResolutionContext,
|
||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
resolvedCall: ResolvedCall<*>,
|
resolvedCall: NewAbstractResolvedCall<*>,
|
||||||
diagnostics: Collection<KotlinCallDiagnostic>,
|
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||||
) {
|
) {
|
||||||
when (resolvedCall) {
|
when (resolvedCall) {
|
||||||
is NewResolvedCallImpl ->
|
|
||||||
reportCallDiagnostic(context, trace, resolvedCall.resolvedCallAtom, resolvedCall.resultingDescriptor, diagnostics)
|
|
||||||
|
|
||||||
is NewVariableAsFunctionResolvedCallImpl -> {
|
is NewVariableAsFunctionResolvedCallImpl -> {
|
||||||
val variableCall = resolvedCall.variableCall
|
val variableCall = resolvedCall.variableCall
|
||||||
val functionCall = resolvedCall.functionCall
|
val functionCall = resolvedCall.functionCall
|
||||||
|
|
||||||
reportCallDiagnostic(context, trace, variableCall.resolvedCallAtom, variableCall.resultingDescriptor, diagnostics)
|
reportCallDiagnostic(context, trace, variableCall, variableCall.resultingDescriptor, diagnostics)
|
||||||
reportCallDiagnostic(context, trace, functionCall.resolvedCallAtom, functionCall.resultingDescriptor, emptyList())
|
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<*>) {
|
private fun bind(trace: BindingTrace, simpleResolvedCall: NewAbstractResolvedCall<*>) {
|
||||||
val tracing = simpleResolvedCall.resolvedCallAtom.atom.psiKotlinCall.tracingStrategy
|
val tracing = simpleResolvedCall.psiKotlinCall.tracingStrategy
|
||||||
|
|
||||||
tracing.bindReference(trace, simpleResolvedCall)
|
tracing.bindReference(trace, simpleResolvedCall)
|
||||||
tracing.bindResolvedCall(trace, simpleResolvedCall)
|
tracing.bindResolvedCall(trace, simpleResolvedCall)
|
||||||
@@ -505,7 +513,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
fun reportCallDiagnostic(
|
fun reportCallDiagnostic(
|
||||||
context: BasicCallResolutionContext,
|
context: BasicCallResolutionContext,
|
||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
completedCallAtom: ResolvedCallAtom,
|
resolvedCall: NewAbstractResolvedCall<*>,
|
||||||
resultingDescriptor: CallableDescriptor,
|
resultingDescriptor: CallableDescriptor,
|
||||||
diagnostics: Collection<KotlinCallDiagnostic>,
|
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||||
) {
|
) {
|
||||||
@@ -513,14 +521,18 @@ class KotlinToResolvedCallTransformer(
|
|||||||
val newContext = context.replaceBindingTrace(trackingTrace)
|
val newContext = context.replaceBindingTrace(trackingTrace)
|
||||||
|
|
||||||
val diagnosticHolder = KotlinDiagnosticsHolder.SimpleHolder()
|
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 allDiagnostics = diagnostics + diagnosticHolder.getDiagnostics()
|
||||||
|
|
||||||
val diagnosticReporter = DiagnosticReporterByTrackingStrategy(
|
val diagnosticReporter = DiagnosticReporterByTrackingStrategy(
|
||||||
constantExpressionEvaluator,
|
constantExpressionEvaluator,
|
||||||
newContext,
|
newContext,
|
||||||
completedCallAtom.atom.psiKotlinCall,
|
resolvedCall.psiKotlinCall,
|
||||||
context.dataFlowValueFactory,
|
context.dataFlowValueFactory,
|
||||||
allDiagnostics,
|
allDiagnostics,
|
||||||
smartCastManager,
|
smartCastManager,
|
||||||
@@ -533,8 +545,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
|
|
||||||
if (diagnostic is ResolvedUsingDeprecatedVisibility) {
|
if (diagnostic is ResolvedUsingDeprecatedVisibility) {
|
||||||
reportResolvedUsingDeprecatedVisibility(
|
reportResolvedUsingDeprecatedVisibility(
|
||||||
completedCallAtom.atom.psiKotlinCall.psiCall, completedCallAtom.candidateDescriptor,
|
resolvedCall.psiKotlinCall.psiCall, resolvedCall.candidateDescriptor, resultingDescriptor, diagnostic, trace,
|
||||||
resultingDescriptor, diagnostic, trace,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -202,7 +202,7 @@ class PSIPartialCallInfo(
|
|||||||
class PSICompletedCallInfo(
|
class PSICompletedCallInfo(
|
||||||
override val callResolutionResult: CompletedCallResolutionResult,
|
override val callResolutionResult: CompletedCallResolutionResult,
|
||||||
context: BasicCallResolutionContext,
|
context: BasicCallResolutionContext,
|
||||||
val resolvedCall: ResolvedCall<*>,
|
val resolvedCall: NewAbstractResolvedCall<*>,
|
||||||
tracingStrategy: TracingStrategy
|
tracingStrategy: TracingStrategy
|
||||||
) : CallInfo(callResolutionResult, context, tracingStrategy), CompletedCallInfo
|
) : 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.SmartList
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.compactIfPossible
|
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 argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
||||||
abstract val kotlinCall: KotlinCall
|
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 argumentToParameterMap: Map<ValueArgument, ArgumentMatchImpl>? = null
|
||||||
protected var _valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>? = null
|
protected var _valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>? = null
|
||||||
@@ -39,9 +42,15 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>() : ResolvedCall<D>
|
|||||||
return _valueArguments!!
|
return _valueArguments!!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setValueArguments(m: Map<ValueParameterDescriptor, ResolvedValueArgument>) {
|
||||||
|
_valueArguments = m
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun setResultingSubstitutor(substitutor: NewTypeSubstitutor?) {}
|
||||||
|
|
||||||
override fun getValueArgumentsByIndex(): List<ResolvedValueArgument>? {
|
override fun getValueArgumentsByIndex(): List<ResolvedValueArgument>? {
|
||||||
val arguments = ArrayList<ResolvedValueArgument?>(candidateDescriptor.valueParameters.size)
|
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)
|
arguments.add(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +95,7 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>() : ResolvedCall<D>
|
|||||||
nonTrivialUpdatedResultInfo = dataFlowInfo.and(kotlinCall.psiKotlinCall.resultDataFlowInfo)
|
nonTrivialUpdatedResultInfo = dataFlowInfo.and(kotlinCall.psiKotlinCall.resultDataFlowInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun argumentToParameterMap(
|
abstract fun argumentToParameterMap(
|
||||||
resultingDescriptor: CallableDescriptor,
|
resultingDescriptor: CallableDescriptor,
|
||||||
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>,
|
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>,
|
||||||
): Map<ValueArgument, ArgumentMatchImpl>
|
): Map<ValueArgument, ArgumentMatchImpl>
|
||||||
@@ -130,5 +139,4 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>() : ResolvedCall<D>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.compactIfPossible()
|
}.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.types.typeUtil.makeNullable
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
|
|
||||||
class NewResolvedCallImpl<D : CallableDescriptor>(
|
class NewResolvedCallImpl<D : CallableDescriptor>(
|
||||||
val resolvedCallAtom: ResolvedCallAtom,
|
override val resolvedCallAtom: ResolvedCallAtom,
|
||||||
substitutor: NewTypeSubstitutor?,
|
substitutor: NewTypeSubstitutor?,
|
||||||
private var diagnostics: Collection<KotlinCallDiagnostic>,
|
private var diagnostics: Collection<KotlinCallDiagnostic>,
|
||||||
private val typeApproximator: TypeApproximator,
|
private val typeApproximator: TypeApproximator,
|
||||||
override val languageVersionSettings: LanguageVersionSettings,
|
override val languageVersionSettings: LanguageVersionSettings,
|
||||||
) : NewAbstractResolvedCall<D>() {
|
) : NewAbstractResolvedCall<D>() {
|
||||||
var isCompleted = false
|
override val psiKotlinCall: PSIKotlinCall = resolvedCallAtom.atom.psiKotlinCall
|
||||||
|
|
||||||
|
override var isCompleted = false
|
||||||
private set
|
private set
|
||||||
private lateinit var resultingDescriptor: D
|
private lateinit var resultingDescriptor: D
|
||||||
|
|
||||||
@@ -104,7 +105,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
|||||||
dispatchReceiver = dispatchReceiver?.replaceType(newType)
|
dispatchReceiver = dispatchReceiver?.replaceType(newType)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setResultingSubstitutor(substitutor: NewTypeSubstitutor?) {
|
override fun setResultingSubstitutor(substitutor: NewTypeSubstitutor?) {
|
||||||
//clear cached values
|
//clear cached values
|
||||||
argumentToParameterMap = null
|
argumentToParameterMap = null
|
||||||
_valueArguments = null
|
_valueArguments = null
|
||||||
@@ -192,8 +193,12 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
|||||||
val inferredTypeVariablesSubstitutor = substitutor ?: FreshVariableNewTypeSubstitutor.Empty
|
val inferredTypeVariablesSubstitutor = substitutor ?: FreshVariableNewTypeSubstitutor.Empty
|
||||||
|
|
||||||
// TODO: merge last two substitutors to avoid redundant descriptor substitutions
|
// TODO: merge last two substitutors to avoid redundant descriptor substitutions
|
||||||
return substitute(resolvedCallAtom.freshVariablesSubstitutor).substitute(resolvedCallAtom.knownParametersSubstitutor)
|
return substitute(resolvedCallAtom.freshVariablesSubstitutor)
|
||||||
.substituteAndApproximateTypes(inferredTypeVariablesSubstitutor, if (shouldApproximate) typeApproximator else null)
|
.substitute(resolvedCallAtom.knownParametersSubstitutor)
|
||||||
|
.substituteAndApproximateTypes(
|
||||||
|
inferredTypeVariablesSubstitutor,
|
||||||
|
typeApproximator.takeIf { shouldApproximate }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getArgumentTypeForConstantConvertedArgument(valueArgument: ValueArgument): IntegerValueTypeConstant? {
|
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.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
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.ResolvedValueArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
|
|
||||||
class NewVariableAsFunctionResolvedCallImpl(
|
class NewVariableAsFunctionResolvedCallImpl(
|
||||||
override val variableCall: NewResolvedCallImpl<VariableDescriptor>,
|
override val variableCall: NewAbstractResolvedCall<VariableDescriptor>,
|
||||||
override val functionCall: NewResolvedCallImpl<FunctionDescriptor>,
|
override val functionCall: NewAbstractResolvedCall<FunctionDescriptor>,
|
||||||
) : VariableAsFunctionResolvedCall, ResolvedCall<FunctionDescriptor> by functionCall {
|
) : VariableAsFunctionResolvedCall, NewAbstractResolvedCall<FunctionDescriptor>() {
|
||||||
val baseCall get() = functionCall.resolvedCallAtom.atom.psiKotlinCall.cast<PSIKotlinCallForInvoke>().baseCall
|
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