From c493a76cfbfc8a4bb3d3f2118b23555c34aded19 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 3 Sep 2015 21:15:59 +0300 Subject: [PATCH] Move Declarations: Forbid inside non-top-level declarations. Show error hint instead of window when invoked from editor #KT-8993 Fixed #KT-8777 Fixed --- .../MoveKotlinTopLevelDeclarationsHandler.kt | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveKotlinTopLevelDeclarationsHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveKotlinTopLevelDeclarationsHandler.kt index 9e0791be73c..d558de76a95 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveKotlinTopLevelDeclarationsHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveKotlinTopLevelDeclarationsHandler.kt @@ -34,25 +34,30 @@ import org.jetbrains.kotlin.idea.core.getPackage import org.jetbrains.kotlin.idea.core.refactoring.isInJavaSourceRoot import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.ui.MoveKotlinTopLevelDeclarationsDialog import org.jetbrains.kotlin.psi.* -import java.util.LinkedHashSet +import java.util.* public class MoveKotlinTopLevelDeclarationsHandler : MoveHandlerDelegate() { private fun getSourceDirectories(elements: Array) = elements.mapTo(LinkedHashSet()) { it.containingFile?.parent } private fun doMoveWithCheck( - project: Project, elements: Array, targetContainer: PsiElement?, callback: MoveCallback? + project: Project, elements: Array, targetContainer: PsiElement?, callback: MoveCallback?, editor: Editor? ): Boolean { if (!CommonRefactoringUtil.checkReadOnlyStatusRecursively(project, elements.toList(), true)) return false if (getSourceDirectories(elements).singleOrNull() == null) { - CommonRefactoringUtil.showErrorMessage(RefactoringBundle.message("move.title"), - "All declarations must belong to the same directory", - null, - project) + CommonRefactoringUtil.showErrorHint( + project, editor, "All declarations must belong to the same directory", MOVE_DECLARATIONS, null + ) return false } val elementsToSearch = elements.mapTo(LinkedHashSet()) { it as JetNamedDeclaration } + if (elementsToSearch.any { it.parent !is JetFile }) { + val message = RefactoringBundle.getCannotRefactorMessage("Move declaration is only supported for top-level declarations") + CommonRefactoringUtil.showErrorHint(project, editor, message, MOVE_DECLARATIONS, null) + return true + } + val targetPackageName = MoveClassesOrPackagesImpl.getInitialTargetPackageName(targetContainer, elements) val targetDirectory = MoveClassesOrPackagesImpl.getInitialTargetDirectory(targetContainer, elements) val searchInComments = JavaRefactoringSettings.getInstance()!!.MOVE_SEARCH_IN_COMMENTS @@ -67,25 +72,29 @@ public class MoveKotlinTopLevelDeclarationsHandler : MoveHandlerDelegate() { return true } - override fun canMove(elements: Array, targetContainer: PsiElement?): Boolean { + private fun canMove(elements: Array, targetContainer: PsiElement?, editorMode: Boolean): Boolean { if (!super.canMove(elements, targetContainer)) return false if (getSourceDirectories(elements).singleOrNull() == null) return false return elements.all { e -> if (e is JetClass || (e is JetObjectDeclaration && !e.isObjectLiteral()) || e is JetNamedFunction || e is JetProperty) { val parent = e.parent - parent is JetFile && parent.isInJavaSourceRoot() + (editorMode || parent is JetFile) && parent.isInJavaSourceRoot() } else false } } + override fun canMove(elements: Array, targetContainer: PsiElement?): Boolean { + return canMove(elements, targetContainer, false) + } + override fun isValidTarget(psiElement: PsiElement?, sources: Array): Boolean { return psiElement is PsiPackage || (psiElement is PsiDirectory && psiElement.getPackage() != null) || psiElement is JetFile } override fun doMove(project: Project, elements: Array, targetContainer: PsiElement?, callback: MoveCallback?) { - doMoveWithCheck(project, elements, targetContainer, callback) + doMoveWithCheck(project, elements, targetContainer, callback, null) } override fun tryToMove( @@ -93,7 +102,8 @@ public class MoveKotlinTopLevelDeclarationsHandler : MoveHandlerDelegate() { ): Boolean { val elementsToMove = arrayOf(element) val targetContainer = dataContext?.let { dataContext -> LangDataKeys.TARGET_PSI_ELEMENT.getData(dataContext) } - - return canMove(elementsToMove, targetContainer) && doMoveWithCheck(project, elementsToMove, targetContainer, null) + return canMove(elementsToMove, targetContainer, true) && doMoveWithCheck(project, elementsToMove, targetContainer, null, editor) } } + +private val MOVE_DECLARATIONS = "Move Declarations" \ No newline at end of file