From bf639b1272bd1b3b68d45d03806fcb32e0a33561 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 18 Aug 2017 15:46:07 +0200 Subject: [PATCH] Move logic of EnableUnsupportedFeatureFix into KotlinProjectConfigurator --- .../KotlinWithGradleConfigurator.kt | 52 +++++++++--- .../configuration/KotlinMavenConfigurator.kt | 44 +++++++++- .../KotlinProjectConfigurator.kt | 3 + .../KotlinWithLibraryConfigurator.kt | 24 +++++- .../quickfix/EnableUnsupportedFeatureFix.kt | 80 ++----------------- 5 files changed, 113 insertions(+), 90 deletions(-) diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinWithGradleConfigurator.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinWithGradleConfigurator.kt index 4691e3ff9e5..1dbbe52ccb9 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinWithGradleConfigurator.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinWithGradleConfigurator.kt @@ -34,6 +34,7 @@ import com.intellij.openapi.vfs.WritingAccessProvider import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import com.intellij.psi.PsiManager +import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.CoroutineSupport import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.idea.KotlinPluginUtil @@ -182,6 +183,32 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator { return isModified } + override fun updateLanguageVersion( + module: Module, + languageVersion: String?, + apiVersion: String?, + requiredStdlibVersion: ApiVersion, + forTests: Boolean + ) { + val runtimeUpdateRequired = getRuntimeLibraryVersion(module)?.let { ApiVersion.parse(it) }?.let { runtimeVersion -> + runtimeVersion < requiredStdlibVersion + } ?: false + + if (runtimeUpdateRequired) { + Messages.showErrorDialog(module.project, + "This language feature requires version $requiredStdlibVersion or later of the Kotlin runtime library. " + + "Please update the version in your build script.", + "Update Language Version") + return + } + + val element = changeLanguageVersion(module, languageVersion, apiVersion, forTests) + + element?.let { + OpenFileDescriptor(module.project, it.containingFile.virtualFile, it.textRange.startOffset).navigate(true) + } + } + override fun changeCoroutineConfiguration(module: Module, state: LanguageFeature.State) { val runtimeUpdateRequired = state != LanguageFeature.State.DISABLED && (getRuntimeLibraryVersion(module)?.startsWith("1.0") ?: false) @@ -238,21 +265,20 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator { getManipulator(it).changeCoroutineConfiguration(coroutineOption) } - fun changeLanguageVersion(module: Module, languageVersion: String?, apiVersion: String? = null, forTests: Boolean): PsiElement? { - return changeBuildGradle(module) { buildScriptFile -> - val manipulator = getManipulator(buildScriptFile) - var result: PsiElement? = null - if (languageVersion != null) { - result = manipulator.changeLanguageVersion(languageVersion, forTests) - } + fun changeLanguageVersion(module: Module, languageVersion: String?, apiVersion: String?, forTests: Boolean) = + changeBuildGradle(module) { buildScriptFile -> + val manipulator = getManipulator(buildScriptFile) + var result: PsiElement? = null + if (languageVersion != null) { + result = manipulator.changeLanguageVersion(languageVersion, forTests) + } - if (apiVersion != null) { - result = manipulator.changeApiVersion(apiVersion, forTests) - } + if (apiVersion != null) { + result = manipulator.changeApiVersion(apiVersion, forTests) + } - result - } - } + result + } private fun changeBuildGradle(module: Module, body: (PsiFile) -> PsiElement?): PsiElement? { val buildScriptFile = module.getBuildScriptPsiFile() 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 4d5339686ea..ea5bbe39ffe 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 @@ -37,16 +37,14 @@ import org.jetbrains.idea.maven.dom.model.MavenDomPlugin import org.jetbrains.idea.maven.model.MavenId import org.jetbrains.idea.maven.project.MavenProjectsManager import org.jetbrains.idea.maven.utils.MavenArtifactScope +import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.CoroutineSupport import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.idea.KotlinPluginUtil import org.jetbrains.kotlin.idea.configuration.* import org.jetbrains.kotlin.idea.facet.getRuntimeLibraryVersion import org.jetbrains.kotlin.idea.framework.ui.ConfigureDialogWithModulesAndVersion -import org.jetbrains.kotlin.idea.maven.PomFile -import org.jetbrains.kotlin.idea.maven.changeCoroutineConfiguration -import org.jetbrains.kotlin.idea.maven.excludeMavenChildrenModules -import org.jetbrains.kotlin.idea.maven.kotlinPluginId +import org.jetbrains.kotlin.idea.maven.* import org.jetbrains.kotlin.idea.quickfix.ChangeCoroutineSupportFix import org.jetbrains.kotlin.idea.util.application.runReadAction @@ -194,6 +192,44 @@ abstract class KotlinMavenConfigurator } } + override fun updateLanguageVersion( + module: Module, + languageVersion: String?, + apiVersion: String?, + requiredStdlibVersion: ApiVersion, + forTests: Boolean + ) { + fun doUpdateMavenLanguageVersion(): PsiElement? { + val psi = KotlinMavenConfigurator.findModulePomFile(module) as? XmlFile ?: return null + val pom = PomFile.forFileOrNull(psi) ?: return null + return pom.changeLanguageVersion( + languageVersion, + apiVersion) + } + + val runtimeUpdateRequired = getRuntimeLibraryVersion(module)?.let { ApiVersion.parse(it) }?.let { runtimeVersion -> + runtimeVersion < requiredStdlibVersion + } ?: false + + if (runtimeUpdateRequired) { + Messages.showErrorDialog(module.project, + "This language feature requires version $requiredStdlibVersion or later of the Kotlin runtime library. " + + "Please update the version in your build script.", + "Update Language Version") + return + } + + val element = doUpdateMavenLanguageVersion() + if (element == null) { + Messages.showErrorDialog(module.project, + "Failed to update.pom.xml. Please update the file manually.", + "Update Language Version") + } + else { + OpenFileDescriptor(module.project, element.containingFile.virtualFile, element.textRange.startOffset).navigate(true) + } + } + override fun changeCoroutineConfiguration(module: Module, state: LanguageFeature.State) { val runtimeUpdateRequired = state != LanguageFeature.State.DISABLED && (getRuntimeLibraryVersion(module)?.startsWith("1.0") ?: false) diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinProjectConfigurator.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinProjectConfigurator.kt index 7b88694fbc3..527cc6d1d34 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinProjectConfigurator.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinProjectConfigurator.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.configuration import com.intellij.openapi.extensions.ExtensionPointName import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.resolve.TargetPlatform @@ -48,6 +49,8 @@ interface KotlinProjectConfigurator { val targetPlatform: TargetPlatform + fun updateLanguageVersion(module: Module, languageVersion: String?, apiVersion: String?, requiredStdlibVersion: ApiVersion, forTests: Boolean) + fun changeCoroutineConfiguration(module: Module, state: LanguageFeature.State) companion object { diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt index 25dbda1f11d..7e3d12d6a86 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt @@ -28,6 +28,7 @@ import com.intellij.openapi.vfs.LocalFileSystem import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VfsUtilCore import org.jetbrains.annotations.Contract +import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageVersion @@ -334,7 +335,6 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj val runtimeUpdateRequired = state != LanguageFeature.State.DISABLED && (getRuntimeLibraryVersion(module)?.startsWith("1.0") ?: false) - if (runtimeUpdateRequired && !askUpdateRuntime(module, LanguageFeature.Coroutines.sinceApiVersion)) { return } @@ -347,6 +347,28 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj } } + override fun updateLanguageVersion(module: Module, languageVersion: String?, apiVersion: String?, requiredStdlibVersion: ApiVersion, forTests: Boolean) { + val runtimeUpdateRequired = getRuntimeLibraryVersion(module)?.let { ApiVersion.parse(it) }?.let { runtimeVersion -> + runtimeVersion < requiredStdlibVersion + } ?: false + + if (runtimeUpdateRequired && !askUpdateRuntime(module, requiredStdlibVersion)) { + return + } + + val facetSettings = KotlinFacetSettingsProvider.getInstance(module.project).getInitializedSettings(module) + ModuleRootModificationUtil.updateModel(module) { + with(facetSettings) { + if (languageVersion != null) { + languageLevel = LanguageVersion.fromVersionString(languageVersion) + } + if (apiVersion != null) { + apiLevel = LanguageVersion.fromVersionString(apiVersion) + } + } + } + } + companion object { val DEFAULT_LIBRARY_DIR = "lib" diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt index f92f4f6b7fd..5dc5ac3c495 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt @@ -18,32 +18,25 @@ package org.jetbrains.kotlin.idea.quickfix import com.intellij.openapi.application.ApplicationManager 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.ModuleRootManager -import com.intellij.openapi.roots.ModuleRootModificationUtil import com.intellij.openapi.roots.ex.ProjectRootManagerEx import com.intellij.openapi.roots.libraries.Library import com.intellij.openapi.ui.Messages import com.intellij.psi.PsiElement -import com.intellij.psi.xml.XmlFile import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider import org.jetbrains.kotlin.config.LanguageFeature -import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.idea.KotlinPluginUtil import org.jetbrains.kotlin.idea.actions.internal.KotlinInternalMode import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder -import org.jetbrains.kotlin.idea.configuration.KotlinWithGradleConfigurator +import org.jetbrains.kotlin.idea.configuration.findApplicableConfigurator 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.changeLanguageVersion -import org.jetbrains.kotlin.idea.maven.configuration.KotlinMavenConfigurator import org.jetbrains.kotlin.idea.util.projectStructure.allModules import org.jetbrains.kotlin.idea.versions.findKotlinRuntimeLibrary import org.jetbrains.kotlin.idea.versions.updateLibraries @@ -64,11 +57,6 @@ sealed class EnableUnsupportedFeatureFix( override fun invoke(project: Project, editor: Editor?, file: KtFile) { val module = ModuleUtilCore.findModuleForPsiElement(file) ?: return - val targetVersion = feature.sinceVersion!! - - val runtimeUpdateRequired = getRuntimeLibraryVersion(module)?.let { ApiVersion.parse(it) }?.let { runtimeVersion -> - runtimeVersion < feature.sinceApiVersion - } ?: false val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(module) val targetApiLevel = facetSettings.apiLevel?.let { apiLevel -> @@ -77,67 +65,15 @@ sealed class EnableUnsupportedFeatureFix( else null } - - if (KotlinPluginUtil.isGradleModule(module) || KotlinPluginUtil.isMavenModule(module)) { - if (runtimeUpdateRequired) { - Messages.showErrorDialog(project, - "This language feature requires version ${feature.sinceApiVersion} or later of the Kotlin runtime library. " + - "Please update the version in your build script.", - "Update Language Version") - return - } - - val element = if (KotlinPluginUtil.isGradleModule(module)) { - updateGradleLanguageVersion(module, file, targetApiLevel) - } - else { - updateMavenLanguageVersion(module, targetApiLevel) - } - element?.let { - OpenFileDescriptor(module.project, it.containingFile.virtualFile, it.textRange.startOffset).navigate(true) - } - return - } - - if (runtimeUpdateRequired && !askUpdateRuntime(module, feature.sinceApiVersion)) { - return - } - - ModuleRootModificationUtil.updateModel(module) { - with(facetSettings) { - if (!apiVersionOnly) { - languageLevel = targetVersion - } - if (targetApiLevel != null) { - apiLevel = LanguageVersion.fromVersionString(targetApiLevel) - } - } - } - } - - private fun updateGradleLanguageVersion(module: Module, file: KtFile, targetApiLevel: String?): PsiElement? { val forTests = ModuleRootManager.getInstance(module).fileIndex.isInTestSourceContent(file.virtualFile) - return KotlinWithGradleConfigurator.changeLanguageVersion(module, - if (apiVersionOnly) null else feature.sinceVersion!!.versionString, - targetApiLevel, forTests) - } - private fun updateMavenLanguageVersion(module: Module, targetApiLevel: String?): PsiElement? { - fun doUpdateMavenLanguageVersion(): PsiElement? { - val psi = KotlinMavenConfigurator.findModulePomFile(module) as? XmlFile ?: return null - val pom = PomFile.forFileOrNull(psi) ?: return null - return pom.changeLanguageVersion( - if (apiVersionOnly) null else feature.sinceVersion!!.versionString, - targetApiLevel) - } - - val element = doUpdateMavenLanguageVersion() - if (element == null) { - Messages.showErrorDialog(module.project, - "Failed to update.pom.xml. Please update the file manually.", - text) - } - return element + findApplicableConfigurator(module).updateLanguageVersion( + module, + if (apiVersionOnly) null else feature.sinceVersion!!.versionString, + targetApiLevel, + feature.sinceApiVersion, + forTests + ) } }