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
This commit is contained in:
Mikhail Glukhikh
2017-10-09 15:07:40 +03:00
parent b5e2fa5f94
commit 4bfaa46c15
7 changed files with 57 additions and 31 deletions
@@ -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<ModuleSourceInfo> {
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<ModuleDescriptor>
@@ -159,6 +160,20 @@ val ModuleDescriptor.implementingDescriptors: List<ModuleDescriptor>
})
}
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 {
@@ -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
@@ -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
@@ -0,0 +1,3 @@
// !CHECK_HIGHLIGHTING
class Some
@@ -0,0 +1,5 @@
// !CHECK_HIGHLIGHTING
expect class Expected {
val some: Some
}
@@ -0,0 +1,3 @@
actual class <lineMarker>Expected</lineMarker> {
actual val <lineMarker>some</lineMarker> = Some()
}
@@ -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])
}