From 7346fee5130c2f027b86ce29503b1b849dc9135e Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 20 Apr 2017 18:38:04 +0200 Subject: [PATCH] Quickfix to enable coroutine support works in Maven projects #KT-17521 Fixed --- .../jetbrains/kotlin/idea/maven/PomFile.kt | 12 +++- .../maven/MavenLanguageFeatureQuickFixTest.kt | 4 ++ .../languageFeature/enableCoroutines/pom.xml | 56 ++++++++++++++++++ .../enableCoroutines/pom.xml.after | 59 +++++++++++++++++++ .../languageFeature/enableCoroutines/src.kt | 2 + .../quickfix/ChangeCoroutineSupportFix.kt | 34 +++++++++-- 6 files changed, 160 insertions(+), 7 deletions(-) create mode 100644 idea/idea-maven/testData/languageFeature/enableCoroutines/pom.xml create mode 100644 idea/idea-maven/testData/languageFeature/enableCoroutines/pom.xml.after create mode 100644 idea/idea-maven/testData/languageFeature/enableCoroutines/src.kt 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 86cf88d5006..6d77777f744 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 @@ -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) } diff --git a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/MavenLanguageFeatureQuickFixTest.kt b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/MavenLanguageFeatureQuickFixTest.kt index 9d000450977..4999d2164fe 100644 --- a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/MavenLanguageFeatureQuickFixTest.kt +++ b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/MavenLanguageFeatureQuickFixTest.kt @@ -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()) diff --git a/idea/idea-maven/testData/languageFeature/enableCoroutines/pom.xml b/idea/idea-maven/testData/languageFeature/enableCoroutines/pom.xml new file mode 100644 index 00000000000..9711e6ae81d --- /dev/null +++ b/idea/idea-maven/testData/languageFeature/enableCoroutines/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/enableCoroutines/pom.xml.after b/idea/idea-maven/testData/languageFeature/enableCoroutines/pom.xml.after new file mode 100644 index 00000000000..5b29cc7cef7 --- /dev/null +++ b/idea/idea-maven/testData/languageFeature/enableCoroutines/pom.xml.after @@ -0,0 +1,59 @@ + + + 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 + + + + + enable + + + + + + + \ No newline at end of file diff --git a/idea/idea-maven/testData/languageFeature/enableCoroutines/src.kt b/idea/idea-maven/testData/languageFeature/enableCoroutines/src.kt new file mode 100644 index 00000000000..624d4625e64 --- /dev/null +++ b/idea/idea-maven/testData/languageFeature/enableCoroutines/src.kt @@ -0,0 +1,2 @@ +suspend fun foo() { +} diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt index fa8f3a65fe8..0c33e6ae976 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt @@ -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) }