Create from Usage: Make 'Create annotation' low-priority action

#KT-9116 Fixed
This commit is contained in:
Alexey Sedunov
2016-01-11 17:16:56 +03:00
parent 70a851fe44
commit e7de6400e5
5 changed files with 52 additions and 29 deletions
@@ -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<E : KtElement, D : Any>(
private val actionPriority: IntentionActionPriority = IntentionActionPriority.NORMAL
@@ -37,18 +38,11 @@ abstract class KotlinSingleIntentionActionFactoryWithDelegate<E : KtElement, D :
diagnostic: Diagnostic,
quickFixDataFactory: () -> D?
): List<QuickFixWithDelegateFactory> {
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()
}
}
@@ -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)
}
}
@@ -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<E : KtElement>(
) : KotlinIntentionActionFactoryWithDelegate<E, List<CallableInfo>>() {
private fun newCallableQuickFix(
originalElementPointer: SmartPsiElementPointer<E>,
lowPriority: Boolean,
priority: IntentionActionPriority,
quickFixDataFactory: () -> List<CallableInfo>?,
quickFixFactory: (E, List<CallableInfo>) -> CreateFromUsageFixBase<E>?
): 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<E : KtElement>(
): List<QuickFixWithDelegateFactory> {
val fixes = ArrayList<QuickFixWithDelegateFactory>(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) }
}
@@ -33,10 +33,10 @@ abstract class CreateClassFromUsageFactory<E : KtElement> : 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))
}
}
@@ -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<ParameterInfo> = Collections.emptyList()
)
class CreateClassFromUsageFix<E : KtElement>(
element: E,
val classInfo: ClassInfo
): CreateFromUsageFixBase<E>(element) {
open class CreateClassFromUsageFix<E : KtElement> protected constructor (element: E, val classInfo: ClassInfo): CreateFromUsageFixBase<E>(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<E : KtElement>(
project.executeCommand(text) { builder.build() }
}
}
private class LowPriorityCreateClassFromUsageFix<E : KtElement>(
element: E,
classInfo: ClassInfo
) : CreateClassFromUsageFix<E>(element, classInfo), LowPriorityAction
private class HighPriorityCreateClassFromUsageFix<E : KtElement>(
element: E,
classInfo: ClassInfo
) : CreateClassFromUsageFix<E>(element, classInfo), HighPriorityAction
companion object {
fun <E : KtElement> create(element: E, classInfo: ClassInfo): CreateClassFromUsageFix<E> {
return when (classInfo.kind.actionPriority) {
IntentionActionPriority.NORMAL -> CreateClassFromUsageFix(element, classInfo)
IntentionActionPriority.LOW -> LowPriorityCreateClassFromUsageFix(element, classInfo)
IntentionActionPriority.HIGH -> HighPriorityCreateClassFromUsageFix(element, classInfo)
}
}
}
}