Multiplatform Project: Fix impl-by-header search and vice versa
This commit is contained in:
+17
-11
@@ -71,7 +71,19 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null)
|
|||||||
fun checkHeaderDeclarationHasImplementation(
|
fun checkHeaderDeclarationHasImplementation(
|
||||||
reportOn: KtDeclaration, descriptor: MemberDescriptor, diagnosticHolder: DiagnosticSink, checkImpl: Boolean
|
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<Incompatible, Collection<MemberDescriptor>>
|
||||||
|
diagnosticHolder.report(Errors.HEADER_WITHOUT_IMPLEMENTATION.on(
|
||||||
|
reportOn, descriptor, moduleToCheck ?: descriptor.module, incompatibility))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildCompatibilityMap(descriptor: MemberDescriptor, checkImpl: Boolean): Map<Compatibility, List<MemberDescriptor>>? {
|
||||||
|
return when (descriptor) {
|
||||||
is CallableMemberDescriptor -> {
|
is CallableMemberDescriptor -> {
|
||||||
descriptor.findNamesakesFromTheSameModule().filter { impl ->
|
descriptor.findNamesakesFromTheSameModule().filter { impl ->
|
||||||
descriptor != impl &&
|
descriptor != impl &&
|
||||||
@@ -91,14 +103,6 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null)
|
|||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compatibility != null && !compatibility.containsKey(Compatible)) {
|
|
||||||
assert(compatibility.keys.all { it is Incompatible })
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
val incompatibility = compatibility as Map<Incompatible, Collection<MemberDescriptor>>
|
|
||||||
diagnosticHolder.report(Errors.HEADER_WITHOUT_IMPLEMENTATION.on(
|
|
||||||
reportOn, descriptor, moduleToCheck ?: descriptor.module, incompatibility))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkImplementationHasHeaderDeclaration(
|
private fun checkImplementationHasHeaderDeclaration(
|
||||||
@@ -144,7 +148,9 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun CallableMemberDescriptor.findNamesakesFromTheSameModule(): Collection<CallableMemberDescriptor> {
|
fun MemberDescriptor.findCompatibleDescriptors() = buildCompatibilityMap(this, false)?.get(Compatible) ?: emptyList()
|
||||||
|
|
||||||
|
private fun CallableMemberDescriptor.findNamesakesFromTheSameModule(): Collection<CallableMemberDescriptor> {
|
||||||
val packageFqName = (containingDeclaration as? PackageFragmentDescriptor)?.fqName ?: return emptyList()
|
val packageFqName = (containingDeclaration as? PackageFragmentDescriptor)?.fqName ?: return emptyList()
|
||||||
val myModule = moduleToCheck ?: module
|
val myModule = moduleToCheck ?: module
|
||||||
val scope = myModule.getPackage(packageFqName).memberScope
|
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
|
} // TODO: only obtain descriptors from our module to start with
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ClassifierDescriptorWithTypeParameters.findClassifiersFromTheSameModule(): Collection<ClassifierDescriptorWithTypeParameters> {
|
private fun ClassifierDescriptorWithTypeParameters.findClassifiersFromTheSameModule(): Collection<ClassifierDescriptorWithTypeParameters> {
|
||||||
val myModule = moduleToCheck ?: module
|
val myModule = moduleToCheck ?: module
|
||||||
val classId = classId ?: return emptyList()
|
val classId = classId ?: return emptyList()
|
||||||
|
|
||||||
|
|||||||
@@ -50,14 +50,7 @@ fun ModuleDescriptor.hasDeclarationOf(descriptor: MemberDescriptor) = declaratio
|
|||||||
|
|
||||||
private fun ModuleDescriptor.declarationOf(descriptor: MemberDescriptor): DeclarationDescriptor? =
|
private fun ModuleDescriptor.declarationOf(descriptor: MemberDescriptor): DeclarationDescriptor? =
|
||||||
with (HeaderImplDeclarationChecker(this)) {
|
with (HeaderImplDeclarationChecker(this)) {
|
||||||
when (descriptor) {
|
descriptor.findCompatibleDescriptors().firstOrNull { it.isHeader }
|
||||||
is CallableMemberDescriptor ->
|
|
||||||
descriptor.findNamesakesFromTheSameModule().filter { it.isHeader }.firstOrNull()
|
|
||||||
is ClassifierDescriptorWithTypeParameters ->
|
|
||||||
descriptor.findClassifiersFromTheSameModule().filter { it is ClassDescriptor && it.isHeader }.firstOrNull()
|
|
||||||
else ->
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getHeaderDeclarationTooltip(declaration: KtDeclaration): String? {
|
fun getHeaderDeclarationTooltip(declaration: KtDeclaration): String? {
|
||||||
@@ -87,4 +80,4 @@ internal fun KtDeclaration.liftToHeader(): KtDeclaration? {
|
|||||||
hasModifier(KtTokens.IMPL_KEYWORD) -> headerDeclarationIfAny()
|
hasModifier(KtTokens.IMPL_KEYWORD) -> headerDeclarationIfAny()
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,11 +33,7 @@ fun ModuleDescriptor.hasImplementationsOf(descriptor: MemberDescriptor) =
|
|||||||
|
|
||||||
private fun ModuleDescriptor.implementationsOf(descriptor: MemberDescriptor): List<DeclarationDescriptor> =
|
private fun ModuleDescriptor.implementationsOf(descriptor: MemberDescriptor): List<DeclarationDescriptor> =
|
||||||
with (HeaderImplDeclarationChecker(this)) {
|
with (HeaderImplDeclarationChecker(this)) {
|
||||||
when (descriptor) {
|
descriptor.findCompatibleDescriptors().filter { it.isImpl }
|
||||||
is CallableMemberDescriptor -> descriptor.findNamesakesFromTheSameModule().filter { it.isImpl }
|
|
||||||
is ClassDescriptor -> descriptor.findClassifiersFromTheSameModule().filter { it.isImpl }
|
|
||||||
else -> emptyList()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPlatformImplementationTooltip(declaration: KtDeclaration): String? {
|
fun getPlatformImplementationTooltip(declaration: KtDeclaration): String? {
|
||||||
|
|||||||
Reference in New Issue
Block a user