[NI] Clear partially resolved calls after resolve of top-level call
#KT-32433 Fixed
This commit is contained in:
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.name.FqNameUnsafe;
|
|||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext;
|
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext;
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemCompleter;
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemCompleter;
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.PartialCallContainer;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.PartialCallResolutionResult;
|
import org.jetbrains.kotlin.resolve.calls.model.PartialCallResolutionResult;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||||
@@ -121,7 +122,7 @@ public interface BindingContext {
|
|||||||
new BasicWritableSlice<>(DO_NOTHING);
|
new BasicWritableSlice<>(DO_NOTHING);
|
||||||
|
|
||||||
WritableSlice<Call, ResolvedCall<?>> RESOLVED_CALL = new BasicWritableSlice<>(DO_NOTHING);
|
WritableSlice<Call, ResolvedCall<?>> RESOLVED_CALL = new BasicWritableSlice<>(DO_NOTHING);
|
||||||
WritableSlice<Call, PartialCallResolutionResult> ONLY_RESOLVED_CALL = new BasicWritableSlice<>(DO_NOTHING);
|
WritableSlice<Call, PartialCallContainer> ONLY_RESOLVED_CALL = new BasicWritableSlice<>(DO_NOTHING);
|
||||||
WritableSlice<Call, BasicCallResolutionContext> PARTIAL_CALL_RESOLUTION_CONTEXT = new BasicWritableSlice<>(DO_NOTHING);
|
WritableSlice<Call, BasicCallResolutionContext> PARTIAL_CALL_RESOLUTION_CONTEXT = new BasicWritableSlice<>(DO_NOTHING);
|
||||||
WritableSlice<KtExpression, Call> DELEGATE_EXPRESSION_TO_PROVIDE_DELEGATE_CALL = new BasicWritableSlice<>(DO_NOTHING);
|
WritableSlice<KtExpression, Call> DELEGATE_EXPRESSION_TO_PROVIDE_DELEGATE_CALL = new BasicWritableSlice<>(DO_NOTHING);
|
||||||
WritableSlice<Call, TailRecursionKind> TAIL_RECURSION_CALL = Slices.createSimpleSlice();
|
WritableSlice<Call, TailRecursionKind> TAIL_RECURSION_CALL = Slices.createSimpleSlice();
|
||||||
|
|||||||
+10
-6
@@ -76,6 +76,14 @@ class KotlinToResolvedCallTransformer(
|
|||||||
companion object {
|
companion object {
|
||||||
private val REPORT_MISSING_NEW_INFERENCE_DIAGNOSTIC
|
private val REPORT_MISSING_NEW_INFERENCE_DIAGNOSTIC
|
||||||
get() = false
|
get() = false
|
||||||
|
|
||||||
|
fun keyForPartiallyResolvedCall(resolvedCallAtom: ResolvedCallAtom): Call {
|
||||||
|
val psiKotlinCall = resolvedCallAtom.atom.psiKotlinCall
|
||||||
|
return if (psiKotlinCall is PSIKotlinCallForInvoke)
|
||||||
|
psiKotlinCall.baseCall.psiCall
|
||||||
|
else
|
||||||
|
psiKotlinCall.psiCall
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <D : CallableDescriptor> onlyTransform(
|
fun <D : CallableDescriptor> onlyTransform(
|
||||||
@@ -92,13 +100,9 @@ class KotlinToResolvedCallTransformer(
|
|||||||
is PartialCallResolutionResult -> {
|
is PartialCallResolutionResult -> {
|
||||||
val candidate = baseResolvedCall.resultCallAtom
|
val candidate = baseResolvedCall.resultCallAtom
|
||||||
|
|
||||||
val psiKotlinCall = candidate.atom.psiKotlinCall
|
val psiCall = keyForPartiallyResolvedCall(candidate)
|
||||||
val psiCall = if (psiKotlinCall is PSIKotlinCallForInvoke)
|
|
||||||
psiKotlinCall.baseCall.psiCall
|
|
||||||
else
|
|
||||||
psiKotlinCall.psiCall
|
|
||||||
|
|
||||||
context.trace.record(BindingContext.ONLY_RESOLVED_CALL, psiCall, baseResolvedCall)
|
context.trace.record(BindingContext.ONLY_RESOLVED_CALL, psiCall, PartialCallContainer(baseResolvedCall))
|
||||||
context.trace.record(BindingContext.PARTIAL_CALL_RESOLUTION_CONTEXT, psiCall, context)
|
context.trace.record(BindingContext.PARTIAL_CALL_RESOLUTION_CONTEXT, psiCall, context)
|
||||||
|
|
||||||
context.inferenceSession.addPartialCallInfo(
|
context.inferenceSession.addPartialCallInfo(
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ internal fun createSimplePSICallArgument(
|
|||||||
|
|
||||||
val ktExpression = KtPsiUtil.getLastElementDeparenthesized(valueArgument.getArgumentExpression(), statementFilter) ?: return null
|
val ktExpression = KtPsiUtil.getLastElementDeparenthesized(valueArgument.getArgumentExpression(), statementFilter) ?: return null
|
||||||
val onlyResolvedCall = ktExpression.getCall(bindingContext)?.let {
|
val onlyResolvedCall = ktExpression.getCall(bindingContext)?.let {
|
||||||
bindingContext.get(BindingContext.ONLY_RESOLVED_CALL, it)
|
bindingContext.get(BindingContext.ONLY_RESOLVED_CALL, it)?.result
|
||||||
}
|
}
|
||||||
// todo hack for if expression: sometimes we not write properly type information for branches
|
// todo hack for if expression: sometimes we not write properly type information for branches
|
||||||
val baseType = typeInfoForArgument.type?.unwrap() ?: onlyResolvedCall?.resultCallAtom?.freshReturnType ?: return null
|
val baseType = typeInfoForArgument.type?.unwrap() ?: onlyResolvedCall?.resultCallAtom?.freshReturnType ?: return null
|
||||||
|
|||||||
@@ -595,7 +595,7 @@ class PSICallResolver(
|
|||||||
?: ktExpression?.getCall(bindingContext)
|
?: ktExpression?.getCall(bindingContext)
|
||||||
|
|
||||||
val onlyResolvedCall = call?.let {
|
val onlyResolvedCall = call?.let {
|
||||||
bindingContext.get(BindingContext.ONLY_RESOLVED_CALL, it)
|
bindingContext.get(BindingContext.ONLY_RESOLVED_CALL, it)?.result
|
||||||
}
|
}
|
||||||
if (onlyResolvedCall != null) {
|
if (onlyResolvedCall != null) {
|
||||||
subCallArgument = SubKotlinCallArgumentImpl(
|
subCallArgument = SubKotlinCallArgumentImpl(
|
||||||
|
|||||||
+11
@@ -78,6 +78,8 @@ class ResolvedAtomCompleter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun completeResolvedCall(resolvedCallAtom: ResolvedCallAtom, diagnostics: Collection<KotlinCallDiagnostic>): ResolvedCall<*>? {
|
fun completeResolvedCall(resolvedCallAtom: ResolvedCallAtom, diagnostics: Collection<KotlinCallDiagnostic>): ResolvedCall<*>? {
|
||||||
|
clearPartiallyResolvedCall(resolvedCallAtom)
|
||||||
|
|
||||||
if (resolvedCallAtom.atom.psiKotlinCall is PSIKotlinCallForVariable) return null
|
if (resolvedCallAtom.atom.psiKotlinCall is PSIKotlinCallForVariable) return null
|
||||||
|
|
||||||
val resolvedCall = kotlinToResolvedCallTransformer.transformToResolvedCall<CallableDescriptor>(
|
val resolvedCall = kotlinToResolvedCallTransformer.transformToResolvedCall<CallableDescriptor>(
|
||||||
@@ -116,6 +118,15 @@ class ResolvedAtomCompleter(
|
|||||||
return resolvedCall
|
return resolvedCall
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun clearPartiallyResolvedCall(resolvedCallAtom: ResolvedCallAtom) {
|
||||||
|
val psiCall = KotlinToResolvedCallTransformer.keyForPartiallyResolvedCall(resolvedCallAtom)
|
||||||
|
|
||||||
|
val partialCallContainer = topLevelTrace[BindingContext.ONLY_RESOLVED_CALL, psiCall]
|
||||||
|
if (partialCallContainer != null) {
|
||||||
|
topLevelTrace.record(BindingContext.ONLY_RESOLVED_CALL, psiCall, PartialCallContainer.empty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val ResolvedLambdaAtom.isCoercedToUnit: Boolean
|
private val ResolvedLambdaAtom.isCoercedToUnit: Boolean
|
||||||
get() {
|
get() {
|
||||||
val returnTypes =
|
val returnTypes =
|
||||||
|
|||||||
@@ -238,4 +238,10 @@ val ResolvedCallAtom.freshReturnType: UnwrappedType?
|
|||||||
get() {
|
get() {
|
||||||
val returnType = candidateDescriptor.returnType ?: return null
|
val returnType = candidateDescriptor.returnType ?: return null
|
||||||
return substitutor.safeSubstitute(returnType.unwrap())
|
return substitutor.safeSubstitute(returnType.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PartialCallContainer(val result: PartialCallResolutionResult?) {
|
||||||
|
companion object {
|
||||||
|
val empty = PartialCallContainer(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// IGNORE_BACKEND: JS_IR
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
import kotlin.collections.HashMap
|
||||||
|
|
||||||
|
class Inv1<T>
|
||||||
|
|
||||||
|
class Inv2<K, V>
|
||||||
|
|
||||||
|
class Something {
|
||||||
|
val guilds = Inv2<Int, Inv1<String>>()
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
guilds[0] = Inv1()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun <K, V> Inv2<K, V>.set(key: K, value: V) { }
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
Something().test()
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+5
@@ -17044,6 +17044,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentWithArrayLHS.kt");
|
runTest("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentWithArrayLHS.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("genericArrayAccessCall.kt")
|
||||||
|
public void testGenericArrayAccessCall() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/operatorConventions/genericArrayAccessCall.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("incDecOnObject.kt")
|
@TestMetadata("incDecOnObject.kt")
|
||||||
public void testIncDecOnObject() throws Exception {
|
public void testIncDecOnObject() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt");
|
runTest("compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt");
|
||||||
|
|||||||
+5
@@ -17044,6 +17044,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentWithArrayLHS.kt");
|
runTest("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentWithArrayLHS.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("genericArrayAccessCall.kt")
|
||||||
|
public void testGenericArrayAccessCall() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/operatorConventions/genericArrayAccessCall.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("incDecOnObject.kt")
|
@TestMetadata("incDecOnObject.kt")
|
||||||
public void testIncDecOnObject() throws Exception {
|
public void testIncDecOnObject() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt");
|
runTest("compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt");
|
||||||
|
|||||||
+5
@@ -15929,6 +15929,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentWithArrayLHS.kt");
|
runTest("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentWithArrayLHS.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("genericArrayAccessCall.kt")
|
||||||
|
public void testGenericArrayAccessCall() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/operatorConventions/genericArrayAccessCall.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("incDecOnObject.kt")
|
@TestMetadata("incDecOnObject.kt")
|
||||||
public void testIncDecOnObject() throws Exception {
|
public void testIncDecOnObject() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt");
|
runTest("compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt");
|
||||||
|
|||||||
Generated
+5
@@ -13099,6 +13099,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentWithArrayLHS.kt");
|
runTest("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentWithArrayLHS.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("genericArrayAccessCall.kt")
|
||||||
|
public void testGenericArrayAccessCall() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/operatorConventions/genericArrayAccessCall.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("incDecOnObject.kt")
|
@TestMetadata("incDecOnObject.kt")
|
||||||
public void testIncDecOnObject() throws Exception {
|
public void testIncDecOnObject() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt");
|
runTest("compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt");
|
||||||
|
|||||||
+5
@@ -14254,6 +14254,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentWithArrayLHS.kt");
|
runTest("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentWithArrayLHS.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("genericArrayAccessCall.kt")
|
||||||
|
public void testGenericArrayAccessCall() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/operatorConventions/genericArrayAccessCall.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("incDecOnObject.kt")
|
@TestMetadata("incDecOnObject.kt")
|
||||||
public void testIncDecOnObject() throws Exception {
|
public void testIncDecOnObject() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt");
|
runTest("compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user