From 4bfaa46c15f3f3e257d9d2a01d00ff88ce055496 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Mon, 9 Oct 2017 15:07:40 +0300 Subject: [PATCH] Add correct mapping of module descriptor to implementedDescriptor Now implements dependency is taken into account here Old commonModuleOrNull() was deleted Test (JVM + 2xCommon) was added --- .../jetbrains/kotlin/idea/facet/facetUtils.kt | 29 ++++++++++++++----- .../highlighter/markers/HasExpectedMarker.kt | 26 ++--------------- .../markers/KotlinLineMarkerProvider.kt | 3 +- .../transitiveCommon/common_base/base.kt | 3 ++ .../transitiveCommon/common_user/user.kt | 5 ++++ .../transitiveCommon/jvm/jvm.kt | 3 ++ .../resolve/MultiModuleLineMarkerTest.kt | 19 ++++++++++++ 7 files changed, 57 insertions(+), 31 deletions(-) create mode 100644 idea/testData/multiModuleLineMarker/transitiveCommon/common_base/base.kt create mode 100644 idea/testData/multiModuleLineMarker/transitiveCommon/common_user/user.kt create mode 100644 idea/testData/multiModuleLineMarker/transitiveCommon/jvm/jvm.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt index ad68853f91e..739cd2e3f10 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt @@ -130,16 +130,17 @@ private fun Module.findImplementingModules(modelsProvider: IdeModifiableModelsPr } } +private fun Module.getModuleInfo(baseModuleSourceInfo: ModuleSourceInfo): ModuleSourceInfo? = + when (baseModuleSourceInfo) { + is ModuleProductionSourceInfo -> productionSourceInfo() + is ModuleTestSourceInfo -> testSourceInfo() + else -> null + } + private fun Module.findImplementingModuleInfos(moduleSourceInfo: ModuleSourceInfo): List { val modelsProvider = IdeModifiableModelsProviderImpl(project) val implementingModules = findImplementingModules(modelsProvider) - return implementingModules.mapNotNull { - when (moduleSourceInfo) { - is ModuleProductionSourceInfo -> it.productionSourceInfo() - is ModuleTestSourceInfo -> it.testSourceInfo() - else -> null - } - } + return implementingModules.mapNotNull { it.getModuleInfo(moduleSourceInfo) } } val ModuleDescriptor.implementingDescriptors: List @@ -159,6 +160,20 @@ val ModuleDescriptor.implementingDescriptors: List }) } +val ModuleDescriptor.implementedDescriptor: ModuleDescriptor? + get() { + val moduleSourceInfo = getCapability(ModuleInfo.Capability) as? ModuleSourceInfo ?: return null + val module = moduleSourceInfo.module + + val modelsProvider = IdeModifiableModelsProviderImpl(module.project) + val implementedModuleName = module.findImplementedModuleName(modelsProvider) + val implementedModule = implementedModuleName?.let { modelsProvider.findIdeModule(it) } + val implementedModuleInfo = implementedModule?.getModuleInfo(moduleSourceInfo) + return implementedModuleInfo?.let { + KotlinCacheService.getInstance(module.project).getResolutionFacadeByModuleInfo(it, it.platform)?.moduleDescriptor + } + } + fun Module.getOrCreateFacet(modelsProvider: IdeModifiableModelsProvider, useProjectSettings: Boolean, commitModel: Boolean = false): KotlinFacet { diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/HasExpectedMarker.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/HasExpectedMarker.kt index 8e40292f652..446156504b8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/HasExpectedMarker.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/HasExpectedMarker.kt @@ -16,41 +16,21 @@ package org.jetbrains.kotlin.idea.highlighter.markers -import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.idea.caches.resolve.ModuleProductionSourceInfo -import org.jetbrains.kotlin.idea.caches.resolve.ModuleTestSourceInfo import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.core.toDescriptor +import org.jetbrains.kotlin.idea.facet.implementedDescriptor import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils -import org.jetbrains.kotlin.resolve.MultiTargetPlatform import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker import org.jetbrains.kotlin.resolve.descriptorUtil.module -import org.jetbrains.kotlin.resolve.getMultiTargetPlatform import org.jetbrains.kotlin.utils.addToStdlib.safeAs -val ModuleDescriptor.sourceKind: SourceKind - get() = when (getCapability(ModuleInfo.Capability)) { - is ModuleProductionSourceInfo -> SourceKind.PRODUCTION - is ModuleTestSourceInfo -> SourceKind.TEST - else -> SourceKind.OTHER - } - -enum class SourceKind { OTHER, PRODUCTION, TEST } - -fun ModuleDescriptor.commonModuleOrNull(): ModuleDescriptor? { - val sourceKind = sourceKind - return allDependencyModules.firstOrNull { dependency -> - dependency.getMultiTargetPlatform() == MultiTargetPlatform.Common && dependency.sourceKind == sourceKind - } -} - fun ModuleDescriptor.hasDeclarationOf(descriptor: MemberDescriptor) = declarationOf(descriptor) != null private fun ModuleDescriptor.declarationOf(descriptor: MemberDescriptor): DeclarationDescriptor? = @@ -62,7 +42,7 @@ fun getExpectedDeclarationTooltip(declaration: KtDeclaration?): String? { val descriptor = declaration?.toDescriptor() as? MemberDescriptor ?: return null val platformModuleDescriptor = declaration.containingKtFile.findModuleDescriptor() - val commonModuleDescriptor = platformModuleDescriptor.commonModuleOrNull() ?: return null + val commonModuleDescriptor = platformModuleDescriptor.implementedDescriptor ?: return null if (!commonModuleDescriptor.hasDeclarationOf(descriptor)) return null return "Has declaration in common module" @@ -72,7 +52,7 @@ fun navigateToExpectedDeclaration(declaration: KtDeclaration?) { declaration?.expectedDeclarationIfAny()?.navigate(false) } -internal fun MemberDescriptor.expectedDescriptor() = module.commonModuleOrNull()?.declarationOf(this) +internal fun MemberDescriptor.expectedDescriptor() = module.implementedDescriptor?.declarationOf(this) internal fun KtDeclaration.expectedDeclarationIfAny(): KtDeclaration? { val expectedDescriptor = (toDescriptor() as? MemberDescriptor)?.expectedDescriptor() ?: return null diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt index 636af7d0934..341a0a98d48 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt @@ -44,6 +44,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor import org.jetbrains.kotlin.idea.core.isInheritable import org.jetbrains.kotlin.idea.core.isOverridable import org.jetbrains.kotlin.idea.core.toDescriptor +import org.jetbrains.kotlin.idea.facet.implementedDescriptor import org.jetbrains.kotlin.idea.facet.implementingDescriptors import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.lexer.KtTokens @@ -325,7 +326,7 @@ private fun collectExpectedMarkers(declaration: KtNamedDeclaration, val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return val platformModuleDescriptor = declaration.containingKtFile.findModuleDescriptor() - val commonModuleDescriptor = platformModuleDescriptor.commonModuleOrNull() ?: return + val commonModuleDescriptor = platformModuleDescriptor.implementedDescriptor ?: return if (!commonModuleDescriptor.hasDeclarationOf(descriptor)) return val anchor = declaration.expectOrActualAnchor diff --git a/idea/testData/multiModuleLineMarker/transitiveCommon/common_base/base.kt b/idea/testData/multiModuleLineMarker/transitiveCommon/common_base/base.kt new file mode 100644 index 00000000000..74767981207 --- /dev/null +++ b/idea/testData/multiModuleLineMarker/transitiveCommon/common_base/base.kt @@ -0,0 +1,3 @@ +// !CHECK_HIGHLIGHTING + +class Some \ No newline at end of file diff --git a/idea/testData/multiModuleLineMarker/transitiveCommon/common_user/user.kt b/idea/testData/multiModuleLineMarker/transitiveCommon/common_user/user.kt new file mode 100644 index 00000000000..dc238bf98a3 --- /dev/null +++ b/idea/testData/multiModuleLineMarker/transitiveCommon/common_user/user.kt @@ -0,0 +1,5 @@ +// !CHECK_HIGHLIGHTING + +expect class Expected { + val some: Some +} \ No newline at end of file diff --git a/idea/testData/multiModuleLineMarker/transitiveCommon/jvm/jvm.kt b/idea/testData/multiModuleLineMarker/transitiveCommon/jvm/jvm.kt new file mode 100644 index 00000000000..68715f9470e --- /dev/null +++ b/idea/testData/multiModuleLineMarker/transitiveCommon/jvm/jvm.kt @@ -0,0 +1,3 @@ +actual class Expected { + actual val some = Some() +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleLineMarkerTest.kt b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleLineMarkerTest.kt index 68f25620a89..527f9c4f4e8 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleLineMarkerTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleLineMarkerTest.kt @@ -121,6 +121,25 @@ class MultiModuleLineMarkerTest : AbstractMultiModuleHighlightingTest() { checkHighlightingInAllFiles() } + fun testTransitiveCommon() { + val commonBaseModule = module("common_base", TestJdkKind.MOCK_JDK) + commonBaseModule.createFacet(TargetPlatformKind.Common, false) + + val commonUserModule = module("common_user", TestJdkKind.MOCK_JDK) + commonUserModule.createFacet(TargetPlatformKind.Common, false) + commonUserModule.enableMultiPlatform() + commonUserModule.addDependency(commonBaseModule) + + val jvmPlatform = TargetPlatformKind.Jvm[JvmTarget.JVM_1_6] + val jvmModule = module("jvm", TestJdkKind.MOCK_JDK) + jvmModule.createFacet(jvmPlatform, implementedModuleName = "common_user") + jvmModule.enableMultiPlatform() + jvmModule.addDependency(commonBaseModule) + jvmModule.addDependency(commonUserModule) + + checkHighlightingInAllFiles() + } + fun testWithOverloads() { doMultiPlatformTest(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]) }