Skip to content

Commit 26537cd

Browse files
committed
Kotlin Facet: Distinguish compiler arguments specified for different source sets
#KT-16698 Fixed
1 parent 0e583aa commit 26537cd

File tree

4 files changed

+253
-29
lines changed

4 files changed

+253
-29
lines changed

idea/kotlin-gradle-tooling/src/KotlinGradleModelBuilder.kt

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,35 @@
1717
package org.jetbrains.kotlin.gradle
1818

1919
import org.gradle.api.Project
20+
import org.gradle.api.Task
2021
import org.gradle.api.artifacts.ProjectDependency
2122
import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder
2223
import org.jetbrains.plugins.gradle.tooling.ModelBuilderService
2324
import java.io.Serializable
2425
import java.lang.Exception
26+
import java.lang.reflect.InvocationTargetException
27+
import java.lang.reflect.Method
28+
29+
typealias CompilerArgumentsBySourceSet = Map<String, List<String>>
2530

2631
interface KotlinGradleModel : Serializable {
2732
val implements: String?
28-
val currentCompilerArguments: List<String>?
29-
val defaultCompilerArguments: List<String>?
33+
val currentCompilerArgumentsBySourceSet: CompilerArgumentsBySourceSet
34+
val defaultCompilerArgumentsBySourceSet: CompilerArgumentsBySourceSet
3035
val coroutines: String?
3136
}
3237

3338
class KotlinGradleModelImpl(
3439
override val implements: String?,
35-
override val currentCompilerArguments: List<String>?,
36-
override val defaultCompilerArguments: List<String>?,
40+
override val currentCompilerArgumentsBySourceSet: CompilerArgumentsBySourceSet,
41+
override val defaultCompilerArgumentsBySourceSet: CompilerArgumentsBySourceSet,
3742
override val coroutines: String?
3843
) : KotlinGradleModel
3944

4045
class KotlinGradleModelBuilder : ModelBuilderService {
4146
companion object {
42-
val compileTasks = listOf("compileKotlin", "compileKotlin2Js")
47+
val kotlinCompileTaskClasses = listOf("org.jetbrains.kotlin.gradle.tasks.KotlinCompile_Decorated",
48+
"org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile_Decorated")
4349
}
4450

4551
override fun getErrorMessageBuilder(project: Project, e: Exception): ErrorMessageBuilder {
@@ -57,15 +63,35 @@ class KotlinGradleModelBuilder : ModelBuilderService {
5763
return null
5864
}
5965

66+
private fun Class<*>.findGetterMethod(name: String): Method? {
67+
generateSequence(this) { it.superclass }.forEach {
68+
try {
69+
return it.getDeclaredMethod(name)
70+
}
71+
catch(e: Exception) {
72+
// Check next super class
73+
}
74+
}
75+
return null
76+
}
77+
6078
@Suppress("UNCHECKED_CAST")
61-
private fun getCompilerArguments(project: Project, methodName: String): List<String>? {
62-
val compileTask = compileTasks.mapNotNull { project.getTasksByName(it, false).firstOrNull() }.firstOrNull() ?: return null
79+
private fun collectCompilerArguments(
80+
compileTask: Task,
81+
methodName: String,
82+
argumentsBySourceSet: MutableMap<String, List<String>>
83+
) {
6384
val taskClass = compileTask.javaClass
64-
return try {
65-
taskClass.getDeclaredMethod(methodName).invoke(compileTask) as List<String>
85+
val sourceSetName = try {
86+
taskClass.findGetterMethod("getSourceSetName\$kotlin_gradle_plugin")?.invoke(compileTask) as? String
87+
} catch (e : InvocationTargetException) {
88+
null // can be thrown if property is not initialized yet
89+
} ?: "main"
90+
try {
91+
argumentsBySourceSet[sourceSetName] = taskClass.getDeclaredMethod(methodName).invoke(compileTask) as List<String>
6692
}
6793
catch (e : NoSuchMethodException) {
68-
null
94+
// No argument accessor method is available
6995
}
7096
}
7197

@@ -86,11 +112,22 @@ class KotlinGradleModelBuilder : ModelBuilderService {
86112
}
87113
}
88114

89-
override fun buildAll(modelName: String?, project: Project) =
90-
KotlinGradleModelImpl(
91-
getImplements(project),
92-
getCompilerArguments(project, "getSerializedCompilerArguments"),
93-
getCompilerArguments(project, "getDefaultSerializedCompilerArguments"),
94-
getCoroutines(project)
95-
)
115+
override fun buildAll(modelName: String?, project: Project): KotlinGradleModelImpl {
116+
val currentCompilerArgumentsBySourceSet = LinkedHashMap<String, List<String>>()
117+
val defaultCompilerArgumentsBySourceSet = LinkedHashMap<String, List<String>>()
118+
119+
project.getAllTasks(false)[project]?.forEach { compileTask ->
120+
if (compileTask.javaClass.name !in kotlinCompileTaskClasses) return@forEach
121+
122+
collectCompilerArguments(compileTask, "getSerializedCompilerArguments", currentCompilerArgumentsBySourceSet)
123+
collectCompilerArguments(compileTask, "getDefaultSerializedCompilerArguments", defaultCompilerArgumentsBySourceSet)
124+
}
125+
126+
return KotlinGradleModelImpl(
127+
getImplements(project),
128+
currentCompilerArgumentsBySourceSet,
129+
defaultCompilerArgumentsBySourceSet,
130+
getCoroutines(project)
131+
)
132+
}
96133
}

idea/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleProjectResolverExtension.kt

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
2525
import com.intellij.openapi.roots.DependencyScope
2626
import com.intellij.openapi.util.Key
2727
import org.gradle.tooling.model.idea.IdeaModule
28+
import org.jetbrains.kotlin.gradle.CompilerArgumentsBySourceSet
2829
import org.jetbrains.kotlin.gradle.KotlinGradleModel
2930
import org.jetbrains.kotlin.gradle.KotlinGradleModelBuilder
3031
import org.jetbrains.kotlin.psi.UserDataProperty
@@ -33,9 +34,12 @@ import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
3334
import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension
3435
import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverUtil.getModuleId
3536

36-
var DataNode<ModuleData>.currentCompilerArguments by UserDataProperty(Key.create<List<String>>("CURRENT_COMPILER_ARGUMENTS"))
37-
var DataNode<ModuleData>.defaultCompilerArguments by UserDataProperty(Key.create<List<String>>("DEFAULT_COMPILER_ARGUMENTS"))
38-
var DataNode<ModuleData>.coroutines by UserDataProperty(Key.create<String>("KOTLIN_COROUTINES"))
37+
var DataNode<ModuleData>.currentCompilerArgumentsBySourceSet
38+
by UserDataProperty(Key.create<CompilerArgumentsBySourceSet>("CURRENT_COMPILER_ARGUMENTS"))
39+
var DataNode<ModuleData>.defaultCompilerArgumentsBySourceSet
40+
by UserDataProperty(Key.create<CompilerArgumentsBySourceSet>("DEFAULT_COMPILER_ARGUMENTS"))
41+
var DataNode<ModuleData>.coroutines
42+
by UserDataProperty(Key.create<String>("KOTLIN_COROUTINES"))
3943

4044
class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension() {
4145
override fun getToolingExtensionsClasses(): Set<Class<out Any>> {
@@ -61,8 +65,8 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
6165
}
6266
}
6367

64-
ideModule.currentCompilerArguments = gradleModel.currentCompilerArguments
65-
ideModule.defaultCompilerArguments = gradleModel.defaultCompilerArguments
68+
ideModule.currentCompilerArgumentsBySourceSet = gradleModel.currentCompilerArgumentsBySourceSet
69+
ideModule.defaultCompilerArgumentsBySourceSet = gradleModel.defaultCompilerArgumentsBySourceSet
6670
ideModule.coroutines = gradleModel.coroutines
6771

6872
super.populateModuleDependencies(gradleModule, ideModule, ideProject)

idea/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class KotlinGradleSourceSetDataService : AbstractProjectDataService<GradleSource
6262
val ideModule = modelsProvider.findIdeModule(sourceSetData) ?: continue
6363

6464
val moduleNode = ExternalSystemApiUtil.findParent(sourceSetNode, ProjectKeys.MODULE) ?: continue
65-
val kotlinFacet = configureFacetByGradleModule(moduleNode, ideModule, modelsProvider) ?: continue
65+
val kotlinFacet = configureFacetByGradleModule(moduleNode, sourceSetNode, ideModule, modelsProvider) ?: continue
6666
GradleProjectImportHandler.getInstances(project).forEach { it.importBySourceSet(kotlinFacet, sourceSetNode) }
6767
}
6868
}
@@ -83,7 +83,7 @@ class KotlinGradleProjectDataService : AbstractProjectDataService<ModuleData, Vo
8383

