Move logic of EnableUnsupportedFeatureFix into KotlinProjectConfigurator

This commit is contained in:
Dmitry Jemerov
2017-08-18 15:46:07 +02:00
parent 6fbb370eae
commit bf639b1272
5 changed files with 113 additions and 90 deletions
@@ -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()
@@ -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)
@@ -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 {
@@ -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"
@@ -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
)
}
}