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:
+3
-4
@@ -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)
|
||||
|
||||
+1
-2
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
-2
@@ -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
|
||||
|
||||
+12
-33
@@ -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),
|
||||
|
||||
@@ -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)
|
||||
Generated
+5
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user