Move Declarations: Forbid inside non-top-level declarations. Show error hint instead of window when invoked from editor
#KT-8993 Fixed #KT-8777 Fixed
This commit is contained in:
+21
-11
@@ -34,25 +34,30 @@ import org.jetbrains.kotlin.idea.core.getPackage
|
|||||||
import org.jetbrains.kotlin.idea.core.refactoring.isInJavaSourceRoot
|
import org.jetbrains.kotlin.idea.core.refactoring.isInJavaSourceRoot
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.ui.MoveKotlinTopLevelDeclarationsDialog
|
import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.ui.MoveKotlinTopLevelDeclarationsDialog
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import java.util.LinkedHashSet
|
import java.util.*
|
||||||
|
|
||||||
public class MoveKotlinTopLevelDeclarationsHandler : MoveHandlerDelegate() {
|
public class MoveKotlinTopLevelDeclarationsHandler : MoveHandlerDelegate() {
|
||||||
private fun getSourceDirectories(elements: Array<out PsiElement>) = elements.mapTo(LinkedHashSet()) { it.containingFile?.parent }
|
private fun getSourceDirectories(elements: Array<out PsiElement>) = elements.mapTo(LinkedHashSet()) { it.containingFile?.parent }
|
||||||
|
|
||||||
private fun doMoveWithCheck(
|
private fun doMoveWithCheck(
|
||||||
project: Project, elements: Array<out PsiElement>, targetContainer: PsiElement?, callback: MoveCallback?
|
project: Project, elements: Array<out PsiElement>, targetContainer: PsiElement?, callback: MoveCallback?, editor: Editor?
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (!CommonRefactoringUtil.checkReadOnlyStatusRecursively(project, elements.toList(), true)) return false
|
if (!CommonRefactoringUtil.checkReadOnlyStatusRecursively(project, elements.toList(), true)) return false
|
||||||
if (getSourceDirectories(elements).singleOrNull() == null) {
|
if (getSourceDirectories(elements).singleOrNull() == null) {
|
||||||
CommonRefactoringUtil.showErrorMessage(RefactoringBundle.message("move.title"),
|
CommonRefactoringUtil.showErrorHint(
|
||||||
"All declarations must belong to the same directory",
|
project, editor, "All declarations must belong to the same directory", MOVE_DECLARATIONS, null
|
||||||
null,
|
)
|
||||||
project)
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
val elementsToSearch = elements.mapTo(LinkedHashSet()) { it as JetNamedDeclaration }
|
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 targetPackageName = MoveClassesOrPackagesImpl.getInitialTargetPackageName(targetContainer, elements)
|
||||||
val targetDirectory = MoveClassesOrPackagesImpl.getInitialTargetDirectory(targetContainer, elements)
|
val targetDirectory = MoveClassesOrPackagesImpl.getInitialTargetDirectory(targetContainer, elements)
|
||||||
val searchInComments = JavaRefactoringSettings.getInstance()!!.MOVE_SEARCH_IN_COMMENTS
|
val searchInComments = JavaRefactoringSettings.getInstance()!!.MOVE_SEARCH_IN_COMMENTS
|
||||||
@@ -67,25 +72,29 @@ public class MoveKotlinTopLevelDeclarationsHandler : MoveHandlerDelegate() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun canMove(elements: Array<out PsiElement>, targetContainer: PsiElement?): Boolean {
|
private fun canMove(elements: Array<out PsiElement>, targetContainer: PsiElement?, editorMode: Boolean): Boolean {
|
||||||
if (!super.canMove(elements, targetContainer)) return false
|
if (!super.canMove(elements, targetContainer)) return false
|
||||||
if (getSourceDirectories(elements).singleOrNull() == null) return false
|
if (getSourceDirectories(elements).singleOrNull() == null) return false
|
||||||
|
|
||||||
return elements.all { e ->
|
return elements.all { e ->
|
||||||
if (e is JetClass || (e is JetObjectDeclaration && !e.isObjectLiteral()) || e is JetNamedFunction || e is JetProperty) {
|
if (e is JetClass || (e is JetObjectDeclaration && !e.isObjectLiteral()) || e is JetNamedFunction || e is JetProperty) {
|
||||||
val parent = e.parent
|
val parent = e.parent
|
||||||
parent is JetFile && parent.isInJavaSourceRoot()
|
(editorMode || parent is JetFile) && parent.isInJavaSourceRoot()
|
||||||
}
|
}
|
||||||
else false
|
else false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun canMove(elements: Array<out PsiElement>, targetContainer: PsiElement?): Boolean {
|
||||||
|
return canMove(elements, targetContainer, false)
|
||||||
|
}
|
||||||
|
|
||||||
override fun isValidTarget(psiElement: PsiElement?, sources: Array<out PsiElement>): Boolean {
|
override fun isValidTarget(psiElement: PsiElement?, sources: Array<out PsiElement>): Boolean {
|
||||||
return psiElement is PsiPackage || (psiElement is PsiDirectory && psiElement.getPackage() != null) || psiElement is JetFile
|
return psiElement is PsiPackage || (psiElement is PsiDirectory && psiElement.getPackage() != null) || psiElement is JetFile
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doMove(project: Project, elements: Array<out PsiElement>, targetContainer: PsiElement?, callback: MoveCallback?) {
|
override fun doMove(project: Project, elements: Array<out PsiElement>, targetContainer: PsiElement?, callback: MoveCallback?) {
|
||||||
doMoveWithCheck(project, elements, targetContainer, callback)
|
doMoveWithCheck(project, elements, targetContainer, callback, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tryToMove(
|
override fun tryToMove(
|
||||||
@@ -93,7 +102,8 @@ public class MoveKotlinTopLevelDeclarationsHandler : MoveHandlerDelegate() {
|
|||||||
): Boolean {
|
): Boolean {
|
||||||
val elementsToMove = arrayOf(element)
|
val elementsToMove = arrayOf(element)
|
||||||
val targetContainer = dataContext?.let { dataContext -> LangDataKeys.TARGET_PSI_ELEMENT.getData(dataContext) }
|
val targetContainer = dataContext?.let { dataContext -> LangDataKeys.TARGET_PSI_ELEMENT.getData(dataContext) }
|
||||||
|
return canMove(elementsToMove, targetContainer, true) && doMoveWithCheck(project, elementsToMove, targetContainer, null, editor)
|
||||||
return canMove(elementsToMove, targetContainer) && doMoveWithCheck(project, elementsToMove, targetContainer, null)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val MOVE_DECLARATIONS = "Move Declarations"
|
||||||
Reference in New Issue
Block a user