Quickfix to enable coroutine support works in Maven projects

#KT-17521 Fixed
This commit is contained in:
Dmitry Jemerov
2017-04-20 18:38:04 +02:00
parent aabd560eef
commit 7346fee513
6 changed files with 160 additions and 7 deletions
@@ -303,7 +303,7 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
return configurationTag.add(newTag) as XmlTag
}
fun addPluginConfiguration(plugin: MavenDomPlugin, optionName: String, optionValue: String) {
fun addPluginConfiguration(plugin: MavenDomPlugin, optionName: String, optionValue: String): XmlTag {
val configurationTag = plugin.configuration.ensureTagExists()
val existingTag = configurationTag.findFirstSubTag(optionName)
if (existingTag != null) {
@@ -312,6 +312,7 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
else {
configurationTag.add(configurationTag.createChildTag(optionName, optionValue))
}
return configurationTag
}
fun addPluginRepository(id: String, name: String, url: String, snapshots: Boolean = false, releases: Boolean = true): MavenDomRepository {
@@ -601,5 +602,12 @@ private fun PomFile.changeConfigurationOrProperty(kotlinPlugin: MavenDomPlugin,
}
}
return null
return addPluginConfiguration(kotlinPlugin, configurationTagName, value)
}
fun PomFile.changeCoroutineConfiguration(value: String): PsiElement? {
val kotlinPlugin = findPlugin(MavenId(KotlinMavenConfigurator.GROUP_ID,
KotlinMavenConfigurator.MAVEN_PLUGIN_ID,
null)) ?: return null
return changeConfigurationOrProperty(kotlinPlugin, "experimentalCoroutines", "kotlin.compiler.experimental.coroutines", value)
}
@@ -62,6 +62,10 @@ class MavenLanguageFeatureQuickFixTest : MavenImportingTestCase() {
doTest("Set module language version to 1.1")
}
@Test fun testEnableCoroutines() {
doTest("Enable coroutine support in the current module")
}
private fun doTest(intentionName: String) {
val pomVFile = createProjectSubFile("pom.xml", File(getTestDataPath(), "pom.xml").readText())
val sourceVFile = createProjectSubFile("src/main/kotlin/src.kt", File(getTestDataPath(), "src.kt").readText())
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>maventest</groupId>
<artifactId>maventest</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<kotlin.version>$VERSION$</kotlin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jre8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>wrong-goal</goal>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>maventest</groupId>
<artifactId>maventest</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<kotlin.version>$VERSION$</kotlin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jre8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>wrong-goal</goal>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<experimentalCoroutines>enable</experimentalCoroutines>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,2 @@
suspend fun foo() {
}
@@ -19,12 +19,14 @@ package org.jetbrains.kotlin.idea.quickfix
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.fileEditor.OpenFileDescriptor
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ModuleRootModificationUtil
import com.intellij.openapi.roots.ex.ProjectRootManagerEx
import com.intellij.openapi.ui.Messages
import com.intellij.psi.PsiElement
import com.intellij.psi.xml.XmlFile
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.config.CoroutineSupport
import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider
@@ -37,6 +39,9 @@ import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgu
import org.jetbrains.kotlin.idea.configuration.KotlinWithGradleConfigurator
import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.facet.getRuntimeLibraryVersion
import org.jetbrains.kotlin.idea.maven.PomFile
import org.jetbrains.kotlin.idea.maven.changeCoroutineConfiguration
import org.jetbrains.kotlin.idea.maven.configuration.KotlinMavenConfigurator
import org.jetbrains.kotlin.psi.KtFile
sealed class ChangeCoroutineSupportFix(
@@ -55,7 +60,7 @@ sealed class ChangeCoroutineSupportFix(
val runtimeUpdateRequired = coroutineSupportEnabled &&
(getRuntimeLibraryVersion(module)?.startsWith("1.0") ?: false)
if (KotlinPluginUtil.isGradleModule(module)) {
if (KotlinPluginUtil.isGradleModule(module) || KotlinPluginUtil.isMavenModule(module)) {
if (runtimeUpdateRequired) {
Messages.showErrorDialog(project,
"Coroutines support requires version 1.1 or later of the Kotlin runtime library. " +
@@ -64,9 +69,13 @@ sealed class ChangeCoroutineSupportFix(
return
}
val element = KotlinWithGradleConfigurator.changeCoroutineConfiguration(
val element = if (KotlinPluginUtil.isGradleModule(module))
KotlinWithGradleConfigurator.changeCoroutineConfiguration(
module, CoroutineSupport.getCompilerArgument(coroutineSupport)
)
)
else
changeMavenCoroutineConfiguration(module, CoroutineSupport.getCompilerArgument(coroutineSupport))
if (element != null) {
OpenFileDescriptor(project, element.containingFile.virtualFile, element.textRange.startOffset).navigate(true)
}
@@ -85,6 +94,22 @@ sealed class ChangeCoroutineSupportFix(
}
}
private fun changeMavenCoroutineConfiguration(module: Module, value: String): PsiElement? {
fun doChangeMavenCoroutineConfiguration(): PsiElement? {
val psi = KotlinMavenConfigurator.findModulePomFile(module) as? XmlFile ?: return null
val pom = PomFile.forFileOrNull(psi) ?: return null
return pom.changeCoroutineConfiguration(value)
}
val element = doChangeMavenCoroutineConfiguration()
if (element == null) {
Messages.showErrorDialog(module.project,
"Failed to update.pom.xml. Please update the file manually.",
text)
}
return element
}
}
class InProject(element: PsiElement, coroutineSupport: LanguageFeature.State) : ChangeCoroutineSupportFix(element, coroutineSupport) {
@@ -131,11 +156,10 @@ sealed class ChangeCoroutineSupportFix(
else -> return emptyList()
}
val module = ModuleUtilCore.findModuleForPsiElement(diagnostic.psiElement) ?: return emptyList()
if (KotlinPluginUtil.isMavenModule(module)) return emptyList()
val facetSettings = KotlinFacet.get(module)?.configuration?.settings
val configureInProject = (facetSettings == null || facetSettings.useProjectSettings) &&
!KotlinPluginUtil.isGradleModule(module)
!KotlinPluginUtil.isGradleModule(module) && !KotlinPluginUtil.isMavenModule(module)
val quickFixConstructor: (PsiElement, LanguageFeature.State) -> ChangeCoroutineSupportFix =
if (configureInProject) ::InProject else ::InModule
return newCoroutineSupports.map { quickFixConstructor(diagnostic.psiElement, it) }