Optimize memory usage during import of MPP projects
#KT-30767 Fixed
This commit is contained in:
+1
-1
@@ -196,7 +196,7 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
|
||||
if (LOG.isDebugEnabled) {
|
||||
LOG.debug("Start populate module dependencies. Gradle module: [$gradleModule], Ide module: [$ideModule], Ide project: [$ideProject]")
|
||||
}
|
||||
val mppModel = resolverCtx.getExtraProject(gradleModule, KotlinMPPGradleModel::class.java)?.let { KotlinMPPGradleModelImpl(it) }
|
||||
val mppModel = resolverCtx.getMppModel(gradleModule)
|
||||
if (mppModel != null) {
|
||||
mppModel.targets.forEach { target ->
|
||||
KotlinStatisticsTrigger.trigger(
|
||||
|
||||
+21
-8
@@ -45,6 +45,7 @@ import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverUtil.ge
|
||||
import org.jetbrains.plugins.gradle.service.project.ProjectResolverContext
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
@Order(ExternalSystemConstants.UNORDERED + 1)
|
||||
open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
||||
@@ -83,7 +84,7 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
||||
super.populateModuleCompileOutputSettings(gradleModule, ideModule)
|
||||
}
|
||||
|
||||
val mppModel = resolverCtx.getExtraProject(gradleModule, KotlinMPPGradleModel::class.java)?.let { KotlinMPPGradleModelImpl(it) } ?: return
|
||||
val mppModel = resolverCtx.getMppModel(gradleModule) ?: return
|
||||
val ideaOutDir = File(ideModule.data.linkedExternalProjectPath, "out")
|
||||
val projectDataNode = ideModule.getDataNode(ProjectKeys.PROJECT)!!
|
||||
val moduleOutputsMap = projectDataNode.getUserData(MODULES_OUTPUTS)!!
|
||||
@@ -153,6 +154,8 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
val proxyObjectCloningCache = WeakHashMap<Any, Any>()
|
||||
|
||||
fun initializeModuleData(
|
||||
gradleModule: IdeaModule,
|
||||
mainModuleNode: DataNode<ModuleData>,
|
||||
@@ -164,7 +167,7 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
||||
val mainModuleFileDirectoryPath = mainModuleData.moduleFileDirectoryPath
|
||||
|
||||
val externalProject = resolverCtx.getExtraProject(gradleModule, ExternalProject::class.java)
|
||||
val mppModel = resolverCtx.getExtraProject(gradleModule, KotlinMPPGradleModel::class.java)?.let { KotlinMPPGradleModelImpl(it) }
|
||||
val mppModel = resolverCtx.getMppModel(gradleModule)
|
||||
if (mppModel == null || externalProject == null) return
|
||||
|
||||
val jdkName = gradleModule.jdkNameIfAny
|
||||
@@ -311,8 +314,7 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
||||
ideModule: DataNode<ModuleData>,
|
||||
resolverCtx: ProjectResolverContext
|
||||
) {
|
||||
val mppModel =
|
||||
resolverCtx.getExtraProject(gradleModule, KotlinMPPGradleModel::class.java)?.let { KotlinMPPGradleModelImpl(it) } ?: return
|
||||
val mppModel = resolverCtx.getMppModel(gradleModule) ?: return
|
||||
if (resolverCtx.getExtraProject(gradleModule, ExternalProject::class.java) == null) return
|
||||
processSourceSets(gradleModule, mppModel, ideModule, resolverCtx) { dataNode, sourceSet ->
|
||||
if (dataNode == null || sourceSet.platform == KotlinPlatform.ANDROID) return@processSourceSets
|
||||
@@ -339,8 +341,7 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
||||
ideModule: DataNode<ModuleData>,
|
||||
resolverCtx: ProjectResolverContext
|
||||
) {
|
||||
val mppModel =
|
||||
resolverCtx.getExtraProject(gradleModule, KotlinMPPGradleModel::class.java)?.let { KotlinMPPGradleModelImpl(it) } ?: return
|
||||
val mppModel = resolverCtx.getMppModel(gradleModule) ?: return
|
||||
val sourceSetMap = ideProject.getUserData(GradleProjectResolver.RESOLVED_SOURCE_SETS) ?: return
|
||||
val artifactsMap = ideProject.getUserData(CONFIGURATION_ARTIFACTS) ?: return
|
||||
val substitutor = KotlinNativeLibrariesDependencySubstitutor(mppModel, gradleModule, resolverCtx)
|
||||
@@ -615,7 +616,7 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
||||
resolverCtx: ProjectResolverContext
|
||||
): KotlinSourceSetInfo? {
|
||||
if (sourceSet.platform.isNotSupported()) return null
|
||||
return KotlinSourceSetInfo(KotlinSourceSetImpl(sourceSet)).also { info ->
|
||||
return KotlinSourceSetInfo(sourceSet).also { info ->
|
||||
val languageSettings = sourceSet.languageSettings
|
||||
info.moduleId = getKotlinModuleId(gradleModule, sourceSet, resolverCtx)
|
||||
info.gradleModuleId = getModuleId(resolverCtx, gradleModule)
|
||||
@@ -645,7 +646,7 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
||||
resolverCtx: ProjectResolverContext
|
||||
): KotlinSourceSetInfo? {
|
||||
if (compilation.platform.isNotSupported()) return null
|
||||
return KotlinSourceSetInfo(KotlinCompilationImpl(compilation)).also { sourceSetInfo ->
|
||||
return KotlinSourceSetInfo(compilation).also { sourceSetInfo ->
|
||||
sourceSetInfo.moduleId = getKotlinModuleId(gradleModule, compilation, resolverCtx)
|
||||
sourceSetInfo.gradleModuleId = getModuleId(resolverCtx, gradleModule)
|
||||
sourceSetInfo.platform = compilation.platform
|
||||
@@ -697,3 +698,15 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
||||
) ?: false
|
||||
}
|
||||
}
|
||||
|
||||
fun ProjectResolverContext.getMppModel(gradleModule: IdeaModule): KotlinMPPGradleModel? =
|
||||
this.getExtraProject(gradleModule, KotlinMPPGradleModel::class.java)
|
||||
?.let { kotlinMppModel ->
|
||||
KotlinMPPGradleProjectResolver.proxyObjectCloningCache[kotlinMppModel] as? KotlinMPPGradleModelImpl ?: KotlinMPPGradleModelImpl(
|
||||
kotlinMppModel,
|
||||
KotlinMPPGradleProjectResolver.proxyObjectCloningCache
|
||||
).also {
|
||||
KotlinMPPGradleProjectResolver.proxyObjectCloningCache[kotlinMppModel] = it
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,20 @@ import org.jetbrains.plugins.gradle.model.ExternalDependency
|
||||
import org.jetbrains.plugins.gradle.model.ModelFactory
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
import java.util.*
|
||||
|
||||
typealias KotlinDependency = ExternalDependency
|
||||
|
||||
fun KotlinDependency.deepCopy(): KotlinDependency = ModelFactory.createCopy(this)
|
||||
fun KotlinDependency.deepCopy(cache: MutableMap<Any, Any>): KotlinDependency {
|
||||
val cachedValue = cache[this] as? KotlinDependency
|
||||
if (cachedValue != null) {
|
||||
return cachedValue
|
||||
} else {
|
||||
val result = ModelFactory.createCopy(this)
|
||||
cache[this] = result
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
interface KotlinModule : Serializable {
|
||||
val name: String
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
data class KotlinSourceSetImpl(
|
||||
override val name: String,
|
||||
@@ -18,12 +19,12 @@ data class KotlinSourceSetImpl(
|
||||
val defaultIsTestModule: Boolean = false
|
||||
) : KotlinSourceSet {
|
||||
|
||||
constructor(kotlinSourceSet: KotlinSourceSet) : this(
|
||||
constructor(kotlinSourceSet: KotlinSourceSet, cloningCache: MutableMap<Any, Any>) : this(
|
||||
kotlinSourceSet.name,
|
||||
KotlinLanguageSettingsImpl(kotlinSourceSet.languageSettings),
|
||||
HashSet(kotlinSourceSet.sourceDirs),
|
||||
HashSet(kotlinSourceSet.resourceDirs),
|
||||
kotlinSourceSet.dependencies.map { it.deepCopy() }.toSet(),
|
||||
kotlinSourceSet.dependencies.map { it.deepCopy(cloningCache) }.toSet(),
|
||||
HashSet(kotlinSourceSet.dependsOnSourceSets),
|
||||
kotlinSourceSet.platform,
|
||||
kotlinSourceSet.isTestModule
|
||||
@@ -87,10 +88,14 @@ data class KotlinCompilationImpl(
|
||||
) : KotlinCompilation {
|
||||
|
||||
// create deep copy
|
||||
constructor(kotlinCompilation: KotlinCompilation) : this(
|
||||
constructor(kotlinCompilation: KotlinCompilation, cloningCache: MutableMap<Any, Any>) : this(
|
||||
kotlinCompilation.name,
|
||||
kotlinCompilation.sourceSets.map { KotlinSourceSetImpl(it) }.toList(),
|
||||
kotlinCompilation.dependencies.map { it.deepCopy() }.toSet(),
|
||||
kotlinCompilation.sourceSets.map { initialSourceSet ->
|
||||
(cloningCache[initialSourceSet] as? KotlinSourceSet) ?: KotlinSourceSetImpl(initialSourceSet, cloningCache).also {
|
||||
cloningCache[initialSourceSet] = it
|
||||
}
|
||||
}.toList(),
|
||||
kotlinCompilation.dependencies.map { it.deepCopy(cloningCache) }.toSet(),
|
||||
KotlinCompilationOutputImpl(kotlinCompilation.output),
|
||||
KotlinCompilationArgumentsImpl(kotlinCompilation.arguments),
|
||||
ArrayList(kotlinCompilation.dependencyClasspath)
|
||||
@@ -126,12 +131,16 @@ data class KotlinTargetImpl(
|
||||
) : KotlinTarget {
|
||||
override fun toString() = name
|
||||
|
||||
constructor(target: KotlinTarget) : this(
|
||||
constructor(target: KotlinTarget, cloningCache: MutableMap<Any, Any>) : this(
|
||||
target.name,
|
||||
target.presetName,
|
||||
target.disambiguationClassifier,
|
||||
KotlinPlatform.byId(target.platform.id) ?: KotlinPlatform.COMMON,
|
||||
target.compilations.map { KotlinCompilationImpl(it) }.toList(),
|
||||
target.compilations.map { initialCompilation ->
|
||||
(cloningCache[initialCompilation] as? KotlinCompilation) ?: KotlinCompilationImpl(initialCompilation, cloningCache).also {
|
||||
cloningCache[initialCompilation] = it
|
||||
}
|
||||
}.toList(),
|
||||
KotlinTargetJarImpl(target.jar?.archiveFile)
|
||||
)
|
||||
}
|
||||
@@ -147,9 +156,18 @@ data class KotlinMPPGradleModelImpl(
|
||||
override val kotlinNativeHome: String
|
||||
) : KotlinMPPGradleModel {
|
||||
|
||||
constructor(mppModel: KotlinMPPGradleModel) : this(
|
||||
mppModel.sourceSets.mapValues { KotlinSourceSetImpl(it.value) },
|
||||
mppModel.targets.map { KotlinTargetImpl(it) }.toList(),
|
||||
constructor(mppModel: KotlinMPPGradleModel, cloningCache: MutableMap<Any, Any>) : this(
|
||||
mppModel.sourceSets.mapValues { initialSourceSet ->
|
||||
(cloningCache[initialSourceSet] as? KotlinSourceSet) ?: KotlinSourceSetImpl(
|
||||
initialSourceSet.value,
|
||||
cloningCache
|
||||
).also { cloningCache[initialSourceSet] = it }
|
||||
},
|
||||
mppModel.targets.map { initialTarget ->
|
||||
(cloningCache[initialTarget] as? KotlinTarget) ?: KotlinTargetImpl(initialTarget, cloningCache).also {
|
||||
cloningCache[initialTarget] = it
|
||||
}
|
||||
}.toList(),
|
||||
ExtraFeaturesImpl(mppModel.extraFeatures.coroutinesState),
|
||||
mppModel.kotlinNativeHome
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user