Consider platform compatibility in library usage index
Logic of module dependencies is enhanced to filter out incompatible common -> platform dependencies. However the reversed index for getting all modules that use libraries doesn't take this filtering into account and returns all modules based exclusively on order entries. This leads to incorrect library dependency calculation. ^KT-44638 Verification pending
This commit is contained in:
@@ -173,7 +173,7 @@ private fun ideaModelDependencies(
|
||||
return correctedResult
|
||||
}
|
||||
|
||||
private fun TargetPlatform.canDependOn(other: IdeaModuleInfo, isHmppEnabled: Boolean): Boolean {
|
||||
internal fun TargetPlatform.canDependOn(other: IdeaModuleInfo, isHmppEnabled: Boolean): Boolean {
|
||||
if (isHmppEnabled) {
|
||||
// HACK: allow depending on stdlib even if platforms do not match
|
||||
if (isNative() && other is AbstractKlibLibraryInfo && other.libraryRoot.endsWith(KONAN_STDLIB_NAME)) return true
|
||||
|
||||
+13
-2
@@ -19,6 +19,7 @@ import com.intellij.util.containers.ContainerUtil
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import org.jetbrains.kotlin.idea.core.util.CachedValue
|
||||
import org.jetbrains.kotlin.idea.core.util.getValue
|
||||
import org.jetbrains.kotlin.idea.project.isHMPPEnabled
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.isCommon
|
||||
import java.util.*
|
||||
@@ -62,7 +63,7 @@ class LibraryDependenciesCacheImpl(private val project: Project) : LibraryDepend
|
||||
|
||||
val platform = libraryInfo.platform
|
||||
|
||||
for (module in getLibraryUsageIndex().modulesLibraryIsUsedIn[libraryInfo.library]) {
|
||||
for (module in getLibraryUsageIndex().getModulesLibraryIsUsedIn(libraryInfo)) {
|
||||
if (!processedModules.add(module)) continue
|
||||
|
||||
ModuleRootManager.getInstance(module).orderEntries().recursively().satisfying(condition).process(object : RootPolicy<Unit>() {
|
||||
@@ -109,7 +110,7 @@ class LibraryDependenciesCacheImpl(private val project: Project) : LibraryDepend
|
||||
}
|
||||
|
||||
private inner class LibraryUsageIndex {
|
||||
val modulesLibraryIsUsedIn: MultiMap<Library, Module> = MultiMap.createSet()
|
||||
private val modulesLibraryIsUsedIn: MultiMap<Library, Module> = MultiMap.createSet()
|
||||
|
||||
init {
|
||||
for (module in ModuleManager.getInstance(project).modules) {
|
||||
@@ -123,5 +124,15 @@ class LibraryDependenciesCacheImpl(private val project: Project) : LibraryDepend
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getModulesLibraryIsUsedIn(libraryInfo: LibraryInfo) = sequence<Module> {
|
||||
val ideaModelInfosCache = getIdeaModelInfosCache(project)
|
||||
for (module in modulesLibraryIsUsedIn[libraryInfo.library]) {
|
||||
val mappedModuleInfos = ideaModelInfosCache.getModuleInfosForModule(module)
|
||||
if (mappedModuleInfos.any { it.platform.canDependOn(libraryInfo, module.isHMPPEnabled) }) {
|
||||
yield(module)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
fun checkCloneableIsAbsent(array: Array<String>) {
|
||||
array.<!UNRESOLVED_REFERENCE!>clone<!>()
|
||||
}
|
||||
|
||||
@<!UNRESOLVED_REFERENCE!>Metadata<!>
|
||||
class MetaUnresolved
|
||||
@@ -0,0 +1,10 @@
|
||||
// See KT-44638
|
||||
|
||||
MODULE jvm { platform=[JVM] }
|
||||
MODULE js { platform=[JS] }
|
||||
MODULE common { platform=[JVM, JS] }
|
||||
|
||||
jvm -> STDLIB_JVM, MOCK_JDK { kind=DEPENDENCY }
|
||||
js -> STDLIB_JS { kind=DEPENDENCY }
|
||||
common -> STDLIB_COMMON, STDLIB_JVM { kind=DEPENDENCY }
|
||||
jvm -> common { kind=DEPENDS_ON }
|
||||
@@ -0,0 +1,6 @@
|
||||
fun checkCloneableIsAbsent(array: Array<String>) {
|
||||
array.<!UNRESOLVED_REFERENCE!>clone<!>()
|
||||
}
|
||||
|
||||
@<!UNRESOLVED_REFERENCE!>Metadata<!>
|
||||
class MetaUnresolved
|
||||
@@ -0,0 +1,6 @@
|
||||
fun checkCloneable(array: Array<String>) {
|
||||
array.clone()
|
||||
}
|
||||
|
||||
<!EXPLICIT_METADATA_IS_DISALLOWED!>@Metadata<!>
|
||||
class MetaWithError
|
||||
@@ -26,10 +26,12 @@ import org.jetbrains.kotlin.idea.caches.project.ModuleTestSourceInfo
|
||||
import org.jetbrains.kotlin.idea.framework.CommonLibraryKind
|
||||
import org.jetbrains.kotlin.idea.framework.JSLibraryKind
|
||||
import org.jetbrains.kotlin.idea.framework.platform
|
||||
import org.jetbrains.kotlin.idea.stubs.createMultiplatformFacetM3
|
||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase.*
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.idea.util.getProjectJdkTableSafe
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.js.JsPlatforms
|
||||
import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||
import org.jetbrains.kotlin.test.util.addDependency
|
||||
@@ -316,6 +318,7 @@ class IdeaModuleInfoTest : ModuleTestCase() {
|
||||
a.addDependency(stdlibJvm)
|
||||
|
||||
val b = module("b")
|
||||
b.setUpPlatform(JsPlatforms.defaultJsPlatform)
|
||||
b.addDependency(stdlibCommon)
|
||||
b.addDependency(stdlibJs)
|
||||
|
||||
@@ -480,6 +483,14 @@ class IdeaModuleInfoTest : ModuleTestCase() {
|
||||
kind = JSLibraryKind
|
||||
)
|
||||
|
||||
private fun Module.setUpPlatform(targetPlatform: TargetPlatform) {
|
||||
createMultiplatformFacetM3(
|
||||
platformKind = targetPlatform,
|
||||
dependsOnModuleNames = listOf(),
|
||||
pureKotlinSourceFolders = listOf(),
|
||||
)
|
||||
}
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
|
||||
|
||||
Generated
+5
@@ -199,6 +199,11 @@ public class MultiplatformAnalysisTestGenerated extends AbstractMultiplatformAna
|
||||
runTest("idea/testData/multiplatform/overrideExpectWithCompositeType/");
|
||||
}
|
||||
|
||||
@TestMetadata("platformDependencyInCommon")
|
||||
public void testPlatformDependencyInCommon() throws Exception {
|
||||
runTest("idea/testData/multiplatform/platformDependencyInCommon/");
|
||||
}
|
||||
|
||||
@TestMetadata("platformSpecificChecksInCommon")
|
||||
public void testPlatformSpecificChecksInCommon() throws Exception {
|
||||
runTest("idea/testData/multiplatform/platformSpecificChecksInCommon/");
|
||||
|
||||
Reference in New Issue
Block a user