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.codeInsight.daemon.impl.PsiElementListNavigator
import com.intellij.ide.util.DefaultPsiElementCellRenderer import com.intellij.ide.util.DefaultPsiElementCellRenderer
import com.intellij.psi.PsiElement 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.core.toDescriptor
import org.jetbrains.kotlin.idea.util.actualsForExpected import org.jetbrains.kotlin.idea.util.actualsForExpected
import org.jetbrains.kotlin.idea.util.hasActualsFor
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.MultiTargetPlatform import org.jetbrains.kotlin.resolve.MultiTargetPlatform
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.getMultiTargetPlatform import org.jetbrains.kotlin.resolve.getMultiTargetPlatform
import java.awt.event.MouseEvent import java.awt.event.MouseEvent
fun getPlatformActualTooltip(declaration: KtDeclaration?): String? { fun getPlatformActualTooltip(declaration: KtDeclaration?): String? {
val descriptor = declaration?.toDescriptor() as? MemberDescriptor ?: return null val actualDeclarations = declaration?.actualsForExpected() ?: return null
val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor() if (actualDeclarations.isEmpty()) return null
val platformModulesWithActuals = commonModuleDescriptor.implementingDescriptors.filter { return actualDeclarations.asSequence()
it.hasActualsFor(descriptor) .mapNotNull { it.toDescriptor()?.module }
} .groupBy { it.getMultiTargetPlatform() }
if (platformModulesWithActuals.isEmpty()) return null .filter { (platform, _) -> platform != null }
.entries
return platformModulesWithActuals.joinToString(prefix = "Has actuals in ") { .joinToString(prefix = "Has actuals in ") { (platform, modules) ->
(it.getMultiTargetPlatform() as MultiTargetPlatform.Specific).platform 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?) { fun navigateToPlatformActual(e: MouseEvent?, declaration: KtDeclaration?) {