Introduce ModuleDescriptor.findImplementingDescriptor() via facets

This function is now used instead of allImplementingCompatibleModules,
thus allowing it to be deleted together with allImplementingModules

So #KT-17369 Fixed
So #KT-17374 Fixed
May fix also some other MPP issues
This commit is contained in:
Mikhail Glukhikh
2017-09-26 16:15:50 +03:00
parent c9f11e4bc2
commit 5687fe6e39
14 changed files with 66 additions and 66 deletions
@@ -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<String, TargetPlatformKind<*>> 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<Module> {
return modelsProvider.modules.filter { module ->
module.findImplementedModuleName(modelsProvider) == name
}
}
fun ModuleDescriptor.findImplementingDescriptors(): List<ModuleDescriptor> {
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 {
@@ -0,0 +1,68 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.descriptors.MemberDescriptor
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
import org.jetbrains.kotlin.psi.KtPsiUtil
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
import org.jetbrains.kotlin.resolve.BindingTraceContext
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.diagnostics.SimpleDiagnostics
class PlatformExpectedAnnotator : Annotator {
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
val declaration = element as? KtDeclaration ?: return
if (!isExpectedDeclaration(declaration)) return
if (TargetPlatformDetector.getPlatform(declaration.containingKtFile) !is TargetPlatform.Common) return
val implementingModules = declaration.findModuleDescriptor().findImplementingDescriptors()
if (implementingModules.isEmpty()) return
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return
if (!descriptor.isExpect) return
val trace = BindingTraceContext()
for (module in implementingModules) {
ExpectedActualDeclarationChecker.checkExpectedDeclarationHasActual(declaration, descriptor, trace, module)
}
val suppressionCache = KotlinCacheService.getInstance(declaration.project).getSuppressionCache()
val filteredList = trace.bindingContext.diagnostics.filter { diagnostic ->
!suppressionCache.isSuppressed(declaration, diagnostic.factory.name, diagnostic.severity)
}
if (filteredList.isEmpty()) return
KotlinPsiChecker().annotateElement(declaration, holder, SimpleDiagnostics(filteredList))
}
private fun isExpectedDeclaration(declaration: KtDeclaration): Boolean {
return declaration.hasExpectModifier() ||
declaration is KtClassOrObject && KtPsiUtil.getOutermostClassOrObject(declaration)?.hasExpectModifier() == true
}
}
@@ -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<DeclarationDe
if (this is MemberDescriptor) {
if (!this.isExpect) return emptyList()
return module.allImplementingCompatibleModules.flatMap { it.actualsFor(this) }
return module.findImplementingDescriptors().flatMap { it.actualsFor(this) }
}
if (this is ValueParameterDescriptor) {
@@ -16,11 +16,13 @@
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.highlighter.sourceKind
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
@@ -30,6 +32,15 @@ import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.getMultiTargetPlatform
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 ->
@@ -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
@@ -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)
}