diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2LocalInspectionTestGenerated.java b/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2LocalInspectionTestGenerated.java index 73ddc7dab2ad..e059761b7d7d 100644 --- a/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2LocalInspectionTestGenerated.java +++ b/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2LocalInspectionTestGenerated.java @@ -8324,6 +8324,11 @@ public abstract class K2LocalInspectionTestGenerated extends AbstractK2LocalInsp runTest("testData/inspectionsLocal/kotlinOptionsToCompilerOptions/allprojects.gradle.kts"); } + @TestMetadata("assignmentOperation2params.gradle.kts") + public void testAssignmentOperation2params_gradle() throws Exception { + runTest("testData/inspectionsLocal/kotlinOptionsToCompilerOptions/assignmentOperation2params.gradle.kts"); + } + @TestMetadata("assignmentOperation.gradle.kts") public void testAssignmentOperation_gradle() throws Exception { runTest("testData/inspectionsLocal/kotlinOptionsToCompilerOptions/assignmentOperation.gradle.kts"); @@ -8359,6 +8364,36 @@ public abstract class K2LocalInspectionTestGenerated extends AbstractK2LocalInsp runTest("testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsAddAllFromList.gradle.kts"); } + @TestMetadata("freeCompilerArgsMinusFreeCompilerArgs.gradle.kts") + public void testFreeCompilerArgsMinusFreeCompilerArgs_gradle() throws Exception { + runTest("testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMinusFreeCompilerArgs.gradle.kts"); + } + + @TestMetadata("freeCompilerArgsMultipleAddition1.gradle.kts") + public void testFreeCompilerArgsMultipleAddition1_gradle() throws Exception { + runTest("testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition1.gradle.kts"); + } + + @TestMetadata("freeCompilerArgsMultipleAddition2.gradle.kts") + public void testFreeCompilerArgsMultipleAddition2_gradle() throws Exception { + runTest("testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition2.gradle.kts"); + } + + @TestMetadata("freeCompilerArgsMultipleAddition3.gradle.kts") + public void testFreeCompilerArgsMultipleAddition3_gradle() throws Exception { + runTest("testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition3.gradle.kts"); + } + + @TestMetadata("freeCompilerArgsMultipleAddition4.gradle.kts") + public void testFreeCompilerArgsMultipleAddition4_gradle() throws Exception { + runTest("testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition4.gradle.kts"); + } + + @TestMetadata("freeCompilerArgsMultipleAddition5.gradle.kts") + public void testFreeCompilerArgsMultipleAddition5_gradle() throws Exception { + runTest("testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition5.gradle.kts"); + } + @TestMetadata("freeCompilerArgsPlusFreeCompilerArgs.gradle.kts") public void testFreeCompilerArgsPlusFreeCompilerArgs_gradle() throws Exception { runTest("testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsPlusFreeCompilerArgs.gradle.kts"); diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/assignmentOperation2params.gradle.kts b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/assignmentOperation2params.gradle.kts new file mode 100644 index 000000000000..3d8470338428 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/assignmentOperation2params.gradle.kts @@ -0,0 +1,27 @@ +// PROBLEM: Use of deprecated 'kotlinOptions' DSL +// FIX: Replace 'kotlinOptions' with 'compilerOptions' +plugins { + kotlin("jvm") version "2.0.0" +} + +group = "org.example" +version = "1.0-SNAPSHOT" + +repositories { + mavenCentral() +} + +dependencies { + testImplementation(kotlin("test")) +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(8) +} + +tasks.named("compileKotlin", org.jetbrains.kotlin.gradle.tasks.KotlinCompile::class.java) { + kotlinOptions.freeCompilerArgs += "-Xexport-kdoc" + "-Xopt-in=kotlin.RequiresOptIn" +} diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/assignmentOperation2params.gradle.kts.after b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/assignmentOperation2params.gradle.kts.after new file mode 100644 index 000000000000..db6a249b3880 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/assignmentOperation2params.gradle.kts.after @@ -0,0 +1,27 @@ +// PROBLEM: Use of deprecated 'kotlinOptions' DSL +// FIX: Replace 'kotlinOptions' with 'compilerOptions' +plugins { + kotlin("jvm") version "2.0.0" +} + +group = "org.example" +version = "1.0-SNAPSHOT" + +repositories { + mavenCentral() +} + +dependencies { + testImplementation(kotlin("test")) +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(8) +} + +tasks.named("compileKotlin", org.jetbrains.kotlin.gradle.tasks.KotlinCompile::class.java) { + compilerOptions.freeCompilerArgs.addAll("-Xexport-kdoc", "-Xopt-in=kotlin.RequiresOptIn") +} diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMinusFreeCompilerArgs.gradle.kts b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMinusFreeCompilerArgs.gradle.kts new file mode 100644 index 000000000000..162f51af3899 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMinusFreeCompilerArgs.gradle.kts @@ -0,0 +1,23 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version "2.0.0" +} + +repositories { + mavenCentral() +} + +subprojects { + apply(plugin = "org.jetbrains.kotlin.jvm") + + dependencies { + implementation(kotlin("stdlib-jdk8")) + } + + tasks.withType().all { + kotlinOptions { + freeCompilerArgs = freeCompilerArgs - "-Xopt-in=kotlin.RequiresOptIn" + } + } +} diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMinusFreeCompilerArgs.gradle.kts.after b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMinusFreeCompilerArgs.gradle.kts.after new file mode 100644 index 000000000000..a050fe93fa3a --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMinusFreeCompilerArgs.gradle.kts.after @@ -0,0 +1,23 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version "2.0.0" +} + +repositories { + mavenCentral() +} + +subprojects { + apply(plugin = "org.jetbrains.kotlin.jvm") + + dependencies { + implementation(kotlin("stdlib-jdk8")) + } + + tasks.withType().all { + compilerOptions { + freeCompilerArgs = freeCompilerArgs - "-Xopt-in=kotlin.RequiresOptIn" + } + } +} diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition1.gradle.kts b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition1.gradle.kts new file mode 100644 index 000000000000..c585bdc9515a --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition1.gradle.kts @@ -0,0 +1,24 @@ +// FIX: Replace 'kotlinOptions' with 'compilerOptions' +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version "2.0.0" +} + +repositories { + mavenCentral() +} + +subprojects { + apply(plugin = "org.jetbrains.kotlin.jvm") + + dependencies { + implementation(kotlin("stdlib-jdk8")) + } + + tasks.withType().all { + kotlinOptions { + freeCompilerArgs = freeCompilerArgs + "-Xopt-in=kotlin.RequiresOptIn" + "-Xjvm-default=all" + } + } +} diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition1.gradle.kts.after b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition1.gradle.kts.after new file mode 100644 index 000000000000..14747a51b75b --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition1.gradle.kts.after @@ -0,0 +1,24 @@ +// FIX: Replace 'kotlinOptions' with 'compilerOptions' +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version "2.0.0" +} + +repositories { + mavenCentral() +} + +subprojects { + apply(plugin = "org.jetbrains.kotlin.jvm") + + dependencies { + implementation(kotlin("stdlib-jdk8")) + } + + tasks.withType().all { + compilerOptions { + freeCompilerArgs.addAll("-Xopt-in=kotlin.RequiresOptIn", "-Xjvm-default=all") + } + } +} diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition2.gradle.kts b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition2.gradle.kts new file mode 100644 index 000000000000..8f26a150a956 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition2.gradle.kts @@ -0,0 +1,24 @@ +// FIX: Replace 'kotlinOptions' with 'compilerOptions' +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version "2.0.0" +} + +repositories { + mavenCentral() +} + +subprojects { + apply(plugin = "org.jetbrains.kotlin.jvm") + + dependencies { + implementation(kotlin("stdlib-jdk8")) + } + + tasks.withType().all { + kotlinOptions { + freeCompilerArgs = project.benchmark.compilerOpts + project.compilerArgs + } + } +} diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition2.gradle.kts.after b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition2.gradle.kts.after new file mode 100644 index 000000000000..130091b54994 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition2.gradle.kts.after @@ -0,0 +1,24 @@ +// FIX: Replace 'kotlinOptions' with 'compilerOptions' +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version "2.0.0" +} + +repositories { + mavenCentral() +} + +subprojects { + apply(plugin = "org.jetbrains.kotlin.jvm") + + dependencies { + implementation(kotlin("stdlib-jdk8")) + } + + tasks.withType().all { + compilerOptions { + freeCompilerArgs.addAll(project.benchmark.compilerOpts, project.compilerArgs) + } + } +} diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition3.gradle.kts b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition3.gradle.kts new file mode 100644 index 000000000000..2c2468a25467 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition3.gradle.kts @@ -0,0 +1,28 @@ +// FIX: Replace 'kotlinOptions' with 'compilerOptions' +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version "2.0.0" +} + +repositories { + mavenCentral() +} + +subprojects { + apply(plugin = "org.jetbrains.kotlin.jvm") + + dependencies { + implementation(kotlin("stdlib-jdk8")) + } + + tasks.withType().all { + kotlinOptions { + freeCompilerArgs = freeCompilerArgs + + "-opt-in=androidx.compose.foundation.ExperimentalFoundationApi" + + "-opt-in=androidx.compose.animation.ExperimentalAnimationApi" + + "-opt-in=androidx.compose.material3.ExperimentalMaterial3Api" + + "-opt-in=com.google.accompanist.permissions.ExperimentalPermissionsApi" + } + } +} diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition3.gradle.kts.after b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition3.gradle.kts.after new file mode 100644 index 000000000000..451397af1115 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition3.gradle.kts.after @@ -0,0 +1,29 @@ +// FIX: Replace 'kotlinOptions' with 'compilerOptions' +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version "2.0.0" +} + +repositories { + mavenCentral() +} + +subprojects { + apply(plugin = "org.jetbrains.kotlin.jvm") + + dependencies { + implementation(kotlin("stdlib-jdk8")) + } + + tasks.withType().all { + compilerOptions { + freeCompilerArgs.addAll( + "-opt-in=androidx.compose.foundation.ExperimentalFoundationApi", + "-opt-in=androidx.compose.animation.ExperimentalAnimationApi", + "-opt-in=androidx.compose.material3.ExperimentalMaterial3Api", + "-opt-in=com.google.accompanist.permissions.ExperimentalPermissionsApi" + ) + } + } +} diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition4.gradle.kts b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition4.gradle.kts new file mode 100644 index 000000000000..1e14a7455595 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition4.gradle.kts @@ -0,0 +1,24 @@ +// FIX: Replace 'kotlinOptions' with 'compilerOptions' +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version "2.0.0" +} + +repositories { + mavenCentral() +} + +subprojects { + apply(plugin = "org.jetbrains.kotlin.jvm") + + dependencies { + implementation(kotlin("stdlib-jdk8")) + } + + tasks.withType().all { + kotlinOptions { + freeCompilerArgs += allLibraries.map { listOf("-include-binary", it) }.flatten() + linkerFlags + } + } +} diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition4.gradle.kts.after b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition4.gradle.kts.after new file mode 100644 index 000000000000..c5a899972bb8 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition4.gradle.kts.after @@ -0,0 +1,24 @@ +// FIX: Replace 'kotlinOptions' with 'compilerOptions' +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version "2.0.0" +} + +repositories { + mavenCentral() +} + +subprojects { + apply(plugin = "org.jetbrains.kotlin.jvm") + + dependencies { + implementation(kotlin("stdlib-jdk8")) + } + + tasks.withType().all { + compilerOptions { + freeCompilerArgs.addAll(allLibraries.map { listOf("-include-binary", it) }.flatten(), linkerFlags) + } + } +} diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition5.gradle.kts b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition5.gradle.kts new file mode 100644 index 000000000000..b6974c76208e --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition5.gradle.kts @@ -0,0 +1,34 @@ +// FIX: Replace 'kotlinOptions' with 'compilerOptions' +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version "2.0.0" +} + +repositories { + mavenCentral() +} + +subprojects { + apply(plugin = "org.jetbrains.kotlin.jvm") + + dependencies { + implementation(kotlin("stdlib-jdk8")) + } + + tasks.withType().all { + kotlinOptions { + freeCompilerArgs = freeCompilerArgs + listOf( + "-Xopt-in=kotlin.RequiresOptIn", + "-Xopt-in=kotlin.ExperimentalStdlibApi", + "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-Xopt-in=kotlinx.coroutines.FlowPreview", + "-Xopt-in=kotlin.time.ExperimentalTime", + "-Xopt-in=kotlin.RequiresOptIn", + "-Xjvm-default=all", + "-XXLanguage:+DataObjects", + "-Xcontext-receivers" + ) + } + } +} diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition5.gradle.kts.after b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition5.gradle.kts.after new file mode 100644 index 000000000000..4209c481c3b8 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsMultipleAddition5.gradle.kts.after @@ -0,0 +1,36 @@ +// FIX: Replace 'kotlinOptions' with 'compilerOptions' +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version "2.0.0" +} + +repositories { + mavenCentral() +} + +subprojects { + apply(plugin = "org.jetbrains.kotlin.jvm") + + dependencies { + implementation(kotlin("stdlib-jdk8")) + } + + tasks.withType().all { + compilerOptions { + freeCompilerArgs.addAll( + listOf( + "-Xopt-in=kotlin.RequiresOptIn", + "-Xopt-in=kotlin.ExperimentalStdlibApi", + "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-Xopt-in=kotlinx.coroutines.FlowPreview", + "-Xopt-in=kotlin.time.ExperimentalTime", + "-Xopt-in=kotlin.RequiresOptIn", + "-Xjvm-default=all", + "-XXLanguage:+DataObjects", + "-Xcontext-receivers" + ) + ) + } + } +} diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsPlusFreeCompilerArgs.gradle.kts.after b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsPlusFreeCompilerArgs.gradle.kts.after index c86cf9475fd3..05dc53b702ff 100644 --- a/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsPlusFreeCompilerArgs.gradle.kts.after +++ b/plugins/kotlin/code-insight/inspections-k2/tests/testData/inspectionsLocal/kotlinOptionsToCompilerOptions/freeCompilerArgsPlusFreeCompilerArgs.gradle.kts.after @@ -25,6 +25,6 @@ kotlin { tasks.withType> { compilerOptions { - freeCompilerArgs = freeCompilerArgs + "-Xopt-in=kotlin.RequiresOptIn" + freeCompilerArgs.addAll("-Xopt-in=kotlin.RequiresOptIn") } } diff --git a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/configuration/utils/KotlinOptionsToCompilerOptionsMigrator.kt b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/configuration/utils/KotlinOptionsToCompilerOptionsMigrator.kt index f2f5e54367d3..62c5c313f58d 100644 --- a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/configuration/utils/KotlinOptionsToCompilerOptionsMigrator.kt +++ b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/configuration/utils/KotlinOptionsToCompilerOptionsMigrator.kt @@ -1,6 +1,7 @@ // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.gradleJava.configuration.utils +import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.PsiFile import org.jetbrains.annotations.ApiStatus import org.jetbrains.kotlin.idea.base.util.module @@ -14,6 +15,7 @@ import org.jetbrains.kotlin.psi.KtReferenceExpression import org.jetbrains.kotlin.resolve.calls.util.getCalleeExpressionIfAny import org.jetbrains.kotlin.tooling.core.KotlinToolingVersion import java.util.function.Function +import kotlin.String data class CompilerOption(val expression: String, val classToImport: FqName? = null, val compilerOptionValue: String? = null) @@ -29,44 +31,29 @@ fun expressionContainsOperationForbiddenToReplace(binaryExpression: KtBinaryExpr fun getReplacementForOldKotlinOptionIfNeeded(binaryExpression: KtBinaryExpression): Replacement? { val rightPartOfBinaryExpression = binaryExpression.right ?: return null - val textOfRightPartOfBinaryExpression = rightPartOfBinaryExpression.text val leftPartOfBinaryExpression = binaryExpression.left ?: return null val textOfLeftPartOfBinaryExpression = leftPartOfBinaryExpression.text - // We don't touch strings like `freeCompilerArgs = freeCompilerArgs + "-Xopt-in=kotlin.RequiresOptIn"` - if (rightPartOfBinaryExpression is KtBinaryExpression) { - return getReplacementOnlyOfKotlinOptionsIfNeeded(binaryExpression, textOfLeftPartOfBinaryExpression) + val (optionName, replacementOfKotlinOptionsIfNeeded) = getOptionName(leftPartOfBinaryExpression) + ?: return null + + if (rightPartOfBinaryExpression is KtBinaryExpression && !optionName.contains("freeCompilerArgs")) { + return getReplacementOnlyOfKotlinOptionsIfNeeded(rightPartOfBinaryExpression, textOfLeftPartOfBinaryExpression) } - val replacement = StringBuilder() - val optionName = when (leftPartOfBinaryExpression) { - is KtDotQualifiedExpression -> { - val partBeforeDot = leftPartOfBinaryExpression.receiverExpression.text - - if (!partBeforeDot.contains("kotlinOptions")) { - if (partBeforeDot != "options") { - return null - } - } else { - replacement.append("compilerOptions.") - } - leftPartOfBinaryExpression.getCalleeExpressionIfAny()?.text ?: return null - } - - is KtReferenceExpression -> { - textOfLeftPartOfBinaryExpression - } - - else -> { - return null - } - } + val (optionValue, valueContainsMultipleValues) = getOptionValue(rightPartOfBinaryExpression, optionName) ?: return null val operationReference = binaryExpression.operationReference.text val expressionForCompilerOption = - getReplacementForOldKotlinOptionIfNeeded(replacement, optionName, textOfRightPartOfBinaryExpression, operationReference) + getReplacementForOldKotlinOptionIfNeeded( + replacementOfKotlinOptionsIfNeeded, + optionName, + optionValue, + operationReference, + valueContainsMultipleValues + ) if (expressionForCompilerOption != null) { return Replacement(binaryExpression, expressionForCompilerOption.expression, expressionForCompilerOption.classToImport) } @@ -74,19 +61,97 @@ fun getReplacementForOldKotlinOptionIfNeeded(binaryExpression: KtBinaryExpressio return getReplacementOnlyOfKotlinOptionsIfNeeded(binaryExpression, textOfLeftPartOfBinaryExpression) } +private fun getOptionValue(expression: KtExpression, optionName: String): Pair? { + val optionValue: String + val valueContainsMultipleValues: Boolean + if (expression is KtBinaryExpression) { + if (expression.operationReference.text != "+") { + return null + } + if (optionName == "freeCompilerArgs") { + val leftPart = expression.left ?: return null + val rightPart = expression.right ?: return null + val optionValues = getOptionsFromFreeCompilerArgsExpression(leftPart, mutableSetOf(rightPart.text)) ?: return null + optionValue = StringUtil.join(optionValues.reversed(), ", ") + valueContainsMultipleValues = true + } else { + return null + } + } else { + optionValue = expression.text + valueContainsMultipleValues = false + } + return Pair(optionValue, valueContainsMultipleValues) +} + +/** + * Returns collection of option values or null if something goes wrong. + */ +private fun getOptionsFromFreeCompilerArgsExpression(expression: KtExpression, optionValues: MutableSet): Set? { + if (expression is KtBinaryExpression) { + val operationReference = expression.operationReference.text + if (operationReference != "+") { + return null + } else { + optionValues.add(expression.right?.text ?: return null) + getOptionsFromFreeCompilerArgsExpression(expression.left ?: return null, optionValues) + } + } else { + if (expression.text != "freeCompilerArgs") { + optionValues.add(expression.text) + } + } + return optionValues +} + +private fun getOptionName(expression: KtExpression): Pair? { + val replacementOfKotlinOptionsIfNeeded = StringBuilder() + val optionName = when (expression) { + is KtDotQualifiedExpression -> { + val partBeforeDot = expression.receiverExpression.text + + if (!partBeforeDot.contains("kotlinOptions")) { + if (partBeforeDot != "options") { + return null + } + } else { + replacementOfKotlinOptionsIfNeeded.append("compilerOptions.") + } + expression.getCalleeExpressionIfAny()?.text ?: return null + } + + is KtReferenceExpression -> { + expression.text + } + + else -> { + return null + } + } + return Pair(optionName, replacementOfKotlinOptionsIfNeeded) +} + fun kotlinVersionIsEqualOrHigher(major: Int, minor: Int, patch: Int, file: PsiFile): Boolean { val version = file.module?.kotlinGradlePluginVersion ?: return false return version >= KotlinToolingVersion(major, minor, patch, classifier = null) } -private fun getOperationReplacer(operationReference: String, optionValue: String): String? { +private fun getOperationReplacer( + operationReference: String, + optionValue: String, + valueContainsMultipleValues: Boolean = false +): String? { return when (operationReference) { "=" -> { - "set" + if (valueContainsMultipleValues) { + "addAll" + } else { + "set" + } } "+=" -> { - if (!collectionsNamesRegex.find(optionValue)?.value.isNullOrEmpty()) { + if (!collectionsNamesRegex.find(optionValue)?.value.isNullOrEmpty() || valueContainsMultipleValues) { "addAll" } else { "add" @@ -104,13 +169,20 @@ private fun getReplacementForOldKotlinOptionIfNeeded( optionName: String, optionValue: String, operationReference: String, + valueContainsMultipleValues: Boolean = false, ): CompilerOption? { - - val operationReplacer = getOperationReplacer(operationReference, optionValue) ?: return null + val operationReplacer = + getOperationReplacer(operationReference, optionValue, valueContainsMultipleValues) ?: return null // jvmTarget, apiVersion and languageVersion val versionOptionData = optionsWithValuesMigratedFromNumericStringsToEnums[optionName] if (versionOptionData != null) { - return getCompilerOptionForVersionValue(versionOptionData, optionValue, replacement, optionName, operationReplacer) + return getCompilerOptionForVersionValue( + versionOptionData, + optionValue, + replacement, + optionName, + operationReplacer + ) } else if (jsOptions.contains(optionName)) { // JS options val processedOptionValue = optionValue.removeSurrounding("\"", "\"") val jsOptionsValuesStringToEnumCorrespondence = jsOptions[optionName] ?: return null @@ -126,8 +198,11 @@ private fun getReplacementForOldKotlinOptionIfNeeded( } private fun getCompilerOptionForVersionValue( - versionOptionData: VersionOption, optionValue: String, replacement: StringBuilder, - optionName: String, operationReplacer: String, + versionOptionData: VersionOption, + optionValue: String, + replacement: StringBuilder, + optionName: String, + operationReplacer: String, ): CompilerOption? { val processedOptionValue = optionValue.removeSurrounding("\"", "\"") val convertedValue = versionOptionData.mappingRule.apply(processedOptionValue)