SOE protection when enumerating dependencies of common modules
#KT-20937 Fixed
This commit is contained in:
+46
-34
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.run
|
|||||||
|
|
||||||
import com.intellij.execution.configurations.JavaRunConfigurationModule
|
import com.intellij.execution.configurations.JavaRunConfigurationModule
|
||||||
import com.intellij.execution.configurations.ModuleBasedConfiguration
|
import com.intellij.execution.configurations.ModuleBasedConfiguration
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
|
||||||
import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager
|
import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager
|
||||||
import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType
|
import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType
|
||||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||||
@@ -41,6 +40,7 @@ import org.jetbrains.plugins.gradle.service.project.data.ExternalProjectDataCach
|
|||||||
import org.jetbrains.plugins.gradle.settings.GradleSystemRunningSettings
|
import org.jetbrains.plugins.gradle.settings.GradleSystemRunningSettings
|
||||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import kotlin.concurrent.getOrSet
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures that build/run actions are always delegated to Gradle for multiplatform projects.
|
* Ensures that build/run actions are always delegated to Gradle for multiplatform projects.
|
||||||
@@ -104,41 +104,44 @@ class MultiplatformGradleProjectTaskRunner : GradleProjectTaskRunner() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultiplatformGradleOrderEnumeratorHandler : OrderEnumerationHandler() {
|
class MultiplatformGradleOrderEnumeratorHandler(val factory: MultiplatformGradleOrderEnumeratorHandler.FactoryImpl) : OrderEnumerationHandler() {
|
||||||
override fun addCustomModuleRoots(type: OrderRootType, rootModel: ModuleRootModel, result: MutableCollection<String>, includeProduction: Boolean, includeTests: Boolean): Boolean {
|
override fun addCustomModuleRoots(type: OrderRootType, rootModel: ModuleRootModel, result: MutableCollection<String>, includeProduction: Boolean, includeTests: Boolean): Boolean {
|
||||||
if (type != OrderRootType.CLASSES) return false
|
if (factory.isEnumerating(rootModel.module)) return false
|
||||||
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, rootModel.module)) return false
|
factory.startEnumerating(rootModel.module)
|
||||||
|
try {
|
||||||
|
if (type != OrderRootType.CLASSES) return false
|
||||||
|
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, rootModel.module)) return false
|
||||||
|
|
||||||
if (!GradleSystemRunningSettings.getInstance().isUseGradleAwareMake) {
|
if (!GradleSystemRunningSettings.getInstance().isUseGradleAwareMake) {
|
||||||
val gradleProjectPath = ExternalSystemModulePropertyManager.getInstance(rootModel.module).getRootProjectPath() ?: return false
|
val gradleProjectPath = ExternalSystemModulePropertyManager.getInstance(rootModel.module).getRootProjectPath() ?: return false
|
||||||
val externalProjectDataCache = ExternalProjectDataCache.getInstance(rootModel.module.project)!!
|
val externalProjectDataCache = ExternalProjectDataCache.getInstance(rootModel.module.project)!!
|
||||||
val externalRootProject = externalProjectDataCache.getRootExternalProject(GradleConstants.SYSTEM_ID,
|
val externalRootProject = externalProjectDataCache.getRootExternalProject(GradleConstants.SYSTEM_ID,
|
||||||
File(gradleProjectPath)) ?: return false
|
File(gradleProjectPath)) ?: return false
|
||||||
|
|
||||||
val externalSourceSets = externalProjectDataCache.findExternalProject(externalRootProject, rootModel.module)
|
val externalSourceSets = externalProjectDataCache.findExternalProject(externalRootProject, rootModel.module)
|
||||||
|
|
||||||
for (sourceSet in externalSourceSets.values) {
|
for (sourceSet in externalSourceSets.values) {
|
||||||
if (includeTests) {
|
if (includeTests) {
|
||||||
addOutputModuleRoots(sourceSet.sources[ExternalSystemSourceType.TEST], result)
|
addOutputModuleRoots(sourceSet.sources[ExternalSystemSourceType.TEST], result)
|
||||||
}
|
}
|
||||||
if (includeProduction) {
|
if (includeProduction) {
|
||||||
addOutputModuleRoots(sourceSet.sources[ExternalSystemSourceType.SOURCE], result)
|
addOutputModuleRoots(sourceSet.sources[ExternalSystemSourceType.SOURCE], result)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val implModule = rootModel.module.findJvmImplementationModule()
|
val implModule = rootModel.module.findJvmImplementationModule()
|
||||||
if (implModule != null) {
|
implModule
|
||||||
LOG.info("JVM implementation module for ${rootModel.module.name} is ${implModule.name}")
|
?.rootManager
|
||||||
}
|
?.orderEntries()
|
||||||
implModule
|
?.satisfying { orderEntry -> (orderEntry as? ModuleOrderEntry)?.module != rootModel.module }
|
||||||
?.rootManager
|
?.compileOnly()
|
||||||
?.orderEntries()
|
?.classesRoots
|
||||||
?.satisfying { orderEntry -> (orderEntry as? ModuleOrderEntry)?.module != rootModel.module }
|
?.mapTo(result) { it.url }
|
||||||
?.compileOnly()
|
|
||||||
?.classesRoots
|
|
||||||
?.mapTo(result) { it.url }
|
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
factory.doneEnumerating(rootModel.module)
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,18 +149,27 @@ class MultiplatformGradleOrderEnumeratorHandler : OrderEnumerationHandler() {
|
|||||||
directorySet?.gradleOutputDirs?.mapTo(result) { VfsUtilCore.pathToUrl(it.absolutePath) }
|
directorySet?.gradleOutputDirs?.mapTo(result) { VfsUtilCore.pathToUrl(it.absolutePath) }
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
val LOG = Logger.getInstance(MultiplatformGradleOrderEnumeratorHandler::class.java)
|
|
||||||
}
|
|
||||||
|
|
||||||
class FactoryImpl : Factory() {
|
class FactoryImpl : Factory() {
|
||||||
|
private val activeSet = ThreadLocal<MutableSet<Module>>()
|
||||||
|
|
||||||
|
fun startEnumerating(module: Module) {
|
||||||
|
activeSet.getOrSet { hashSetOf() } += module
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doneEnumerating(module: Module) {
|
||||||
|
activeSet.get()?.remove(module)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isEnumerating(module: Module) = activeSet.get()?.contains(module) ?: false
|
||||||
|
|
||||||
override fun isApplicable(module: Module): Boolean {
|
override fun isApplicable(module: Module): Boolean {
|
||||||
return ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module) &&
|
return ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module) &&
|
||||||
module.isMultiplatformModule()
|
module.isMultiplatformModule() &&
|
||||||
|
!isEnumerating(module)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createHandler(module: Module): OrderEnumerationHandler =
|
override fun createHandler(module: Module): OrderEnumerationHandler =
|
||||||
MultiplatformGradleOrderEnumeratorHandler()
|
MultiplatformGradleOrderEnumeratorHandler(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user