mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-05 01:50:56 +07:00
[KTIJ-25227] Use CompilerArgumentsAware to resolve CompilerArguments for KGP < 1.9
This commit will take care of removing the classpath of the Compile Task from the resolved CompilerArguments as this classpath is undesired and can take too much memory. JPS builds will restore the classpath from the IJ project model. Classpath entries added as freeCompilerArgs are still relevant. This commit also ensures that the jvmTarget is present in the List of argument Strings for older KGP plugins that omitted 1.6 targets as it was their default value. KTIJ-25227 GitOrigin-RevId: 721dee6ee0f490b7c06c5fd6af5e777cf5760466
This commit is contained in:
committed by
intellij-monorepo-bot
parent
72bde52b9b
commit
660b16d4ff
@@ -193,8 +193,8 @@ fun applyCompilerArgumentsToFacet(
|
||||
K2NativeCompilerArguments::shortModuleName.name,
|
||||
K2NativeCompilerArguments::noendorsedlibs.name,
|
||||
|
||||
K2JSCompilerArguments::main.name,
|
||||
K2JSCompilerArguments::metaInfo.name,
|
||||
K2JSCompilerArguments::outputFile.name,
|
||||
)
|
||||
|
||||
fun exposeAsAdditionalArgument(property: KProperty1<CommonCompilerArguments, Any?>) =
|
||||
|
||||
@@ -347,9 +347,6 @@ fun configureFacetWithCompilerArguments(
|
||||
compilerArguments: CommonCompilerArguments,
|
||||
) {
|
||||
applyCompilerArgumentsToFacet(compilerArguments, kotlinFacet, modelsProvider)
|
||||
if (compilerArguments is K2JVMCompilerArguments) run {
|
||||
adjustClasspath(kotlinFacet, compilerArguments.classpathArray?.toSet() ?: return@run)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAdditionalVisibleModuleNames(moduleNode: DataNode<ModuleData>, sourceSetName: String): Set<String> {
|
||||
@@ -364,12 +361,3 @@ private fun getAdditionalVisibleModuleNames(moduleNode: DataNode<ModuleData>, so
|
||||
}.map { it.id }
|
||||
.toSet()
|
||||
}
|
||||
|
||||
internal fun adjustClasspath(kotlinFacet: KotlinFacet, dependencyClasspath: Set<String>) {
|
||||
if (dependencyClasspath.isEmpty()) return
|
||||
val arguments = kotlinFacet.configuration.settings.compilerArguments as? K2JVMCompilerArguments ?: return
|
||||
val fullClasspath = arguments.classpathArray.orEmpty()
|
||||
if (fullClasspath.isEmpty()) return
|
||||
val newClasspath = fullClasspath.toSet() - dependencyClasspath.toSet()
|
||||
arguments.classpathArray = if (newClasspath.isNotEmpty()) newClasspath.toTypedArray() else null
|
||||
}
|
||||
|
||||
@@ -70,10 +70,7 @@ class GradleFacetImportTest8 : KotlinGradleImportingTestCase() {
|
||||
assertFalse(compilerArguments!!.autoAdvanceApiVersion)
|
||||
assertEquals(JvmPlatforms.jvm8, targetPlatform)
|
||||
assertEquals("1.7", (compilerArguments as K2JVMCompilerArguments).jvmTarget)
|
||||
assertEquals(
|
||||
"-Xallow-no-source-files -Xdump-declarations-to=tmp",
|
||||
compilerSettings!!.additionalArguments
|
||||
)
|
||||
assertEquals("-Xdump-declarations-to=tmp", compilerSettings!!.additionalArguments)
|
||||
}
|
||||
|
||||
with(testFacetSettings) {
|
||||
@@ -84,7 +81,7 @@ class GradleFacetImportTest8 : KotlinGradleImportingTestCase() {
|
||||
assertEquals(JvmPlatforms.jvm6, targetPlatform)
|
||||
assertEquals("1.6", (compilerArguments as K2JVMCompilerArguments).jvmTarget)
|
||||
assertEquals(
|
||||
"-Xallow-no-source-files -Xdump-declarations-to=tmpTest",
|
||||
"-Xdump-declarations-to=tmpTest",
|
||||
compilerSettings!!.additionalArguments
|
||||
)
|
||||
}
|
||||
@@ -130,10 +127,7 @@ class GradleFacetImportTest8 : KotlinGradleImportingTestCase() {
|
||||
assertEquals("1.3", apiLevel!!.versionString)
|
||||
assertEquals(JvmPlatforms.jvm8, targetPlatform)
|
||||
assertEquals("1.7", (compilerArguments as K2JVMCompilerArguments).jvmTarget)
|
||||
assertEquals(
|
||||
"-Xallow-no-source-files -Xdump-declarations-to=tmp",
|
||||
compilerSettings!!.additionalArguments
|
||||
)
|
||||
assertEquals("-Xdump-declarations-to=tmp", compilerSettings!!.additionalArguments)
|
||||
}
|
||||
|
||||
with(facetSettings("project.myTest")) {
|
||||
@@ -141,10 +135,7 @@ class GradleFacetImportTest8 : KotlinGradleImportingTestCase() {
|
||||
assertEquals("1.0", apiLevel!!.versionString)
|
||||
assertEquals(JvmPlatforms.jvm6, targetPlatform)
|
||||
assertEquals("1.6", (compilerArguments as K2JVMCompilerArguments).jvmTarget)
|
||||
assertEquals(
|
||||
"-Xallow-no-source-files -Xdump-declarations-to=tmpTest",
|
||||
compilerSettings!!.additionalArguments
|
||||
)
|
||||
assertEquals("-Xdump-declarations-to=tmpTest", compilerSettings!!.additionalArguments)
|
||||
}
|
||||
|
||||
assertAllModulesConfigured()
|
||||
@@ -522,7 +513,7 @@ class GradleFacetImportTest8 : KotlinGradleImportingTestCase() {
|
||||
|
||||
with(facetSettings) {
|
||||
assertEquals(
|
||||
listOf("-Xallow-no-source-files", "-Xbuild-file=module with spaces"),
|
||||
listOf("-Xbuild-file=module with spaces"),
|
||||
compilerSettings!!.additionalArgumentsAsList
|
||||
)
|
||||
}
|
||||
@@ -639,9 +630,9 @@ class GradleFacetImportTest8 : KotlinGradleImportingTestCase() {
|
||||
fun testJDKImport() {
|
||||
val mockJdkPath = FileUtil.toSystemDependentName("${PathManager.getHomePath()}/community/java/mockJDK-1.8")
|
||||
runWriteActionAndWait {
|
||||
val jdk = JavaSdk.getInstance().createJdk("myJDK", mockJdkPath)
|
||||
runReadAction<ProjectJdkTable> { ProjectJdkTable.getInstance() }.addJdk(jdk)
|
||||
ProjectRootManager.getInstance(myProject).projectSdk = jdk
|
||||
val jdk = JavaSdk.getInstance().createJdk("myJDK", mockJdkPath)
|
||||
runReadAction<ProjectJdkTable> { ProjectJdkTable.getInstance() }.addJdk(jdk)
|
||||
ProjectRootManager.getInstance(myProject).projectSdk = jdk
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -654,9 +645,9 @@ class GradleFacetImportTest8 : KotlinGradleImportingTestCase() {
|
||||
assertEquals(mockJdkPath, moduleSDK.homePath?.let(FileUtil::toSystemDependentName))
|
||||
} finally {
|
||||
runWriteActionAndWait {
|
||||
val jdkTable = runReadAction<ProjectJdkTable> { ProjectJdkTable.getInstance() }
|
||||
jdkTable.removeJdk(jdkTable.findJdk("myJDK")!!)
|
||||
ProjectRootManager.getInstance(myProject).projectSdk = null
|
||||
val jdkTable = runReadAction<ProjectJdkTable> { ProjectJdkTable.getInstance() }
|
||||
jdkTable.removeJdk(jdkTable.findJdk("myJDK")!!)
|
||||
ProjectRootManager.getInstance(myProject).projectSdk = null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -775,7 +766,7 @@ class GradleFacetImportTest8 : KotlinGradleImportingTestCase() {
|
||||
assertEquals(LanguageVersion.KOTLIN_1_3, facetSettings.languageLevel)
|
||||
|
||||
// We haven't lost internal argument during importing to facet
|
||||
assertEquals("-Xallow-no-source-files -XXLanguage:+InlineClasses", facetSettings.compilerSettings?.additionalArguments)
|
||||
assertEquals("-XXLanguage:+InlineClasses", facetSettings.compilerSettings?.additionalArguments)
|
||||
|
||||
// Inline classes are enabled even though LV = 1.3
|
||||
assertEquals(
|
||||
@@ -814,11 +805,7 @@ class GradleFacetImportTest8 : KotlinGradleImportingTestCase() {
|
||||
configureByFiles()
|
||||
importProject()
|
||||
|
||||
assertEquals(
|
||||
"-Xallow-no-source-files",
|
||||
testFacetSettings.compilerSettings!!.additionalArguments
|
||||
)
|
||||
|
||||
assertEquals("", testFacetSettings.compilerSettings!!.additionalArguments)
|
||||
assertAllModulesConfigured()
|
||||
}
|
||||
|
||||
|
||||
@@ -9,18 +9,18 @@ fun KotlinCompileTaskReflection(task: Task): KotlinCompileTaskReflection {
|
||||
|
||||
interface KotlinCompileTaskReflection {
|
||||
val task: Task
|
||||
val legacyCompilerArguments: List<String>
|
||||
val serializedCompilerArguments: List<String>
|
||||
}
|
||||
|
||||
private class KotlinCompileTaskReflectionImpl(override val task: Task) : KotlinCompileTaskReflection {
|
||||
override val legacyCompilerArguments: List<String>
|
||||
override val serializedCompilerArguments: List<String>
|
||||
get() = runCatching {
|
||||
task.callReflectiveGetter<List<String>>("getSerializedCompilerArguments", logger)
|
||||
}.recoverCatching {
|
||||
logger.logIssue("Failed calling 'getSerializedCompilerArguments'", it)
|
||||
task.callReflectiveGetter<List<String>>("getSerializedCompilerArgumentsIgnoreClasspathIssues", logger)
|
||||
}.onFailure {
|
||||
logger.logIssue("Failed getting 'legacyCompilerArguments' from '${task.path}'")
|
||||
logger.logIssue("Failed getting 'serializedCompilerArguments' from '${task.path}'")
|
||||
}.getOrNull().orEmpty()
|
||||
|
||||
|
||||
|
||||
@@ -4,13 +4,135 @@ package org.jetbrains.kotlin.idea.gradleTooling
|
||||
import org.gradle.api.Task
|
||||
import org.jetbrains.kotlin.idea.gradleTooling.reflect.KotlinCompileTaskReflection
|
||||
import org.jetbrains.kotlin.idea.gradleTooling.reflect.KotlinCompilerArgumentsResolverReflection
|
||||
import org.jetbrains.kotlin.idea.gradleTooling.reflect.ReflectionLogger
|
||||
import java.lang.reflect.Method
|
||||
|
||||
internal fun resolveCompilerArguments(compileTask: Task): List<String>? {
|
||||
/* Preferred approach in Kotlin 1.9+ */
|
||||
KotlinCompilerArgumentsResolverReflection(compileTask.project, compileTask::class.java.classLoader)?.let { resolver ->
|
||||
return resolver.resolveCompilerArguments(compileTask)
|
||||
/* Service bundled inside Kotlin Gradle Plugin */
|
||||
val compilerArgumentsResolver = KotlinCompilerArgumentsResolverReflection(compileTask.project, compileTask::class.java.classLoader)
|
||||
|
||||
return when {
|
||||
/*
|
||||
Preferred approach in Kotlin 1.9+:
|
||||
Using a service inside KGP that is capable of resolving the arguments properly
|
||||
*/
|
||||
compilerArgumentsResolver != null -> compilerArgumentsResolver.resolveCompilerArguments(compileTask)
|
||||
|
||||
/*
|
||||
Fallback for Kotlin Gradle Plugins < 1.9:
|
||||
Using the 'CompilerArgumentsAware' infrastructure in KGP, calling into it via reflection and
|
||||
fixing up known issues in KGP reflectively.
|
||||
|
||||
Native Compile Tasks however do only support requesting the arguments in serialised format.
|
||||
Other compile tasks will allow the createCompilerArgs + setupCompilerArgs approach
|
||||
*/
|
||||
compileTask.isKotlinNativeCompileTask -> resolveCompilerArgumentsForKGPLower19ForNativeCompileTask(compileTask)
|
||||
else -> resolveCompilerArgumentsForKGPLower19(compileTask)
|
||||
}
|
||||
}
|
||||
|
||||
fun resolveCompilerArgumentsForKGPLower19ForNativeCompileTask(compileTask: Task): List<String> {
|
||||
/*
|
||||
Resolve arguments using 'serializedCompilerArguments' as native tasks do not support createCompilerArgs&setupCompilerArgs methods
|
||||
*/
|
||||
return KotlinCompileTaskReflection(compileTask).serializedCompilerArguments
|
||||
}
|
||||
|
||||
|
||||
fun resolveCompilerArgumentsForKGPLower19(compileTask: Task): List<String>? {
|
||||
val logger = ReflectionLogger(compileTask.javaClass)
|
||||
|
||||
/*
|
||||
Create compiler arguments by using the CompilerArgumentsAware methods
|
||||
(createCompilerArgs followed by setupCompilerArgs)
|
||||
*/
|
||||
val compileTaskClass = compileTask.javaClass
|
||||
val compilerArguments = compileTask["createCompilerArgs"] ?: run {
|
||||
logger.logIssue("Failed creating compiler arguments from ${compileTask.path}")
|
||||
return null
|
||||
}
|
||||
|
||||
/* Less preferred approach w/o IdeCompilerArgumentsResolver on KGP */
|
||||
return KotlinCompileTaskReflection(compileTask).legacyCompilerArguments
|
||||
val setupCompilerArgsMethod = compileTaskClass.getMethodOrNull(
|
||||
"setupCompilerArgs", compilerArguments::class.java, Boolean::class.java, Boolean::class.java
|
||||
) ?: run {
|
||||
logger.logIssue("No 'setupCompilerArgs' method found on '${compileTask.path}'")
|
||||
return null
|
||||
}
|
||||
setupCompilerArgsMethod.doSetupCompilerArgs(compileTask, compilerArguments)
|
||||
|
||||
/*
|
||||
Previous Kotlin Gradle Plugin versions (<1.9) are resolving the classpath of the compile task, adding it
|
||||
directly to the arguments .classpath property. This classpath is undesired as it potentially takes too much memory.
|
||||
JPS builds will be able to infer the classpath from the IJ project model.
|
||||
|
||||
We therefore will remove the classpath manually from the received compiler arguments and then convert the arguments
|
||||
to their List<String> representation.
|
||||
*/
|
||||
val compilerArgumentsClass = compilerArguments.javaClass
|
||||
compilerArgumentsClass.getMethodOrNull("setClasspath", String::class.java)?.invoke(compilerArguments, null)
|
||||
|
||||
|
||||
/*
|
||||
Use the 'ArgumentUtils' list bundled within the Kotlin Gradle Plugin to convert
|
||||
the arguments to List<String>
|
||||
*/
|
||||
return runCatching {
|
||||
val commonToolArgumentsClass = compileTaskClass.classLoader.loadClass(
|
||||
"org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments"
|
||||
)
|
||||
|
||||
val argumentUtilsClass = compileTaskClass.classLoader.loadClass(
|
||||
"org.jetbrains.kotlin.compilerRunner.ArgumentUtils"
|
||||
)
|
||||
|
||||
val toStringListFunction = argumentUtilsClass.getMethodOrNull("convertArgumentsToStringList", commonToolArgumentsClass) ?: run {
|
||||
logger.logIssue("Missing 'convertArgumentsToStringList' function")
|
||||
return null
|
||||
}
|
||||
|
||||
/*
|
||||
Kotlin Gradle Plugin versions before:
|
||||
```
|
||||
Switch `-jvm-target` default to null Mikhael Bogdanov* 14.11.21, 14:23
|
||||
f5da166d7c5efe34541bee0cf207f6b394aca5e5
|
||||
```
|
||||
|
||||
Did set a default jvmTarget value, basically omitting the argument on String conversion (since it's the default value)
|
||||
This however is undesirable, since there are Kotlin Gradle Plugins build with jvmTarget=1.6 as default.
|
||||
When omitting the String argument, then the IDE will fill the absent argument with its default (which might be 1.8 or higher)
|
||||
|
||||
Therefore, we detect this Situation and support older Kotlin Gradle Plugins by explicitly adding this argument again.
|
||||
*/
|
||||
val additionalExplicitArguments: List<String> = runCatching resolveExplicitArguments@{
|
||||
val emptyArgumentsInstance = compilerArgumentsClass.getConstructor().newInstance()
|
||||
val getJvmTargetMethod = compilerArgumentsClass.getMethodOrNull("getJvmTarget") ?: return@resolveExplicitArguments emptyList()
|
||||
val jvmTarget = getJvmTargetMethod.invoke(compilerArguments)
|
||||
val jvmTargetDefault = getJvmTargetMethod.invoke(emptyArgumentsInstance)
|
||||
|
||||
if (jvmTargetDefault != null && jvmTargetDefault == jvmTarget) {
|
||||
listOf("-jvm-target", jvmTarget.toString())
|
||||
} else emptyList()
|
||||
|
||||
}.getOrNull().orEmpty()
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val argumentsAsStrings = (toStringListFunction.invoke(null, compilerArguments) as? List<String>) ?: return null
|
||||
additionalExplicitArguments + argumentsAsStrings
|
||||
}
|
||||
.onFailure { failure -> logger.logIssue("Failed converting $compilerArguments", failure) }
|
||||
.getOrNull()
|
||||
}
|
||||
|
||||
|
||||
private fun Method.doSetupCompilerArgs(compileTask: Task, compilerArgs: Any) {
|
||||
runCatching {
|
||||
invoke(compileTask, compilerArgs, /*defaults only */ false, /* ignore classpath issues */ false)
|
||||
}.recoverCatching {
|
||||
invoke(compileTask, compilerArgs, /* defaults only */ false, /* ignore classpath issues */ true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private const val KOTLIN_NATIVE_COMPILE_CLASS = "org.jetbrains.kotlin.gradle.tasks.AbstractKotlinNativeCompile"
|
||||
private val Task.isKotlinNativeCompileTask: Boolean
|
||||
get() = javaClass.classLoader.loadClassOrNull(KOTLIN_NATIVE_COMPILE_CLASS)?.isAssignableFrom(javaClass) ?: false
|
||||
@@ -53,12 +53,12 @@ project.iosX64Test
|
||||
project.jsMain
|
||||
languageLevel = 1.7
|
||||
apiLevel = 1.7
|
||||
compilerSettings = -opt-in OptInAnnotation
|
||||
compilerSettings = -main call -opt-in OptInAnnotation
|
||||
|
||||
project.jsTest
|
||||
languageLevel = 1.7
|
||||
apiLevel = 1.7
|
||||
compilerSettings = -opt-in OptInAnnotation
|
||||
compilerSettings = -main call -opt-in OptInAnnotation
|
||||
|
||||
project.jvmAndroidMain
|
||||
languageLevel = {{LATEST_STABLE}}
|
||||
|
||||
@@ -53,12 +53,12 @@ project.iosX64Test
|
||||
project.jsMain
|
||||
languageLevel = 1.7
|
||||
apiLevel = 1.7
|
||||
compilerSettings = -opt-in OptInAnnotation
|
||||
compilerSettings = -main call -opt-in OptInAnnotation
|
||||
|
||||
project.jsTest
|
||||
languageLevel = 1.7
|
||||
apiLevel = 1.7
|
||||
compilerSettings = -opt-in OptInAnnotation
|
||||
compilerSettings = -main call -opt-in OptInAnnotation
|
||||
|
||||
project.jvmAndroidMain
|
||||
languageLevel = {{LATEST_STABLE}}
|
||||
|
||||
@@ -53,12 +53,12 @@ project.iosX64Test
|
||||
project.jsMain
|
||||
languageLevel = 1.7
|
||||
apiLevel = 1.7
|
||||
compilerSettings = -opt-in OptInAnnotation
|
||||
compilerSettings = -main call -opt-in OptInAnnotation
|
||||
|
||||
project.jsTest
|
||||
languageLevel = 1.7
|
||||
apiLevel = 1.7
|
||||
compilerSettings = -opt-in OptInAnnotation
|
||||
compilerSettings = -main call -opt-in OptInAnnotation
|
||||
|
||||
project.jvmAndroidMain
|
||||
languageLevel = {{LATEST_STABLE}}
|
||||
|
||||
@@ -53,12 +53,12 @@ project.iosX64Test
|
||||
project.jsMain
|
||||
languageLevel = 1.7
|
||||
apiLevel = 1.7
|
||||
compilerSettings = -opt-in OptInAnnotation
|
||||
compilerSettings = -main call -opt-in OptInAnnotation
|
||||
|
||||
project.jsTest
|
||||
languageLevel = 1.7
|
||||
apiLevel = 1.7
|
||||
compilerSettings = -opt-in OptInAnnotation
|
||||
compilerSettings = -main call -opt-in OptInAnnotation
|
||||
|
||||
project.jvmAndroidMain
|
||||
languageLevel = {{LATEST_STABLE}}
|
||||
|
||||
@@ -59,12 +59,12 @@ project.iosX64Test
|
||||
project.jsMain
|
||||
languageLevel = 1.7
|
||||
apiLevel = 1.7
|
||||
compilerSettings = -opt-in OptInAnnotation -progressive
|
||||
compilerSettings = -main call -opt-in OptInAnnotation -progressive
|
||||
|
||||
project.jsTest
|
||||
languageLevel = 1.7
|
||||
apiLevel = 1.7
|
||||
compilerSettings = -opt-in OptInAnnotation -progressive
|
||||
compilerSettings = -main call -opt-in OptInAnnotation -progressive
|
||||
|
||||
project.jvmAndroidMain
|
||||
languageLevel = 1.7
|
||||
|
||||
@@ -59,12 +59,12 @@ project.iosX64Test
|
||||
project.jsMain
|
||||
languageLevel = 1.7
|
||||
apiLevel = 1.7
|
||||
compilerSettings = -opt-in LangSettingsOptInAnnotation,CompilationOptInAnnotation -progressive
|
||||
compilerSettings = -main call -opt-in LangSettingsOptInAnnotation,CompilationOptInAnnotation -progressive
|
||||
|
||||
project.jsTest
|
||||
languageLevel = 1.7
|
||||
apiLevel = 1.7
|
||||
compilerSettings = -opt-in LangSettingsOptInAnnotation,CompilationOptInAnnotation -progressive
|
||||
compilerSettings = -main call -opt-in LangSettingsOptInAnnotation,CompilationOptInAnnotation -progressive
|
||||
|
||||
project.jvmAndroidMain
|
||||
languageLevel = 1.8
|
||||
|
||||
@@ -53,12 +53,12 @@ project.iosX64Test
|
||||
project.jsMain
|
||||
languageLevel = 1.7
|
||||
apiLevel = 1.7
|
||||
compilerSettings = -opt-in CompilationOptInAnnotation
|
||||
compilerSettings = -main call -opt-in CompilationOptInAnnotation
|
||||
|
||||
project.jsTest
|
||||
languageLevel = 1.7
|
||||
apiLevel = 1.7
|
||||
compilerSettings = -opt-in CompilationOptInAnnotation
|
||||
compilerSettings = -main call -opt-in CompilationOptInAnnotation
|
||||
|
||||
project.jvmAndroidMain
|
||||
languageLevel = {{LATEST_STABLE}}
|
||||
|
||||
@@ -46,10 +46,12 @@ project.iosX64Test
|
||||
project.jsMain
|
||||
languageLevel = {{LATEST_STABLE}}
|
||||
apiLevel = {{LATEST_STABLE}}
|
||||
compilerSettings = -main call
|
||||
|
||||
project.jsTest
|
||||
languageLevel = {{LATEST_STABLE}}
|
||||
apiLevel = {{LATEST_STABLE}}
|
||||
compilerSettings = -main call
|
||||
|
||||
project.jvmMain
|
||||
languageLevel = 1.7
|
||||
|
||||
Reference in New Issue
Block a user