Kotlin Facet: Fix Gradle import without "module per source set" option
#KT-15812 Fixed
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
</extensionPoints>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleSourceSetDataService"/>
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectDataService"/>
|
||||
|
||||
<localInspection
|
||||
|
||||
+64
-30
@@ -23,6 +23,7 @@ import com.intellij.openapi.externalSystem.model.project.ProjectData
|
||||
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.config.CoroutineSupport
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
@@ -43,29 +44,13 @@ interface GradleProjectImportHandler {
|
||||
GradleProjectImportHandler::class.java
|
||||
)
|
||||
|
||||
operator fun invoke(facet: KotlinFacet, sourceSetNode: DataNode<GradleSourceSetData>)
|
||||
fun importBySourceSet(facet: KotlinFacet, sourceSetNode: DataNode<GradleSourceSetData>)
|
||||
fun importByModule(facet: KotlinFacet, moduleNode: DataNode<ModuleData>)
|
||||
}
|
||||
|
||||
class KotlinGradleProjectDataService : AbstractProjectDataService<GradleSourceSetData, Void>() {
|
||||
class KotlinGradleSourceSetDataService : AbstractProjectDataService<GradleSourceSetData, Void>() {
|
||||
override fun getTargetDataKey() = GradleSourceSetData.KEY
|
||||
|
||||
private fun detectPlatformByPlugin(moduleNode: DataNode<ModuleData>): TargetPlatformKind<*>? {
|
||||
val projectNode = ExternalSystemApiUtil.findParent(moduleNode, ProjectKeys.PROJECT)
|
||||
val externalProjectNode = ExternalSystemApiUtil.find(projectNode as DataNode<*>, ExternalProjectDataService.KEY)
|
||||
return externalProjectNode?.let {
|
||||
when (it.data.plugins.values.map { it.id }.firstOrNull { it.startsWith("kotlin-platform-") }) {
|
||||
"kotlin-platform-jvm" -> TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]
|
||||
"kotlin-platform-js" -> TargetPlatformKind.JavaScript
|
||||
"kotlin-platform-common" -> TargetPlatformKind.Common
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun detectPlatformByLibrary(moduleNode: DataNode<ModuleData>): TargetPlatformKind<*>? {
|
||||
return TargetPlatformKind.ALL_PLATFORMS.firstOrNull { moduleNode.getResolvedKotlinStdlibVersionByModuleData(it.mavenLibraryId) != null }
|
||||
}
|
||||
|
||||
override fun postProcess(
|
||||
toImport: Collection<DataNode<GradleSourceSetData>>,
|
||||
projectData: ProjectData?,
|
||||
@@ -76,21 +61,70 @@ class KotlinGradleProjectDataService : AbstractProjectDataService<GradleSourceSe
|
||||
val sourceSetData = sourceSetNode.data
|
||||
val ideModule = modelsProvider.findIdeModule(sourceSetData) ?: continue
|
||||
|
||||
val moduleNode = ExternalSystemApiUtil.findParent(sourceSetNode, ProjectKeys.MODULE)
|
||||
val compilerVersion = moduleNode?.findAll(BuildScriptClasspathData.KEY)?.firstOrNull()?.data?.let(::findKotlinPluginVersion)
|
||||
?: continue
|
||||
val platformKind = detectPlatformByPlugin(moduleNode) ?: detectPlatformByLibrary(moduleNode)
|
||||
|
||||
val coroutinesProperty = findKotlinCoroutinesProperty(project)
|
||||
|
||||
val kotlinFacet = ideModule.getOrCreateFacet(modelsProvider, false)
|
||||
kotlinFacet.configureFacet(compilerVersion, coroutinesProperty, platformKind, modelsProvider)
|
||||
moduleNode.serializedCompilerArguments?.let { parseCompilerArgumentsToFacet(it, kotlinFacet) }
|
||||
GradleProjectImportHandler.getInstances(project).forEach { it(kotlinFacet, sourceSetNode) }
|
||||
val moduleNode = ExternalSystemApiUtil.findParent(sourceSetNode, ProjectKeys.MODULE) ?: continue
|
||||
val kotlinFacet = configureFacetByGradleModule(moduleNode, ideModule, modelsProvider) ?: continue
|
||||
GradleProjectImportHandler.getInstances(project).forEach { it.importBySourceSet(kotlinFacet, sourceSetNode) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinGradleProjectDataService : AbstractProjectDataService<ModuleData, Void>() {
|
||||
override fun getTargetDataKey() = ProjectKeys.MODULE
|
||||
|
||||
override fun postProcess(
|
||||
toImport: MutableCollection<DataNode<ModuleData>>,
|
||||
projectData: ProjectData?,
|
||||
project: Project,
|
||||
modelsProvider: IdeModifiableModelsProvider
|
||||
) {
|
||||
for (moduleNode in toImport) {
|
||||
// If source sets are present, configure facets in the their modules
|
||||
if (ExternalSystemApiUtil.getChildren(moduleNode, GradleSourceSetData.KEY).isNotEmpty()) continue
|
||||
|
||||
val moduleData = moduleNode.data
|
||||
val ideModule = modelsProvider.findIdeModule(moduleData) ?: continue
|
||||
val kotlinFacet = configureFacetByGradleModule(moduleNode, ideModule, modelsProvider) ?: continue
|
||||
GradleProjectImportHandler.getInstances(project).forEach { it.importByModule(kotlinFacet, moduleNode) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun detectPlatformByPlugin(moduleNode: DataNode<ModuleData>): TargetPlatformKind<*>? {
|
||||
val projectNode = ExternalSystemApiUtil.findParent(moduleNode, ProjectKeys.PROJECT)
|
||||
val externalProjectNode = ExternalSystemApiUtil.find(projectNode as DataNode<*>, ExternalProjectDataService.KEY)
|
||||
return externalProjectNode?.let {
|
||||
when (it.data.plugins.values.map { it.id }.firstOrNull { it.startsWith("kotlin-platform-") }) {
|
||||
"kotlin-platform-jvm" -> TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]
|
||||
"kotlin-platform-js" -> TargetPlatformKind.JavaScript
|
||||
"kotlin-platform-common" -> TargetPlatformKind.Common
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun detectPlatformByLibrary(moduleNode: DataNode<ModuleData>): TargetPlatformKind<*>? {
|
||||
return TargetPlatformKind.ALL_PLATFORMS.firstOrNull { moduleNode.getResolvedKotlinStdlibVersionByModuleData(it.mavenLibraryId) != null }
|
||||
}
|
||||
|
||||
private fun configureFacetByGradleModule(
|
||||
moduleNode: DataNode<ModuleData>,
|
||||
ideModule: Module,
|
||||
modelsProvider: IdeModifiableModelsProvider
|
||||
): KotlinFacet? {
|
||||
val compilerVersion = moduleNode.findAll(BuildScriptClasspathData.KEY).firstOrNull()?.data?.let(::findKotlinPluginVersion)
|
||||
?: return null
|
||||
val platformKind = detectPlatformByPlugin(moduleNode) ?: detectPlatformByLibrary(moduleNode)
|
||||
|
||||
val coroutinesProperty = findKotlinCoroutinesProperty(ideModule.project)
|
||||
|
||||
val kotlinFacet = ideModule.getOrCreateFacet(modelsProvider, false)
|
||||
kotlinFacet.configureFacet(compilerVersion, coroutinesProperty, platformKind, modelsProvider)
|
||||
|
||||
moduleNode.serializedCompilerArguments?.let { parseCompilerArgumentsToFacet(it, kotlinFacet) }
|
||||
|
||||
return kotlinFacet
|
||||
}
|
||||
|
||||
private val gradlePropertyFiles = listOf("local.properties", "gradle.properties")
|
||||
|
||||
private fun findKotlinCoroutinesProperty(project: Project): CoroutineSupport {
|
||||
@@ -155,10 +155,9 @@ val TargetPlatformKind<*>.mavenLibraryId: String
|
||||
fun Module.getOrCreateFacet(modelsProvider: IdeModifiableModelsProvider, useProjectSettings: Boolean): KotlinFacet {
|
||||
val facetModel = modelsProvider.getModifiableFacetModel(this)
|
||||
|
||||
facetModel.findFacet(KotlinFacetType.TYPE_ID, KotlinFacetType.INSTANCE.defaultFacetName)?.let { return it }
|
||||
|
||||
val facet = with(KotlinFacetType.INSTANCE) { createFacet(this@getOrCreateFacet, defaultFacetName, createDefaultConfiguration(), null) }
|
||||
facetModel.addFacet(facet)
|
||||
val facet = facetModel.findFacet(KotlinFacetType.TYPE_ID, KotlinFacetType.INSTANCE.defaultFacetName)
|
||||
?: with(KotlinFacetType.INSTANCE) { createFacet(this@getOrCreateFacet, defaultFacetName, createDefaultConfiguration(), null) }
|
||||
.apply { facetModel.addFacet(this) }
|
||||
facet.configuration.settings.useProjectSettings = useProjectSettings
|
||||
return facet
|
||||
}
|
||||
|
||||
+16
-6
@@ -17,8 +17,10 @@
|
||||
package org.jetbrains.kotlin.annotation.plugin.ide
|
||||
|
||||
import com.intellij.openapi.externalSystem.model.DataNode
|
||||
import com.intellij.openapi.externalSystem.model.ProjectKeys
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData
|
||||
import com.intellij.openapi.externalSystem.model.task.TaskData
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import org.jetbrains.kotlin.idea.configuration.GradleProjectImportHandler
|
||||
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
||||
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
|
||||
@@ -35,18 +37,23 @@ abstract class AbstractGradleImportHandler : GradleProjectImportHandler {
|
||||
abstract val dataStorageTaskName: String
|
||||
abstract val pluginJarFileFromIdea: File
|
||||
|
||||
override fun invoke(facet: KotlinFacet, sourceSetNode: DataNode<GradleSourceSetData>) {
|
||||
modifyCompilerArgumentsForPlugin(facet, getPluginSetup(sourceSetNode),
|
||||
override fun importBySourceSet(facet: KotlinFacet, sourceSetNode: DataNode<GradleSourceSetData>) {
|
||||
modifyCompilerArgumentsForPlugin(facet, getPluginSetupBySourceSet(sourceSetNode),
|
||||
compilerPluginId = compilerPluginId,
|
||||
pluginName = pluginName,
|
||||
annotationOptionName = annotationOptionName)
|
||||
}
|
||||
|
||||
private fun getPluginSetup(
|
||||
sourceSetNode: DataNode<GradleSourceSetData>
|
||||
override fun importByModule(facet: KotlinFacet, moduleNode: DataNode<ModuleData>) {
|
||||
modifyCompilerArgumentsForPlugin(facet, getPluginSetupByModule(moduleNode),
|
||||
compilerPluginId = compilerPluginId,
|
||||
pluginName = pluginName,
|
||||
annotationOptionName = annotationOptionName)
|
||||
}
|
||||
|
||||
private fun getPluginSetupByModule(
|
||||
moduleNode: DataNode<ModuleData>
|
||||
): AnnotationBasedCompilerPluginSetup? {
|
||||
val moduleNode = sourceSetNode.parent ?: return null
|
||||
if (moduleNode.data !is ModuleData) return null
|
||||
val dataStorageTaskData = moduleNode.children.firstOrNull {
|
||||
val data = it.data as? TaskData ?: return@firstOrNull false
|
||||
data.name == dataStorageTaskName
|
||||
@@ -63,4 +70,7 @@ abstract class AbstractGradleImportHandler : GradleProjectImportHandler {
|
||||
|
||||
return AnnotationBasedCompilerPluginSetup(annotationFqNames, classpath)
|
||||
}
|
||||
|
||||
private fun getPluginSetupBySourceSet(sourceSetNode: DataNode<GradleSourceSetData>) =
|
||||
ExternalSystemApiUtil.findParent(sourceSetNode, ProjectKeys.MODULE)?.let { getPluginSetupByModule(it) }
|
||||
}
|
||||
Reference in New Issue
Block a user