diff --git a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt index c3c58e723a9..59de04c2c84 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt @@ -118,7 +118,6 @@ class ResolverForProjectImpl( moduleDescriptor.setDependencies(LazyModuleDependencies( projectContext.storageManager, module, - modulePlatforms, firstDependency, this)) @@ -270,7 +269,6 @@ abstract class AnalyzerFacade { class LazyModuleDependencies( storageManager: StorageManager, private val module: M, - modulePlatforms: (M) -> MultiTargetPlatform?, firstDependency: M? = null, private val resolverForProject: ResolverForProjectImpl ) : ModuleDependencies { @@ -292,14 +290,6 @@ class LazyModuleDependencies( }.toList() } - private val implementingModules = storageManager.createLazyValue { - if (modulePlatforms(module) != MultiTargetPlatform.Common) emptySet() - else resolverForProject.modules - .filterTo(mutableSetOf()) { - modulePlatforms(it) != MultiTargetPlatform.Common && module in it.dependencies() - } - } - override val allDependencies: List get() = dependencies() override val modulesWhoseInternalsAreVisible: Set @@ -308,8 +298,6 @@ class LazyModuleDependencies( resolverForProject.descriptorForModule(it as M) } - override val allImplementingModules: Set - get() = implementingModules().mapTo(mutableSetOf()) { resolverForProject.descriptorForModule(it) } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/ModuleDescriptor.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/ModuleDescriptor.kt index a9262fe6349..d5a2164a41a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/ModuleDescriptor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/ModuleDescriptor.kt @@ -40,9 +40,6 @@ interface ModuleDescriptor : DeclarationDescriptor { */ val allDependencyModules: List - // All platform-specific modules depending on common 'this' module (result is empty if this is platform-specific itself) - val allImplementingModules: Set - fun getCapability(capability: Capability): T? class Capability(val name: String) { diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ModuleDescriptorImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ModuleDescriptorImpl.kt index 1564e153448..b703f9a3482 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ModuleDescriptorImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ModuleDescriptorImpl.kt @@ -48,9 +48,6 @@ class ModuleDescriptorImpl @JvmOverloads constructor( private var packageFragmentProviderForModuleContent: PackageFragmentProvider? = null override var isValid: Boolean = true - set(value) { - field = value - } override fun assertValid() { if (!isValid) { @@ -68,9 +65,6 @@ class ModuleDescriptorImpl @JvmOverloads constructor( override val allDependencyModules: List get() = this.dependencies.sure { "Dependencies of module $id were not set" }.allDependencies.filter { it != this } - override val allImplementingModules: Set - get() = this.dependencies.sure { "Dependencies of module $id were not set" }.allImplementingModules - override fun getPackage(fqName: FqName): PackageViewDescriptor { assertValid() return packages(fqName) @@ -144,12 +138,9 @@ class ModuleDescriptorImpl @JvmOverloads constructor( interface ModuleDependencies { val allDependencies: List val modulesWhoseInternalsAreVisible: Set - val allImplementingModules: Set } class ModuleDependenciesImpl( override val allDependencies: List, override val modulesWhoseInternalsAreVisible: Set -) : ModuleDependencies { - override val allImplementingModules: Set = emptySet() -} +) : ModuleDependencies \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java index cf21ac75fe3..c6885e3a1db 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java @@ -85,12 +85,6 @@ public class ErrorUtils { return emptyList(); } - @NotNull - @Override - public Set getAllImplementingModules() { - return emptySet(); - } - @Override public R accept(@NotNull DeclarationDescriptorVisitor visitor, D data) { return null; diff --git a/idea/ide-common/src/org/jetbrains/kotlin/caches/resolve/KotlinCacheService.kt b/idea/ide-common/src/org/jetbrains/kotlin/caches/resolve/KotlinCacheService.kt index e38c48848cd..d47377a7c55 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/caches/resolve/KotlinCacheService.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/caches/resolve/KotlinCacheService.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.caches.resolve import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.project.Project import com.intellij.psi.PsiFile +import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.resolve.TargetPlatform @@ -33,4 +34,5 @@ interface KotlinCacheService { fun getResolutionFacadeByFile(file: PsiFile, platform: TargetPlatform): ResolutionFacade fun getSuppressionCache(): KotlinSuppressCache + fun getResolutionFacadeByModuleInfo(moduleInfo: ModuleInfo, platform: TargetPlatform): ResolutionFacade? } \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/KotlinCacheServiceImpl.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/KotlinCacheServiceImpl.kt index 4f6bc881abb..ce546117cc9 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/KotlinCacheServiceImpl.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/KotlinCacheServiceImpl.kt @@ -28,8 +28,7 @@ import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.PsiModificationTracker import com.intellij.util.containers.SLRUCache -import org.jetbrains.kotlin.analyzer.LanguageSettingsProvider -import org.jetbrains.kotlin.analyzer.EmptyResolverForProject +import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.caches.resolve.KotlinCacheService import org.jetbrains.kotlin.config.LanguageFeature @@ -367,6 +366,9 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService { return ResolutionFacadeImpl(projectFacade, moduleInfo) } + override fun getResolutionFacadeByModuleInfo(moduleInfo: ModuleInfo, platform: TargetPlatform): ResolutionFacade? = + (moduleInfo as? IdeaModuleInfo)?.let { getResolutionFacadeByModuleInfo(it, platform) } + private fun Collection.filterNotInProjectSource(moduleInfo: IdeaModuleInfo) = mapNotNull { if (it is KtCodeFragment) it.getContextFile() else it }.filter { diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/run/KotlinMultiplatformJUnitRecognizer.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/run/KotlinMultiplatformJUnitRecognizer.kt index bfebf76b95c..3df59c32baf 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/run/KotlinMultiplatformJUnitRecognizer.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/run/KotlinMultiplatformJUnitRecognizer.kt @@ -26,7 +26,7 @@ import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor -import org.jetbrains.kotlin.idea.highlighter.allImplementingCompatibleModules +import org.jetbrains.kotlin.idea.facet.findImplementingDescriptors import org.jetbrains.kotlin.idea.highlighter.markers.actualsFor import org.jetbrains.kotlin.idea.project.targetPlatform import org.jetbrains.kotlin.idea.util.module @@ -41,7 +41,7 @@ class KotlinMultiplatformJUnitRecognizer : JUnitRecognizer() { if (origin.module?.targetPlatform !is TargetPlatformKind.Common) return false val moduleDescriptor = origin.containingKtFile.findModuleDescriptor() - val implModules = moduleDescriptor.allImplementingCompatibleModules + val implModules = moduleDescriptor.findImplementingDescriptors() if (implModules.isEmpty()) return false val bindingContext = origin.analyze(BodyResolveMode.PARTIAL) diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt index faa41192840..ccf163d2ef8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.idea.facet import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider +import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProviderImpl import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.openapi.projectRoots.JavaSdk @@ -26,9 +27,13 @@ import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.ModuleRootModel import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.text.StringUtil +import org.jetbrains.kotlin.analyzer.ModuleInfo +import org.jetbrains.kotlin.caches.resolve.KotlinCacheService import org.jetbrains.kotlin.cli.common.arguments.* import org.jetbrains.kotlin.compilerRunner.ArgumentUtils import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.* import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JsCompilerArgumentsHolder import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JvmCompilerArgumentsHolder import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder @@ -111,6 +116,35 @@ val mavenLibraryIdToPlatform: Map> by lazy { .toMap() } +private fun Module.findImplementedModuleName(modelsProvider: IdeModifiableModelsProvider): String? { + val facetModel = modelsProvider.getModifiableFacetModel(this) + val facet = facetModel.findFacet(KotlinFacetType.TYPE_ID, KotlinFacetType.INSTANCE.defaultFacetName) + return facet?.configuration?.settings?.implementedModuleName +} + +private fun Module.findImplementingModules(modelsProvider: IdeModifiableModelsProvider): List { + return modelsProvider.modules.filter { module -> + module.findImplementedModuleName(modelsProvider) == name + } +} + +fun ModuleDescriptor.findImplementingDescriptors(): List { + val moduleSourceInfo = getCapability(ModuleInfo.Capability) as? ModuleSourceInfo ?: return emptyList() + val module = moduleSourceInfo.module + val modelsProvider = IdeModifiableModelsProviderImpl(module.project) + val implementingModules = module.findImplementingModules(modelsProvider) + return implementingModules.mapNotNull { + val implementingModuleInfo = when (moduleSourceInfo) { + is ModuleProductionSourceInfo -> it.productionSourceInfo() + is ModuleTestSourceInfo -> it.testSourceInfo() + else -> null + } + implementingModuleInfo?.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/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt similarity index 77% rename from idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt rename to idea/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt index 0697129138d..a57b522eab8 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2016 JetBrains s.r.o. + * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,14 +19,11 @@ package org.jetbrains.kotlin.idea.highlighter import com.intellij.lang.annotation.AnnotationHolder import com.intellij.lang.annotation.Annotator import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.caches.resolve.KotlinCacheService import org.jetbrains.kotlin.descriptors.MemberDescriptor -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -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.core.toDescriptor +import org.jetbrains.kotlin.idea.facet.findImplementingDescriptors import org.jetbrains.kotlin.idea.project.TargetPlatformDetector import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDeclaration @@ -37,22 +34,6 @@ import org.jetbrains.kotlin.resolve.TargetPlatform import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker import org.jetbrains.kotlin.resolve.diagnostics.SimpleDiagnostics -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 } - -val ModuleDescriptor.allImplementingCompatibleModules - get() = allImplementingModules.filter { other -> - this.sourceKind == SourceKind.OTHER || - other.sourceKind == SourceKind.OTHER || - other.sourceKind == this.sourceKind - } - class PlatformExpectedAnnotator : Annotator { override fun annotate(element: PsiElement, holder: AnnotationHolder) { val declaration = element as? KtDeclaration ?: return @@ -60,7 +41,7 @@ class PlatformExpectedAnnotator : Annotator { if (TargetPlatformDetector.getPlatform(declaration.containingKtFile) !is TargetPlatform.Common) return - val implementingModules = declaration.findModuleDescriptor().allImplementingCompatibleModules + val implementingModules = declaration.findModuleDescriptor().findImplementingDescriptors() if (implementingModules.isEmpty()) return val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/HasActualMarker.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/HasActualMarker.kt index 18e2ed44336..ace7b71a986 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/HasActualMarker.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/HasActualMarker.kt @@ -22,7 +22,7 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor import org.jetbrains.kotlin.idea.core.toDescriptor -import org.jetbrains.kotlin.idea.highlighter.allImplementingCompatibleModules +import org.jetbrains.kotlin.idea.facet.findImplementingDescriptors import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.MultiTargetPlatform @@ -48,7 +48,7 @@ fun getPlatformActualTooltip(declaration: KtDeclaration): String? { val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return null val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor() - val platformModulesWithActuals = commonModuleDescriptor.allImplementingCompatibleModules.filter { + val platformModulesWithActuals = commonModuleDescriptor.findImplementingDescriptors().filter { it.hasActualsFor(descriptor) } if (platformModulesWithActuals.isEmpty()) return null @@ -74,7 +74,7 @@ private fun DeclarationDescriptor.actualsForExpected(): Collection 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 -> 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 b3a5e2f686e..fe8eee17fe6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt @@ -44,7 +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.highlighter.allImplementingCompatibleModules +import org.jetbrains.kotlin.idea.facet.findImplementingDescriptors import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* @@ -292,7 +292,7 @@ private fun collectActualMarkers(declaration: KtNamedDeclaration, val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor() - if (commonModuleDescriptor.allImplementingCompatibleModules.none { it.hasActualsFor(descriptor) }) return + if (commonModuleDescriptor.findImplementingDescriptors().none { it.hasActualsFor(descriptor) }) return val anchor = declaration.nameIdentifier ?: declaration diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt index fb35dcf561e..12c13394b4b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt @@ -53,9 +53,9 @@ import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.core.isInheritable import org.jetbrains.kotlin.idea.core.toDescriptor +import org.jetbrains.kotlin.idea.facet.findImplementingDescriptors import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindClassUsagesHandler -import org.jetbrains.kotlin.idea.highlighter.allImplementingCompatibleModules import org.jetbrains.kotlin.idea.highlighter.markers.hasActualsFor import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.references.mainReference @@ -334,7 +334,7 @@ class UnusedSymbolInspection : AbstractKotlinInspection() { descriptor as? MemberDescriptor ?: return false val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor() - return commonModuleDescriptor.allImplementingCompatibleModules.any { it.hasActualsFor(descriptor) } || + return commonModuleDescriptor.findImplementingDescriptors().any { it.hasActualsFor(descriptor) } || commonModuleDescriptor.hasActualsFor(descriptor) } diff --git a/idea/testData/multiModuleHighlighting/multiplatform/transitive/common/common.kt b/idea/testData/multiModuleHighlighting/multiplatform/transitive/common/common.kt index d79a7b292e8..f6b60713910 100644 --- a/idea/testData/multiModuleHighlighting/multiplatform/transitive/common/common.kt +++ b/idea/testData/multiModuleHighlighting/multiplatform/transitive/common/common.kt @@ -1 +1 @@ -expect fun foo(): Int \ No newline at end of file +expect fun foo(): Int \ No newline at end of file