MPP: Add ImportedModule for non-Android source set modules
The goal is to work around model disposal service which discards module data without ImportedModule instance
This commit is contained in:
+14
@@ -7,9 +7,12 @@ package org.jetbrains.kotlin.android.configure
|
|||||||
|
|
||||||
import com.android.builder.model.AndroidProject
|
import com.android.builder.model.AndroidProject
|
||||||
import com.android.builder.model.NativeAndroidProject
|
import com.android.builder.model.NativeAndroidProject
|
||||||
|
import com.android.tools.idea.gradle.project.sync.idea.data.model.ImportedModule
|
||||||
|
import com.android.tools.idea.gradle.project.sync.idea.data.service.AndroidProjectKeys.IMPORTED_MODULE
|
||||||
import com.intellij.openapi.externalSystem.model.DataNode
|
import com.intellij.openapi.externalSystem.model.DataNode
|
||||||
import com.intellij.openapi.externalSystem.model.project.ModuleData
|
import com.intellij.openapi.externalSystem.model.project.ModuleData
|
||||||
import com.intellij.openapi.externalSystem.model.project.ProjectData
|
import com.intellij.openapi.externalSystem.model.project.ProjectData
|
||||||
|
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||||
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants
|
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants
|
||||||
import com.intellij.openapi.externalSystem.util.Order
|
import com.intellij.openapi.externalSystem.util.Order
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
@@ -18,7 +21,9 @@ import org.jetbrains.kotlin.gradle.KotlinMPPGradleModel
|
|||||||
import org.jetbrains.kotlin.gradle.KotlinMPPGradleModelBuilder
|
import org.jetbrains.kotlin.gradle.KotlinMPPGradleModelBuilder
|
||||||
import org.jetbrains.kotlin.idea.configuration.KotlinMPPGradleProjectResolver
|
import org.jetbrains.kotlin.idea.configuration.KotlinMPPGradleProjectResolver
|
||||||
import org.jetbrains.kotlin.idea.configuration.KotlinSourceSetInfo
|
import org.jetbrains.kotlin.idea.configuration.KotlinSourceSetInfo
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.kotlinSourceSet
|
||||||
import org.jetbrains.kotlin.idea.util.CopyableDataNodeUserDataProperty
|
import org.jetbrains.kotlin.idea.util.CopyableDataNodeUserDataProperty
|
||||||
|
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
|
||||||
import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension
|
import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension
|
||||||
|
|
||||||
var DataNode<ModuleData>.kotlinAndroidSourceSets: List<KotlinSourceSetInfo>?
|
var DataNode<ModuleData>.kotlinAndroidSourceSets: List<KotlinSourceSetInfo>?
|
||||||
@@ -49,6 +54,15 @@ class KotlinAndroidMPPGradleProjectResolver : AbstractProjectResolverExtension()
|
|||||||
super.populateModuleContentRoots(gradleModule, ideModule)
|
super.populateModuleContentRoots(gradleModule, ideModule)
|
||||||
if (isAndroidProject) {
|
if (isAndroidProject) {
|
||||||
KotlinMPPGradleProjectResolver.populateContentRoots(gradleModule, ideModule, resolverCtx)
|
KotlinMPPGradleProjectResolver.populateContentRoots(gradleModule, ideModule, resolverCtx)
|
||||||
|
// Work around module disposal service which discards modules without accompanying ImportedModule instance
|
||||||
|
for (childNode in ExternalSystemApiUtil.getChildren(ideModule, GradleSourceSetData.KEY)) {
|
||||||
|
if (childNode.kotlinSourceSet == null) continue
|
||||||
|
val moduleName = childNode.data.internalName
|
||||||
|
val importedModule = object : ImportedModule(gradleModule) {
|
||||||
|
override fun getName() = moduleName
|
||||||
|
}
|
||||||
|
ideModule.createChild(IMPORTED_MODULE, importedModule)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+96
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.android.configure
|
||||||
|
|
||||||
|
import com.android.builder.model.AndroidProject
|
||||||
|
import com.android.builder.model.NativeAndroidProject
|
||||||
|
import com.android.tools.idea.gradle.ImportedModule
|
||||||
|
import com.android.tools.idea.gradle.project.sync.idea.data.service.AndroidProjectKeys.IMPORTED_MODULE
|
||||||
|
import com.intellij.openapi.externalSystem.model.DataNode
|
||||||
|
import com.intellij.openapi.externalSystem.model.project.ModuleData
|
||||||
|
import com.intellij.openapi.externalSystem.model.project.ProjectData
|
||||||
|
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||||
|
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants
|
||||||
|
import com.intellij.openapi.externalSystem.util.Order
|
||||||
|
import com.intellij.openapi.util.Key
|
||||||
|
import org.gradle.tooling.model.idea.IdeaModule
|
||||||
|
import org.jetbrains.kotlin.gradle.KotlinMPPGradleModel
|
||||||
|
import org.jetbrains.kotlin.gradle.KotlinMPPGradleModelBuilder
|
||||||
|
import org.jetbrains.kotlin.gradle.KotlinPlatform
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.KotlinMPPGradleProjectResolver
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.KotlinSourceSetInfo
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.kotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.idea.util.CopyableDataNodeUserDataProperty
|
||||||
|
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
|
||||||
|
import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension
|
||||||
|
|
||||||
|
var DataNode<ModuleData>.kotlinAndroidSourceSets: List<KotlinSourceSetInfo>?
|
||||||
|
by CopyableDataNodeUserDataProperty(Key.create("ANDROID_COMPILATIONS"))
|
||||||
|
|
||||||
|
@Order(ExternalSystemConstants.UNORDERED - 1)
|
||||||
|
class KotlinAndroidMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
||||||
|
private val isAndroidProject by lazy {
|
||||||
|
resolverCtx.hasModulesWithModel(AndroidProject::class.java)
|
||||||
|
|| resolverCtx.hasModulesWithModel(NativeAndroidProject::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getToolingExtensionsClasses(): Set<Class<out Any>> {
|
||||||
|
return setOf(KotlinMPPGradleModelBuilder::class.java, Unit::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getExtraProjectModelClasses(): Set<Class<out Any>> {
|
||||||
|
return setOf(KotlinMPPGradleModel::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createModule(gradleModule: IdeaModule, projectDataNode: DataNode<ProjectData>): DataNode<ModuleData> {
|
||||||
|
return super.createModule(gradleModule, projectDataNode).also {
|
||||||
|
initializeModuleData(gradleModule, it, projectDataNode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun populateModuleContentRoots(gradleModule: IdeaModule, ideModule: DataNode<ModuleData>) {
|
||||||
|
super.populateModuleContentRoots(gradleModule, ideModule)
|
||||||
|
if (isAndroidProject) {
|
||||||
|
KotlinMPPGradleProjectResolver.populateContentRoots(gradleModule, ideModule, resolverCtx)
|
||||||
|
// Work around module disposal service which discards modules without accompanying ImportedModule instance
|
||||||
|
for (childNode in ExternalSystemApiUtil.getChildren(ideModule, GradleSourceSetData.KEY)) {
|
||||||
|
if (childNode.kotlinSourceSet == null) continue
|
||||||
|
val moduleName = childNode.data.internalName
|
||||||
|
val importedModule = object : ImportedModule(gradleModule) {
|
||||||
|
override fun getName() = moduleName
|
||||||
|
}
|
||||||
|
ideModule.createChild(IMPORTED_MODULE, importedModule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun populateModuleDependencies(gradleModule: IdeaModule, ideModule: DataNode<ModuleData>, ideProject: DataNode<ProjectData>) {
|
||||||
|
super.populateModuleDependencies(gradleModule, ideModule, ideProject)
|
||||||
|
if (isAndroidProject) {
|
||||||
|
KotlinMPPGradleProjectResolver.populateModuleDependencies(gradleModule, ideProject, ideModule, resolverCtx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initializeModuleData(
|
||||||
|
gradleModule: IdeaModule,
|
||||||
|
mainModuleData: DataNode<ModuleData>,
|
||||||
|
projectDataNode: DataNode<ProjectData>
|
||||||
|
) {
|
||||||
|
if (!isAndroidProject) return
|
||||||
|
|
||||||
|
KotlinMPPGradleProjectResolver.initializeModuleData(gradleModule, mainModuleData, projectDataNode, resolverCtx)
|
||||||
|
|
||||||
|
val mppModel = resolverCtx.getExtraProject(gradleModule, KotlinMPPGradleModel::class.java) ?: return
|
||||||
|
|
||||||
|
mainModuleData.kotlinAndroidSourceSets = mppModel
|
||||||
|
.targets
|
||||||
|
.asSequence()
|
||||||
|
.flatMap { it.compilations.asSequence() }
|
||||||
|
.filter { it.platform == KotlinPlatform.ANDROID }
|
||||||
|
.map { KotlinMPPGradleProjectResolver.createSourceSetInfo(it, gradleModule, resolverCtx) }
|
||||||
|
.toList()
|
||||||
|
}
|
||||||
|
}
|
||||||
+96
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.android.configure
|
||||||
|
|
||||||
|
import com.android.builder.model.AndroidProject
|
||||||
|
import com.android.builder.model.NativeAndroidProject
|
||||||
|
import com.android.tools.idea.gradle.project.sync.idea.data.model.ImportedModule
|
||||||
|
import com.android.tools.idea.gradle.project.sync.idea.data.service.AndroidProjectKeys.IMPORTED_MODULE
|
||||||
|
import com.intellij.openapi.externalSystem.model.DataNode
|
||||||
|
import com.intellij.openapi.externalSystem.model.project.ModuleData
|
||||||
|
import com.intellij.openapi.externalSystem.model.project.ProjectData
|
||||||
|
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||||
|
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants
|
||||||
|
import com.intellij.openapi.externalSystem.util.Order
|
||||||
|
import com.intellij.openapi.util.Key
|
||||||
|
import org.gradle.tooling.model.idea.IdeaModule
|
||||||
|
import org.jetbrains.kotlin.gradle.KotlinMPPGradleModel
|
||||||
|
import org.jetbrains.kotlin.gradle.KotlinMPPGradleModelBuilder
|
||||||
|
import org.jetbrains.kotlin.gradle.KotlinPlatform
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.KotlinMPPGradleProjectResolver
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.KotlinSourceSetInfo
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.kotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.idea.util.CopyableDataNodeUserDataProperty
|
||||||
|
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
|
||||||
|
import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension
|
||||||
|
|
||||||
|
var DataNode<ModuleData>.kotlinAndroidSourceSets: List<KotlinSourceSetInfo>?
|
||||||
|
by CopyableDataNodeUserDataProperty(Key.create("ANDROID_COMPILATIONS"))
|
||||||
|
|
||||||
|
@Order(ExternalSystemConstants.UNORDERED - 1)
|
||||||
|
class KotlinAndroidMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
||||||
|
private val isAndroidProject by lazy {
|
||||||
|
resolverCtx.hasModulesWithModel(AndroidProject::class.java)
|
||||||
|
|| resolverCtx.hasModulesWithModel(NativeAndroidProject::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getToolingExtensionsClasses(): Set<Class<out Any>> {
|
||||||
|
return setOf(KotlinMPPGradleModelBuilder::class.java, Unit::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getExtraProjectModelClasses(): Set<Class<out Any>> {
|
||||||
|
return setOf(KotlinMPPGradleModel::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createModule(gradleModule: IdeaModule, projectDataNode: DataNode<ProjectData>): DataNode<ModuleData> {
|
||||||
|
return super.createModule(gradleModule, projectDataNode).also {
|
||||||
|
initializeModuleData(gradleModule, it, projectDataNode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun populateModuleContentRoots(gradleModule: IdeaModule, ideModule: DataNode<ModuleData>) {
|
||||||
|
super.populateModuleContentRoots(gradleModule, ideModule)
|
||||||
|
if (isAndroidProject) {
|
||||||
|
KotlinMPPGradleProjectResolver.populateContentRoots(gradleModule, ideModule, resolverCtx)
|
||||||
|
// Work around module disposal service which discards modules without accompanying ImportedModule instance
|
||||||
|
for (childNode in ExternalSystemApiUtil.getChildren(ideModule, GradleSourceSetData.KEY)) {
|
||||||
|
if (childNode.kotlinSourceSet == null) continue
|
||||||
|
val moduleName = childNode.data.internalName
|
||||||
|
val importedModule = object : ImportedModule(gradleModule) {
|
||||||
|
override fun getName() = moduleName
|
||||||
|
}
|
||||||
|
ideModule.createChild(IMPORTED_MODULE, importedModule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun populateModuleDependencies(gradleModule: IdeaModule, ideModule: DataNode<ModuleData>, ideProject: DataNode<ProjectData>) {
|
||||||
|
super.populateModuleDependencies(gradleModule, ideModule, ideProject)
|
||||||
|
if (isAndroidProject) {
|
||||||
|
KotlinMPPGradleProjectResolver.populateModuleDependencies(gradleModule, ideProject, ideModule, resolverCtx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initializeModuleData(
|
||||||
|
gradleModule: IdeaModule,
|
||||||
|
mainModuleData: DataNode<ModuleData>,
|
||||||
|
projectDataNode: DataNode<ProjectData>
|
||||||
|
) {
|
||||||
|
if (!isAndroidProject) return
|
||||||
|
|
||||||
|
KotlinMPPGradleProjectResolver.initializeModuleData(gradleModule, mainModuleData, projectDataNode, resolverCtx)
|
||||||
|
|
||||||
|
val mppModel = resolverCtx.getExtraProject(gradleModule, KotlinMPPGradleModel::class.java) ?: return
|
||||||
|
|
||||||
|
mainModuleData.kotlinAndroidSourceSets = mppModel
|
||||||
|
.targets
|
||||||
|
.asSequence()
|
||||||
|
.flatMap { it.compilations.asSequence() }
|
||||||
|
.filter { it.platform == KotlinPlatform.ANDROID }
|
||||||
|
.map { KotlinMPPGradleProjectResolver.createSourceSetInfo(it, gradleModule, resolverCtx) }
|
||||||
|
.toList()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user