From 66265972aade56981db5ba08f2b54b50bf71a03f Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 14 Apr 2017 16:15:59 +0300 Subject: [PATCH] Multiplatform Project: Fix impl-by-header search and vice versa --- .../checkers/HeaderImplDeclarationChecker.kt | 28 +++++++++++-------- .../markers/DeclaredHeaderMarker.kt | 11 ++------ .../markers/ImplementedHeaderMarker.kt | 6 +--- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/HeaderImplDeclarationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/HeaderImplDeclarationChecker.kt index 0a401037451..342f3425657 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/HeaderImplDeclarationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/HeaderImplDeclarationChecker.kt @@ -71,7 +71,19 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null) fun checkHeaderDeclarationHasImplementation( reportOn: KtDeclaration, descriptor: MemberDescriptor, diagnosticHolder: DiagnosticSink, checkImpl: Boolean ) { - val compatibility = when (descriptor) { + val compatibility = buildCompatibilityMap(descriptor, checkImpl) + + if (compatibility != null && !compatibility.containsKey(Compatible)) { + assert(compatibility.keys.all { it is Incompatible }) + @Suppress("UNCHECKED_CAST") + val incompatibility = compatibility as Map> + diagnosticHolder.report(Errors.HEADER_WITHOUT_IMPLEMENTATION.on( + reportOn, descriptor, moduleToCheck ?: descriptor.module, incompatibility)) + } + } + + private fun buildCompatibilityMap(descriptor: MemberDescriptor, checkImpl: Boolean): Map>? { + return when (descriptor) { is CallableMemberDescriptor -> { descriptor.findNamesakesFromTheSameModule().filter { impl -> descriptor != impl && @@ -91,14 +103,6 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null) } else -> null } - - if (compatibility != null && !compatibility.containsKey(Compatible)) { - assert(compatibility.keys.all { it is Incompatible }) - @Suppress("UNCHECKED_CAST") - val incompatibility = compatibility as Map> - diagnosticHolder.report(Errors.HEADER_WITHOUT_IMPLEMENTATION.on( - reportOn, descriptor, moduleToCheck ?: descriptor.module, incompatibility)) - } } private fun checkImplementationHasHeaderDeclaration( @@ -144,7 +148,9 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null) } } - fun CallableMemberDescriptor.findNamesakesFromTheSameModule(): Collection { + fun MemberDescriptor.findCompatibleDescriptors() = buildCompatibilityMap(this, false)?.get(Compatible) ?: emptyList() + + private fun CallableMemberDescriptor.findNamesakesFromTheSameModule(): Collection { val packageFqName = (containingDeclaration as? PackageFragmentDescriptor)?.fqName ?: return emptyList() val myModule = moduleToCheck ?: module val scope = myModule.getPackage(packageFqName).memberScope @@ -156,7 +162,7 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null) } // TODO: only obtain descriptors from our module to start with } - fun ClassifierDescriptorWithTypeParameters.findClassifiersFromTheSameModule(): Collection { + private fun ClassifierDescriptorWithTypeParameters.findClassifiersFromTheSameModule(): Collection { val myModule = moduleToCheck ?: module val classId = classId ?: return emptyList() diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/DeclaredHeaderMarker.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/DeclaredHeaderMarker.kt index 8adbe6458b1..7348f79654d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/DeclaredHeaderMarker.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/DeclaredHeaderMarker.kt @@ -50,14 +50,7 @@ fun ModuleDescriptor.hasDeclarationOf(descriptor: MemberDescriptor) = declaratio private fun ModuleDescriptor.declarationOf(descriptor: MemberDescriptor): DeclarationDescriptor? = with (HeaderImplDeclarationChecker(this)) { - when (descriptor) { - is CallableMemberDescriptor -> - descriptor.findNamesakesFromTheSameModule().filter { it.isHeader }.firstOrNull() - is ClassifierDescriptorWithTypeParameters -> - descriptor.findClassifiersFromTheSameModule().filter { it is ClassDescriptor && it.isHeader }.firstOrNull() - else -> - null - } + descriptor.findCompatibleDescriptors().firstOrNull { it.isHeader } } fun getHeaderDeclarationTooltip(declaration: KtDeclaration): String? { @@ -87,4 +80,4 @@ internal fun KtDeclaration.liftToHeader(): KtDeclaration? { hasModifier(KtTokens.IMPL_KEYWORD) -> headerDeclarationIfAny() else -> null } -} \ No newline at end of file +} diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/ImplementedHeaderMarker.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/ImplementedHeaderMarker.kt index 678b1028ffb..9d7db318584 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/ImplementedHeaderMarker.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/ImplementedHeaderMarker.kt @@ -33,11 +33,7 @@ fun ModuleDescriptor.hasImplementationsOf(descriptor: MemberDescriptor) = private fun ModuleDescriptor.implementationsOf(descriptor: MemberDescriptor): List = with (HeaderImplDeclarationChecker(this)) { - when (descriptor) { - is CallableMemberDescriptor -> descriptor.findNamesakesFromTheSameModule().filter { it.isImpl } - is ClassDescriptor -> descriptor.findClassifiersFromTheSameModule().filter { it.isImpl } - else -> emptyList() - } + descriptor.findCompatibleDescriptors().filter { it.isImpl } } fun getPlatformImplementationTooltip(declaration: KtDeclaration): String? {