mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
rename/move package as everything inside directory
This commit is contained in:
+11
@@ -150,6 +150,17 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends DialogWrapper {
|
||||
refactoringSettings.MOVE_SEARCH_IN_COMMENTS = searchInComments;
|
||||
refactoringSettings.MOVE_SEARCH_FOR_TEXT = searchForTextOccurences;
|
||||
|
||||
performRefactoring(project, directory, aPackage, searchInComments, searchForTextOccurences);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myDestDirectoryField.getTextField();
|
||||
}
|
||||
|
||||
protected void performRefactoring(Project project, PsiDirectory directory, PsiPackage aPackage,
|
||||
boolean searchInComments,
|
||||
boolean searchForTextOccurences) {
|
||||
final VirtualFile sourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(directory.getVirtualFile());
|
||||
if (sourceRoot == null) {
|
||||
Messages.showErrorDialog(project, RefactoringBundle.message("destination.directory.does.not.correspond.to.any.package"),
|
||||
|
||||
+277
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* User: anna
|
||||
* Date: 28-Dec-2009
|
||||
*/
|
||||
package com.intellij.refactoring.move.moveClassesOrPackages;
|
||||
|
||||
import com.intellij.codeInsight.ChangeContextUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.listeners.RefactoringElementListener;
|
||||
import com.intellij.refactoring.move.MoveCallback;
|
||||
import com.intellij.refactoring.rename.RenameUtil;
|
||||
import com.intellij.refactoring.util.NonCodeUsageInfo;
|
||||
import com.intellij.refactoring.util.RefactoringUIUtil;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.usageView.UsageViewDescriptor;
|
||||
import com.intellij.usageView.UsageViewUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor {
|
||||
private final PsiDirectory[] myDirectories;
|
||||
private PsiDirectory myTargetDirectory;
|
||||
private boolean mySearchInComments;
|
||||
private boolean mySearchInNonJavaFiles;
|
||||
private Map<PsiClass, TargetDirectoryWrapper> myClassesToMove;
|
||||
private NonCodeUsageInfo[] myNonCodeUsages;
|
||||
private MoveCallback myMoveCallback;
|
||||
|
||||
public MoveDirectoryWithClassesProcessor(Project project,
|
||||
PsiDirectory[] directories,
|
||||
PsiDirectory targetDirectory,
|
||||
boolean searchInComments,
|
||||
boolean searchInNonJavaFiles,
|
||||
boolean includeSelf,
|
||||
MoveCallback moveCallback) {
|
||||
super(project);
|
||||
myDirectories = directories;
|
||||
myTargetDirectory = targetDirectory;
|
||||
mySearchInComments = searchInComments;
|
||||
mySearchInNonJavaFiles = searchInNonJavaFiles;
|
||||
myMoveCallback = moveCallback;
|
||||
myClassesToMove = new HashMap<PsiClass, TargetDirectoryWrapper>();
|
||||
for (PsiDirectory dir : directories) {
|
||||
collectClasses(myClassesToMove, dir, includeSelf ? dir.getParentDirectory() : dir, getTargetDirectory(dir));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) {
|
||||
PsiElement[] elements = new PsiElement[myClassesToMove.size()];
|
||||
final PsiClass[] classes = myClassesToMove.keySet().toArray(new PsiClass[myClassesToMove.keySet().size()]);
|
||||
System.arraycopy(classes, 0, elements, 0, classes.length);
|
||||
return new MoveClassesOrPackagesViewDescriptor(elements, false, false, getTargetName());
|
||||
}
|
||||
|
||||
protected String getTargetName() {
|
||||
return RefactoringUIUtil.getDescription(getTargetDirectory(null).getTargetDirectory(), false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public UsageInfo[] findUsages() {
|
||||
final List<UsageInfo> usages = new ArrayList<UsageInfo>();
|
||||
final Set<String> packageNames = new HashSet<String>();
|
||||
for (PsiClass psiClass : myClassesToMove.keySet()) {
|
||||
Collections.addAll(usages, MoveClassesOrPackagesUtil.findUsages(psiClass, mySearchInComments, mySearchInNonJavaFiles, psiClass.getName()));
|
||||
final String fqName = psiClass.getQualifiedName();
|
||||
assert fqName != null;
|
||||
packageNames.add(StringUtil.getPackageName(fqName));
|
||||
}
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject);
|
||||
for (String packageName : packageNames) {
|
||||
final PsiPackage aPackage = psiFacade.findPackage(packageName);
|
||||
if (aPackage != null) {
|
||||
boolean remainsNothing = true;
|
||||
for (PsiDirectory packageDirectory : aPackage.getDirectories()) {
|
||||
if (!isUnderRefactoring(packageDirectory)) {
|
||||
remainsNothing = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (remainsNothing) {
|
||||
for (PsiReference reference : ReferencesSearch.search(aPackage)) {
|
||||
final PsiElement element = reference.getElement();
|
||||
final PsiImportStatementBase statementBase = PsiTreeUtil.getParentOfType(element, PsiImportStatementBase.class);
|
||||
if (statementBase != null && statementBase.isOnDemand()) {
|
||||
usages.add(new RemoveOnDemandImportStatementsUsageInfo(statementBase));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return UsageViewUtil.removeDuplicatedUsages(usages.toArray(new UsageInfo[usages.size()]));
|
||||
}
|
||||
|
||||
private boolean isUnderRefactoring(PsiDirectory packageDirectory) {
|
||||
for (PsiDirectory directory : myDirectories) {
|
||||
if (PsiTreeUtil.isAncestor(directory, packageDirectory, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
|
||||
final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
|
||||
for (PsiClass psiClass : myClassesToMove.keySet()) {
|
||||
try {
|
||||
myClassesToMove.get(psiClass).checkMove(psiClass);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
conflicts.putValue(psiClass, e.getMessage());
|
||||
}
|
||||
}
|
||||
return showConflicts(conflicts);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void refreshElements(PsiElement[] elements) {}
|
||||
|
||||
@Override
|
||||
public void performRefactoring(UsageInfo[] usages) {
|
||||
final Map<PsiElement, PsiElement> oldToNewElementsMapping = new HashMap<PsiElement, PsiElement>();
|
||||
for (PsiClass psiClass : myClassesToMove.keySet()) {
|
||||
ChangeContextUtil.encodeContextInfo(psiClass, true);
|
||||
final RefactoringElementListener listener = getTransaction().getElementListener(psiClass);
|
||||
final PsiClass newClass = MoveClassesOrPackagesUtil.doMoveClass(psiClass, myClassesToMove.get(psiClass).findOrCreateTargetDirectory());
|
||||
oldToNewElementsMapping.put(psiClass, newClass);
|
||||
listener.elementMoved(newClass);
|
||||
}
|
||||
for (PsiClass psiClass : myClassesToMove.keySet()) {
|
||||
ChangeContextUtil.decodeContextInfo(psiClass, null, null);
|
||||
}
|
||||
myNonCodeUsages = MoveClassesOrPackagesProcessor.retargetUsages(usages, oldToNewElementsMapping);
|
||||
for (UsageInfo usage : usages) {
|
||||
if (usage instanceof RemoveOnDemandImportStatementsUsageInfo) {
|
||||
final PsiElement element = usage.getElement();
|
||||
if (element != null) {
|
||||
element.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (PsiDirectory directory : myDirectories) {
|
||||
directory.delete();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performPsiSpoilingRefactoring() {
|
||||
RenameUtil.renameNonCodeUsages(myProject, myNonCodeUsages);
|
||||
if (myMoveCallback != null) {
|
||||
myMoveCallback.refactoringCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
private static void collectClasses(Map<PsiClass, TargetDirectoryWrapper> classesToMove,
|
||||
PsiDirectory directory,
|
||||
PsiDirectory rootDirectory,
|
||||
@NotNull TargetDirectoryWrapper targetDirectory) {
|
||||
final PsiElement[] children = directory.getChildren();
|
||||
final String relativePath = VfsUtil.getRelativePath(directory.getVirtualFile(), rootDirectory.getVirtualFile(), '/');
|
||||
|
||||
final TargetDirectoryWrapper newTargetDirectory = relativePath.length() == 0
|
||||
? targetDirectory
|
||||
: targetDirectory.findOrCreateChild(relativePath);
|
||||
for (PsiElement child : children) {
|
||||
if (child instanceof PsiJavaFile) {
|
||||
for (PsiClass aClass : ((PsiJavaFile)child).getClasses()) {
|
||||
classesToMove.put(aClass, newTargetDirectory);
|
||||
}
|
||||
}
|
||||
else if (child instanceof PsiDirectory){
|
||||
collectClasses(classesToMove, (PsiDirectory)child, directory, newTargetDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCommandName() {
|
||||
return RefactoringBundle.message("moving.directories.command");
|
||||
}
|
||||
|
||||
public TargetDirectoryWrapper getTargetDirectory(PsiDirectory dir) {
|
||||
return new TargetDirectoryWrapper(myTargetDirectory);
|
||||
}
|
||||
|
||||
private static class RemoveOnDemandImportStatementsUsageInfo extends UsageInfo {
|
||||
public RemoveOnDemandImportStatementsUsageInfo(PsiImportStatementBase statementBase) {
|
||||
super(statementBase);
|
||||
}
|
||||
}
|
||||
|
||||
public static class TargetDirectoryWrapper {
|
||||
private TargetDirectoryWrapper myParentDirectory;
|
||||
private PsiDirectory myTargetDirectory;
|
||||
private String myRelativePath;
|
||||
|
||||
public TargetDirectoryWrapper(PsiDirectory targetDirectory) {
|
||||
myTargetDirectory = targetDirectory;
|
||||
}
|
||||
|
||||
public TargetDirectoryWrapper(TargetDirectoryWrapper parentDirectory, String relativePath) {
|
||||
myParentDirectory = parentDirectory;
|
||||
myRelativePath = relativePath;
|
||||
}
|
||||
|
||||
public TargetDirectoryWrapper(PsiDirectory parentDirectory, String relativePath) {
|
||||
myTargetDirectory = parentDirectory.findSubdirectory(relativePath);
|
||||
//in case it was null
|
||||
myParentDirectory = new TargetDirectoryWrapper(parentDirectory);
|
||||
myRelativePath = relativePath;
|
||||
}
|
||||
|
||||
public PsiDirectory findOrCreateTargetDirectory() {
|
||||
if (myTargetDirectory == null) {
|
||||
final PsiDirectory root = myParentDirectory.findOrCreateTargetDirectory();
|
||||
|
||||
myTargetDirectory = root.findSubdirectory(myRelativePath);
|
||||
if (myTargetDirectory == null) {
|
||||
myTargetDirectory = root.createSubdirectory(myRelativePath);
|
||||
}
|
||||
}
|
||||
return myTargetDirectory;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiDirectory getTargetDirectory() {
|
||||
return myTargetDirectory;
|
||||
}
|
||||
|
||||
public TargetDirectoryWrapper findOrCreateChild(String relativePath) {
|
||||
if (myTargetDirectory != null) {
|
||||
final PsiDirectory psiDirectory = myTargetDirectory.findSubdirectory(relativePath);
|
||||
if (psiDirectory != null) {
|
||||
return new TargetDirectoryWrapper(psiDirectory);
|
||||
}
|
||||
}
|
||||
return new TargetDirectoryWrapper(this, relativePath);
|
||||
}
|
||||
|
||||
public void checkMove(PsiClass psiClass) throws IncorrectOperationException {
|
||||
if (myTargetDirectory != null) {
|
||||
psiClass.getManager().checkMove(psiClass, myTargetDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+38
-43
@@ -19,21 +19,20 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.JavaDirectoryService;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiPackage;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.move.MoveCallback;
|
||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil;
|
||||
import com.intellij.refactoring.util.MoveRenameUsageInfo;
|
||||
import com.intellij.refactoring.util.RadioUpDownListener;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class MovePackagesHandler extends MoveClassesOrPackagesHandlerBase {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.move.moveClassesOrPackages.MovePackagesHandler");
|
||||
@@ -50,10 +49,10 @@ public class MovePackagesHandler extends MoveClassesOrPackagesHandlerBase {
|
||||
}
|
||||
|
||||
public void doMove(final Project project, final PsiElement[] elements, final PsiElement targetContainer, final MoveCallback callback) {
|
||||
if (targetContainer == null && canMoveOrRearrangePackages(elements) ) {
|
||||
PsiDirectory[] directories = new PsiDirectory[elements.length];
|
||||
if (canMoveOrRearrangePackages(elements) ) {
|
||||
final PsiDirectory[] directories = new PsiDirectory[elements.length];
|
||||
System.arraycopy(elements, 0, directories, 0, directories.length);
|
||||
SelectMoveOrRearrangePackageDialog dialog = new SelectMoveOrRearrangePackageDialog(project, directories);
|
||||
SelectMoveOrRearrangePackageDialog dialog = new SelectMoveOrRearrangePackageDialog(project, directories, targetContainer == null);
|
||||
dialog.show();
|
||||
if (!dialog.isOK()) return;
|
||||
|
||||
@@ -63,40 +62,29 @@ public class MovePackagesHandler extends MoveClassesOrPackagesHandlerBase {
|
||||
}
|
||||
|
||||
if (dialog.isMoveDirectory()) {
|
||||
final ArrayList<MoveRenameUsageInfo> usages = new ArrayList<MoveRenameUsageInfo>();
|
||||
for (PsiDirectory directory : directories) {
|
||||
final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(directory);
|
||||
if (aPackage != null) {
|
||||
for (PsiReference reference : ReferencesSearch.search(aPackage, directory.getUseScope())) {
|
||||
usages.add(new MoveRenameUsageInfo(reference, aPackage));
|
||||
}
|
||||
}
|
||||
if (targetContainer instanceof PsiDirectory) {
|
||||
final JavaRefactoringSettings refactoringSettings = JavaRefactoringSettings.getInstance();
|
||||
final MoveDirectoryWithClassesProcessor processor =
|
||||
new MoveDirectoryWithClassesProcessor(project, directories, (PsiDirectory)targetContainer,
|
||||
refactoringSettings.RENAME_SEARCH_IN_COMMENTS_FOR_PACKAGE,
|
||||
refactoringSettings.RENAME_SEARCH_IN_COMMENTS_FOR_PACKAGE, true, callback);
|
||||
processor.run();
|
||||
}
|
||||
|
||||
final PsiElement[] targetDirectory = new PsiElement[]{targetContainer};
|
||||
|
||||
MoveFilesOrDirectoriesUtil.doMove(project, elements, targetDirectory, new MoveCallback() {
|
||||
public void refactoringCompleted() {
|
||||
if (callback != null) callback.refactoringCompleted();
|
||||
if (targetDirectory[0] instanceof PsiDirectory) {
|
||||
final PsiPackage destPackage = JavaDirectoryService.getInstance().getPackage((PsiDirectory)targetDirectory[0]);
|
||||
if (destPackage != null) {
|
||||
for (MoveRenameUsageInfo usage : usages) {
|
||||
final PsiPackage aPackage = (PsiPackage)usage.getReferencedElement();
|
||||
if (aPackage != null) {
|
||||
final PsiReference reference = usage.getReference();
|
||||
if (reference != null) {
|
||||
final PsiPackage pack = JavaPsiFacade.getInstance(project).findPackage(StringUtil.getQualifiedName(destPackage.getQualifiedName(), aPackage.getName()));
|
||||
if (pack != null) {
|
||||
reference.bindToElement(pack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
new MoveClassesOrPackagesToNewDirectoryDialog(directories[0], new PsiElement[2], callback) {
|
||||
@Override
|
||||
protected void performRefactoring(Project project,
|
||||
final PsiDirectory targetDirectory,
|
||||
PsiPackage aPackage,
|
||||
boolean searchInComments,
|
||||
boolean searchForTextOccurences) {
|
||||
final MoveDirectoryWithClassesProcessor processor =
|
||||
new MoveDirectoryWithClassesProcessor(project, directories, targetDirectory, searchInComments, searchForTextOccurences,
|
||||
true, callback);
|
||||
processor.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
}.show();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -131,10 +119,16 @@ public class MovePackagesHandler extends MoveClassesOrPackagesHandlerBase {
|
||||
private JRadioButton myRbMoveDirectory;
|
||||
|
||||
private final PsiDirectory[] myDirectories;
|
||||
private final boolean myRearrangePackagesEnabled;
|
||||
|
||||
public SelectMoveOrRearrangePackageDialog(Project project, PsiDirectory[] directories) {
|
||||
this(project, directories, true);
|
||||
}
|
||||
|
||||
public SelectMoveOrRearrangePackageDialog(Project project, PsiDirectory[] directories, boolean rearrangePackagesEnabled) {
|
||||
super(project, true);
|
||||
myDirectories = directories;
|
||||
myRearrangePackagesEnabled = rearrangePackagesEnabled;
|
||||
setTitle(RefactoringBundle.message("select.refactoring.title"));
|
||||
init();
|
||||
}
|
||||
@@ -184,13 +178,14 @@ public class MovePackagesHandler extends MoveClassesOrPackagesHandlerBase {
|
||||
}
|
||||
myRbRearrangePackage = new JRadioButton();
|
||||
myRbRearrangePackage.setText(rearrangeDescription);
|
||||
myRbRearrangePackage.setVisible(myRearrangePackagesEnabled);
|
||||
|
||||
final String moveDirectoryDescription;
|
||||
if (myDirectories.length > 1) {
|
||||
moveDirectoryDescription = "Move " + myDirectories.length + " directories to another directory";
|
||||
moveDirectoryDescription = "Move everything from " + myDirectories.length + " directories to another directory";
|
||||
}
|
||||
else {
|
||||
moveDirectoryDescription = "Move directory " + myDirectories[0].getVirtualFile().getPresentableUrl() + " to another directory";
|
||||
moveDirectoryDescription = "Move everything from " + myDirectories[0].getVirtualFile().getPresentableUrl() + " to another directory";
|
||||
}
|
||||
myRbMoveDirectory = new JRadioButton();
|
||||
myRbMoveDirectory.setMnemonic('d');
|
||||
|
||||
+86
-18
@@ -22,11 +22,17 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.lang.TitledHandler;
|
||||
import com.intellij.refactoring.move.moveClassesOrPackages.MoveDirectoryWithClassesProcessor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -37,7 +43,7 @@ public class DirectoryAsPackageRenameHandler implements RenameHandler, TitledHan
|
||||
|
||||
public boolean isAvailableOnDataContext(final DataContext dataContext) {
|
||||
final PsiElement element = PsiElementRenameHandler.getElement(dataContext);
|
||||
return element instanceof PsiDirectory;
|
||||
return element instanceof PsiDirectory && ProjectRootManager.getInstance(element.getProject()).getFileIndex().isInContent(((PsiDirectory)element).getVirtualFile());
|
||||
}
|
||||
|
||||
public boolean isRenaming(final DataContext dataContext) {
|
||||
@@ -59,9 +65,9 @@ public class DirectoryAsPackageRenameHandler implements RenameHandler, TitledHan
|
||||
doRename(element, project, element, editor);
|
||||
}
|
||||
|
||||
public static void doRename(PsiElement element, Project project, PsiElement nameSuggestionContext, Editor editor) {
|
||||
PsiDirectory psiDirectory = (PsiDirectory)element;
|
||||
PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(psiDirectory);
|
||||
public static void doRename(PsiElement element, final Project project, PsiElement nameSuggestionContext, Editor editor) {
|
||||
final PsiDirectory psiDirectory = (PsiDirectory)element;
|
||||
final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(psiDirectory);
|
||||
final String qualifiedName = aPackage != null ? aPackage.getQualifiedName() : "";
|
||||
if (aPackage == null || qualifiedName.length() == 0/*default package*/ ||
|
||||
!JavaPsiFacade.getInstance(project).getNameHelper().isIdentifier(psiDirectory.getName())) {
|
||||
@@ -74,25 +80,87 @@ public class DirectoryAsPackageRenameHandler implements RenameHandler, TitledHan
|
||||
PsiElementRenameHandler.rename(aPackage, project, nameSuggestionContext, editor);
|
||||
}
|
||||
else { // the directory corresponds to a package that has multiple associated directories
|
||||
StringBuffer message = new StringBuffer();
|
||||
RenameUtil.buildPackagePrefixChangedMessage(virtualFiles, message, qualifiedName);
|
||||
buildMultipleDirectoriesInPackageMessage(message, aPackage, directories);
|
||||
message.append(RefactoringBundle.message("directories.and.all.references.to.package.will.be.renamed", psiDirectory.getVirtualFile().getPresentableUrl()));
|
||||
int ret =
|
||||
Messages.showDialog(project, message.toString(), RefactoringBundle.message("warning.title"),
|
||||
new String[]{
|
||||
RefactoringBundle.message("rename.package.button.text"),
|
||||
RefactoringBundle.message("rename.directory.button.text"),
|
||||
CommonBundle.getCancelButtonText()}, 0, Messages.getWarningIcon());
|
||||
if (ret == 0) {
|
||||
PsiElementRenameHandler.rename(aPackage, project, nameSuggestionContext, editor);
|
||||
} else if (ret == 1){
|
||||
PsiElementRenameHandler.rename(psiDirectory, project, nameSuggestionContext, editor);
|
||||
final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();
|
||||
boolean inLib = false;
|
||||
for (PsiDirectory directory : directories) {
|
||||
inLib |= !projectFileIndex.isInContent(directory.getVirtualFile());
|
||||
}
|
||||
|
||||
final PsiDirectory[] projectDirectories = aPackage.getDirectories(GlobalSearchScope.projectScope(project));
|
||||
if (inLib) {
|
||||
final String promptMessage = "Package \'" +
|
||||
aPackage.getName() +
|
||||
"\' contains directories in libraries which cannot be renamed. Do you want to rename current directory";
|
||||
if (projectDirectories.length > 0) {
|
||||
int ret = Messages
|
||||
.showDialog(project, promptMessage + " or all directories in project?", RefactoringBundle.message("warning.title"),
|
||||
new String[]{RefactoringBundle.message("rename.current.directory"),
|
||||
RefactoringBundle.message("rename.directories"), CommonBundle.getCancelButtonText()}, 0,
|
||||
Messages.getWarningIcon());
|
||||
renameDirs(project, nameSuggestionContext, editor, psiDirectory, aPackage, ret == 0 ? new PsiDirectory[] {psiDirectory} : projectDirectories);
|
||||
}
|
||||
else {
|
||||
if (Messages.showDialog(project, promptMessage + "?", RefactoringBundle.message("warning.title"),
|
||||
new String[]{CommonBundle.getOkButtonText(), CommonBundle.getCancelButtonText()}, 0,
|
||||
Messages.getWarningIcon()) == DialogWrapper.OK_EXIT_CODE) {
|
||||
renameDirs(project, nameSuggestionContext, editor, psiDirectory, aPackage, psiDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
final StringBuffer message = new StringBuffer();
|
||||
RenameUtil.buildPackagePrefixChangedMessage(virtualFiles, message, qualifiedName);
|
||||
buildMultipleDirectoriesInPackageMessage(message, aPackage, directories);
|
||||
message.append(RefactoringBundle.message("directories.and.all.references.to.package.will.be.renamed",
|
||||
psiDirectory.getVirtualFile().getPresentableUrl()));
|
||||
int ret = Messages.showDialog(project, message.toString(), RefactoringBundle.message("warning.title"),
|
||||
new String[]{RefactoringBundle.message("rename.package.button.text"),
|
||||
RefactoringBundle.message("rename.directory.button.text"), CommonBundle.getCancelButtonText()}, 0,
|
||||
Messages.getWarningIcon());
|
||||
if (ret == 0) {
|
||||
PsiElementRenameHandler.rename(aPackage, project, nameSuggestionContext, editor);
|
||||
}
|
||||
else if (ret == 1) {
|
||||
renameDirs(project, nameSuggestionContext, editor, psiDirectory, aPackage, psiDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void renameDirs(final Project project,
|
||||
final PsiElement nameSuggestionContext,
|
||||
final Editor editor,
|
||||
final PsiDirectory contextDirectory,
|
||||
final PsiPackage aPackage,
|
||||
final PsiDirectory... dirsToRename) {
|
||||
final RenameDialog dialog = new RenameDialog(project, contextDirectory, nameSuggestionContext, editor) {
|
||||
@Override
|
||||
protected void doAction() {
|
||||
final String newName = StringUtil.getQualifiedName(StringUtil.getPackageName(aPackage.getQualifiedName()), getNewName());
|
||||
final MoveDirectoryWithClassesProcessor moveProcessor =
|
||||
new MoveDirectoryWithClassesProcessor(project, dirsToRename, null, isSearchInComments(), isSearchInNonJavaFiles(), false, null) {
|
||||
@Override
|
||||
public TargetDirectoryWrapper getTargetDirectory(final PsiDirectory dir) {
|
||||
return new TargetDirectoryWrapper(dir.getParentDirectory(), getNewName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTargetName() {
|
||||
return newName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCommandName() {
|
||||
return dirsToRename.length == 1 ? "Rename directory" : "Rename directories";
|
||||
}
|
||||
};
|
||||
invokeRefactoring(moveProcessor);
|
||||
}
|
||||
};
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static void buildMultipleDirectoriesInPackageMessage(StringBuffer message,
|
||||
PsiPackage aPackage,
|
||||
PsiDirectory[] directories) {
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package pack2;
|
||||
|
||||
import pack1.*;
|
||||
import target.pack1.S1;
|
||||
|
||||
public class UsagesFromBoth {
|
||||
S1 s1;
|
||||
S2 s2;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package target.pack1;
|
||||
|
||||
public class S1{}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package pack1;
|
||||
|
||||
public class S2{}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package pack2;
|
||||
|
||||
import pack1.*;
|
||||
import target.pack1.S1;
|
||||
|
||||
public class UsagesFromBoth2 {
|
||||
S1 s1;
|
||||
S2 s2;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package pack1;
|
||||
|
||||
public class S1{}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package pack2;
|
||||
|
||||
import pack1.*;
|
||||
|
||||
public class UsagesFromBoth {
|
||||
S1 s1;
|
||||
S2 s2;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package pack1;
|
||||
|
||||
public class S2{}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package pack2;
|
||||
|
||||
import pack1.*;
|
||||
|
||||
public class UsagesFromBoth2 {
|
||||
S1 s1;
|
||||
S2 s2;
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package pack2;
|
||||
|
||||
import pack1.*;
|
||||
import target.pack1.S1;
|
||||
import target.pack1.subpack.SS;
|
||||
|
||||
public class UsagesFromBoth {
|
||||
S1 s1;
|
||||
S2 s2;
|
||||
SS ss;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package target.pack1;
|
||||
|
||||
public class S1{}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package target.pack1.subpack;
|
||||
|
||||
public class SS {}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package pack1;
|
||||
|
||||
public class S2{}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package pack2;
|
||||
|
||||
import pack1.*;
|
||||
import target.pack1.S1;
|
||||
|
||||
public class UsagesFromBoth2 {
|
||||
S1 s1;
|
||||
S2 s2;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package pack1;
|
||||
|
||||
public class S1{}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package pack1.subpack;
|
||||
|
||||
public class SS {}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package pack2;
|
||||
|
||||
import pack1.*;
|
||||
import pack1.subpack.*;
|
||||
|
||||
public class UsagesFromBoth {
|
||||
S1 s1;
|
||||
S2 s2;
|
||||
SS ss;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package pack1;
|
||||
|
||||
public class S2{}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package pack2;
|
||||
|
||||
import pack1.*;
|
||||
|
||||
public class UsagesFromBoth2 {
|
||||
S1 s1;
|
||||
S2 s2;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
|
||||
package com.intellij.refactoring;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.roots.ContentEntry;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiPackage;
|
||||
import com.intellij.refactoring.move.moveClassesOrPackages.MoveDirectoryWithClassesProcessor;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
public class MovePackageAsDirectoryTest extends MultiFileTestCase {
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return JavaTestUtil.getJavaTestDataPath();
|
||||
}
|
||||
|
||||
protected String getTestRoot() {
|
||||
return "/refactoring/movePackageAsDir/";
|
||||
}
|
||||
|
||||
public void testMovePackage() throws Exception {
|
||||
doTest(createAction("pack1", "target"));
|
||||
}
|
||||
|
||||
public void testRemoveUnresolvedImports() throws Exception {
|
||||
doTest(createAction("pack1", "target"));
|
||||
}
|
||||
|
||||
private PerformAction createAction(final String packageName, final String targetPackageName) {
|
||||
return new PerformAction() {
|
||||
public void performAction(VirtualFile rootDir, VirtualFile rootAfter) throws Exception {
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject);
|
||||
final Comparator<PsiDirectory> directoryComparator = new Comparator<PsiDirectory>() {
|
||||
public int compare(PsiDirectory o1, PsiDirectory o2) {
|
||||
return o1.getVirtualFile().getPresentableUrl().compareTo(o2.getVirtualFile().getPresentableUrl());
|
||||
}
|
||||
};
|
||||
|
||||
final PsiPackage sourcePackage = psiFacade.findPackage(packageName);
|
||||
assertNotNull(sourcePackage);
|
||||
final PsiDirectory[] srcDirectories = sourcePackage.getDirectories();
|
||||
assertEquals(srcDirectories.length, 2);
|
||||
Arrays.sort(srcDirectories, directoryComparator);
|
||||
|
||||
final PsiPackage targetPackage = psiFacade.findPackage(targetPackageName);
|
||||
assertNotNull(targetPackage);
|
||||
final PsiDirectory[] targetDirectories = targetPackage.getDirectories();
|
||||
Arrays.sort(targetDirectories, directoryComparator);
|
||||
assertTrue(targetDirectories.length > 0);
|
||||
|
||||
new MoveDirectoryWithClassesProcessor(getProject(), new PsiDirectory[]{srcDirectories[0]}, targetDirectories[0], false, false, true, null).run();
|
||||
FileDocumentManager.getInstance().saveAllDocuments();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected void setupProject(VirtualFile rootDir) {
|
||||
final ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel();
|
||||
final ContentEntry contentEntry = rootModel.addContentEntry(rootDir);
|
||||
final VirtualFile[] children = rootDir.getChildren();
|
||||
for (VirtualFile child : children) {
|
||||
if (child.getName().startsWith("src")) {
|
||||
contentEntry.addSourceFolder(child, false);
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
rootModel.commit();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -219,6 +219,8 @@ multiple.directories.correspond.to.package=Multiple directories correspond to pa
|
||||
directories.and.all.references.to.package.will.be.renamed=\n\nDo you want to rename the whole package or directory \n{0} only?
|
||||
rename.package.button.text=Rename &package
|
||||
rename.directory.button.text=Rename &directory
|
||||
rename.directories= Rename &all
|
||||
rename.current.directory= Rename ¤t
|
||||
warning.title=Warning
|
||||
replace.constructor.with.factory.method.title=Replace Constructor With Factory Method
|
||||
class.does.not.have.implicit.default.consructor=Class {0} does not have implicit default consructor.
|
||||
|
||||
Reference in New Issue
Block a user