diff --git a/ChangeLog.md b/ChangeLog.md index 4750b20ba26..74194a10360 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -473,6 +473,7 @@ These artifacts include extensions for the types available in the latter JDKs, s ##### New features - [`KT-15068`](https://youtrack.jetbrains.com/issue/KT-15068) Implement intention which rename file according to the top-level class name +- Implement quickfix which enables/disables coroutine support in module or project ## 1.0.6 diff --git a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java index 45d374fda6c..5477a26b2ee 100644 --- a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java +++ b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java @@ -289,9 +289,11 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co public void apply() throws ConfigurationException { commonCompilerArguments.suppressWarnings = generateNoWarningsCheckBox.isSelected(); if (isProjectSettings) { - boolean languageVersionChanged = commonCompilerArguments.languageVersion != getSelectedLanguageVersion(); + boolean shouldInvalidateCaches = + commonCompilerArguments.languageVersion != getSelectedLanguageVersion() || + !coroutineSupportComboBox.getSelectedItem().equals(CoroutineSupport.byCompilerArguments(commonCompilerArguments)); commonCompilerArguments.languageVersion = getSelectedLanguageVersion(); - if (languageVersionChanged) { + if (shouldInvalidateCaches) { ApplicationUtilsKt.runWriteAction( new Function0() { @Override diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt new file mode 100644 index 00000000000..9933836f196 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt @@ -0,0 +1,95 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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.openapi.roots.ModuleRootModificationUtil +import com.intellij.openapi.roots.ex.ProjectRootManagerEx +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.config.CoroutineSupport +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.diagnostics.Diagnostic +import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.idea.KotlinPluginUtil +import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder +import org.jetbrains.kotlin.idea.facet.KotlinFacet +import org.jetbrains.kotlin.psi.KtFile + +sealed class ChangeCoroutineSupportFix( + element: PsiElement, + protected val coroutineSupport: CoroutineSupport +) : KotlinQuickFixAction(element) { + class InModule(element: PsiElement, coroutineSupport: CoroutineSupport) : ChangeCoroutineSupportFix(element, coroutineSupport) { + override fun getText() = "${super.getText()} in the current module" + + override fun invoke(project: Project, editor: Editor?, file: KtFile) { + val module = ModuleUtilCore.findModuleForPsiElement(file) ?: return + val facetSettings = KotlinFacet.get(module)?.configuration?.settings ?: return + ModuleRootModificationUtil.updateModel(module) { + facetSettings.compilerInfo.coroutineSupport = coroutineSupport + } + } + } + + class InProject(element: PsiElement, coroutineSupport: CoroutineSupport) : ChangeCoroutineSupportFix(element, coroutineSupport) { + override fun getText() = "${super.getText()} in the project" + + override fun invoke(project: Project, editor: Editor?, file: KtFile) { + with (KotlinCommonCompilerArgumentsHolder.getInstance(project).settings) { + coroutinesEnable = coroutineSupport == CoroutineSupport.ENABLED + coroutinesWarn = coroutineSupport == CoroutineSupport.ENABLED_WITH_WARNING + coroutinesError = coroutineSupport == CoroutineSupport.DISABLED + } + ProjectRootManagerEx.getInstanceEx(project).makeRootsChange({}, false, true) + } + } + + override fun getFamilyName() = "Enable/Disable coroutine support" + + override fun getText(): String { + return when (coroutineSupport) { + CoroutineSupport.DISABLED -> "Disable coroutine support" + CoroutineSupport.ENABLED_WITH_WARNING -> "Enable coroutine support (with warning)" + CoroutineSupport.ENABLED -> "Enable coroutine support" + } + } + + companion object : KotlinIntentionActionsFactory() { + override fun doCreateActions(diagnostic: Diagnostic): List { + val newCoroutineSupports = when (diagnostic.factory) { + Errors.EXPERIMENTAL_FEATURE_ERROR -> { + if (Errors.EXPERIMENTAL_FEATURE_ERROR.cast(diagnostic).a != LanguageFeature.Coroutines) return emptyList() + listOf(CoroutineSupport.ENABLED_WITH_WARNING, CoroutineSupport.ENABLED) + } + Errors.EXPERIMENTAL_FEATURE_WARNING -> { + if (Errors.EXPERIMENTAL_FEATURE_WARNING.cast(diagnostic).a != LanguageFeature.Coroutines) return emptyList() + listOf(CoroutineSupport.ENABLED, CoroutineSupport.DISABLED) + } + else -> return emptyList() + } + val module = ModuleUtilCore.findModuleForPsiElement(diagnostic.psiElement) ?: return emptyList() + if (KotlinPluginUtil.isGradleModule(module) || KotlinPluginUtil.isMavenModule(module)) return emptyList() + val facetSettings = KotlinFacet.get(module)?.configuration?.settings + val quickFixConstructor: (PsiElement, CoroutineSupport) -> ChangeCoroutineSupportFix = + if (facetSettings == null || facetSettings.useProjectSettings) ::InProject else ::InModule + return newCoroutineSupports.map { quickFixConstructor(diagnostic.psiElement, it) } + } + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index 4bfc3026cc8..a03fe85221d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -469,5 +469,8 @@ class QuickFixRegistrar : QuickFixContributor { ErrorsJs.WRONG_EXTERNAL_DECLARATION.registerFactory(MigrateExternalExtensionFix) UNSUPPORTED_FEATURE.registerFactory(EnableUnsupportedFeatureFix) + + EXPERIMENTAL_FEATURE_ERROR.registerFactory(ChangeCoroutineSupportFix) + EXPERIMENTAL_FEATURE_WARNING.registerFactory(ChangeCoroutineSupportFix) } }