From f8449bf15a89ede2c7b805c652dc9f93b5cac108 Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Tue, 3 Sep 2019 17:55:30 +0300 Subject: [PATCH] [NI] Clear partially resolved calls after resolve of top-level call #KT-32433 Fixed --- .../kotlin/resolve/BindingContext.java | 3 ++- .../tower/KotlinToResolvedCallTransformer.kt | 16 ++++++++----- .../resolve/calls/tower/NewCallArguments.kt | 2 +- .../resolve/calls/tower/PSICallResolver.kt | 2 +- .../calls/tower/ResolvedAtomCompleter.kt | 11 +++++++++ .../resolve/calls/model/ResolutionAtoms.kt | 8 ++++++- .../genericArrayAccessCall.kt | 23 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 5 ++++ .../LightAnalysisModeTestGenerated.java | 5 ++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 5 ++++ .../IrJsCodegenBoxTestGenerated.java | 5 ++++ .../semantics/JsCodegenBoxTestGenerated.java | 5 ++++ 12 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 compiler/testData/codegen/box/operatorConventions/genericArrayAccessCall.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java index bb6c10cbe95..ac5a6eeb7fa 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.name.FqNameUnsafe; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext; 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.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; @@ -121,7 +122,7 @@ public interface BindingContext { new BasicWritableSlice<>(DO_NOTHING); WritableSlice> RESOLVED_CALL = new BasicWritableSlice<>(DO_NOTHING); - WritableSlice ONLY_RESOLVED_CALL = new BasicWritableSlice<>(DO_NOTHING); + WritableSlice ONLY_RESOLVED_CALL = new BasicWritableSlice<>(DO_NOTHING); WritableSlice PARTIAL_CALL_RESOLUTION_CONTEXT = new BasicWritableSlice<>(DO_NOTHING); WritableSlice DELEGATE_EXPRESSION_TO_PROVIDE_DELEGATE_CALL = new BasicWritableSlice<>(DO_NOTHING); WritableSlice TAIL_RECURSION_CALL = Slices.createSimpleSlice(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt index 9a32c1f0383..a7ec273aad7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt @@ -76,6 +76,14 @@ class KotlinToResolvedCallTransformer( companion object { private val REPORT_MISSING_NEW_INFERENCE_DIAGNOSTIC get() = false + + fun keyForPartiallyResolvedCall(resolvedCallAtom: ResolvedCallAtom): Call { + val psiKotlinCall = resolvedCallAtom.atom.psiKotlinCall + return if (psiKotlinCall is PSIKotlinCallForInvoke) + psiKotlinCall.baseCall.psiCall + else + psiKotlinCall.psiCall + } } fun onlyTransform( @@ -92,13 +100,9 @@ class KotlinToResolvedCallTransformer( is PartialCallResolutionResult -> { val candidate = baseResolvedCall.resultCallAtom - val psiKotlinCall = candidate.atom.psiKotlinCall - val psiCall = if (psiKotlinCall is PSIKotlinCallForInvoke) - psiKotlinCall.baseCall.psiCall - else - psiKotlinCall.psiCall + val psiCall = keyForPartiallyResolvedCall(candidate) - 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.inferenceSession.addPartialCallInfo( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewCallArguments.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewCallArguments.kt index 5d0d440ad2f..cba94ee2ae7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewCallArguments.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewCallArguments.kt @@ -295,7 +295,7 @@ internal fun createSimplePSICallArgument( val ktExpression = KtPsiUtil.getLastElementDeparenthesized(valueArgument.getArgumentExpression(), statementFilter) ?: return null 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 val baseType = typeInfoForArgument.type?.unwrap() ?: onlyResolvedCall?.resultCallAtom?.freshReturnType ?: return null diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt index 098bdaf3c88..82a956c5b55 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt @@ -595,7 +595,7 @@ class PSICallResolver( ?: ktExpression?.getCall(bindingContext) val onlyResolvedCall = call?.let { - bindingContext.get(BindingContext.ONLY_RESOLVED_CALL, it) + bindingContext.get(BindingContext.ONLY_RESOLVED_CALL, it)?.result } if (onlyResolvedCall != null) { subCallArgument = SubKotlinCallArgumentImpl( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt index 070501f554f..efb40162fc1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt @@ -78,6 +78,8 @@ class ResolvedAtomCompleter( } fun completeResolvedCall(resolvedCallAtom: ResolvedCallAtom, diagnostics: Collection): ResolvedCall<*>? { + clearPartiallyResolvedCall(resolvedCallAtom) + if (resolvedCallAtom.atom.psiKotlinCall is PSIKotlinCallForVariable) return null val resolvedCall = kotlinToResolvedCallTransformer.transformToResolvedCall( @@ -116,6 +118,15 @@ class ResolvedAtomCompleter( 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 get() { val returnTypes = diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt index eb59a56cbc3..de93cdb0afb 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt @@ -238,4 +238,10 @@ val ResolvedCallAtom.freshReturnType: UnwrappedType? get() { val returnType = candidateDescriptor.returnType ?: return null return substitutor.safeSubstitute(returnType.unwrap()) - } \ No newline at end of file + } + +class PartialCallContainer(val result: PartialCallResolutionResult?) { + companion object { + val empty = PartialCallContainer(null) + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/operatorConventions/genericArrayAccessCall.kt b/compiler/testData/codegen/box/operatorConventions/genericArrayAccessCall.kt new file mode 100644 index 00000000000..dd2010957c3 --- /dev/null +++ b/compiler/testData/codegen/box/operatorConventions/genericArrayAccessCall.kt @@ -0,0 +1,23 @@ +// IGNORE_BACKEND: JS_IR +// WITH_RUNTIME + +import kotlin.collections.HashMap + +class Inv1 + +class Inv2 + +class Something { + val guilds = Inv2>() + + fun test() { + guilds[0] = Inv1() + } +} + +operator fun Inv2.set(key: K, value: V) { } + +fun box(): String { + Something().test() + return "OK" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 115bb682ffc..6bc20a9bf0c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -17044,6 +17044,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { 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") public void testIncDecOnObject() throws Exception { runTest("compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 15ae4189ec2..5715a27c645 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -17044,6 +17044,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes 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") public void testIncDecOnObject() throws Exception { runTest("compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index ea9da6c2fae..ff806bacdc1 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -15929,6 +15929,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes 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") public void testIncDecOnObject() throws Exception { runTest("compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 12be23a474b..17f39a81d06 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -13099,6 +13099,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { 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") public void testIncDecOnObject() throws Exception { runTest("compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index bf426d172de..ccae3d7a27f 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -14254,6 +14254,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { 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") public void testIncDecOnObject() throws Exception { runTest("compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt");