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.
This commit is contained in:
Yan Zhulanow
2019-05-22 19:25:22 +09:00
parent b4f515a436
commit 54f78a2920
9 changed files with 30 additions and 46 deletions
@@ -105,7 +105,7 @@ public class ResolutionResultsHandler {
successfulAndIncomplete.addAll(successfulCandidates);
successfulAndIncomplete.addAll(incompleteCandidates);
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(
successfulAndIncomplete, true, context.isDebuggerContext, checkArgumentsMode, languageVersionSettings);
successfulAndIncomplete, true, checkArgumentsMode, languageVersionSettings);
if (results.isSingleResult()) {
MutableResolvedCall<D> 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<D> 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 <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> chooseAndReportMaximallySpecific(
@NotNull Set<MutableResolvedCall<D>> candidates,
boolean discriminateGenerics,
boolean isDebuggerContext,
@NotNull CheckArgumentTypesMode checkArgumentsMode,
@NotNull LanguageVersionSettings languageVersionSettings
) {
@@ -217,7 +216,7 @@ public class ResolutionResultsHandler {
}
Set<MutableResolvedCall<D>> specificCalls =
myResolver.chooseMaximallySpecificCandidates(refinedCandidates, checkArgumentsMode, discriminateGenerics, isDebuggerContext);
myResolver.chooseMaximallySpecificCandidates(refinedCandidates, checkArgumentsMode, discriminateGenerics);
if (specificCalls.size() == 1) {
return OverloadResolutionResultsImpl.success(specificCalls.iterator().next());
@@ -129,8 +129,6 @@ class KotlinCallResolver(
expectedType: UnwrappedType?,
candidates: Collection<KotlinResolutionCandidate>
): 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)
@@ -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
)
}
}
@@ -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
@@ -61,13 +61,12 @@ open class OverloadingConflictResolver<C : Any>(
fun chooseMaximallySpecificCandidates(
candidates: Collection<C>,
checkArgumentsMode: CheckArgumentTypesMode,
discriminateGenerics: Boolean,
isDebuggerContext: Boolean
discriminateGenerics: Boolean
): Set<C> {
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<C : Any>(
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<C : Any>(
private fun findMaximallySpecific(
candidates: Set<C>,
checkArgumentsMode: CheckArgumentTypesMode,
discriminateGenerics: Boolean,
isDebuggerContext: Boolean
discriminateGenerics: Boolean
): C? =
if (candidates.size <= 1)
candidates.firstOrNull()
@@ -155,29 +153,29 @@ open class OverloadingConflictResolver<C : Any>(
}
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<C>, isDebuggerContext: Boolean): Set<C>? {
private fun findMaximallySpecificVariableAsFunctionCalls(candidates: Collection<C>): Set<C>? {
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<C : Any>(
}
}
private fun findMaximallySpecificCall(
candidates: Set<C>,
discriminateGenerics: Boolean,
isDebuggerContext: Boolean
): C? {
private fun findMaximallySpecificCall(candidates: Set<C>, discriminateGenerics: Boolean): C? {
val filteredCandidates = uniquifyCandidatesSet(candidates)
if (filteredCandidates.size <= 1) return filteredCandidates.singleOrNull()
@@ -205,9 +199,7 @@ open class OverloadingConflictResolver<C : Any>(
}
}
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 <C : Any> Collection<C>.exactMaxWith(isNotWorse: (C, C) -> Boolean): C? {
@@ -361,19 +353,6 @@ open class OverloadingConflictResolver<C : Any>(
return true
}
private fun isOfNotLessSpecificVisibilityForDebugger(
call1: FlatSignature<C>,
call2: FlatSignature<C>,
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`,
@@ -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),
+6
View File
@@ -0,0 +1,6 @@
import java.util.ArrayList
fun foo() {
val a = ArrayList<String>()
<caret>val x = 5
}
@@ -0,0 +1 @@
a.<error descr="[INVISIBLE_MEMBER] Cannot access 'ensureCapacityInternal': it is private in 'ArrayList'">ensureCapacityInternal</error>(0)
@@ -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");