From e7de6400e521e02888c88d60d591699b4af51278 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 11 Jan 2016 17:16:56 +0300 Subject: [PATCH] Create from Usage: Make 'Create annotation' low-priority action #KT-9116 Fixed --- ...otlinIntentionActionFactoryWithDelegate.kt | 18 +++------ .../quickfix/QuickFixWithDelegateFactory.kt | 8 ++++ .../CreateCallableMemberFromUsageFactory.kt | 13 +++---- .../CreateClassFromUsageFactory.kt | 4 +- .../createClass/CreateClassFromUsageFix.kt | 38 +++++++++++++++---- 5 files changed, 52 insertions(+), 29 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/KotlinIntentionActionFactoryWithDelegate.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/KotlinIntentionActionFactoryWithDelegate.kt index e12d763115f..56876841b6f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/KotlinIntentionActionFactoryWithDelegate.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/KotlinIntentionActionFactoryWithDelegate.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode +import org.jetbrains.kotlin.utils.addToStdlib.singletonList abstract class KotlinSingleIntentionActionFactoryWithDelegate( private val actionPriority: IntentionActionPriority = IntentionActionPriority.NORMAL @@ -37,18 +38,11 @@ abstract class KotlinSingleIntentionActionFactoryWithDelegate D? ): List { - fun createAction(): IntentionAction? { - val originalElement = originalElementPointer.element ?: return null - val data = quickFixDataFactory() ?: return null - return createFix(originalElement, data) - } - - val delegateFactory = when (actionPriority) { - IntentionActionPriority.NORMAL -> QuickFixWithDelegateFactory(::createAction) - IntentionActionPriority.HIGH -> HighPriorityQuickFixWithDelegateFactory(::createAction) - IntentionActionPriority.LOW -> LowPriorityQuickFixWithDelegateFactory(::createAction) - } - return listOf(delegateFactory) + return QuickFixWithDelegateFactory(actionPriority) factory@ { + val originalElement = originalElementPointer.element ?: return@factory null + val data = quickFixDataFactory() ?: return@factory null + createFix(originalElement, data) + }.singletonList() } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixWithDelegateFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixWithDelegateFactory.kt index af5923ceebf..ffab4cdb897 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixWithDelegateFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixWithDelegateFactory.kt @@ -77,4 +77,12 @@ fun IntentionAction.detectPriority(): IntentionActionPriority { is HighPriorityAction -> IntentionActionPriority.HIGH else -> IntentionActionPriority.NORMAL } +} + +fun QuickFixWithDelegateFactory(priority: IntentionActionPriority, createAction: () -> IntentionAction?): QuickFixWithDelegateFactory { + return when (priority) { + IntentionActionPriority.NORMAL -> QuickFixWithDelegateFactory(createAction) + IntentionActionPriority.HIGH -> HighPriorityQuickFixWithDelegateFactory(createAction) + IntentionActionPriority.LOW -> LowPriorityQuickFixWithDelegateFactory(createAction) + } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableMemberFromUsageFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableMemberFromUsageFactory.kt index 5908c23ac4b..f7727403ff9 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableMemberFromUsageFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableMemberFromUsageFactory.kt @@ -18,8 +18,8 @@ package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable import com.intellij.psi.SmartPsiElementPointer import org.jetbrains.kotlin.diagnostics.Diagnostic +import org.jetbrains.kotlin.idea.quickfix.IntentionActionPriority import org.jetbrains.kotlin.idea.quickfix.KotlinIntentionActionFactoryWithDelegate -import org.jetbrains.kotlin.idea.quickfix.LowPriorityQuickFixWithDelegateFactory import org.jetbrains.kotlin.idea.quickfix.QuickFixWithDelegateFactory import org.jetbrains.kotlin.idea.quickfix.createFromUsage.CreateFromUsageFixBase import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.CallableInfo @@ -34,16 +34,15 @@ abstract class CreateCallableMemberFromUsageFactory( ) : KotlinIntentionActionFactoryWithDelegate>() { private fun newCallableQuickFix( originalElementPointer: SmartPsiElementPointer, - lowPriority: Boolean, + priority: IntentionActionPriority, quickFixDataFactory: () -> List?, quickFixFactory: (E, List) -> CreateFromUsageFixBase? ): QuickFixWithDelegateFactory { - val delegateFactory = { + return QuickFixWithDelegateFactory(priority) { val data = quickFixDataFactory().orEmpty() val originalElement = originalElementPointer.element if (data.isNotEmpty() && originalElement != null) quickFixFactory(originalElement, data) else null } - return if (lowPriority) LowPriorityQuickFixWithDelegateFactory(delegateFactory) else QuickFixWithDelegateFactory(delegateFactory) } protected open fun createCallableInfo(element: E, diagnostic: Diagnostic): CallableInfo? = null @@ -58,18 +57,18 @@ abstract class CreateCallableMemberFromUsageFactory( ): List { val fixes = ArrayList(3) - newCallableQuickFix(originalElementPointer, false, quickFixDataFactory) { element, data -> + newCallableQuickFix(originalElementPointer, IntentionActionPriority.NORMAL, quickFixDataFactory) { element, data -> CreateCallableFromUsageFix(element, data) }.let { fixes.add(it) } - newCallableQuickFix(originalElementPointer, false, quickFixDataFactory) f@ { element, data -> + newCallableQuickFix(originalElementPointer, IntentionActionPriority.NORMAL, quickFixDataFactory) f@ { element, data -> (data.singleOrNull() as? PropertyInfo)?.let { CreateParameterFromUsageFix.createFixForPrimaryConstructorPropertyParameter(element, it) } }.let { fixes.add(it) } if (extensionsSupported) { - newCallableQuickFix(originalElementPointer, true, quickFixDataFactory) { element, data -> + newCallableQuickFix(originalElementPointer, IntentionActionPriority.LOW, quickFixDataFactory) { element, data -> CreateExtensionCallableFromUsageFix(element, data) }.let { fixes.add(it) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromUsageFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromUsageFactory.kt index ead2d4c8660..bc876076299 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromUsageFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromUsageFactory.kt @@ -33,10 +33,10 @@ abstract class CreateClassFromUsageFactory : KotlinIntentionActio val possibleClassKinds = getPossibleClassKinds(originalElementPointer.element ?: return emptyList(), diagnostic) val classFixes = possibleClassKinds.map { classKind -> - QuickFixWithDelegateFactory { + QuickFixWithDelegateFactory(classKind.actionPriority) { val currentElement = originalElementPointer.element ?: return@QuickFixWithDelegateFactory null val data = quickFixDataFactory() ?: return@QuickFixWithDelegateFactory null - CreateClassFromUsageFix(currentElement, data.copy(kind = classKind)) + CreateClassFromUsageFix.create(currentElement, data.copy(kind = classKind)) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromUsageFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromUsageFix.kt index 944d798c5df..937340584da 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromUsageFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromUsageFix.kt @@ -16,6 +16,8 @@ package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass +import com.intellij.codeInsight.intention.HighPriorityAction +import com.intellij.codeInsight.intention.LowPriorityAction import com.intellij.ide.util.DirectoryChooserUtil import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.editor.Editor @@ -27,16 +29,16 @@ import com.intellij.psi.PsiFile import com.intellij.psi.PsiPackage import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils -import org.jetbrains.kotlin.idea.refactoring.canRefactor -import org.jetbrains.kotlin.idea.refactoring.getOrCreateKotlinFile +import org.jetbrains.kotlin.idea.quickfix.IntentionActionPriority import org.jetbrains.kotlin.idea.quickfix.createFromUsage.CreateFromUsageFixBase import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.* import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.ClassKind.* +import org.jetbrains.kotlin.idea.refactoring.canRefactor +import org.jetbrains.kotlin.idea.refactoring.getOrCreateKotlinFile import org.jetbrains.kotlin.idea.util.application.executeCommand import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile -import java.util.Collections -import java.util.HashMap +import java.util.* enum class ClassKind(val keyword: String, val description: String) { PLAIN_CLASS("class", "class"), @@ -48,6 +50,9 @@ enum class ClassKind(val keyword: String, val description: String) { DEFAULT("", "") // Used as a placeholder and must be replaced with one of the kinds above } +val ClassKind.actionPriority: IntentionActionPriority + get() = if (this == ANNOTATION_CLASS) IntentionActionPriority.LOW else IntentionActionPriority.NORMAL + data class ClassInfo( val kind: ClassKind = ClassKind.DEFAULT, val name: String, @@ -59,10 +64,7 @@ data class ClassInfo( val parameterInfos: List = Collections.emptyList() ) -class CreateClassFromUsageFix( - element: E, - val classInfo: ClassInfo -): CreateFromUsageFixBase(element) { +open class CreateClassFromUsageFix protected constructor (element: E, val classInfo: ClassInfo): CreateFromUsageFixBase(element) { override fun getText() = "Create ${classInfo.kind.description} '${classInfo.name}'" override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean { @@ -125,4 +127,24 @@ class CreateClassFromUsageFix( project.executeCommand(text) { builder.build() } } } + + private class LowPriorityCreateClassFromUsageFix( + element: E, + classInfo: ClassInfo + ) : CreateClassFromUsageFix(element, classInfo), LowPriorityAction + + private class HighPriorityCreateClassFromUsageFix( + element: E, + classInfo: ClassInfo + ) : CreateClassFromUsageFix(element, classInfo), HighPriorityAction + + companion object { + fun create(element: E, classInfo: ClassInfo): CreateClassFromUsageFix { + return when (classInfo.kind.actionPriority) { + IntentionActionPriority.NORMAL -> CreateClassFromUsageFix(element, classInfo) + IntentionActionPriority.LOW -> LowPriorityCreateClassFromUsageFix(element, classInfo) + IntentionActionPriority.HIGH -> HighPriorityCreateClassFromUsageFix(element, classInfo) + } + } + } }