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
new file mode 100644
index 00000000000..6fff47ae6f4
--- /dev/null
+++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CliArgumentStringBuilder.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
+ * that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.cli.common.arguments
+
+import org.jetbrains.kotlin.config.LanguageFeature
+
+object CliArgumentStringBuilder {
+ const val languagePrefix = "-XXLanguage:"
+
+ private val LanguageFeature.State.sign: String
+ get() = when (this) {
+ LanguageFeature.State.ENABLED -> "+"
+ LanguageFeature.State.DISABLED -> "-"
+ LanguageFeature.State.ENABLED_WITH_WARNING -> "+" // not supported normally
+ LanguageFeature.State.ENABLED_WITH_ERROR -> "-" // not supported normally
+ }
+
+ fun LanguageFeature.buildArgumentString(state: LanguageFeature.State): String {
+ return "$languagePrefix${state.sign}$name"
+ }
+}
\ 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 63429e0f041..e5151466863 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
@@ -21,6 +21,8 @@ import com.intellij.openapi.roots.ExternalLibraryDescriptor
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.config.LanguageFeature
import org.jetbrains.kotlin.idea.configuration.KotlinWithGradleConfigurator.Companion.getBuildScriptSettingsPsiFile
import org.jetbrains.kotlin.idea.util.application.runReadAction
@@ -156,14 +158,7 @@ class GroovyBuildScriptManipulator(
state: LanguageFeature.State,
forTests: Boolean
): PsiElement? {
- val sign = when (state) {
- LanguageFeature.State.ENABLED -> "+"
- LanguageFeature.State.DISABLED -> "-"
- LanguageFeature.State.ENABLED_WITH_WARNING -> "+" // not supported normally
- LanguageFeature.State.ENABLED_WITH_ERROR -> "-" // not supported normally
- }
- val languagePrefix = "-XXLanguage:"
- val featureArgumentString = "$languagePrefix$sign${feature.name}"
+ val featureArgumentString = feature.buildArgumentString(state)
val parameterName = "freeCompilerArgs"
return addOrReplaceKotlinTaskParameter(
scriptFile,
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 7027d1bd3e7..fbf44b4e60b 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
@@ -21,6 +21,8 @@ import com.intellij.openapi.roots.ExternalLibraryDescriptor
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.config.LanguageFeature
import org.jetbrains.kotlin.idea.configuration.KotlinWithGradleConfigurator.Companion.getBuildScriptSettingsPsiFile
import org.jetbrains.kotlin.idea.inspections.gradle.GradleHeuristicHelper.PRODUCTION_DEPENDENCY_STATEMENTS
@@ -311,14 +313,7 @@ class KotlinBuildScriptManipulator(
state: LanguageFeature.State,
forTests: Boolean
): PsiElement? {
- val sign = when (state) {
- LanguageFeature.State.ENABLED -> "+"
- LanguageFeature.State.DISABLED -> "-"
- LanguageFeature.State.ENABLED_WITH_WARNING -> "+" // not supported normally
- LanguageFeature.State.ENABLED_WITH_ERROR -> "-" // not supported normally
- }
- val languagePrefix = "-XXLanguage:"
- val featureArgumentString = "$languagePrefix$sign${feature.name}"
+ val featureArgumentString = feature.buildArgumentString(state)
val parameterName = "freeCompilerArgs"
return addOrReplaceKotlinTaskParameter(
parameterName,
diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/PomFile.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/PomFile.kt
index 6f1124f0a32..b4d67de858c 100644
--- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/PomFile.kt
+++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/PomFile.kt
@@ -39,7 +39,9 @@ import org.jetbrains.idea.maven.project.MavenProject
import org.jetbrains.idea.maven.project.MavenProjectsManager
import org.jetbrains.idea.maven.utils.MavenArtifactScope
import org.jetbrains.jps.model.java.JavaSourceRootType
+import org.jetbrains.kotlin.cli.common.arguments.CliArgumentStringBuilder.buildArgumentString
import org.jetbrains.kotlin.config.KotlinSourceRootType
+import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.idea.configuration.RepositoryDescription
import org.jetbrains.kotlin.idea.maven.configuration.KotlinMavenConfigurator
import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType
@@ -441,18 +443,6 @@ class PomFile private constructor(private val xmlFile: XmlFile, val domModel: Ma
null
)
- private fun MavenDomElement.createChildTag(name: String, value: String? = null) = xmlTag?.createChildTag(name, value)
- private fun XmlTag.createChildTag(name: String, value: String? = null) = createChildTag(name, namespace, value, false)!!
-
- private tailrec fun XmlTag.deleteCascade() {
- val oldParent = this.parentTag
- delete()
-
- if (oldParent != null && oldParent.subTags.isEmpty()) {
- oldParent.deleteCascade()
- }
- }
-
private fun ensureElement(projectElement: XmlTag, localName: String): XmlTag {
require(localName in recommendedElementsOrder) { "You can only ensure presence or the elements from the recommendation list" }
@@ -700,3 +690,40 @@ fun PomFile.changeCoroutineConfiguration(value: String): PsiElement? {
) ?: return null
return changeConfigurationOrProperty(kotlinPlugin, "experimentalCoroutines", "kotlin.compiler.experimental.coroutines", value)
}
+
+fun PomFile.changeFeatureConfiguration(
+ feature: LanguageFeature,
+ state: LanguageFeature.State
+): PsiElement? {
+ val kotlinPlugin = findPlugin(
+ MavenId(
+ KotlinMavenConfigurator.GROUP_ID,
+ KotlinMavenConfigurator.MAVEN_PLUGIN_ID,
+ null
+ )
+ ) ?: return null
+ val configurationTag = kotlinPlugin.configuration.ensureTagExists()
+ val argsSubTag = configurationTag.findSubTags("args").firstOrNull()
+ ?: run {
+ val childTag = configurationTag.createChildTag("args")
+ configurationTag.add(childTag) as XmlTag
+ }
+
+ argsSubTag.findSubTags("arg").filter { feature.name in it.value.text }.forEach { it.deleteCascade() }
+ val featureArgumentString = feature.buildArgumentString(state)
+ val childTag = argsSubTag.createChildTag("arg", featureArgumentString)
+ return argsSubTag.add(childTag)
+}
+
+private fun MavenDomElement.createChildTag(name: String, value: String? = null) = xmlTag?.createChildTag(name, value)
+private fun XmlTag.createChildTag(name: String, value: String? = null) = createChildTag(name, namespace, value, false)!!
+
+private tailrec fun XmlTag.deleteCascade() {
+ val oldParent = this.parentTag
+ delete()
+
+ if (oldParent != null && oldParent.subTags.isEmpty()) {
+ oldParent.deleteCascade()
+ }
+}
+
diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinMavenConfigurator.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinMavenConfigurator.kt
index 14eaacc0d38..f95c3c950e6 100644
--- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinMavenConfigurator.kt
+++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinMavenConfigurator.kt
@@ -290,7 +290,15 @@ protected constructor(
)
return
}
- // TODO: here we should make something like https://kotlinlang.org/docs/reference/using-maven.html#specifying-compiler-options
+
+ val element = changeMavenFeatureConfiguration(
+ module, feature, state, messageTitle
+ )
+
+ if (element != null) {
+ OpenFileDescriptor(module.project, element.containingFile.virtualFile, element.textRange.startOffset).navigate(true)
+ }
+
}
private fun changeMavenCoroutineConfiguration(
@@ -315,6 +323,25 @@ protected constructor(
return element
}
+ private fun changeMavenFeatureConfiguration(
+ module: Module,
+ feature: LanguageFeature,
+ state: LanguageFeature.State,
+ messageTitle: String
+ ): PsiElement? {
+ val psi = KotlinMavenConfigurator.findModulePomFile(module) as? XmlFile ?: return null
+ val pom = PomFile.forFileOrNull(psi) ?: return null
+ val element = pom.changeFeatureConfiguration(feature, state)
+ if (element == null) {
+ Messages.showErrorDialog(
+ module.project,
+ "Failed to update.pom.xml. Please update the file manually.",
+ messageTitle
+ )
+ }
+ return element
+ }
+
companion object {
const val GROUP_ID = "org.jetbrains.kotlin"
const val MAVEN_PLUGIN_ID = "kotlin-maven-plugin"
diff --git a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/MavenUpdateConfigurationQuickFixTest.kt b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/MavenUpdateConfigurationQuickFixTest.kt
index 45e046e226b..730406fbaeb 100644
--- a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/MavenUpdateConfigurationQuickFixTest.kt
+++ b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/MavenUpdateConfigurationQuickFixTest.kt
@@ -74,6 +74,11 @@ class MavenUpdateConfigurationQuickFixTest : MavenImportingTestCase() {
doTest("Enable coroutine support in the current module")
}
+ @Test
+ fun testEnableInlineClasses() {
+ doTest("Enable inline classes support in the current module")
+ }
+
@Test
fun testAddKotlinReflect() {
doTest("Add kotlin-reflect.jar to the classpath")
diff --git a/idea/idea-maven/testData/languageFeature/enableInlineClasses/pom.xml b/idea/idea-maven/testData/languageFeature/enableInlineClasses/pom.xml
new file mode 100644
index 00000000000..9711e6ae81d
--- /dev/null
+++ b/idea/idea-maven/testData/languageFeature/enableInlineClasses/pom.xml
@@ -0,0 +1,56 @@
+
+
+ 4.0.0
+
+ maventest
+ maventest
+ 1.0-SNAPSHOT
+
+ $VERSION$
+
+
+
+ org.jetbrains.kotlin
+ kotlin-stdlib-jre8
+ ${kotlin.version}
+
+
+ org.jetbrains.kotlin
+ kotlin-test
+ ${kotlin.version}
+ test
+
+
+
+
+ ${project.basedir}/src/main/kotlin
+
+
+ org.jetbrains.kotlin
+ kotlin-maven-plugin
+ ${kotlin.version}
+
+
+ compile
+ compile
+
+ wrong-goal
+ compile
+
+
+
+ test-compile
+ test-compile
+
+ test-compile
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/idea/idea-maven/testData/languageFeature/enableInlineClasses/pom.xml.after b/idea/idea-maven/testData/languageFeature/enableInlineClasses/pom.xml.after
new file mode 100644
index 00000000000..8643092295f
--- /dev/null
+++ b/idea/idea-maven/testData/languageFeature/enableInlineClasses/pom.xml.after
@@ -0,0 +1,61 @@
+
+
+ 4.0.0
+
+ maventest
+ maventest
+ 1.0-SNAPSHOT
+
+ $VERSION$
+
+
+
+ org.jetbrains.kotlin
+ kotlin-stdlib-jre8
+ ${kotlin.version}
+
+
+ org.jetbrains.kotlin
+ kotlin-test
+ ${kotlin.version}
+ test
+
+
+
+
+ ${project.basedir}/src/main/kotlin
+
+
+ org.jetbrains.kotlin
+ kotlin-maven-plugin
+ ${kotlin.version}
+
+
+ compile
+ compile
+
+ wrong-goal
+ compile
+
+
+
+ test-compile
+ test-compile
+
+ test-compile
+
+
+
+
+
+ -XXLanguage:+InlineClasses
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/idea/idea-maven/testData/languageFeature/enableInlineClasses/src.kt b/idea/idea-maven/testData/languageFeature/enableInlineClasses/src.kt
new file mode 100644
index 00000000000..046aa8d2172
--- /dev/null
+++ b/idea/idea-maven/testData/languageFeature/enableInlineClasses/src.kt
@@ -0,0 +1 @@
+inline class My(val x: Int)