KT-44043 [Sealed interfaces]: quickfix for top level abstractions
This commit is contained in:
@@ -174,6 +174,9 @@ fix.move.file.to.package.text=Move file to {0}
|
|||||||
fix.change.package.family=Change file's package to match directory
|
fix.change.package.family=Change file's package to match directory
|
||||||
fix.change.package.text=Change file''s package to {0}
|
fix.change.package.text=Change file''s package to {0}
|
||||||
|
|
||||||
|
fix.move.to.sealed.family=Move hierarchy member to the package/module of its sealed parent
|
||||||
|
fix.move.to.sealed.text=Move {0} to the package/module of {1}
|
||||||
|
|
||||||
action.add.import.chooser.title=Imports
|
action.add.import.chooser.title=Imports
|
||||||
|
|
||||||
goto.super.chooser.function.title=Choose super function
|
goto.super.chooser.function.title=Choose super function
|
||||||
|
|||||||
+1
@@ -150,6 +150,7 @@ internal class MoveKotlinDeclarationsHandlerTestActions(private val caseDataKeep
|
|||||||
targetPackageName: String,
|
targetPackageName: String,
|
||||||
targetDirectory: PsiDirectory?,
|
targetDirectory: PsiDirectory?,
|
||||||
targetFile: KtFile?,
|
targetFile: KtFile?,
|
||||||
|
freezeTargets: Boolean,
|
||||||
moveToPackage: Boolean,
|
moveToPackage: Boolean,
|
||||||
moveCallback: MoveCallback?
|
moveCallback: MoveCallback?
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* 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.quickfix
|
||||||
|
|
||||||
|
import com.intellij.openapi.actionSystem.LangDataKeys
|
||||||
|
import com.intellij.openapi.actionSystem.impl.SimpleDataContext
|
||||||
|
import com.intellij.openapi.editor.Editor
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.roots.ProjectFileIndex
|
||||||
|
import com.intellij.psi.PsiDirectory
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.psi.util.parentOfType
|
||||||
|
import org.jetbrains.kotlin.descriptors.containingPackage
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveKotlinDeclarationsHandler
|
||||||
|
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
||||||
|
import org.jetbrains.kotlin.idea.util.projectStructure.module
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||||
|
|
||||||
|
class MoveToSealedMatchingPackageFix(element: KtTypeReference) : KotlinQuickFixAction<KtTypeReference>(element) {
|
||||||
|
|
||||||
|
private val moveHandler = MoveKotlinDeclarationsHandler(false)
|
||||||
|
|
||||||
|
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||||
|
val typeReference = element ?: return
|
||||||
|
|
||||||
|
// 'element' references sealed class/interface in extension list
|
||||||
|
val classToMove = typeReference.parentOfType<KtClass>() ?: return
|
||||||
|
val defaultTargetDir = typeReference.resolveToDir() ?: return
|
||||||
|
|
||||||
|
val parentContext = SimpleDataContext.getProjectContext(project)
|
||||||
|
val context = SimpleDataContext.getSimpleContext(LangDataKeys.TARGET_PSI_ELEMENT.name, defaultTargetDir, parentContext)
|
||||||
|
|
||||||
|
moveHandler.tryToMove(classToMove, project, context, null, editor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KtTypeReference.resolveToDir(): PsiDirectory? {
|
||||||
|
val ktUserType = typeElement as? KtUserType ?: return null
|
||||||
|
val ktNameReferenceExpression = ktUserType.referenceExpression as? KtNameReferenceExpression ?: return null
|
||||||
|
val declDescriptor = ktNameReferenceExpression.resolveMainReferenceToDescriptors().singleOrNull() ?: return null
|
||||||
|
|
||||||
|
val packageName = declDescriptor.containingPackage()?.asString() ?: return null
|
||||||
|
|
||||||
|
val projectFileIndex = ProjectFileIndex.getInstance(project)
|
||||||
|
val ktClassInQuestion = DescriptorToSourceUtils.getSourceFromDescriptor(declDescriptor) as? KtClass ?: return null
|
||||||
|
val module = projectFileIndex.getModuleForFile(ktClassInQuestion.containingFile.virtualFile) ?: return null
|
||||||
|
val psiPackage =
|
||||||
|
KotlinJavaPsiFacade.getInstance(project).findPackage(packageName, GlobalSearchScope.moduleScope(module)) ?: return null
|
||||||
|
|
||||||
|
return psiPackage.directories.find { it.module == module }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun startInWriteAction(): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getText(): String {
|
||||||
|
val typeReference = element ?: return ""
|
||||||
|
val referencedName = (typeReference.typeElement as? KtUserType)?.referenceExpression?.getReferencedName() ?: return ""
|
||||||
|
|
||||||
|
val classToMove = typeReference.parentOfType<KtClass>() ?: return ""
|
||||||
|
return KotlinBundle.message("fix.move.to.sealed.text", classToMove.nameAsSafeName.asString(), referencedName)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFamilyName(): String {
|
||||||
|
return KotlinBundle.message("fix.move.to.sealed.family")
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object : KotlinSingleIntentionActionFactory() {
|
||||||
|
override fun createAction(diagnostic: Diagnostic): MoveToSealedMatchingPackageFix? {
|
||||||
|
val annotationEntry = diagnostic.psiElement as? KtTypeReference ?: return null
|
||||||
|
return MoveToSealedMatchingPackageFix(annotationEntry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -664,5 +664,8 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
INCOMPATIBLE_THROWS_OVERRIDE.registerFactory(RemoveAnnotationFix)
|
INCOMPATIBLE_THROWS_OVERRIDE.registerFactory(RemoveAnnotationFix)
|
||||||
|
|
||||||
INLINE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER.registerFactory(InlineClassConstructorNotValParameterFactory)
|
INLINE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER.registerFactory(InlineClassConstructorNotValParameterFactory)
|
||||||
|
|
||||||
|
SEALED_INHERITOR_IN_DIFFERENT_PACKAGE.registerFactory(MoveToSealedMatchingPackageFix)
|
||||||
|
SEALED_INHERITOR_IN_DIFFERENT_MODULE.registerFactory(MoveToSealedMatchingPackageFix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -155,6 +155,7 @@ class ExtractDeclarationFromCurrentFileIntention : SelfTargetingRangeIntention<K
|
|||||||
packageName.asString(),
|
packageName.asString(),
|
||||||
directory,
|
directory,
|
||||||
targetFile as? KtFile,
|
targetFile as? KtFile,
|
||||||
|
/* freezeTargets */ false,
|
||||||
/* moveToPackage = */ true,
|
/* moveToPackage = */ true,
|
||||||
/* searchInComments = */ true,
|
/* searchInComments = */ true,
|
||||||
/* searchForTextOccurrences = */ true,
|
/* searchForTextOccurrences = */ true,
|
||||||
|
|||||||
+9
-1
@@ -32,7 +32,6 @@ import com.intellij.refactoring.util.CommonRefactoringUtil
|
|||||||
import org.jetbrains.kotlin.asJava.unwrapped
|
import org.jetbrains.kotlin.asJava.unwrapped
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.core.getPackage
|
import org.jetbrains.kotlin.idea.core.getPackage
|
||||||
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringSettings
|
|
||||||
import org.jetbrains.kotlin.idea.refactoring.canRefactor
|
import org.jetbrains.kotlin.idea.refactoring.canRefactor
|
||||||
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.KotlinSelectNestedClassRefactoringDialog
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui.KotlinSelectNestedClassRefactoringDialog
|
||||||
@@ -67,6 +66,7 @@ private val defaultHandlerActions = object : MoveKotlinDeclarationsHandlerAction
|
|||||||
targetPackageName: String,
|
targetPackageName: String,
|
||||||
targetDirectory: PsiDirectory?,
|
targetDirectory: PsiDirectory?,
|
||||||
targetFile: KtFile?,
|
targetFile: KtFile?,
|
||||||
|
freezeTargets: Boolean,
|
||||||
moveToPackage: Boolean,
|
moveToPackage: Boolean,
|
||||||
moveCallback: MoveCallback?
|
moveCallback: MoveCallback?
|
||||||
) = MoveKotlinTopLevelDeclarationsDialog(
|
) = MoveKotlinTopLevelDeclarationsDialog(
|
||||||
@@ -75,6 +75,7 @@ private val defaultHandlerActions = object : MoveKotlinDeclarationsHandlerAction
|
|||||||
targetPackageName,
|
targetPackageName,
|
||||||
targetDirectory,
|
targetDirectory,
|
||||||
targetFile,
|
targetFile,
|
||||||
|
freezeTargets,
|
||||||
moveToPackage,
|
moveToPackage,
|
||||||
moveCallback
|
moveCallback
|
||||||
).show()
|
).show()
|
||||||
@@ -93,8 +94,14 @@ private val defaultHandlerActions = object : MoveKotlinDeclarationsHandlerAction
|
|||||||
class MoveKotlinDeclarationsHandler internal constructor(private val handlerActions: MoveKotlinDeclarationsHandlerActions) :
|
class MoveKotlinDeclarationsHandler internal constructor(private val handlerActions: MoveKotlinDeclarationsHandlerActions) :
|
||||||
MoveHandlerDelegate() {
|
MoveHandlerDelegate() {
|
||||||
|
|
||||||
|
private var freezeTargets: Boolean = true
|
||||||
|
|
||||||
constructor() : this(defaultHandlerActions)
|
constructor() : this(defaultHandlerActions)
|
||||||
|
|
||||||
|
constructor(freezeTargets: Boolean) : this() {
|
||||||
|
this.freezeTargets = freezeTargets
|
||||||
|
}
|
||||||
|
|
||||||
private fun getUniqueContainer(elements: Array<out PsiElement>): PsiElement? {
|
private fun getUniqueContainer(elements: Array<out PsiElement>): PsiElement? {
|
||||||
val allTopLevel = elements.all { isTopLevelInFileOrScript(it) }
|
val allTopLevel = elements.all { isTopLevelInFileOrScript(it) }
|
||||||
|
|
||||||
@@ -203,6 +210,7 @@ class MoveKotlinDeclarationsHandler internal constructor(private val handlerActi
|
|||||||
targetPackageName,
|
targetPackageName,
|
||||||
targetDirectory,
|
targetDirectory,
|
||||||
targetFile,
|
targetFile,
|
||||||
|
freezeTargets,
|
||||||
moveToPackage,
|
moveToPackage,
|
||||||
callback
|
callback
|
||||||
)
|
)
|
||||||
|
|||||||
+1
@@ -30,6 +30,7 @@ internal interface MoveKotlinDeclarationsHandlerActions {
|
|||||||
targetPackageName: String,
|
targetPackageName: String,
|
||||||
targetDirectory: PsiDirectory?,
|
targetDirectory: PsiDirectory?,
|
||||||
targetFile: KtFile?,
|
targetFile: KtFile?,
|
||||||
|
freezeTargets: Boolean,
|
||||||
moveToPackage: Boolean,
|
moveToPackage: Boolean,
|
||||||
moveCallback: MoveCallback?
|
moveCallback: MoveCallback?
|
||||||
)
|
)
|
||||||
|
|||||||
+22
-5
@@ -6,12 +6,15 @@
|
|||||||
package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui;
|
package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui;
|
||||||
|
|
||||||
import com.intellij.ide.util.DirectoryChooser;
|
import com.intellij.ide.util.DirectoryChooser;
|
||||||
|
import com.intellij.openapi.module.Module;
|
||||||
|
import com.intellij.openapi.module.ModuleUtilCore;
|
||||||
import com.intellij.openapi.options.ConfigurationException;
|
import com.intellij.openapi.options.ConfigurationException;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
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.psi.search.GlobalSearchScope;
|
||||||
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;
|
||||||
@@ -30,6 +33,7 @@ import kotlin.collections.CollectionsKt;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle;
|
import org.jetbrains.kotlin.idea.KotlinBundle;
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinFileType;
|
||||||
import org.jetbrains.kotlin.idea.core.util.PhysicalFileSystemUtilsKt;
|
import org.jetbrains.kotlin.idea.core.util.PhysicalFileSystemUtilsKt;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringSettings;
|
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringSettings;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfo;
|
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfo;
|
||||||
@@ -74,12 +78,15 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
private JCheckBox cbApplyMPPDeclarationsMove;
|
private JCheckBox cbApplyMPPDeclarationsMove;
|
||||||
private KotlinMemberSelectionTable memberTable;
|
private KotlinMemberSelectionTable memberTable;
|
||||||
|
|
||||||
|
private final boolean freezeTargets;
|
||||||
|
|
||||||
public MoveKotlinTopLevelDeclarationsDialog(
|
public MoveKotlinTopLevelDeclarationsDialog(
|
||||||
@NotNull Project project,
|
@NotNull Project project,
|
||||||
@NotNull Set<KtNamedDeclaration> elementsToMove,
|
@NotNull Set<KtNamedDeclaration> elementsToMove,
|
||||||
@Nullable String targetPackageName,
|
@Nullable String targetPackageName,
|
||||||
@Nullable PsiDirectory targetDirectory,
|
@Nullable PsiDirectory targetDirectory,
|
||||||
@Nullable KtFile targetFile,
|
@Nullable KtFile targetFile,
|
||||||
|
boolean freezeTargets,
|
||||||
boolean moveToPackage,
|
boolean moveToPackage,
|
||||||
@Nullable MoveCallback moveCallback
|
@Nullable MoveCallback moveCallback
|
||||||
) {
|
) {
|
||||||
@@ -88,6 +95,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
targetPackageName,
|
targetPackageName,
|
||||||
targetDirectory,
|
targetDirectory,
|
||||||
targetFile,
|
targetFile,
|
||||||
|
freezeTargets,
|
||||||
moveToPackage,
|
moveToPackage,
|
||||||
KotlinRefactoringSettings.getInstance().MOVE_SEARCH_IN_COMMENTS,
|
KotlinRefactoringSettings.getInstance().MOVE_SEARCH_IN_COMMENTS,
|
||||||
KotlinRefactoringSettings.getInstance().MOVE_SEARCH_FOR_TEXT,
|
KotlinRefactoringSettings.getInstance().MOVE_SEARCH_FOR_TEXT,
|
||||||
@@ -102,6 +110,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
@Nullable String targetPackageName,
|
@Nullable String targetPackageName,
|
||||||
@Nullable PsiDirectory targetDirectory,
|
@Nullable PsiDirectory targetDirectory,
|
||||||
@Nullable KtFile targetFile,
|
@Nullable KtFile targetFile,
|
||||||
|
boolean freezeTargets,
|
||||||
boolean moveToPackage,
|
boolean moveToPackage,
|
||||||
boolean searchInComments,
|
boolean searchInComments,
|
||||||
boolean searchForTextOccurrences,
|
boolean searchForTextOccurrences,
|
||||||
@@ -110,6 +119,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
@Nullable MoveCallback moveCallback
|
@Nullable MoveCallback moveCallback
|
||||||
) {
|
) {
|
||||||
super(project, true);
|
super(project, true);
|
||||||
|
this.freezeTargets = freezeTargets;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
@@ -127,7 +137,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
|
|
||||||
initPackageChooser(targetPackageName, targetDirectory, sourceFiles);
|
initPackageChooser(targetPackageName, targetDirectory, sourceFiles);
|
||||||
|
|
||||||
initFileChooser(targetFile, elementsToMove, sourceFiles);
|
initFileChooser(targetFile, freezeTargets ? targetDirectory : null, elementsToMove, sourceFiles);
|
||||||
|
|
||||||
initMoveToButtons(moveToPackage);
|
initMoveToButtons(moveToPackage);
|
||||||
|
|
||||||
@@ -214,6 +224,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
) {
|
) {
|
||||||
if (targetPackageName != null) {
|
if (targetPackageName != null) {
|
||||||
classPackageChooser.prependItem(targetPackageName);
|
classPackageChooser.prependItem(targetPackageName);
|
||||||
|
classPackageChooser.setEnabled(freezeTargets);
|
||||||
}
|
}
|
||||||
|
|
||||||
((KotlinDestinationFolderComboBox) destinationFolderCB).setData(
|
((KotlinDestinationFolderComboBox) destinationFolderCB).setData(
|
||||||
@@ -225,7 +236,8 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
setErrorText(s);
|
setErrorText(s);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
classPackageChooser.getChildComponent()
|
classPackageChooser.getChildComponent(),
|
||||||
|
!freezeTargets
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,6 +280,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
|
|
||||||
private void initFileChooser(
|
private void initFileChooser(
|
||||||
@Nullable KtFile targetFile,
|
@Nullable KtFile targetFile,
|
||||||
|
@Nullable PsiDirectory targetDirectory,
|
||||||
@NotNull Set<KtNamedDeclaration> elementsToMove,
|
@NotNull Set<KtNamedDeclaration> elementsToMove,
|
||||||
@NotNull List<KtFile> sourceFiles
|
@NotNull List<KtFile> sourceFiles
|
||||||
) {
|
) {
|
||||||
@@ -276,11 +289,15 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
throw new AssertionError("File chooser initialization failed");
|
throw new AssertionError("File chooser initialization failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Module targetModule = (targetDirectory != null)? ModuleUtilCore.findModuleForPsiElement(targetDirectory) : null;
|
||||||
|
GlobalSearchScope targetModuleScope = targetModule == null ? null
|
||||||
|
: GlobalSearchScope.getScopeRestrictedByFileTypes(targetModule.getModuleScope(), KotlinFileType.INSTANCE);
|
||||||
|
|
||||||
fileChooser.addActionListener(e -> {
|
fileChooser.addActionListener(e -> {
|
||||||
KotlinFileChooserDialog dialog = new KotlinFileChooserDialog(
|
KotlinFileChooserDialog dialog = new KotlinFileChooserDialog(
|
||||||
KotlinBundle.message("text.choose.containing.file"),
|
KotlinBundle.message("text.choose.containing.file"),
|
||||||
myProject
|
myProject,
|
||||||
);
|
targetModuleScope, getTargetPackage());
|
||||||
|
|
||||||
File targetFile1 = new File(fileChooser.getText());
|
File targetFile1 = new File(fileChooser.getText());
|
||||||
PsiFile targetPsiFile = PhysicalFileSystemUtilsKt.toPsiFile(targetFile1, myProject);
|
PsiFile targetPsiFile = PhysicalFileSystemUtilsKt.toPsiFile(targetFile1, myProject);
|
||||||
@@ -364,7 +381,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
UIUtil.setEnabled(rbMoveToFile, !needToMoveMPPDeclarations, true);
|
UIUtil.setEnabled(rbMoveToFile, !needToMoveMPPDeclarations, true);
|
||||||
|
|
||||||
boolean moveToPackage = rbMoveToPackage.isSelected();
|
boolean moveToPackage = rbMoveToPackage.isSelected();
|
||||||
classPackageChooser.setEnabled(moveToPackage);
|
classPackageChooser.setEnabled(moveToPackage && freezeTargets);
|
||||||
updateFileNameInPackageField();
|
updateFileNameInPackageField();
|
||||||
fileChooser.setEnabled(!moveToPackage);
|
fileChooser.setEnabled(!moveToPackage);
|
||||||
UIUtil.setEnabled(targetPanel, moveToPackage && !needToMoveMPPDeclarations && hasAnySourceRoots(), true);
|
UIUtil.setEnabled(targetPanel, moveToPackage && !needToMoveMPPDeclarations && hasAnySourceRoots(), true);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.idea.refactoring.ui
|
package org.jetbrains.kotlin.idea.refactoring.ui
|
||||||
|
|
||||||
import com.intellij.ide.util.AbstractTreeClassChooserDialog
|
import com.intellij.ide.util.AbstractTreeClassChooserDialog
|
||||||
|
import com.intellij.ide.util.TreeChooser
|
||||||
import com.intellij.ide.util.gotoByName.GotoFileModel
|
import com.intellij.ide.util.gotoByName.GotoFileModel
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.search.FilenameIndex
|
import com.intellij.psi.search.FilenameIndex
|
||||||
@@ -19,13 +20,15 @@ import javax.swing.tree.DefaultMutableTreeNode
|
|||||||
|
|
||||||
class KotlinFileChooserDialog(
|
class KotlinFileChooserDialog(
|
||||||
title: String,
|
title: String,
|
||||||
project: Project
|
project: Project,
|
||||||
|
searchScope: GlobalSearchScope?,
|
||||||
|
packageName: String?
|
||||||
) : AbstractTreeClassChooserDialog<KtFile>(
|
) : AbstractTreeClassChooserDialog<KtFile>(
|
||||||
title,
|
title,
|
||||||
project,
|
project,
|
||||||
project.projectScope().restrictToKotlinSources(),
|
searchScope ?: project.projectScope().restrictToKotlinSources(),
|
||||||
KtFile::class.java,
|
KtFile::class.java,
|
||||||
null,
|
ScopeAwareClassFilter(searchScope, packageName),
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
false,
|
false,
|
||||||
@@ -45,4 +48,20 @@ class KotlinFileChooserDialog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun createChooseByNameModel() = GotoFileModel(this.project)
|
override fun createChooseByNameModel() = GotoFileModel(this.project)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class [AbstractTreeClassChooserDialog] unfortunately doesn't filter the file tree according to the provided "scope".
|
||||||
|
* As a workaround we use filter preventing wrong file selection.
|
||||||
|
*/
|
||||||
|
private class ScopeAwareClassFilter(val searchScope: GlobalSearchScope?, val packageName: String?) : TreeChooser.Filter<KtFile> {
|
||||||
|
override fun isAccepted(element: KtFile?): Boolean {
|
||||||
|
if (element == null) return false
|
||||||
|
if (searchScope == null && packageName == null) return true
|
||||||
|
|
||||||
|
val matchesSearchScope = searchScope?.accept(element.virtualFile) ?: true
|
||||||
|
val matchesPackage = packageName?.let { element.packageFqName.asString() == it } ?: true
|
||||||
|
|
||||||
|
return matchesSearchScope && matchesPackage
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user