Has actual (new MPP): handle possible actual in "common" module

Before this commit, we assumed all actual declarations are
in platform modules, and each platform has no more than one actual.
In new MPP, actual declarations can be also in common code,
and each platform as well as common code can include
more than one actual declarations for given expected.

#KT-26217 Fixed
This commit is contained in:
Mikhail Glukhikh
2018-08-20 12:06:06 +03:00
parent 18d43a2fce
commit 9b29651371
@@ -19,29 +19,34 @@ package org.jetbrains.kotlin.idea.highlighter.markers
import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator
import com.intellij.ide.util.DefaultPsiElementCellRenderer
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.MemberDescriptor
import org.jetbrains.kotlin.idea.caches.project.implementingDescriptors
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.core.toDescriptor
import org.jetbrains.kotlin.idea.util.actualsForExpected
import org.jetbrains.kotlin.idea.util.hasActualsFor
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.MultiTargetPlatform
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.getMultiTargetPlatform
import java.awt.event.MouseEvent
fun getPlatformActualTooltip(declaration: KtDeclaration?): String? {
val descriptor = declaration?.toDescriptor() as? MemberDescriptor ?: return null
val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
val actualDeclarations = declaration?.actualsForExpected() ?: return null
if (actualDeclarations.isEmpty()) return null
val platformModulesWithActuals = commonModuleDescriptor.implementingDescriptors.filter {
it.hasActualsFor(descriptor)
}
if (platformModulesWithActuals.isEmpty()) return null
return platformModulesWithActuals.joinToString(prefix = "Has actuals in ") {
(it.getMultiTargetPlatform() as MultiTargetPlatform.Specific).platform
}
return actualDeclarations.asSequence()
.mapNotNull { it.toDescriptor()?.module }
.groupBy { it.getMultiTargetPlatform() }
.filter { (platform, _) -> platform != null }
.entries
.joinToString(prefix = "Has actuals in ") { (platform, modules) ->
val modulesSuffix = if (modules.size <= 1) "" else " (${modules.size} modules)"
when (platform) {
is MultiTargetPlatform.Specific ->
"${platform.platform}$modulesSuffix"
MultiTargetPlatform.Common ->
"common$modulesSuffix"
null ->
throw AssertionError("Platform should not be null")
}
}
}
fun navigateToPlatformActual(e: MouseEvent?, declaration: KtDeclaration?) {