Introduce skeleton for ChangeGeneralLanguageFeatureSupportFix

Part of KT-26775 and KT-26774
This commit is contained in:
Mikhail Glukhikh
2018-09-18 15:47:08 +03:00
parent fd3dfe0710
commit b194be7665
10 changed files with 218 additions and 22 deletions
@@ -56,6 +56,8 @@ interface KotlinProjectConfigurator {
fun changeCoroutineConfiguration(module: Module, state: LanguageFeature.State)
fun changeGeneralFeatureConfiguration(module: Module, feature: LanguageFeature, state: LanguageFeature.State)
fun addLibraryDependency(module: Module, element: PsiElement, library: ExternalLibraryDescriptor, libraryJarDescriptors: List<LibraryJarDescriptor>)
companion object {
@@ -19,9 +19,8 @@ import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.psi.PsiElement
import org.jetbrains.annotations.Contract
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.idea.KotlinPluginUtil
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder
import org.jetbrains.kotlin.idea.facet.getRuntimeLibraryVersion
import org.jetbrains.kotlin.idea.facet.toApiVersion
import org.jetbrains.kotlin.idea.framework.ui.CreateLibraryDialogWithModules
import org.jetbrains.kotlin.idea.framework.ui.FileUIUtils
import org.jetbrains.kotlin.idea.quickfix.askUpdateRuntime
@@ -332,7 +331,7 @@ abstract class KotlinWithLibraryConfigurator protected constructor() : KotlinPro
override fun changeCoroutineConfiguration(module: Module, state: LanguageFeature.State) {
val runtimeUpdateRequired = state != LanguageFeature.State.DISABLED &&
(getRuntimeLibraryVersion(module)?.startsWith("1.0") ?: false)
getRuntimeLibraryVersion(module).toApiVersion() == ApiVersion.KOTLIN_1_0
if (runtimeUpdateRequired && !askUpdateRuntime(module, LanguageFeature.Coroutines.sinceApiVersion)) {
return
@@ -346,6 +345,30 @@ abstract class KotlinWithLibraryConfigurator protected constructor() : KotlinPro
}
}
override fun changeGeneralFeatureConfiguration(
module: Module,
feature: LanguageFeature,
state: LanguageFeature.State
) {
val sinceVersion = feature.sinceApiVersion
if (state != LanguageFeature.State.DISABLED &&
getRuntimeLibraryVersion(module).toApiVersion() < sinceVersion &&
!askUpdateRuntime(module, sinceVersion)
) {
return
}
val facetSettings = KotlinFacetSettingsProvider.getInstance(module.project).getInitializedSettings(module)
ModuleRootModificationUtil.updateModel(module) {
facetSettings.apiLevel = LanguageVersion.KOTLIN_1_3
facetSettings.languageLevel = LanguageVersion.KOTLIN_1_3
facetSettings.compilerSettings?.apply {
// TODO: JPS, module
}
}
}
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
@@ -0,0 +1,84 @@
/*
* 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.idea.quickfix
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerSettings
import org.jetbrains.kotlin.idea.configuration.BuildSystemType
import org.jetbrains.kotlin.idea.configuration.findApplicableConfigurator
import org.jetbrains.kotlin.idea.configuration.getBuildSystemType
import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.roots.invalidateProjectRoots
import org.jetbrains.kotlin.psi.KtFile
sealed class ChangeGeneralLanguageFeatureSupportFix(
element: PsiElement,
feature: LanguageFeature,
featureSupport: LanguageFeature.State
) : AbstractChangeFeatureSupportLevelFix(element, feature, featureSupport, feature.presentableName) {
class InModule(
element: PsiElement,
feature: LanguageFeature,
featureSupport: LanguageFeature.State
) : ChangeGeneralLanguageFeatureSupportFix(element, feature, featureSupport) {
override fun getText() = "${super.getText()} in the current module"
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
val module = ModuleUtilCore.findModuleForPsiElement(file) ?: return
findApplicableConfigurator(module).changeGeneralFeatureConfiguration(module, feature, featureSupport)
}
}
class InProject(
element: PsiElement,
feature: LanguageFeature,
featureSupport: LanguageFeature.State
) : ChangeGeneralLanguageFeatureSupportFix(element, feature, featureSupport) {
override fun getText() = "${super.getText()} in the project"
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
if (featureSupportEnabled) {
if (!checkUpdateRuntime(project, feature.sinceApiVersion)) return
}
KotlinCompilerSettings.getInstance(project).update {
// TODO: JPS, project
}
project.invalidateProjectRoots()
}
}
companion object : FeatureSupportIntentionActionsFactory() {
private val supportedFeatures = listOf(LanguageFeature.InlineClasses)
fun getFixText(feature: LanguageFeature, state: LanguageFeature.State) = getFixText(state, feature.presentableName)
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction> {
val module = ModuleUtilCore.findModuleForPsiElement(diagnostic.psiElement) ?: return emptyList()
fun shouldConfigureInProject(): Boolean {
val facetSettings = KotlinFacet.get(module)?.configuration?.settings
return (facetSettings == null || facetSettings.useProjectSettings) &&
module.getBuildSystemType() == BuildSystemType.JPS
}
return supportedFeatures.flatMap { feature ->
doCreateActions(
diagnostic, feature, allowWarningAndErrorMode = false,
quickFixConstructor = if (shouldConfigureInProject()) ::InProject else ::InModule
)
}
}
}
}
@@ -36,6 +36,9 @@ class JvmQuickFixRegistrar : QuickFixContributor {
EXPERIMENTAL_FEATURE_ERROR.registerFactory(ChangeCoroutineSupportFix)
EXPERIMENTAL_FEATURE_WARNING.registerFactory(ChangeCoroutineSupportFix)
EXPERIMENTAL_FEATURE_ERROR.registerFactory(ChangeGeneralLanguageFeatureSupportFix)
EXPERIMENTAL_FEATURE_WARNING.registerFactory(ChangeGeneralLanguageFeatureSupportFix)
NO_REFLECTION_IN_CLASS_PATH.registerFactory(AddReflectionQuickFix)
MISSING_SCRIPT_BASE_CLASS.registerFactory(AddScriptRuntimeQuickFix)