Prioritize resolution anchors during resolution

When required dependency is present both in source dependencies and in
library dependencies, the former one should be selected.

#KT-24309
This commit is contained in:
Pavel Kirpichenkov
2020-07-24 12:21:30 +03:00
parent f8ee976720
commit 24d8aee2bb
2 changed files with 11 additions and 12 deletions
@@ -237,9 +237,9 @@ class QualifiedExpressionResolver(val languageVersionSettings: LanguageVersionSe
if (!languageVersionSettings.isLibraryToSourceAnalysisEnabled) return primaryImportingScope
val resolutionAnchor = moduleDescriptor.getResolutionAnchorIfAny() ?: return primaryImportingScope
val secondaryImportingScope = processReferenceInContextOf(resolutionAnchor) ?: return primaryImportingScope
if (primaryImportingScope == null) return secondaryImportingScope
return CompositePrioritizedImportingScope(primaryImportingScope, secondaryImportingScope)
val anchorImportingScope = processReferenceInContextOf(resolutionAnchor) ?: return primaryImportingScope
if (primaryImportingScope == null) return anchorImportingScope
return CompositePrioritizedImportingScope(anchorImportingScope, primaryImportingScope)
}
private fun doProcessImportReference(
@@ -18,31 +18,30 @@ package org.jetbrains.kotlin.descriptors
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.resolve.RESOLUTION_ANCHOR_PROVIDER_CAPABILITY
import org.jetbrains.kotlin.resolve.getResolutionAnchorIfAny
fun ModuleDescriptor.findClassifierAcrossModuleDependencies(classId: ClassId): ClassifierDescriptor? = withAnchorFallback {
fun ModuleDescriptor.findClassifierAcrossModuleDependencies(classId: ClassId): ClassifierDescriptor? = withResolutionAnchor {
val packageViewDescriptor = getPackage(classId.packageFqName)
val segments = classId.relativeClassName.pathSegments()
val topLevelClass = packageViewDescriptor.memberScope.getContributedClassifier(
segments.first(),
NoLookupLocation.FROM_DESERIALIZATION
) ?: return@withAnchorFallback null
) ?: return@withResolutionAnchor null
var result = topLevelClass
for (name in segments.subList(1, segments.size)) {
if (result !is ClassDescriptor) return@withAnchorFallback null
if (result !is ClassDescriptor) return@withResolutionAnchor null
result = result.unsubstitutedInnerClassesScope
.getContributedClassifier(name, NoLookupLocation.FROM_DESERIALIZATION) as? ClassDescriptor
?: return@withAnchorFallback null
?: return@withResolutionAnchor null
}
return@withAnchorFallback result
return@withResolutionAnchor result
}
private inline fun ModuleDescriptor.withAnchorFallback(
crossinline doSearch: ModuleDescriptor.() -> ClassifierDescriptor?
private inline fun ModuleDescriptor.withResolutionAnchor(
crossinline doSearch: ModuleDescriptor.() -> ClassifierDescriptor?
): ClassifierDescriptor? {
val anchor = getResolutionAnchorIfAny()
return if (anchor == null) doSearch() else doSearch() ?: anchor.doSearch()
return if (anchor == null) doSearch() else anchor.doSearch() ?: doSearch()
}
fun ModuleDescriptor.findClassAcrossModuleDependencies(classId: ClassId): ClassDescriptor? =