diff --git a/idea/src/org/jetbrains/kotlin/idea/actions/JetAddFunctionToClassifierAction.kt b/idea/src/org/jetbrains/kotlin/idea/actions/JetAddFunctionToClassifierAction.kt index 50183eef250..f594da5fe89 100644 --- a/idea/src/org/jetbrains/kotlin/idea/actions/JetAddFunctionToClassifierAction.kt +++ b/idea/src/org/jetbrains/kotlin/idea/actions/JetAddFunctionToClassifierAction.kt @@ -16,9 +16,6 @@ package org.jetbrains.kotlin.idea.actions -import com.intellij.codeInsight.hint.QuestionAction -import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.command.CommandProcessor import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import com.intellij.openapi.ui.popup.JBPopupFactory @@ -36,10 +33,10 @@ import org.jetbrains.kotlin.idea.JetBundle import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.idea.util.ShortenReferences +import org.jetbrains.kotlin.idea.util.application.executeWriteCommand import org.jetbrains.kotlin.psi.JetClass import org.jetbrains.kotlin.psi.JetNamedFunction import org.jetbrains.kotlin.psi.JetPsiFactory -import java.util.* /** * Changes method signature to one of provided signatures. @@ -48,14 +45,8 @@ import java.util.* class JetAddFunctionToClassifierAction( private val project: Project, private val editor: Editor?, - functionsToAdd: List -) : QuestionAction { - private val functionsToAdd: List - - init { - this.functionsToAdd = ArrayList(functionsToAdd) - } - + private val functionsToAdd: List +) { private fun addFunction( project: Project, typeDescriptor: ClassDescriptor, @@ -66,57 +57,40 @@ class JetAddFunctionToClassifierAction( PsiDocumentManager.getInstance(project).commitAllDocuments() val classifierDeclaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, typeDescriptor) as JetClass - CommandProcessor.getInstance().executeCommand(project, object : Runnable { - override fun run() { - ApplicationManager.getApplication().runWriteAction(object : Runnable { - override fun run() { - val psiFactory = JetPsiFactory(classifierDeclaration) - val body = classifierDeclaration.getOrCreateBody() - var functionBody = "" - if (typeDescriptor.kind != ClassKind.INTERFACE && functionDescriptor.modality != Modality.ABSTRACT) { - functionBody = "{}" - val returnType = functionDescriptor.returnType - if (returnType == null || !KotlinBuiltIns.isUnit(returnType)) { - functionBody = "{ throw UnsupportedOperationException() }" - } - } - val functionElement = psiFactory.createFunction(signatureString + functionBody) - val anchor = body.rBrace - val insertedFunctionElement = body.addBefore(functionElement, anchor) as JetNamedFunction + project.executeWriteCommand(JetBundle.message("add.function.to.type.action")) { + val body = classifierDeclaration.getOrCreateBody() - ShortenReferences.DEFAULT.process(insertedFunctionElement) - } - }) + var functionBody = "" + if (typeDescriptor.kind != ClassKind.INTERFACE && functionDescriptor.modality != Modality.ABSTRACT) { + functionBody = "{}" + val returnType = functionDescriptor.returnType + if (returnType == null || !KotlinBuiltIns.isUnit(returnType)) { + functionBody = "{ throw UnsupportedOperationException() }" + } } - }, JetBundle.message("add.function.to.type.action"), null) + val functionElement = JetPsiFactory(project).createFunction(signatureString + functionBody) + val insertedFunctionElement = body.addBefore(functionElement, body.rBrace) as JetNamedFunction + + ShortenReferences.DEFAULT.process(insertedFunctionElement) + } } - override fun execute(): Boolean { - if (functionsToAdd.isEmpty()) { - return false - } + fun execute() { + if (functionsToAdd.isEmpty()) return if (functionsToAdd.size == 1 || editor == null || !editor.component.isShowing) { addFunction(functionsToAdd.get(0)) } else { - chooseFunctionAndAdd() + JBPopupFactory.getInstance().createListPopup(functionPopup).showInBestPositionFor(editor) } - - return true - } - - private fun chooseFunctionAndAdd() { - JBPopupFactory.getInstance().createListPopup(functionPopup).showInBestPositionFor(editor!!) } private val functionPopup: ListPopupStep<*> get() { return object : BaseListPopupStep(JetBundle.message("add.function.to.type.action.type.chooser"), functionsToAdd) { - override fun isAutoSelectionEnabled(): Boolean { - return false - } + override fun isAutoSelectionEnabled() = false override fun onChosen(selectedValue: FunctionDescriptor, finalChoice: Boolean): PopupStep? { if (finalChoice) { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionToSupertypeFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionToSupertypeFix.kt index 02ced3d5723..241fe913cce 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionToSupertypeFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionToSupertypeFix.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.idea.quickfix -import com.google.common.collect.Lists import com.intellij.codeInsight.intention.IntentionAction import com.intellij.openapi.command.CommandProcessor import com.intellij.openapi.editor.Editor @@ -34,12 +33,12 @@ import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.JetNamedFunction import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.types.JetType -import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.checker.JetTypeChecker +import org.jetbrains.kotlin.types.typeUtil.supertypes import java.util.* class AddFunctionToSupertypeFix(element: JetNamedFunction) : JetHintAction(element) { - private val functionsToAdd: List = generateFunctionsToAdd(element) + private val functionsToAdd = generateFunctionsToAdd(element) override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean { return super.isAvailable(project, editor, file) && !functionsToAdd.isEmpty() @@ -48,11 +47,11 @@ class AddFunctionToSupertypeFix(element: JetNamedFunction) : JetHintAction { val functionDescriptor = functionElement.resolveToDescriptor() as FunctionDescriptor val containingClass = functionDescriptor.containingDeclaration as? ClassDescriptor ?: return emptyList() - val functions = ArrayList() // TODO: filter out impossible supertypes (for example when argument's type isn't visible in a superclass). - for (supertypeDescriptor in getSupertypes(containingClass)) { - if (KotlinBuiltIns.isAnyOrNullableAny(supertypeDescriptor.defaultType)) continue - functions.add(generateFunctionSignatureForType(functionDescriptor, supertypeDescriptor)) - } - return functions + return getSupertypes(containingClass) + .filterNot { KotlinBuiltIns.isAnyOrNullableAny(it.defaultType) } + .map { generateFunctionSignatureForType(functionDescriptor, it) } } private fun getSupertypes(classDescriptor: ClassDescriptor): List { - val supertypes = Lists.newArrayList(TypeUtils.getAllSupertypes(classDescriptor.defaultType)) - Collections.sort(supertypes, object : Comparator { + val supertypes = classDescriptor.defaultType.supertypes().sortedWith(object : Comparator { override fun compare(o1: JetType, o2: JetType): Int { - if (o1 == o2) { - return 0 + return when { + o1 == o2 -> 0 + JetTypeChecker.DEFAULT.isSubtypeOf(o1, o2) -> -1 + JetTypeChecker.DEFAULT.isSubtypeOf(o2, o1) -> 1 + else -> o1.toString().compareTo(o2.toString()) } - if (JetTypeChecker.DEFAULT.isSubtypeOf(o1, o2)) { - return -1 - } - if (JetTypeChecker.DEFAULT.isSubtypeOf(o2, o1)) { - return 1 - } - return o1.toString().compareTo(o2.toString()) } }) - val supertypesDescriptors = Lists.newArrayList() - for (supertype in supertypes) { - supertypesDescriptors.add(DescriptorUtils.getClassDescriptorForType(supertype)) - } - return supertypesDescriptors + + return supertypes.map { DescriptorUtils.getClassDescriptorForType(it) } } - private fun generateFunctionSignatureForType( - functionDescriptor: FunctionDescriptor, - typeDescriptor: ClassDescriptor): FunctionDescriptor { + private fun generateFunctionSignatureForType(functionDescriptor: FunctionDescriptor, typeDescriptor: ClassDescriptor): FunctionDescriptor { // TODO: support for generics. - var modality = typeDescriptor.modality - if (typeDescriptor.kind == ClassKind.INTERFACE) { - modality = Modality.OPEN - } + + val modality = if (typeDescriptor.kind == ClassKind.INTERFACE) Modality.OPEN else typeDescriptor.modality + return functionDescriptor.copy( typeDescriptor, modality, @@ -128,14 +116,5 @@ class AddFunctionToSupertypeFix(element: JetNamedFunction) : JetHintAction