8484
val moduleData = moduleNode.data
8585
val ideModule = modelsProvider.findIdeModule(moduleData) ?: continue
86-
val kotlinFacet = configureFacetByGradleModule(moduleNode, ideModule, modelsProvider) ?: continue
86+
val kotlinFacet = configureFacetByGradleModule(moduleNode, null, ideModule, modelsProvider) ?: continue
8787
GradleProjectImportHandler.getInstances(project).forEach { it.importByModule(kotlinFacet, moduleNode) }
8888
}
8989
}
@@ -108,6 +108,7 @@ private fun detectPlatformByLibrary(moduleNode: DataNode<ModuleData>): TargetPla
108108

109109
private fun configureFacetByGradleModule(
110110
moduleNode: DataNode<ModuleData>,
111+
sourceSetNode: DataNode<GradleSourceSetData>?,
111112
ideModule: Module,
112113
modelsProvider: IdeModifiableModelsProvider
113114
): KotlinFacet? {
@@ -121,8 +122,10 @@ private fun configureFacetByGradleModule(
121122
val kotlinFacet = ideModule.getOrCreateFacet(modelsProvider, false)
122123
kotlinFacet.configureFacet(compilerVersion, coroutinesProperty, platformKind, modelsProvider)
123124

124-
val currentCompilerArguments = moduleNode.currentCompilerArguments
125-
val defaultCompilerArguments = moduleNode.defaultCompilerArguments ?: emptyList()
125+
val sourceSetName = sourceSetNode?.data?.id?.let { it.substring(it.lastIndexOf(':') + 1) } ?: "main"
126+
127+
val currentCompilerArguments = moduleNode.currentCompilerArgumentsBySourceSet?.get(sourceSetName)
128+
val defaultCompilerArguments = moduleNode.defaultCompilerArgumentsBySourceSet?.get(sourceSetName) ?: emptyList()
126129
if (currentCompilerArguments != null) {
127130
parseCompilerArgumentsToFacet(currentCompilerArguments, defaultCompilerArguments, kotlinFacet)
128131
}

0 commit comments

Comments
 (0)