diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CliArgumentStringBuilder.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CliArgumentStringBuilder.kt index 6fff47ae6f4..f9688221ee1 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CliArgumentStringBuilder.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CliArgumentStringBuilder.kt @@ -8,7 +8,7 @@ package org.jetbrains.kotlin.cli.common.arguments import org.jetbrains.kotlin.config.LanguageFeature object CliArgumentStringBuilder { - const val languagePrefix = "-XXLanguage:" + private const val languagePrefix = "-XXLanguage:" private val LanguageFeature.State.sign: String get() = when (this) { @@ -21,4 +21,30 @@ object CliArgumentStringBuilder { fun LanguageFeature.buildArgumentString(state: LanguageFeature.State): String { return "$languagePrefix${state.sign}$name" } + + fun String.replaceLanguageFeature( + feature: LanguageFeature, + state: LanguageFeature.State, + prefix: String = "", + postfix: String = "", + separator: String = ", ", + quoted: Boolean = true + ): String { + val existingFeatureIndex = indexOf(feature.name) + val languagePrefixIndex = lastIndexOf(languagePrefix, existingFeatureIndex) + val featureArgumentString = feature.buildArgumentString(state) + val quote = if (quoted) "\"" else "" + return if (languagePrefixIndex != -1) { + replaceRange(languagePrefixIndex, existingFeatureIndex + feature.name.length, featureArgumentString) + } else { + val splitText = if (postfix.isNotEmpty()) split(postfix) else listOf(this, "") + if (splitText.size != 2) { + "$prefix$quote$featureArgumentString$quote$postfix" + } else { + val (mainPart, commentPart) = splitText + // In Groovy / Kotlin DSL, we can have comment after [...] or listOf(...) + mainPart + "$separator$quote$featureArgumentString$quote$postfix" + commentPart + } + } + } } \ No newline at end of file diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GroovyBuildScriptManipulator.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GroovyBuildScriptManipulator.kt index e5151466863..2ae609d28a8 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GroovyBuildScriptManipulator.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GroovyBuildScriptManipulator.kt @@ -22,7 +22,7 @@ import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.PsiElement import com.intellij.psi.codeStyle.CodeStyleManager import org.jetbrains.kotlin.cli.common.arguments.CliArgumentStringBuilder.buildArgumentString -import org.jetbrains.kotlin.cli.common.arguments.CliArgumentStringBuilder.languagePrefix +import org.jetbrains.kotlin.cli.common.arguments.CliArgumentStringBuilder.replaceLanguageFeature import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.idea.configuration.KotlinWithGradleConfigurator.Companion.getBuildScriptSettingsPsiFile import org.jetbrains.kotlin.idea.util.application.runReadAction @@ -166,19 +166,8 @@ class GroovyBuildScriptManipulator( "[\"$featureArgumentString\"]", forTests ) { insideKotlinOptions -> - val existingFeatureIndex = text.indexOf(feature.name) - val languagePrefixIndex = text.lastIndexOf(languagePrefix, existingFeatureIndex) - val newText = if (languagePrefixIndex != -1) { - text.substring(0, languagePrefixIndex) + featureArgumentString + text.substring(existingFeatureIndex + feature.name.length) - } else { - val splitText = text.split("]") - if (splitText.size != 2) { - val prefix = if (insideKotlinOptions) "kotlinOptions." else "" - "$prefix$parameterName = [\"$featureArgumentString\"]" - } else { - splitText[0] + ", \"$featureArgumentString\"]" + splitText[1] - } - } + val prefix = if (insideKotlinOptions) "kotlinOptions." else "" + val newText = text.replaceLanguageFeature(feature, state, prefix = "$prefix$parameterName = [", postfix = "]") replaceWithStatementFromText(newText) } } diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinBuildScriptManipulator.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinBuildScriptManipulator.kt index fbf44b4e60b..424fbfd9a3f 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinBuildScriptManipulator.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinBuildScriptManipulator.kt @@ -22,7 +22,7 @@ import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.PsiElement import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.cli.common.arguments.CliArgumentStringBuilder.buildArgumentString -import org.jetbrains.kotlin.cli.common.arguments.CliArgumentStringBuilder.languagePrefix +import org.jetbrains.kotlin.cli.common.arguments.CliArgumentStringBuilder.replaceLanguageFeature import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.idea.configuration.KotlinWithGradleConfigurator.Companion.getBuildScriptSettingsPsiFile import org.jetbrains.kotlin.idea.inspections.gradle.GradleHeuristicHelper.PRODUCTION_DEPENDENCY_STATEMENTS @@ -320,18 +320,7 @@ class KotlinBuildScriptManipulator( "listOf(\"$featureArgumentString\")", forTests ) { - val existingFeatureIndex = text.indexOf(feature.name) - val languagePrefixIndex = text.lastIndexOf(languagePrefix, existingFeatureIndex) - val newText = if (languagePrefixIndex != -1) { - text.substring(0, languagePrefixIndex) + featureArgumentString + text.substring(existingFeatureIndex + feature.name.length) - } else { - val splitText = text.split(")") - if (splitText.size != 2) { - "$parameterName = listOf(\"$featureArgumentString\")" - } else { - splitText[0] + ", \"$featureArgumentString\")" + splitText[1] - } - } + val newText = text.replaceLanguageFeature(feature, state, prefix = "$parameterName = listOf(", postfix = ")") replace(psiFactory.createExpression(newText)) } } diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt index 5af5f3f2737..b487f98b3af 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt @@ -18,6 +18,7 @@ import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.psi.PsiElement import org.jetbrains.annotations.Contract +import org.jetbrains.kotlin.cli.common.arguments.CliArgumentStringBuilder.replaceLanguageFeature import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.idea.facet.getRuntimeLibraryVersion import org.jetbrains.kotlin.idea.facet.toApiVersion @@ -362,10 +363,10 @@ abstract class KotlinWithLibraryConfigurator protected constructor() : KotlinPro val facetSettings = KotlinFacetSettingsProvider.getInstance(module.project).getInitializedSettings(module) ModuleRootModificationUtil.updateModel(module) { - facetSettings.apiLevel = LanguageVersion.KOTLIN_1_3 - facetSettings.languageLevel = LanguageVersion.KOTLIN_1_3 + facetSettings.apiLevel = feature.sinceVersion + facetSettings.languageLevel = feature.sinceVersion facetSettings.compilerSettings?.apply { - // TODO: JPS, module + additionalArguments = additionalArguments.replaceLanguageFeature(feature, state, separator = " ", quoted = false) } } } diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/ChangeGeneralLanguageFeatureSupportFix.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/ChangeGeneralLanguageFeatureSupportFix.kt index 729615c1985..a47199c4a19 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/ChangeGeneralLanguageFeatureSupportFix.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/ChangeGeneralLanguageFeatureSupportFix.kt @@ -11,6 +11,7 @@ import com.intellij.openapi.module.ModuleUtilCore import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ModuleRootManager import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.cli.common.arguments.CliArgumentStringBuilder.replaceLanguageFeature import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerSettings @@ -55,7 +56,7 @@ sealed class ChangeGeneralLanguageFeatureSupportFix( if (!checkUpdateRuntime(project, feature.sinceApiVersion)) return } KotlinCompilerSettings.getInstance(project).update { - // TODO: JPS, project + additionalArguments = additionalArguments.replaceLanguageFeature(feature, featureSupport, separator = " ", quoted = false) } project.invalidateProjectRoots() } diff --git a/idea/testData/gradle/configurator/enableFeatureSupportToExistentArguments/build.gradle b/idea/testData/gradle/configurator/enableFeatureSupportToExistentArguments/build.gradle index b22b58c6a64..921a8e27472 100644 --- a/idea/testData/gradle/configurator/enableFeatureSupportToExistentArguments/build.gradle +++ b/idea/testData/gradle/configurator/enableFeatureSupportToExistentArguments/build.gradle @@ -19,6 +19,6 @@ dependencies { } compileKotlin { kotlinOptions { - freeCompilerArgs = ["-XXLanguage:+SamConversionForKotlinFunctions"] + freeCompilerArgs = ["-XXLanguage:+SamConversionForKotlinFunctions"] // Free compiler arguments } } diff --git a/idea/testData/gradle/configurator/enableFeatureSupportToExistentArguments/build.gradle.after b/idea/testData/gradle/configurator/enableFeatureSupportToExistentArguments/build.gradle.after index 1b0db94a1bb..8491200434a 100644 --- a/idea/testData/gradle/configurator/enableFeatureSupportToExistentArguments/build.gradle.after +++ b/idea/testData/gradle/configurator/enableFeatureSupportToExistentArguments/build.gradle.after @@ -20,5 +20,6 @@ dependencies { compileKotlin { kotlinOptions { freeCompilerArgs = ["-XXLanguage:+SamConversionForKotlinFunctions", "-XXLanguage:+InlineClasses"] + // Free compiler arguments } }