Add FUS support to move refactoring
This commit is contained in:
committed by
Igor Yakovlev
parent
f489eda0e7
commit
8877559c02
+42
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.statistics
|
||||||
|
|
||||||
|
object MoveRefactoringFUSCollector {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param isDefault is something changed in Move Refactoring Dialog check-boxes state
|
||||||
|
*/
|
||||||
|
fun log(
|
||||||
|
timeStarted: Long,
|
||||||
|
timeFinished: Long,
|
||||||
|
numberOfEntities: Int,
|
||||||
|
entity: MovedEntity,
|
||||||
|
destination: MoveRefactoringDestination,
|
||||||
|
isDefault: Boolean,
|
||||||
|
isSucceeded: Boolean
|
||||||
|
) {
|
||||||
|
|
||||||
|
val data = mapOf(
|
||||||
|
"lagging" to (timeFinished - timeStarted).toString(),
|
||||||
|
"entity" to entity.toString(),
|
||||||
|
"destination" to destination.toString(),
|
||||||
|
"number_of_entities" to numberOfEntities.toString(),
|
||||||
|
"are_settings_changed" to isDefault.toString(),
|
||||||
|
"succeeded" to isSucceeded.toString()
|
||||||
|
)
|
||||||
|
|
||||||
|
KotlinFUSLogger.log(FUSEventGroups.Refactoring, "Move", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class MoveRefactoringDestination {
|
||||||
|
PACKAGE, FILE, DECLARATION
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class MovedEntity {
|
||||||
|
FUNCTIONS, CLASSES, MIXED, MPPCLASSES, MPPFUNCTIONS, MPPMIXED, PACKAGE, FILES
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -95,7 +95,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
|||||||
<statistics.counterUsagesCollector groupId="kotlin.maven.target" version="3"/>
|
<statistics.counterUsagesCollector groupId="kotlin.maven.target" version="3"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.jps.target" version="3"/>
|
<statistics.counterUsagesCollector groupId="kotlin.jps.target" version="3"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.gradle.library" version="1"/>
|
<statistics.counterUsagesCollector groupId="kotlin.gradle.library" version="1"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.ide.action.refactoring" version="1"/>
|
<statistics.counterUsagesCollector groupId="kotlin.ide.refactoring" version="1"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.ide.newFileTempl" version="1"/>
|
<statistics.counterUsagesCollector groupId="kotlin.ide.newFileTempl" version="1"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.ide.npwizards" version="2"/>
|
<statistics.counterUsagesCollector groupId="kotlin.ide.npwizards" version="2"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.ide.debugger" version="2"/>
|
<statistics.counterUsagesCollector groupId="kotlin.ide.debugger" version="2"/>
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
|||||||
<statistics.counterUsagesCollector groupId="kotlin.maven.target" version="3"/>
|
<statistics.counterUsagesCollector groupId="kotlin.maven.target" version="3"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.jps.target" version="3"/>
|
<statistics.counterUsagesCollector groupId="kotlin.jps.target" version="3"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.gradle.library" version="1"/>
|
<statistics.counterUsagesCollector groupId="kotlin.gradle.library" version="1"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.ide.action.refactoring" version="1"/>
|
<statistics.counterUsagesCollector groupId="kotlin.ide.refactoring" version="1"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.ide.newFileTempl" version="1"/>
|
<statistics.counterUsagesCollector groupId="kotlin.ide.newFileTempl" version="1"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.ide.npwizards" version="2"/>
|
<statistics.counterUsagesCollector groupId="kotlin.ide.npwizards" version="2"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.ide.debugger" version="2"/>
|
<statistics.counterUsagesCollector groupId="kotlin.ide.debugger" version="2"/>
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
|||||||
<statistics.counterUsagesCollector groupId="kotlin.maven.target" version="3"/>
|
<statistics.counterUsagesCollector groupId="kotlin.maven.target" version="3"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.jps.target" version="3"/>
|
<statistics.counterUsagesCollector groupId="kotlin.jps.target" version="3"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.gradle.library" version="1"/>
|
<statistics.counterUsagesCollector groupId="kotlin.gradle.library" version="1"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.ide.action.refactoring" version="1"/>
|
<statistics.counterUsagesCollector groupId="kotlin.ide.refactoring" version="1"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.ide.newFileTempl" version="1"/>
|
<statistics.counterUsagesCollector groupId="kotlin.ide.newFileTempl" version="1"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.ide.npwizards" version="2"/>
|
<statistics.counterUsagesCollector groupId="kotlin.ide.npwizards" version="2"/>
|
||||||
<statistics.counterUsagesCollector groupId="kotlin.ide.debugger" version="2"/>
|
<statistics.counterUsagesCollector groupId="kotlin.ide.debugger" version="2"/>
|
||||||
|
|||||||
+4
-4
@@ -104,7 +104,7 @@ internal class MoveKotlinDeclarationsHandlerTestActions(private val caseDataKeep
|
|||||||
|
|
||||||
caseDataKeeper.caseData = model.testDataString()
|
caseDataKeeper.caseData = model.testDataString()
|
||||||
|
|
||||||
model.computeModelResult(throwOnConflicts = true).run()
|
model.computeModelResult(throwOnConflicts = true).processor.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doWithMoveKotlinNestedClassesToUpperLevelModel(nestedClass: KtClassOrObject, targetContainer: PsiElement?) {
|
private fun doWithMoveKotlinNestedClassesToUpperLevelModel(nestedClass: KtClassOrObject, targetContainer: PsiElement?) {
|
||||||
@@ -135,7 +135,7 @@ internal class MoveKotlinDeclarationsHandlerTestActions(private val caseDataKeep
|
|||||||
|
|
||||||
caseDataKeeper.caseData = model.testDataString()
|
caseDataKeeper.caseData = model.testDataString()
|
||||||
|
|
||||||
model.computeModelResult(throwOnConflicts = true).run()
|
model.computeModelResult(throwOnConflicts = true).processor.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invokeMoveKotlinNestedClassesRefactoring(
|
override fun invokeMoveKotlinNestedClassesRefactoring(
|
||||||
@@ -188,7 +188,7 @@ internal class MoveKotlinDeclarationsHandlerTestActions(private val caseDataKeep
|
|||||||
|
|
||||||
caseDataKeeper.caseData = model.testDataString()
|
caseDataKeeper.caseData = model.testDataString()
|
||||||
|
|
||||||
model.computeModelResult(throwOnConflicts = true).run()
|
model.computeModelResult(throwOnConflicts = true).processor.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invokeKotlinSelectNestedClassChooser(nestedClass: KtClassOrObject, targetContainer: PsiElement?) {
|
override fun invokeKotlinSelectNestedClassChooser(nestedClass: KtClassOrObject, targetContainer: PsiElement?) {
|
||||||
@@ -236,7 +236,7 @@ internal class MoveKotlinDeclarationsHandlerTestActions(private val caseDataKeep
|
|||||||
caseDataKeeper.caseData = model.testDataString()
|
caseDataKeeper.caseData = model.testDataString()
|
||||||
|
|
||||||
project.executeCommand(MoveHandler.REFACTORING_NAME) {
|
project.executeCommand(MoveHandler.REFACTORING_NAME) {
|
||||||
model.computeModelResult().run()
|
model.computeModelResult().processor.run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+13
-3
@@ -6,11 +6,21 @@
|
|||||||
package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui
|
package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui
|
||||||
|
|
||||||
import com.intellij.openapi.options.ConfigurationException
|
import com.intellij.openapi.options.ConfigurationException
|
||||||
|
import com.intellij.refactoring.BaseRefactoringProcessor
|
||||||
|
import org.jetbrains.kotlin.idea.statistics.MoveRefactoringFUSCollector.MovedEntity
|
||||||
|
import org.jetbrains.kotlin.idea.statistics.MoveRefactoringFUSCollector.MoveRefactoringDestination
|
||||||
|
|
||||||
internal interface Model<out T> {
|
internal class ModelResultWithFUSData(
|
||||||
|
val processor: BaseRefactoringProcessor,
|
||||||
|
val elementsCount: Int,
|
||||||
|
val entityToMove: MovedEntity,
|
||||||
|
val destination: MoveRefactoringDestination
|
||||||
|
)
|
||||||
|
|
||||||
|
internal interface Model {
|
||||||
@Throws(ConfigurationException::class)
|
@Throws(ConfigurationException::class)
|
||||||
fun computeModelResult(throwOnConflicts: Boolean = false): T
|
fun computeModelResult(throwOnConflicts: Boolean = false): ModelResultWithFUSData
|
||||||
|
|
||||||
@Throws(ConfigurationException::class)
|
@Throws(ConfigurationException::class)
|
||||||
fun computeModelResult(): T
|
fun computeModelResult(): ModelResultWithFUSData
|
||||||
}
|
}
|
||||||
+28
-7
@@ -18,7 +18,10 @@ import com.intellij.openapi.ui.DialogWrapper
|
|||||||
import com.intellij.openapi.ui.TextComponentAccessor
|
import com.intellij.openapi.ui.TextComponentAccessor
|
||||||
import com.intellij.openapi.util.Disposer
|
import com.intellij.openapi.util.Disposer
|
||||||
import com.intellij.openapi.vfs.LocalFileSystem
|
import com.intellij.openapi.vfs.LocalFileSystem
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.PsiDirectory
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
|
import com.intellij.psi.PsiFileSystemItem
|
||||||
|
import com.intellij.psi.PsiManager
|
||||||
import com.intellij.refactoring.RefactoringBundle
|
import com.intellij.refactoring.RefactoringBundle
|
||||||
import com.intellij.refactoring.copy.CopyFilesOrDirectoriesDialog
|
import com.intellij.refactoring.copy.CopyFilesOrDirectoriesDialog
|
||||||
import com.intellij.refactoring.copy.CopyFilesOrDirectoriesHandler
|
import com.intellij.refactoring.copy.CopyFilesOrDirectoriesHandler
|
||||||
@@ -34,9 +37,10 @@ import org.jetbrains.kotlin.idea.KotlinBundle
|
|||||||
import org.jetbrains.kotlin.idea.core.packageMatchesDirectoryOrImplicit
|
import org.jetbrains.kotlin.idea.core.packageMatchesDirectoryOrImplicit
|
||||||
import org.jetbrains.kotlin.idea.core.util.onTextChange
|
import org.jetbrains.kotlin.idea.core.util.onTextChange
|
||||||
import org.jetbrains.kotlin.idea.refactoring.isInKotlinAwareSourceRoot
|
import org.jetbrains.kotlin.idea.refactoring.isInKotlinAwareSourceRoot
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.KotlinAwareMoveFilesOrDirectoriesProcessor
|
import org.jetbrains.kotlin.idea.refactoring.move.logFusForMoveRefactoring
|
||||||
import org.jetbrains.kotlin.idea.util.application.executeCommand
|
import org.jetbrains.kotlin.idea.util.application.executeCommand
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import java.util.*
|
||||||
import javax.swing.JComponent
|
import javax.swing.JComponent
|
||||||
|
|
||||||
class KotlinAwareMoveFilesOrDirectoriesDialog(
|
class KotlinAwareMoveFilesOrDirectoriesDialog(
|
||||||
@@ -69,6 +73,7 @@ class KotlinAwareMoveFilesOrDirectoriesDialog(
|
|||||||
}
|
}
|
||||||
private val openInEditorCb = NonFocusableCheckBox(KotlinBundle.message("checkbox.text.open.moved.files.in.editor"))
|
private val openInEditorCb = NonFocusableCheckBox(KotlinBundle.message("checkbox.text.open.moved.files.in.editor"))
|
||||||
private val updatePackageDirectiveCb = NonFocusableCheckBox()
|
private val updatePackageDirectiveCb = NonFocusableCheckBox()
|
||||||
|
private val initializedCheckBoxesState: BitSet
|
||||||
|
|
||||||
override fun getHelpId() = HELP_ID
|
override fun getHelpId() = HELP_ID
|
||||||
|
|
||||||
@@ -76,6 +81,14 @@ class KotlinAwareMoveFilesOrDirectoriesDialog(
|
|||||||
title = RefactoringBundle.message("move.title")
|
title = RefactoringBundle.message("move.title")
|
||||||
init()
|
init()
|
||||||
initializeData()
|
initializeData()
|
||||||
|
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createActions() = arrayOf(okAction, cancelAction, helpAction)
|
override fun createActions() = arrayOf(okAction, cancelAction, helpAction)
|
||||||
@@ -163,7 +176,7 @@ class KotlinAwareMoveFilesOrDirectoriesDialog(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getModel(): Model<KotlinAwareMoveFilesOrDirectoriesProcessor> {
|
private fun getModel(): Model {
|
||||||
|
|
||||||
val directory = LocalFileSystem.getInstance().findFileByPath(selectedDirectoryName)?.let {
|
val directory = LocalFileSystem.getInstance().findFileByPath(selectedDirectoryName)?.let {
|
||||||
PsiManager.getInstance(project).findDirectory(it)
|
PsiManager.getInstance(project).findDirectory(it)
|
||||||
@@ -188,20 +201,28 @@ class KotlinAwareMoveFilesOrDirectoriesDialog(
|
|||||||
|
|
||||||
override fun doOKAction() {
|
override fun doOKAction() {
|
||||||
|
|
||||||
val processor: KotlinAwareMoveFilesOrDirectoriesProcessor
|
val modelResult: ModelResultWithFUSData
|
||||||
try {
|
try {
|
||||||
processor = getModel().computeModelResult()
|
modelResult = getModel().computeModelResult()
|
||||||
} catch (e: ConfigurationException) {
|
} catch (e: ConfigurationException) {
|
||||||
setErrorText(e.message)
|
setErrorText(e.message)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
project.executeCommand(MoveHandler.REFACTORING_NAME) {
|
project.executeCommand(MoveHandler.REFACTORING_NAME) {
|
||||||
processor.run()
|
with(modelResult) {
|
||||||
|
logFusForMoveRefactoring(
|
||||||
|
elementsCount,
|
||||||
|
entityToMove,
|
||||||
|
destination,
|
||||||
|
getCheckboxesState(applyDefaults = false) == initializedCheckBoxesState,
|
||||||
|
Runnable { processor.run() }
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setConfigurationValue(id = MOVE_FILES_OPEN_IN_EDITOR, value = openInEditorCb.isSelected, defaultValue = false)
|
|
||||||
setConfigurationValue(id = MOVE_FILES_SEARCH_REFERENCES, value = searchReferencesCb.isSelected, defaultValue = true)
|
setConfigurationValue(id = MOVE_FILES_SEARCH_REFERENCES, value = searchReferencesCb.isSelected, defaultValue = true)
|
||||||
|
setConfigurationValue(id = MOVE_FILES_OPEN_IN_EDITOR, value = openInEditorCb.isSelected, defaultValue = false)
|
||||||
|
|
||||||
RecentsManager.getInstance(project).registerRecentEntry(RECENT_KEYS, targetDirectoryField.childComponent.text)
|
RecentsManager.getInstance(project).registerRecentEntry(RECENT_KEYS, targetDirectoryField.childComponent.text)
|
||||||
|
|
||||||
|
|||||||
+15
-5
@@ -20,19 +20,20 @@ import org.jetbrains.kotlin.idea.refactoring.isInKotlinAwareSourceRoot
|
|||||||
import org.jetbrains.kotlin.idea.refactoring.move.getOrCreateDirectory
|
import org.jetbrains.kotlin.idea.refactoring.move.getOrCreateDirectory
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.KotlinAwareMoveFilesOrDirectoriesProcessor
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.KotlinAwareMoveFilesOrDirectoriesProcessor
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.updatePackageDirective
|
import org.jetbrains.kotlin.idea.refactoring.move.updatePackageDirective
|
||||||
|
import org.jetbrains.kotlin.idea.statistics.MoveRefactoringFUSCollector
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import java.nio.file.InvalidPathException
|
import java.nio.file.InvalidPathException
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
|
||||||
class KotlinAwareMoveFilesOrDirectoriesModel(
|
internal class KotlinAwareMoveFilesOrDirectoriesModel(
|
||||||
val project: Project,
|
val project: Project,
|
||||||
val elementsToMove: List<PsiFileSystemItem>,
|
val elementsToMove: List<PsiFileSystemItem>,
|
||||||
val targetDirectoryName: String,
|
val targetDirectoryName: String,
|
||||||
val updatePackageDirective: Boolean,
|
val updatePackageDirective: Boolean,
|
||||||
val searchReferences: Boolean,
|
val searchReferences: Boolean,
|
||||||
val moveCallback: MoveCallback?
|
val moveCallback: MoveCallback?
|
||||||
) : Model<KotlinAwareMoveFilesOrDirectoriesProcessor> {
|
) : Model {
|
||||||
|
|
||||||
private fun checkedGetElementsToMove(selectedDirectory: PsiDirectory): List<PsiElement> {
|
private fun checkedGetElementsToMove(selectedDirectory: PsiDirectory): List<PsiElement> {
|
||||||
|
|
||||||
@@ -94,20 +95,29 @@ class KotlinAwareMoveFilesOrDirectoriesModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Throws(ConfigurationException::class)
|
@Throws(ConfigurationException::class)
|
||||||
override fun computeModelResult(throwOnConflicts: Boolean): KotlinAwareMoveFilesOrDirectoriesProcessor {
|
override fun computeModelResult(throwOnConflicts: Boolean): ModelResultWithFUSData {
|
||||||
|
|
||||||
checkModel()
|
checkModel()
|
||||||
|
|
||||||
val selectedDir = checkedGetTargetDirectory()
|
val selectedDir = checkedGetTargetDirectory()
|
||||||
|
|
||||||
return KotlinAwareMoveFilesOrDirectoriesProcessor(
|
val elementsToMove = checkedGetElementsToMove(selectedDir)
|
||||||
|
|
||||||
|
val processor = KotlinAwareMoveFilesOrDirectoriesProcessor(
|
||||||
project,
|
project,
|
||||||
checkedGetElementsToMove(selectedDir),
|
elementsToMove,
|
||||||
selectedDir,
|
selectedDir,
|
||||||
searchReferences = searchReferences,
|
searchReferences = searchReferences,
|
||||||
searchInComments = false,
|
searchInComments = false,
|
||||||
searchInNonJavaFiles = false,
|
searchInNonJavaFiles = false,
|
||||||
moveCallback = moveCallback
|
moveCallback = moveCallback
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return ModelResultWithFUSData(
|
||||||
|
processor,
|
||||||
|
elementsToMove.size,
|
||||||
|
MoveRefactoringFUSCollector.MovedEntity.FILES,
|
||||||
|
MoveRefactoringFUSCollector.MoveRefactoringDestination.PACKAGE
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+18
-5
@@ -34,7 +34,7 @@ import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringUtilKt;
|
|||||||
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfo;
|
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfo;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionPanel;
|
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionPanel;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionTable;
|
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionTable;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*;
|
import org.jetbrains.kotlin.idea.refactoring.move.MoveUtilsKt;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.ui.KotlinTypeReferenceEditorComboWithBrowseButton;
|
import org.jetbrains.kotlin.idea.refactoring.ui.KotlinTypeReferenceEditorComboWithBrowseButton;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
@@ -82,6 +82,13 @@ public class MoveKotlinNestedClassesDialog extends RefactoringDialog {
|
|||||||
validateButtons();
|
validateButtons();
|
||||||
|
|
||||||
myHelpAction.setEnabled(false);
|
myHelpAction.setEnabled(false);
|
||||||
|
|
||||||
|
initializedCheckBoxesState = getCheckboxesState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int initializedCheckBoxesState;
|
||||||
|
private int getCheckboxesState() {
|
||||||
|
return openInEditorCheckBox.isSelected() ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initClassChooser(@NotNull KtClassOrObject initialTargetClass) {
|
private void initClassChooser(@NotNull KtClassOrObject initialTargetClass) {
|
||||||
@@ -217,7 +224,7 @@ public class MoveKotlinNestedClassesDialog extends RefactoringDialog {
|
|||||||
return "#" + getClass().getName();
|
return "#" + getClass().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Model<MoveKotlinDeclarationsProcessor> getModel() {
|
private Model getModel() {
|
||||||
return new MoveKotlinNestedClassesModel(
|
return new MoveKotlinNestedClassesModel(
|
||||||
myProject,
|
myProject,
|
||||||
openInEditorCheckBox.isSelected(),
|
openInEditorCheckBox.isSelected(),
|
||||||
@@ -230,16 +237,22 @@ public class MoveKotlinNestedClassesDialog extends RefactoringDialog {
|
|||||||
@Override
|
@Override
|
||||||
protected void doAction() {
|
protected void doAction() {
|
||||||
|
|
||||||
MoveKotlinDeclarationsProcessor processor;
|
ModelResultWithFUSData modelResult;
|
||||||
try {
|
try {
|
||||||
processor = getModel().computeModelResult();
|
modelResult = getModel().computeModelResult();
|
||||||
}
|
}
|
||||||
catch (ConfigurationException e) {
|
catch (ConfigurationException e) {
|
||||||
setErrorText(e.getMessage());
|
setErrorText(e.getMessage());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeRefactoring(processor);
|
MoveUtilsKt.logFusForMoveRefactoring(
|
||||||
|
modelResult.getElementsCount(),
|
||||||
|
modelResult.getEntityToMove(),
|
||||||
|
modelResult.getDestination(),
|
||||||
|
getCheckboxesState() == initializedCheckBoxesState,
|
||||||
|
() -> invokeRefactoring(modelResult.getProcessor())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+12
-3
@@ -13,6 +13,8 @@ import com.intellij.refactoring.RefactoringBundle
|
|||||||
import com.intellij.refactoring.move.MoveCallback
|
import com.intellij.refactoring.move.MoveCallback
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*
|
||||||
|
import org.jetbrains.kotlin.idea.statistics.MoveRefactoringFUSCollector.MoveRefactoringDestination
|
||||||
|
import org.jetbrains.kotlin.idea.statistics.MoveRefactoringFUSCollector.MovedEntity
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
|
|
||||||
@@ -23,7 +25,7 @@ internal class MoveKotlinNestedClassesModel(
|
|||||||
val originalClass: KtClassOrObject,
|
val originalClass: KtClassOrObject,
|
||||||
val targetClass: PsiElement?,
|
val targetClass: PsiElement?,
|
||||||
val moveCallback: MoveCallback?
|
val moveCallback: MoveCallback?
|
||||||
) : Model<MoveKotlinDeclarationsProcessor> {
|
) : Model {
|
||||||
|
|
||||||
private fun getCheckedTargetClass(): KtElement {
|
private fun getCheckedTargetClass(): KtElement {
|
||||||
val targetClass = this.targetClass ?: throw ConfigurationException(RefactoringBundle.message("no.destination.class.specified"))
|
val targetClass = this.targetClass ?: throw ConfigurationException(RefactoringBundle.message("no.destination.class.specified"))
|
||||||
@@ -51,7 +53,7 @@ internal class MoveKotlinNestedClassesModel(
|
|||||||
override fun computeModelResult() = computeModelResult(throwOnConflicts = false)
|
override fun computeModelResult() = computeModelResult(throwOnConflicts = false)
|
||||||
|
|
||||||
@Throws(ConfigurationException::class)
|
@Throws(ConfigurationException::class)
|
||||||
override fun computeModelResult(throwOnConflicts: Boolean): MoveKotlinDeclarationsProcessor {
|
override fun computeModelResult(throwOnConflicts: Boolean): ModelResultWithFUSData {
|
||||||
val elementsToMove = selectedElementsToMove
|
val elementsToMove = selectedElementsToMove
|
||||||
val target = KotlinMoveTargetForExistingElement(getCheckedTargetClass())
|
val target = KotlinMoveTargetForExistingElement(getCheckedTargetClass())
|
||||||
val delegate = MoveDeclarationsDelegate.NestedClass()
|
val delegate = MoveDeclarationsDelegate.NestedClass()
|
||||||
@@ -67,6 +69,13 @@ internal class MoveKotlinNestedClassesModel(
|
|||||||
openInEditor = openInEditorCheckBox
|
openInEditor = openInEditorCheckBox
|
||||||
)
|
)
|
||||||
|
|
||||||
return MoveKotlinDeclarationsProcessor(descriptor, Mover.Default, throwOnConflicts)
|
val processor = MoveKotlinDeclarationsProcessor(descriptor, Mover.Default, throwOnConflicts)
|
||||||
|
|
||||||
|
return ModelResultWithFUSData(
|
||||||
|
processor,
|
||||||
|
elementsToMove.size,
|
||||||
|
MovedEntity.CLASSES,
|
||||||
|
MoveRefactoringDestination.DECLARATION
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+26
-5
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.idea.core.KotlinNameSuggester;
|
|||||||
import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator;
|
import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringSettings;
|
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringSettings;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.MoveUtilsKt;
|
import org.jetbrains.kotlin.idea.refactoring.move.MoveUtilsKt;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveKotlinDeclarationsProcessor;
|
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
import org.jetbrains.kotlin.psi.KtClass;
|
import org.jetbrains.kotlin.psi.KtClass;
|
||||||
import org.jetbrains.kotlin.psi.KtClassBody;
|
import org.jetbrains.kotlin.psi.KtClassBody;
|
||||||
@@ -41,6 +40,7 @@ import org.jetbrains.kotlin.types.KotlinType;
|
|||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.util.BitSet;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -126,6 +126,19 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase {
|
|||||||
return ((ClassDescriptor) innerClassDescriptor.getContainingDeclaration()).getDefaultType();
|
return ((ClassDescriptor) innerClassDescriptor.getContainingDeclaration()).getDefaultType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BitSet initializedCheckBoxesState;
|
||||||
|
private BitSet getCheckboxesState(boolean applyDefaults) {
|
||||||
|
|
||||||
|
BitSet state = new BitSet(3);
|
||||||
|
|
||||||
|
state.set(0, !applyDefaults && searchInCommentsCheckBox.isSelected()); //searchInCommentsCheckBox default is false
|
||||||
|
state.set(1, !applyDefaults && searchForTextOccurrencesCheckBox.isSelected()); //searchForTextOccurrencesCheckBox default is false
|
||||||
|
state.set(2, passOuterClassCheckBox.isSelected());
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void init() {
|
protected void init() {
|
||||||
classNameField.setText(innerClass.getName());
|
classNameField.setText(innerClass.getName());
|
||||||
@@ -182,6 +195,8 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase {
|
|||||||
searchInCommentsCheckBox.setSelected(settings.MOVE_TO_UPPER_LEVEL_SEARCH_IN_COMMENTS);
|
searchInCommentsCheckBox.setSelected(settings.MOVE_TO_UPPER_LEVEL_SEARCH_IN_COMMENTS);
|
||||||
|
|
||||||
super.init();
|
super.init();
|
||||||
|
|
||||||
|
initializedCheckBoxesState = getCheckboxesState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -233,7 +248,7 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Model<MoveKotlinDeclarationsProcessor> getModel() {
|
private Model getModel() {
|
||||||
return new MoveKotlinNestedClassesToUpperLevelModelWithUIChooser(
|
return new MoveKotlinNestedClassesToUpperLevelModelWithUIChooser(
|
||||||
project,
|
project,
|
||||||
innerClass,
|
innerClass,
|
||||||
@@ -251,9 +266,9 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase {
|
|||||||
@Override
|
@Override
|
||||||
protected void doAction() {
|
protected void doAction() {
|
||||||
|
|
||||||
MoveKotlinDeclarationsProcessor processor;
|
ModelResultWithFUSData modelResult;
|
||||||
try {
|
try {
|
||||||
processor = getModel().computeModelResult();
|
modelResult = getModel().computeModelResult();
|
||||||
}
|
}
|
||||||
catch (ConfigurationException e) {
|
catch (ConfigurationException e) {
|
||||||
setErrorText(e.getMessage());
|
setErrorText(e.getMessage());
|
||||||
@@ -266,6 +281,12 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase {
|
|||||||
|
|
||||||
saveOpenInEditorOption();
|
saveOpenInEditorOption();
|
||||||
|
|
||||||
invokeRefactoring(processor);
|
MoveUtilsKt.logFusForMoveRefactoring(
|
||||||
|
modelResult.getElementsCount(),
|
||||||
|
modelResult.getEntityToMove(),
|
||||||
|
modelResult.getDestination(),
|
||||||
|
getCheckboxesState(false).equals(initializedCheckBoxesState),
|
||||||
|
() -> invokeRefactoring(modelResult.getProcessor())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+19
-8
@@ -28,6 +28,8 @@ import org.jetbrains.kotlin.idea.refactoring.createKotlinFile
|
|||||||
import org.jetbrains.kotlin.idea.refactoring.move.getTargetPackageFqName
|
import org.jetbrains.kotlin.idea.refactoring.move.getTargetPackageFqName
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*
|
||||||
import org.jetbrains.kotlin.idea.roots.getSuitableDestinationSourceRoots
|
import org.jetbrains.kotlin.idea.roots.getSuitableDestinationSourceRoots
|
||||||
|
import org.jetbrains.kotlin.idea.statistics.MoveRefactoringFUSCollector.MovedEntity
|
||||||
|
import org.jetbrains.kotlin.idea.statistics.MoveRefactoringFUSCollector.MoveRefactoringDestination
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
@@ -48,7 +50,7 @@ internal abstract class MoveKotlinNestedClassesToUpperLevelModel(
|
|||||||
val isSearchInNonJavaFiles: Boolean,
|
val isSearchInNonJavaFiles: Boolean,
|
||||||
val packageName: String,
|
val packageName: String,
|
||||||
val isOpenInEditor: Boolean
|
val isOpenInEditor: Boolean
|
||||||
) : Model<MoveKotlinDeclarationsProcessor> {
|
) : Model {
|
||||||
|
|
||||||
protected abstract fun chooseSourceRoot(
|
protected abstract fun chooseSourceRoot(
|
||||||
newPackage: PackageWrapper,
|
newPackage: PackageWrapper,
|
||||||
@@ -157,9 +159,9 @@ internal abstract class MoveKotlinNestedClassesToUpperLevelModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Throws(ConfigurationException::class)
|
@Throws(ConfigurationException::class)
|
||||||
private fun getMoveTarget(): KotlinMoveTarget {
|
private fun getMoveTarget(): Pair<KotlinMoveTarget, MoveRefactoringDestination> {
|
||||||
val target = getTargetContainerWithValidation()
|
val target = getTargetContainerWithValidation()
|
||||||
if (target is PsiDirectory) {
|
return if (target is PsiDirectory) {
|
||||||
val targetPackageFqName = getTargetPackageFqName(target)
|
val targetPackageFqName = getTargetPackageFqName(target)
|
||||||
?: throw ConfigurationException(KotlinBundle.message("text.cannot.find.target.package.name"))
|
?: throw ConfigurationException(KotlinBundle.message("text.cannot.find.target.package.name"))
|
||||||
|
|
||||||
@@ -169,13 +171,15 @@ internal abstract class MoveKotlinNestedClassesToUpperLevelModel(
|
|||||||
|
|
||||||
val targetFileName = suggestedName + "." + KotlinFileType.EXTENSION
|
val targetFileName = suggestedName + "." + KotlinFileType.EXTENSION
|
||||||
|
|
||||||
return KotlinMoveTargetForDeferredFile(
|
val target = KotlinMoveTargetForDeferredFile(
|
||||||
targetPackageFqName,
|
targetPackageFqName,
|
||||||
target,
|
target,
|
||||||
targetFile = null
|
targetFile = null
|
||||||
) { createKotlinFile(targetFileName, target, targetPackageFqName.asString()) }
|
) { createKotlinFile(targetFileName, target, targetPackageFqName.asString()) }
|
||||||
|
|
||||||
|
target to MoveRefactoringDestination.FILE
|
||||||
} else {
|
} else {
|
||||||
return KotlinMoveTargetForExistingElement(target as KtElement)
|
KotlinMoveTargetForExistingElement(target as KtElement) to MoveRefactoringDestination.DECLARATION
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +187,7 @@ internal abstract class MoveKotlinNestedClassesToUpperLevelModel(
|
|||||||
override fun computeModelResult() = computeModelResult(throwOnConflicts = false)
|
override fun computeModelResult() = computeModelResult(throwOnConflicts = false)
|
||||||
|
|
||||||
@Throws(ConfigurationException::class)
|
@Throws(ConfigurationException::class)
|
||||||
override fun computeModelResult(throwOnConflicts: Boolean): MoveKotlinDeclarationsProcessor {
|
override fun computeModelResult(throwOnConflicts: Boolean): ModelResultWithFUSData {
|
||||||
|
|
||||||
val moveTarget = getMoveTarget()
|
val moveTarget = getMoveTarget()
|
||||||
|
|
||||||
@@ -192,7 +196,7 @@ internal abstract class MoveKotlinNestedClassesToUpperLevelModel(
|
|||||||
val moveDescriptor = MoveDeclarationsDescriptor(
|
val moveDescriptor = MoveDeclarationsDescriptor(
|
||||||
project,
|
project,
|
||||||
MoveSource(innerClass),
|
MoveSource(innerClass),
|
||||||
moveTarget,
|
moveTarget.first,
|
||||||
delegate,
|
delegate,
|
||||||
searchInComments,
|
searchInComments,
|
||||||
isSearchInNonJavaFiles,
|
isSearchInNonJavaFiles,
|
||||||
@@ -201,6 +205,13 @@ internal abstract class MoveKotlinNestedClassesToUpperLevelModel(
|
|||||||
openInEditor = isOpenInEditor
|
openInEditor = isOpenInEditor
|
||||||
)
|
)
|
||||||
|
|
||||||
return MoveKotlinDeclarationsProcessor(moveDescriptor, Mover.Default, throwOnConflicts)
|
val processor = MoveKotlinDeclarationsProcessor(moveDescriptor, Mover.Default, throwOnConflicts)
|
||||||
|
|
||||||
|
return ModelResultWithFUSData(
|
||||||
|
processor = processor,
|
||||||
|
elementsCount = 1,
|
||||||
|
entityToMove = MovedEntity.CLASSES,
|
||||||
|
destination = moveTarget.second
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-10
@@ -12,7 +12,6 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
|||||||
import com.intellij.openapi.util.Pass;
|
import com.intellij.openapi.util.Pass;
|
||||||
import com.intellij.psi.PsiDirectory;
|
import com.intellij.psi.PsiDirectory;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
import com.intellij.refactoring.BaseRefactoringProcessor;
|
|
||||||
import com.intellij.refactoring.RefactoringBundle;
|
import com.intellij.refactoring.RefactoringBundle;
|
||||||
import com.intellij.refactoring.classMembers.AbstractMemberInfoModel;
|
import com.intellij.refactoring.classMembers.AbstractMemberInfoModel;
|
||||||
import com.intellij.refactoring.classMembers.MemberInfoBase;
|
import com.intellij.refactoring.classMembers.MemberInfoBase;
|
||||||
@@ -42,7 +41,6 @@ import org.jetbrains.kotlin.idea.refactoring.move.MoveUtilsKt;
|
|||||||
import org.jetbrains.kotlin.idea.refactoring.ui.KotlinDestinationFolderComboBox;
|
import org.jetbrains.kotlin.idea.refactoring.ui.KotlinDestinationFolderComboBox;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.ui.KotlinFileChooserDialog;
|
import org.jetbrains.kotlin.idea.refactoring.ui.KotlinFileChooserDialog;
|
||||||
import org.jetbrains.kotlin.idea.util.ExpectActualUtilKt;
|
import org.jetbrains.kotlin.idea.util.ExpectActualUtilKt;
|
||||||
import org.jetbrains.kotlin.psi.KtElement;
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile;
|
import org.jetbrains.kotlin.psi.KtFile;
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration;
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration;
|
||||||
import org.jetbrains.kotlin.psi.KtPureElement;
|
import org.jetbrains.kotlin.psi.KtPureElement;
|
||||||
@@ -51,10 +49,8 @@ import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
|
|||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.idea.roots.ProjectRootUtilsKt.getSuitableDestinationSourceRoots;
|
import static org.jetbrains.kotlin.idea.roots.ProjectRootUtilsKt.getSuitableDestinationSourceRoots;
|
||||||
|
|
||||||
@@ -148,6 +144,24 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
initMemberInfo(elementsToMove, sourceFiles);
|
initMemberInfo(elementsToMove, sourceFiles);
|
||||||
|
|
||||||
updateControls();
|
updateControls();
|
||||||
|
|
||||||
|
initializedCheckBoxesState = getCheckboxesState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BitSet initializedCheckBoxesState;
|
||||||
|
private BitSet getCheckboxesState(boolean applyDefaults) {
|
||||||
|
|
||||||
|
BitSet state = new BitSet(7);
|
||||||
|
|
||||||
|
state.set(0, applyDefaults || cbSearchInComments.isSelected()); //cbSearchInComments default is true
|
||||||
|
state.set(1, applyDefaults || cbSearchTextOccurrences.isSelected()); //cbSearchTextOccurrences default is true
|
||||||
|
state.set(2, applyDefaults || cbDeleteEmptySourceFiles.isSelected()); //cbDeleteEmptySourceFiles default is true
|
||||||
|
state.set(3, applyDefaults || cbApplyMPPDeclarationsMove.isSelected()); //cbApplyMPPDeclarationsMove default is true
|
||||||
|
state.set(4, cbSpecifyFileNameInPackage.isSelected());
|
||||||
|
state.set(5, cbUpdatePackageDirective.isSelected());
|
||||||
|
state.set(6, cbSearchReferences.isSelected());
|
||||||
|
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<KtFile> getSourceFiles(@NotNull Collection<KtNamedDeclaration> elementsToMove) {
|
private static List<KtFile> getSourceFiles(@NotNull Collection<KtNamedDeclaration> elementsToMove) {
|
||||||
@@ -427,16 +441,18 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
return elementsToMove;
|
return elementsToMove;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Model<BaseRefactoringProcessor> getModel() throws ConfigurationException {
|
private MoveKotlinTopLevelDeclarationsModel getModel() throws ConfigurationException {
|
||||||
|
|
||||||
DirectoryChooser.ItemWrapper selectedItem = (DirectoryChooser.ItemWrapper) destinationFolderCB.getComboBox().getSelectedItem();
|
DirectoryChooser.ItemWrapper selectedItem = (DirectoryChooser.ItemWrapper) destinationFolderCB.getComboBox().getSelectedItem();
|
||||||
PsiDirectory selectedPsiDirectory = selectedItem != null ? selectedItem.getDirectory() : initialTargetDirectory;
|
PsiDirectory selectedPsiDirectory = selectedItem != null ? selectedItem.getDirectory() : initialTargetDirectory;
|
||||||
|
|
||||||
boolean mppDeclarationSelected = cbApplyMPPDeclarationsMove.isSelected() && isMppDeclarationSelected();
|
boolean mppDeclarationSelected = cbApplyMPPDeclarationsMove.isSelected() && isMppDeclarationSelected();
|
||||||
|
|
||||||
|
List<KtNamedDeclaration> selectedElements = getSelectedElementsToMoveChecked();
|
||||||
|
|
||||||
return new MoveKotlinTopLevelDeclarationsModel(
|
return new MoveKotlinTopLevelDeclarationsModel(
|
||||||
myProject,
|
myProject,
|
||||||
getSelectedElementsToMoveChecked(),
|
selectedElements,
|
||||||
getTargetPackage(),
|
getTargetPackage(),
|
||||||
selectedPsiDirectory,
|
selectedPsiDirectory,
|
||||||
tfFileNameInPackage.getText(),
|
tfFileNameInPackage.getText(),
|
||||||
@@ -456,9 +472,9 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
@Override
|
@Override
|
||||||
protected void doAction() {
|
protected void doAction() {
|
||||||
|
|
||||||
BaseRefactoringProcessor processor;
|
ModelResultWithFUSData modelResult;
|
||||||
try {
|
try {
|
||||||
processor = getModel().computeModelResult();
|
modelResult = getModel().computeModelResult();
|
||||||
}
|
}
|
||||||
catch (ConfigurationException e) {
|
catch (ConfigurationException e) {
|
||||||
setErrorText(e.getMessage());
|
setErrorText(e.getMessage());
|
||||||
@@ -468,7 +484,13 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
saveRefactoringSettings();
|
saveRefactoringSettings();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
invokeRefactoring(processor);
|
MoveUtilsKt.logFusForMoveRefactoring(
|
||||||
|
modelResult.getElementsCount(),
|
||||||
|
modelResult.getEntityToMove(),
|
||||||
|
modelResult.getDestination(),
|
||||||
|
getCheckboxesState(false).equals(initializedCheckBoxesState),
|
||||||
|
() -> invokeRefactoring(modelResult.getProcessor())
|
||||||
|
);
|
||||||
} catch (IncorrectOperationException e) {
|
} catch (IncorrectOperationException e) {
|
||||||
CommonRefactoringUtil.showErrorMessage(RefactoringBundle.message("error.title"), e.getMessage(), null, myProject);
|
CommonRefactoringUtil.showErrorMessage(RefactoringBundle.message("error.title"), e.getMessage(), null, myProject);
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-4
@@ -27,11 +27,15 @@ import org.jetbrains.kotlin.idea.refactoring.getOrCreateKotlinFile
|
|||||||
import org.jetbrains.kotlin.idea.refactoring.move.getOrCreateDirectory
|
import org.jetbrains.kotlin.idea.refactoring.move.getOrCreateDirectory
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.updatePackageDirective
|
import org.jetbrains.kotlin.idea.refactoring.move.updatePackageDirective
|
||||||
|
import org.jetbrains.kotlin.idea.statistics.MoveRefactoringFUSCollector.MovedEntity
|
||||||
|
import org.jetbrains.kotlin.idea.statistics.MoveRefactoringFUSCollector.MoveRefactoringDestination
|
||||||
import org.jetbrains.kotlin.idea.util.collectAllExpectAndActualDeclaration
|
import org.jetbrains.kotlin.idea.util.collectAllExpectAndActualDeclaration
|
||||||
import org.jetbrains.kotlin.idea.util.isEffectivelyActual
|
import org.jetbrains.kotlin.idea.util.isEffectivelyActual
|
||||||
import org.jetbrains.kotlin.idea.util.isExpectDeclaration
|
import org.jetbrains.kotlin.idea.util.isExpectDeclaration
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.psi.KtFunction
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.InvalidPathException
|
import java.nio.file.InvalidPathException
|
||||||
@@ -53,7 +57,7 @@ internal class MoveKotlinTopLevelDeclarationsModel(
|
|||||||
val isFullFileMove: Boolean,
|
val isFullFileMove: Boolean,
|
||||||
val applyMPPDeclarations: Boolean,
|
val applyMPPDeclarations: Boolean,
|
||||||
val moveCallback: MoveCallback?
|
val moveCallback: MoveCallback?
|
||||||
) : Model<BaseRefactoringProcessor> {
|
) : Model {
|
||||||
|
|
||||||
private inline fun <T, K> Set<T>.mapToSingleOrNull(transform: (T) -> K?): K? =
|
private inline fun <T, K> Set<T>.mapToSingleOrNull(transform: (T) -> K?): K? =
|
||||||
mapTo(mutableSetOf(), transform).singleOrNull()
|
mapTo(mutableSetOf(), transform).singleOrNull()
|
||||||
@@ -217,15 +221,29 @@ internal class MoveKotlinTopLevelDeclarationsModel(
|
|||||||
override fun computeModelResult() = computeModelResult(throwOnConflicts = false)
|
override fun computeModelResult() = computeModelResult(throwOnConflicts = false)
|
||||||
|
|
||||||
@Throws(ConfigurationException::class)
|
@Throws(ConfigurationException::class)
|
||||||
override fun computeModelResult(throwOnConflicts: Boolean): BaseRefactoringProcessor {
|
override fun computeModelResult(throwOnConflicts: Boolean): ModelResultWithFUSData {
|
||||||
|
|
||||||
verifyBeforeRun()
|
verifyBeforeRun()
|
||||||
|
|
||||||
|
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 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 destination = if (isMoveToPackage) MoveRefactoringDestination.PACKAGE else MoveRefactoringDestination.FILE
|
||||||
|
|
||||||
if (isFullFileMove && isMoveToPackage) {
|
if (isFullFileMove && isMoveToPackage) {
|
||||||
tryMoveFile(throwOnConflicts)?.let { return it }
|
tryMoveFile(throwOnConflicts)?.let {
|
||||||
|
return ModelResultWithFUSData(it, elementsToMove.size, entity, destination)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return moveDeclaration(throwOnConflicts)
|
val processor = moveDeclaration(throwOnConflicts)
|
||||||
|
return ModelResultWithFUSData(processor, elementsToMove.size, entity, destination)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryMoveFile(throwOnConflicts: Boolean): BaseRefactoringProcessor? {
|
private fun tryMoveFile(throwOnConflicts: Boolean): BaseRefactoringProcessor? {
|
||||||
|
|||||||
+16
-2
@@ -16,6 +16,7 @@ import com.intellij.refactoring.move.MoveHandler
|
|||||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil
|
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.MoveFilesOrDirectoriesHandlerCompat
|
import org.jetbrains.kotlin.idea.refactoring.move.MoveFilesOrDirectoriesHandlerCompat
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.move.logFusForMoveRefactoring
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui.KotlinAwareMoveFilesOrDirectoriesDialog
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui.KotlinAwareMoveFilesOrDirectoriesDialog
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui.KotlinAwareMoveFilesOrDirectoriesModel
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui.KotlinAwareMoveFilesOrDirectoriesModel
|
||||||
import org.jetbrains.kotlin.idea.util.application.executeCommand
|
import org.jetbrains.kotlin.idea.util.application.executeCommand
|
||||||
@@ -60,7 +61,8 @@ class KotlinMoveFilesOrDirectoriesHandler : MoveFilesOrDirectoriesHandlerCompat(
|
|||||||
|
|
||||||
val initialTargetDirectory = MoveFilesOrDirectoriesUtil.getInitialTargetDirectory(targetDirectory, elements)
|
val initialTargetDirectory = MoveFilesOrDirectoriesUtil.getInitialTargetDirectory(targetDirectory, elements)
|
||||||
|
|
||||||
if (ApplicationManager.getApplication().isUnitTestMode && initialTargetDirectory !== null) {
|
val isTestUnitMode = ApplicationManager.getApplication().isUnitTestMode
|
||||||
|
if (isTestUnitMode && initialTargetDirectory !== null) {
|
||||||
KotlinAwareMoveFilesOrDirectoriesModel(
|
KotlinAwareMoveFilesOrDirectoriesModel(
|
||||||
project,
|
project,
|
||||||
adjustedElementsToMove,
|
adjustedElementsToMove,
|
||||||
@@ -70,7 +72,19 @@ class KotlinMoveFilesOrDirectoriesHandler : MoveFilesOrDirectoriesHandlerCompat(
|
|||||||
moveCallback = callback
|
moveCallback = callback
|
||||||
).run {
|
).run {
|
||||||
project.executeCommand(MoveHandler.REFACTORING_NAME) {
|
project.executeCommand(MoveHandler.REFACTORING_NAME) {
|
||||||
computeModelResult().run()
|
with(computeModelResult()) {
|
||||||
|
if (!isTestUnitMode) {
|
||||||
|
logFusForMoveRefactoring(
|
||||||
|
elementsCount,
|
||||||
|
entityToMove,
|
||||||
|
destination,
|
||||||
|
true,
|
||||||
|
Runnable { processor.run() }
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
processor.run()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.idea.refactoring.fqName.isImported
|
|||||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference.ShorteningMode
|
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference.ShorteningMode
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
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.executeCommand
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
||||||
@@ -55,7 +56,9 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
|
|||||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
|
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.lang.System.currentTimeMillis
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import javax.swing.JCheckBox
|
||||||
|
|
||||||
sealed class ContainerInfo {
|
sealed class ContainerInfo {
|
||||||
abstract val fqName: FqName?
|
abstract val fqName: FqName?
|
||||||
@@ -679,4 +682,30 @@ internal fun getTargetPackageFqName(targetContainer: PsiElement): FqName? {
|
|||||||
return if (targetPackage != null) FqName(targetPackage.qualifiedName) else null
|
return if (targetPackage != null) FqName(targetPackage.qualifiedName) else null
|
||||||
}
|
}
|
||||||
return if (targetContainer is KtFile) targetContainer.packageFqName else null
|
return if (targetContainer is KtFile) targetContainer.packageFqName else null
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun logFusForMoveRefactoring(
|
||||||
|
numberOfEntities: Int,
|
||||||
|
entity: MoveRefactoringFUSCollector.MovedEntity,
|
||||||
|
destination: MoveRefactoringFUSCollector.MoveRefactoringDestination,
|
||||||
|
isDefault: Boolean,
|
||||||
|
body: Runnable
|
||||||
|
) {
|
||||||
|
val timeStarted = currentTimeMillis()
|
||||||
|
|
||||||
|
var succeeded = false
|
||||||
|
try {
|
||||||
|
body.run()
|
||||||
|
succeeded = true
|
||||||
|
} finally {
|
||||||
|
MoveRefactoringFUSCollector.log(
|
||||||
|
timeStarted = timeStarted,
|
||||||
|
timeFinished = currentTimeMillis(),
|
||||||
|
numberOfEntities = numberOfEntities,
|
||||||
|
destination = destination,
|
||||||
|
isDefault = isDefault,
|
||||||
|
entity = entity,
|
||||||
|
isSucceeded = succeeded,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user