Refactor Move refactoring

This commit is contained in:
Igor Yakovlev
2020-03-30 15:49:31 +03:00
parent a9de0a219b
commit 5414b9dfb3
7 changed files with 40 additions and 32 deletions
@@ -930,6 +930,8 @@ text.member.extension.call.will.not.be.processed.0=Member extension call won''t
text.move.declaration.no.support.for.companion.objects=Move declaration is not supported for companion objects
text.move.declaration.no.support.for.enums=Move declaration is not supported for enum entries
text.move.declaration.supports.only.top.levels.and.nested.classes=Move declaration is only supported for top-level declarations and nested classes
text.move.declaration.proceed.move.without.mpp.counterparts.text=This refactoring will move selected declaration without it's expect/actual counterparts that may lead to compilation errors.\nDo you wish to proceed?
text.move.declaration.proceed.move.without.mpp.counterparts.title=MPP declarations does not supported by this refactoring.
text.move.declarations=Move declarations
text.move.file.0=Move {0}
text.move.refactoring.not.available.during.indexing=Move refactoring is not available while indexing is in progress
@@ -172,11 +172,11 @@ class MoveKotlinDeclarationsHandler internal constructor(private val handlerActi
}
val initialTargetDirectory = MoveFilesOrDirectoriesUtil.resolveToDirectory(project, initialTargetElement)
if (!ApplicationManager.getApplication().isUnitTestMode && elementsToSearch.any { it.isExpectDeclaration() || it.isEffectivelyActual() }
if (!ApplicationManager.getApplication().isUnitTestMode &&
elementsToSearch.any { it.isExpectDeclaration() || it.isEffectivelyActual() }
) {
val message = RefactoringBundle.getCannotRefactorMessage(
"This refactoring will move selected declaration without it's expect/actual counterparts that may lead to compilation errors.\n\"Do you wish to proceed?\"")
val title = RefactoringBundle.getCannotRefactorMessage("MPP declarations does not supported by this refactoring.")
val message = RefactoringBundle.getCannotRefactorMessage(KotlinBundle.message("text.move.declaration.proceed.move.without.mpp.counterparts.text"))
val title = RefactoringBundle.getCannotRefactorMessage(KotlinBundle.message("text.move.declaration.proceed.move.without.mpp.counterparts.title"))
val proceedWithIncompleteRefactoring = Messages.showYesNoDialog(project, message, title, Messages.getWarningIcon())
if (proceedWithIncompleteRefactoring != Messages.YES) return true
}
@@ -40,7 +40,6 @@ import org.jetbrains.kotlin.idea.refactoring.isInKotlinAwareSourceRoot
import org.jetbrains.kotlin.idea.refactoring.move.logFusForMoveRefactoring
import org.jetbrains.kotlin.idea.util.application.executeCommand
import org.jetbrains.kotlin.psi.KtFile
import java.util.*
import javax.swing.JComponent
class KotlinAwareMoveFilesOrDirectoriesDialog(
@@ -66,6 +65,12 @@ class KotlinAwareMoveFilesOrDirectoriesDialog(
!ApplicationManager.getApplication().isUnitTestMode && PropertiesComponent.getInstance().getBoolean(id, defaultValue)
}
private data class CheckboxesState(
val searchReferences: Boolean,
val openInEditor: Boolean,
val updatePackageDirective: Boolean
)
private val nameLabel = JBLabelDecorator.createJBLabelDecorator().setBold(true)
private val targetDirectoryField = TextFieldWithHistoryWithBrowseButton()
private val searchReferencesCb = NonFocusableCheckBox(KotlinBundle.message("checkbox.text.search.references")).apply {
@@ -73,7 +78,7 @@ class KotlinAwareMoveFilesOrDirectoriesDialog(
}
private val openInEditorCb = NonFocusableCheckBox(KotlinBundle.message("checkbox.text.open.moved.files.in.editor"))
private val updatePackageDirectiveCb = NonFocusableCheckBox()
private val initializedCheckBoxesState: BitSet
private val initializedCheckBoxesState: CheckboxesState
override fun getHelpId() = HELP_ID
@@ -85,11 +90,11 @@ class KotlinAwareMoveFilesOrDirectoriesDialog(
initializedCheckBoxesState = getCheckboxesState(applyDefaults = true)
}
private fun getCheckboxesState(applyDefaults: Boolean) = BitSet(3).apply {
set(0, applyDefaults || searchReferencesCb.isSelected) //searchReferencesCb is true by default
set(1, !applyDefaults && openInEditorCb.isSelected) //openInEditorCb is false by default
set(2, updatePackageDirectiveCb.isSelected)
}
private fun getCheckboxesState(applyDefaults: Boolean) = CheckboxesState(
searchReferences = applyDefaults || searchReferencesCb.isSelected, //searchReferencesCb is true by default
openInEditor = !applyDefaults && openInEditorCb.isSelected, //openInEditorCb is false by default
updatePackageDirective = updatePackageDirectiveCb.isSelected
)
override fun createActions() = arrayOf(okAction, cancelAction, helpAction)
@@ -212,11 +217,11 @@ class KotlinAwareMoveFilesOrDirectoriesDialog(
project.executeCommand(MoveHandler.REFACTORING_NAME) {
with(modelResult) {
logFusForMoveRefactoring(
elementsCount,
entityToMove,
destination,
getCheckboxesState(applyDefaults = false) == initializedCheckBoxesState,
Runnable { processor.run() }
numberOfEntities = elementsCount,
entity = entityToMove,
destination = destination,
isDefault = getCheckboxesState(applyDefaults = false) == initializedCheckBoxesState,
body = processor
)
}
}
@@ -180,7 +180,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
@NotNull Set<KtNamedDeclaration> elementsToMove,
@NotNull List<KtNamedDeclaration> declarations
) {
////KotlinMemberInfo run resolve on declaration so it is good to place it to the process
//KotlinMemberInfo run resolve on declaration so it is good to place it to the process
List<KotlinMemberInfo> memberInfos = MoveUtilsKt.mapWithReadActionInProcess(declarations, myProject, MoveHandler.REFACTORING_NAME, (declaration) -> {
KotlinMemberInfo memberInfo = new KotlinMemberInfo(declaration, false);
memberInfo.setChecked(elementsToMove.contains(declaration));
@@ -336,7 +336,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
}
private boolean isMPPDeclarationInList(List<KtNamedDeclaration> declarations) {
for(KtNamedDeclaration element : declarations) {
for (KtNamedDeclaration element : declarations) {
if (ExpectActualUtilKt.isEffectivelyActual(element, true) ||
ExpectActualUtilKt.isExpectDeclaration(element)) {
return true;
@@ -219,14 +219,16 @@ internal class MoveKotlinTopLevelDeclarationsModel(
}
private fun getFUSParameters(): Pair<MovedEntity, MoveRefactoringDestination> {
val classType = if (elementsToMoveHasMPP) MovedEntity.MPPCLASSES else MovedEntity.CLASSES
val functionType = if (elementsToMoveHasMPP) MovedEntity.MPPFUNCTIONS else MovedEntity.FUNCTIONS
val mixedType = if (elementsToMoveHasMPP) MovedEntity.MPPMIXED else MovedEntity.MIXED
val (classType, functionType, mixedType) =
if (elementsToMoveHasMPP)
Triple(MovedEntity.MPPCLASSES, MovedEntity.MPPFUNCTIONS, MovedEntity.MPPMIXED)
else
Triple(MovedEntity.CLASSES, MovedEntity.FUNCTIONS, MovedEntity.MIXED)
val allClasses = elementsToMove.any { element -> element is KtClassOrObject }
val allFunctions = elementsToMove.any { element -> element is KtFunction }
val entity = if (allClasses && allFunctions) mixedType else
if (allClasses) classType else functionType
val classesAreGoingToMove = elementsToMove.any { it is KtClassOrObject }
val functionsAreGoingToMove = elementsToMove.any { it is KtFunction }
val entity = if (classesAreGoingToMove && functionsAreGoingToMove) mixedType else
if (classesAreGoingToMove) classType else functionType
val destination = if (isMoveToPackage) MoveRefactoringDestination.PACKAGE else MoveRefactoringDestination.FILE
@@ -79,7 +79,7 @@ class KotlinMoveFilesOrDirectoriesHandler : MoveFilesOrDirectoriesHandlerCompat(
entityToMove,
destination,
true,
Runnable { processor.run() }
processor
)
} else {
processor.run()
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.idea.refactoring.move
import com.intellij.ide.util.DirectoryUtil
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.Task
@@ -43,6 +42,7 @@ import org.jetbrains.kotlin.idea.references.KtSimpleNameReference.ShorteningMode
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.statistics.MoveRefactoringFUSCollector
import org.jetbrains.kotlin.idea.util.application.executeCommand
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
import org.jetbrains.kotlin.name.FqName
@@ -720,15 +720,14 @@ internal fun <T> List<KtNamedDeclaration>.mapWithReadActionInProcess(
val result = mutableListOf<T>()
val task: Task.Modal = object : Task.Modal(project, title, false) {
override fun run(indicator: ProgressIndicator) {
val count = 0
val fraction: Double = 1.0 / declarations.size
indicator.fraction = 0.0
ApplicationManager.getApplication().runReadAction(Runnable {
for (declaration in declarations) {
runReadAction {
declarations.forEachIndexed { index, declaration ->
result.add(body(declaration))
indicator.fraction = fraction * count
indicator.fraction = fraction * index
}
})
}
}
}
ProgressManager.getInstance().run(task)