From 54f78a29201e095d5a0fbc4cfe89565255868a42 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Wed, 22 May 2019 19:25:22 +0900 Subject: [PATCH] Debugger: Remove debugger-related hacks in resolution Candidate ordering should be the same in ordinary Kotlin code and in evaluated expressions. With the invention of 'foo_field' syntax, there is no need to do these nasty things any more. --- .../results/ResolutionResultsHandler.java | 7 ++- .../resolve/calls/KotlinCallResolver.kt | 5 +-- .../components/CallableReferenceResolver.kt | 3 +- .../calls/components/ResolutionParts.kt | 2 - .../results/OverloadingConflictResolver.kt | 45 +++++-------------- .../kotlin/resolve/calls/tower/TowerLevels.kt | 2 +- .../checker/codeFragments/privateMembers.kt | 6 +++ .../codeFragments/privateMembers.kt.fragment | 1 + ...CodeFragmentHighlightingTestGenerated.java | 5 +++ 9 files changed, 30 insertions(+), 46 deletions(-) create mode 100644 idea/testData/checker/codeFragments/privateMembers.kt create mode 100644 idea/testData/checker/codeFragments/privateMembers.kt.fragment diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/ResolutionResultsHandler.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/ResolutionResultsHandler.java index 7bedeb1a78a..11eb1b9bbe9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/ResolutionResultsHandler.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/ResolutionResultsHandler.java @@ -105,7 +105,7 @@ public class ResolutionResultsHandler { successfulAndIncomplete.addAll(successfulCandidates); successfulAndIncomplete.addAll(incompleteCandidates); OverloadResolutionResultsImpl results = chooseAndReportMaximallySpecific( - successfulAndIncomplete, true, context.isDebuggerContext, checkArgumentsMode, languageVersionSettings); + successfulAndIncomplete, true, checkArgumentsMode, languageVersionSettings); if (results.isSingleResult()) { MutableResolvedCall resultingCall = results.getResultingCall(); resultingCall.getTrace().moveAllMyDataTo(context.trace); @@ -160,7 +160,7 @@ public class ResolutionResultsHandler { return recordFailedInfo(tracing, trace, myResolver.filterOutEquivalentCalls(new LinkedHashSet<>(thisLevel))); } OverloadResolutionResultsImpl results = chooseAndReportMaximallySpecific( - thisLevel, false, false, checkArgumentsMode, languageVersionSettings); + thisLevel, false, checkArgumentsMode, languageVersionSettings); return recordFailedInfo(tracing, trace, results.getResultingCalls()); } } @@ -196,7 +196,6 @@ public class ResolutionResultsHandler { private OverloadResolutionResultsImpl chooseAndReportMaximallySpecific( @NotNull Set> candidates, boolean discriminateGenerics, - boolean isDebuggerContext, @NotNull CheckArgumentTypesMode checkArgumentsMode, @NotNull LanguageVersionSettings languageVersionSettings ) { @@ -217,7 +216,7 @@ public class ResolutionResultsHandler { } Set> specificCalls = - myResolver.chooseMaximallySpecificCandidates(refinedCandidates, checkArgumentsMode, discriminateGenerics, isDebuggerContext); + myResolver.chooseMaximallySpecificCandidates(refinedCandidates, checkArgumentsMode, discriminateGenerics); if (specificCalls.size() == 1) { return OverloadResolutionResultsImpl.success(specificCalls.iterator().next()); diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt index b5d77f733a7..d3ec72e75b9 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt @@ -129,8 +129,6 @@ class KotlinCallResolver( expectedType: UnwrappedType?, candidates: Collection ): CallResolutionResult { - val isDebuggerContext = candidateFactory.scopeTower.isDebuggerContext - var refinedCandidates = candidates if (!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.RefinedSamAdaptersPriority)) { val nonSynthesized = candidates.filter { !it.resolvedCall.candidateDescriptor.isSynthesized } @@ -142,8 +140,7 @@ class KotlinCallResolver( val maximallySpecificCandidates = overloadingConflictResolver.chooseMaximallySpecificCandidates( refinedCandidates, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, - discriminateGenerics = true, // todo - isDebuggerContext = isDebuggerContext + discriminateGenerics = true // todo ) return kotlinCallCompleter.runCompletion(candidateFactory, maximallySpecificCandidates, expectedType, resolutionCallbacks) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt index 700fb47a662..e8d59800964 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt @@ -130,8 +130,7 @@ class CallableReferenceResolver( return callableReferenceOverloadConflictResolver.chooseMaximallySpecificCandidates( candidates, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, - discriminateGenerics = false, // we can't specify generics explicitly for callable references - isDebuggerContext = scopeTower.isDebuggerContext + discriminateGenerics = false // we can't specify generics explicitly for callable references ) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt index e658ac81c9f..21cccd8f036 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt @@ -49,8 +49,6 @@ internal object CheckVisibility : ResolutionPart() { val containingDescriptor = scopeTower.lexicalScope.ownerDescriptor val dispatchReceiverArgument = resolvedCall.dispatchReceiverArgument - if (scopeTower.isDebuggerContext) return - val receiverValue = dispatchReceiverArgument?.receiver?.receiverValue ?: Visibilities.ALWAYS_SUITABLE_RECEIVER val invisibleMember = Visibilities.findInvisibleMember(receiverValue, resolvedCall.candidateDescriptor, containingDescriptor) ?: return diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt index 2b6a3323172..98923a99ab2 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt @@ -61,13 +61,12 @@ open class OverloadingConflictResolver( fun chooseMaximallySpecificCandidates( candidates: Collection, checkArgumentsMode: CheckArgumentTypesMode, - discriminateGenerics: Boolean, - isDebuggerContext: Boolean + discriminateGenerics: Boolean ): Set { candidates.setIfOneOrEmpty()?.let { return it } val fixedCandidates = if (getVariableCandidates(candidates.first()) != null) { - findMaximallySpecificVariableAsFunctionCalls(candidates, isDebuggerContext) ?: return LinkedHashSet(candidates) + findMaximallySpecificVariableAsFunctionCalls(candidates) ?: return LinkedHashSet(candidates) } else { candidates } @@ -93,13 +92,13 @@ open class OverloadingConflictResolver( return noOverrides } - val maximallySpecific = findMaximallySpecific(noOverrides, checkArgumentsMode, false, isDebuggerContext) + val maximallySpecific = findMaximallySpecific(noOverrides, checkArgumentsMode, false) if (maximallySpecific != null) { return setOf(maximallySpecific) } if (discriminateGenerics) { - val maximallySpecificGenericsDiscriminated = findMaximallySpecific(noOverrides, checkArgumentsMode, true, isDebuggerContext) + val maximallySpecificGenericsDiscriminated = findMaximallySpecific(noOverrides, checkArgumentsMode, true) if (maximallySpecificGenericsDiscriminated != null) { return setOf(maximallySpecificGenericsDiscriminated) } @@ -141,8 +140,7 @@ open class OverloadingConflictResolver( private fun findMaximallySpecific( candidates: Set, checkArgumentsMode: CheckArgumentTypesMode, - discriminateGenerics: Boolean, - isDebuggerContext: Boolean + discriminateGenerics: Boolean ): C? = if (candidates.size <= 1) candidates.firstOrNull() @@ -155,29 +153,29 @@ open class OverloadingConflictResolver( } CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS -> - findMaximallySpecificCall(candidates, discriminateGenerics, isDebuggerContext) + findMaximallySpecificCall(candidates, discriminateGenerics) ?: hasSAMConversion?.let { hasConversion -> findMaximallySpecificCall( candidates.filterNotTo(mutableSetOf()) { hasConversion(it) }, - discriminateGenerics, isDebuggerContext + discriminateGenerics ) } ?: findMaximallySpecificCall( candidates.filterNotTo(mutableSetOf()) { createFlatSignature(it).isSyntheticMember }, - discriminateGenerics, isDebuggerContext + discriminateGenerics ) } // null means ambiguity between variables - private fun findMaximallySpecificVariableAsFunctionCalls(candidates: Collection, isDebuggerContext: Boolean): Set? { + private fun findMaximallySpecificVariableAsFunctionCalls(candidates: Collection): Set? { val variableCalls = candidates.mapTo(newResolvedCallSet(candidates.size)) { getVariableCandidates(it) ?: throw AssertionError("Regular call among variable-as-function calls: $it") } val maxSpecificVariableCalls = chooseMaximallySpecificCandidates( variableCalls, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, - isDebuggerContext = isDebuggerContext, discriminateGenerics = false + discriminateGenerics = false ) val maxSpecificVariableCall = maxSpecificVariableCalls.singleOrNull() ?: return null @@ -186,11 +184,7 @@ open class OverloadingConflictResolver( } } - private fun findMaximallySpecificCall( - candidates: Set, - discriminateGenerics: Boolean, - isDebuggerContext: Boolean - ): C? { + private fun findMaximallySpecificCall(candidates: Set, discriminateGenerics: Boolean): C? { val filteredCandidates = uniquifyCandidatesSet(candidates) if (filteredCandidates.size <= 1) return filteredCandidates.singleOrNull() @@ -205,9 +199,7 @@ open class OverloadingConflictResolver( } } - return bestCandidatesByParameterTypes.exactMaxWith { call1, call2 -> - isOfNotLessSpecificShape(call1, call2) && isOfNotLessSpecificVisibilityForDebugger(call1, call2, isDebuggerContext) - }?.origin + return bestCandidatesByParameterTypes.exactMaxWith { call1, call2 -> isOfNotLessSpecificShape(call1, call2) }?.origin } private inline fun Collection.exactMaxWith(isNotWorse: (C, C) -> Boolean): C? { @@ -361,19 +353,6 @@ open class OverloadingConflictResolver( return true } - private fun isOfNotLessSpecificVisibilityForDebugger( - call1: FlatSignature, - call2: FlatSignature, - isDebuggerContext: Boolean - ): Boolean { - if (isDebuggerContext) { - val isMoreVisible1 = Visibilities.compare(call1.descriptorVisibility(), call2.descriptorVisibility()) - if (isMoreVisible1 != null && isMoreVisible1 < 0) return false - } - - return true - } - /** * Returns `true` if `d1` is definitely not less specific than `d2`, * `false` if `d1` is definitely less specific than `d2`, diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt index 01909ae8685..6bbddb5ca2d 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt @@ -60,7 +60,7 @@ internal abstract class AbstractScopeTowerLevel( } if (dispatchReceiverSmartCastType != null) diagnostics.add(UsedSmartCastForDispatchReceiver(dispatchReceiverSmartCastType)) - val shouldSkipVisibilityCheck = scopeTower.isDebuggerContext || scopeTower.isNewInferenceEnabled + val shouldSkipVisibilityCheck = scopeTower.isNewInferenceEnabled if (!shouldSkipVisibilityCheck) { Visibilities.findInvisibleMember( getReceiverValueWithSmartCast(dispatchReceiver?.receiverValue, dispatchReceiverSmartCastType), diff --git a/idea/testData/checker/codeFragments/privateMembers.kt b/idea/testData/checker/codeFragments/privateMembers.kt new file mode 100644 index 00000000000..b10c80d0791 --- /dev/null +++ b/idea/testData/checker/codeFragments/privateMembers.kt @@ -0,0 +1,6 @@ +import java.util.ArrayList + +fun foo() { + val a = ArrayList() + val x = 5 +} \ No newline at end of file diff --git a/idea/testData/checker/codeFragments/privateMembers.kt.fragment b/idea/testData/checker/codeFragments/privateMembers.kt.fragment new file mode 100644 index 00000000000..15d4d551228 --- /dev/null +++ b/idea/testData/checker/codeFragments/privateMembers.kt.fragment @@ -0,0 +1 @@ +a.ensureCapacityInternal(0) \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/CodeFragmentHighlightingTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/CodeFragmentHighlightingTestGenerated.java index 7dcd912a05c..9aa5a44b620 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/CodeFragmentHighlightingTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/CodeFragmentHighlightingTestGenerated.java @@ -111,6 +111,11 @@ public class CodeFragmentHighlightingTestGenerated extends AbstractCodeFragmentH runTest("idea/testData/checker/codeFragments/privateMember.kt"); } + @TestMetadata("privateMembers.kt") + public void testPrivateMembers() throws Exception { + runTest("idea/testData/checker/codeFragments/privateMembers.kt"); + } + @TestMetadata("protectedMember.kt") public void testProtectedMember() throws Exception { runTest("idea/testData/checker/codeFragments/protectedMember.kt");