diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt index 76f600216e3..418b691dbdd 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt @@ -9,12 +9,10 @@ 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.openapi.roots.ex.ProjectRootManagerEx import com.intellij.psi.PsiElement import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.diagnostics.Diagnostic -import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder import org.jetbrains.kotlin.idea.configuration.BuildSystemType import org.jetbrains.kotlin.idea.configuration.findApplicableConfigurator @@ -24,11 +22,9 @@ import org.jetbrains.kotlin.idea.roots.invalidateProjectRoots import org.jetbrains.kotlin.psi.KtFile sealed class ChangeCoroutineSupportFix( - element: PsiElement, - protected val coroutineSupport: LanguageFeature.State -) : KotlinQuickFixAction(element) { - protected val coroutineSupportEnabled: Boolean - get() = coroutineSupport == LanguageFeature.State.ENABLED || coroutineSupport == LanguageFeature.State.ENABLED_WITH_WARNING + element: PsiElement, + coroutineSupport: LanguageFeature.State +) : AbstractChangeFeatureSupportLevelFix(element, LanguageFeature.Coroutines, coroutineSupport, shortFeatureName) { class InModule(element: PsiElement, coroutineSupport: LanguageFeature.State) : ChangeCoroutineSupportFix(element, coroutineSupport) { override fun getText() = "${super.getText()} in the current module" @@ -36,7 +32,7 @@ sealed class ChangeCoroutineSupportFix( override fun invoke(project: Project, editor: Editor?, file: KtFile) { val module = ModuleUtilCore.findModuleForPsiElement(file) ?: return - findApplicableConfigurator(module).changeCoroutineConfiguration(module, coroutineSupport) + findApplicableConfigurator(module).changeCoroutineConfiguration(module, featureSupport) } } @@ -44,12 +40,12 @@ sealed class ChangeCoroutineSupportFix( override fun getText() = "${super.getText()} in the project" override fun invoke(project: Project, editor: Editor?, file: KtFile) { - if (coroutineSupportEnabled) { + if (featureSupportEnabled) { if (!checkUpdateRuntime(project, LanguageFeature.Coroutines.sinceApiVersion)) return } KotlinCommonCompilerArgumentsHolder.getInstance(project).update { - coroutinesState = when (coroutineSupport) { + coroutinesState = when (featureSupport) { LanguageFeature.State.ENABLED -> CommonCompilerArguments.ENABLE LanguageFeature.State.ENABLED_WITH_WARNING -> CommonCompilerArguments.WARN LanguageFeature.State.ENABLED_WITH_ERROR, LanguageFeature.State.DISABLED -> CommonCompilerArguments.ERROR @@ -60,41 +56,31 @@ sealed class ChangeCoroutineSupportFix( } - override fun getFamilyName() = "Enable/Disable coroutine support" + companion object : FeatureSupportIntentionActionsFactory() { + private const val shortFeatureName = "coroutine" - override fun getText(): String { - return getFixText(coroutineSupport) - } - - companion object : KotlinIntentionActionsFactory() { - fun getFixText(state: LanguageFeature.State): String { - return when (state) { - LanguageFeature.State.ENABLED -> "Enable coroutine support" - LanguageFeature.State.ENABLED_WITH_WARNING -> "Enable coroutine support (with warning)" - LanguageFeature.State.ENABLED_WITH_ERROR, LanguageFeature.State.DISABLED -> "Disable coroutine support" - } - } + fun getFixText(state: LanguageFeature.State) = AbstractChangeFeatureSupportLevelFix.getFixText(state, shortFeatureName) override fun doCreateActions(diagnostic: Diagnostic): List { - val newCoroutineSupports = when (diagnostic.factory) { - Errors.EXPERIMENTAL_FEATURE_ERROR -> { - if (Errors.EXPERIMENTAL_FEATURE_ERROR.cast(diagnostic).a.first != LanguageFeature.Coroutines) return emptyList() - listOf(LanguageFeature.State.ENABLED_WITH_WARNING, LanguageFeature.State.ENABLED) - } - Errors.EXPERIMENTAL_FEATURE_WARNING -> { - if (Errors.EXPERIMENTAL_FEATURE_WARNING.cast(diagnostic).a.first != LanguageFeature.Coroutines) return emptyList() - listOf(LanguageFeature.State.ENABLED, LanguageFeature.State.ENABLED_WITH_ERROR) - } - else -> return emptyList() - } val module = ModuleUtilCore.findModuleForPsiElement(diagnostic.psiElement) ?: return emptyList() - val facetSettings = KotlinFacet.get(module)?.configuration?.settings - val configureInProject = (facetSettings == null || facetSettings.useProjectSettings) && - module.getBuildSystemType() == BuildSystemType.JPS - val quickFixConstructor: (PsiElement, LanguageFeature.State) -> ChangeCoroutineSupportFix = - if (configureInProject) ::InProject else ::InModule - return newCoroutineSupports.map { quickFixConstructor(diagnostic.psiElement, it) } + fun shouldConfigureInProject(): Boolean { + val facetSettings = KotlinFacet.get(module)?.configuration?.settings + return (facetSettings == null || facetSettings.useProjectSettings) && + module.getBuildSystemType() == BuildSystemType.JPS + } + + return doCreateActions( + diagnostic, LanguageFeature.Coroutines, allowWarningAndErrorMode = true, + quickFixConstructor = if (shouldConfigureInProject()) { element, _, coroutineSupport -> + InProject( + element, + coroutineSupport + ) + } else { element, _, coroutineSupport -> + InModule(element, coroutineSupport) + } + ) } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AbstractChangeFeatureSupportLevelFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AbstractChangeFeatureSupportLevelFix.kt new file mode 100644 index 00000000000..04d2a8380f3 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AbstractChangeFeatureSupportLevelFix.kt @@ -0,0 +1,61 @@ +/* + * 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.psi.PsiElement +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.diagnostics.Diagnostic +import org.jetbrains.kotlin.diagnostics.Errors + +abstract class AbstractChangeFeatureSupportLevelFix( + element: PsiElement, + protected val feature: LanguageFeature, + protected val featureSupport: LanguageFeature.State, + private val featureShortName: String = feature.presentableName +) : KotlinQuickFixAction(element) { + protected val featureSupportEnabled: Boolean + get() = featureSupport == LanguageFeature.State.ENABLED || featureSupport == LanguageFeature.State.ENABLED_WITH_WARNING + + final override fun getFamilyName() = "Enable/Disable $featureShortName support" + + override fun getText(): String = getFixText(featureSupport, featureShortName) + + companion object { + fun getFixText(state: LanguageFeature.State, featureShortName: String): String { + return when (state) { + LanguageFeature.State.ENABLED -> "Enable $featureShortName support" + LanguageFeature.State.ENABLED_WITH_WARNING -> "Enable $featureShortName support (with warning)" + LanguageFeature.State.ENABLED_WITH_ERROR, LanguageFeature.State.DISABLED -> "Disable $featureShortName support" + } + } + } + + abstract class FeatureSupportIntentionActionsFactory : KotlinIntentionActionsFactory() { + protected fun doCreateActions( + diagnostic: Diagnostic, + feature: LanguageFeature, + allowWarningAndErrorMode: Boolean, + quickFixConstructor: (PsiElement, LanguageFeature, LanguageFeature.State) -> IntentionAction + ): List { + val newFeatureSupports = when (diagnostic.factory) { + Errors.EXPERIMENTAL_FEATURE_ERROR -> { + if (Errors.EXPERIMENTAL_FEATURE_ERROR.cast(diagnostic).a.first != feature) return emptyList() + if (!allowWarningAndErrorMode) listOf(LanguageFeature.State.ENABLED) + else listOf(LanguageFeature.State.ENABLED_WITH_WARNING, LanguageFeature.State.ENABLED) + } + Errors.EXPERIMENTAL_FEATURE_WARNING -> { + if (Errors.EXPERIMENTAL_FEATURE_WARNING.cast(diagnostic).a.first != feature) return emptyList() + if (!allowWarningAndErrorMode) listOf(LanguageFeature.State.ENABLED) + listOf(LanguageFeature.State.ENABLED, LanguageFeature.State.ENABLED_WITH_ERROR) + } + else -> return emptyList() + } + + return newFeatureSupports.map { quickFixConstructor(diagnostic.psiElement, feature, it) } + } + } +}