rename package: allow to rename by FQN (IDEA-74132)

This commit is contained in:
Anna Kozlova
2014-09-29 09:38:04 +02:00
parent aaa8a2dbe6
commit a2f68bb5d8
5 changed files with 96 additions and 11 deletions
@@ -42,9 +42,6 @@ public class PsiPackageRenameValidator implements RenameInputValidatorEx {
if (!PsiDirectoryFactory.getInstance(project).isValidPackageName(newName)) {
return "Not a valid package name";
}
if (!PsiNameHelper.getInstance(project).isIdentifier(newName)) {
return "Not a valid identifier name";
}
}
return null;
}
@@ -16,13 +16,20 @@
package com.intellij.refactoring.rename;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Comparing;
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.psi.util.PsiUtilCore;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.JavaRefactoringSettings;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.refactoring.move.moveClassesOrPackages.MoveDirectoryWithClassesProcessor;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.MultiMap;
@@ -36,19 +43,78 @@ import java.util.Map;
* @author yole
*/
public class RenamePsiPackageProcessor extends RenamePsiElementProcessor {
private final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.RenamePsiPackageProcessor");
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.RenamePsiPackageProcessor");
public boolean canProcessElement(@NotNull final PsiElement element) {
return element instanceof PsiPackage;
}
@Override
public RenameDialog createRenameDialog(final Project project, final PsiElement element, PsiElement nameSuggestionContext, Editor editor) {
return new RenameDialog(project, element, nameSuggestionContext, editor) {
@Override
protected void createNewNameComponent() {
super.createNewNameComponent();
final String qualifiedName = ((PsiPackage)element).getQualifiedName();
final String packageName = StringUtil.getPackageName(qualifiedName);
preselectExtension(packageName.isEmpty() ? 0 : packageName.length() + 1, qualifiedName.length());
}
@Override
public String[] getSuggestedNames() {
return new String[]{((PsiPackage)element).getQualifiedName()};
}
protected void doAction() {
final PsiPackage psiPackage = (PsiPackage)element;
final String oldName = psiPackage.getQualifiedName();
final String newName = getNewName();
if (!Comparing.strEqual(StringUtil.getPackageName(oldName), StringUtil.getPackageName(newName))) {
final ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex();
final PsiDirectory[] directories = psiPackage.getDirectories();
invokeRefactoring(new MoveDirectoryWithClassesProcessor(myProject, directories, null, isSearchInComments(),
isSearchInNonJavaFiles(), false, null) {
@Override
public TargetDirectoryWrapper getTargetDirectory(final PsiDirectory dir) {
final VirtualFile sourceRoot = index.getSourceRootForFile(dir.getVirtualFile());
LOG.assertTrue(sourceRoot != null);
return new TargetDirectoryWrapper(dir.getManager().findDirectory(sourceRoot), newName.replaceAll("\\.", "\\/"));
}
@Override
public void performRefactoring(UsageInfo[] usages) {
super.performRefactoring(usages);
for (PsiDirectory directory : directories) {
directory.delete();
}
}
@Override
protected String getTargetName() {
return newName;
}
@Override
protected String getCommandName() {
return "Rename package";
}
});
} else {
super.doAction();
}
}
};
}
public void renameElement(final PsiElement element,
final String newName,
final UsageInfo[] usages,
@Nullable RefactoringElementListener listener) throws IncorrectOperationException {
final PsiPackage psiPackage = (PsiPackage)element;
psiPackage.handleQualifiedNameChange(PsiUtilCore.getQualifiedNameAfterRename(psiPackage.getQualifiedName(), newName));
RenameUtil.doRenameGenericNamedElement(element, newName, usages, listener);
final String shortName = StringUtil.getShortName(newName);
psiPackage.handleQualifiedNameChange(PsiUtilCore.getQualifiedNameAfterRename(psiPackage.getQualifiedName(), shortName));
RenameUtil.doRenameGenericNamedElement(element, shortName, usages, listener);
}
public String getQualifiedNameAfterRename(final PsiElement element, final String newName, final boolean nonJava) {
@@ -82,10 +148,11 @@ public class RenamePsiPackageProcessor extends RenamePsiElementProcessor {
}
public static void preparePackageRenaming(PsiPackage psiPackage, final String newName, Map<PsiElement, String> allRenames) {
final String newDirectoryName = StringUtil.getShortName(newName);
final PsiDirectory[] directories = psiPackage.getDirectories();
for (PsiDirectory directory : directories) {
if (!JavaDirectoryService.getInstance().isSourceRoot(directory)) {
allRenames.put(directory, newName);
allRenames.put(directory, newDirectoryName);
}
}
}
@@ -295,11 +295,15 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor
public PsiDirectory findOrCreateTargetDirectory() throws IncorrectOperationException{
if (myTargetDirectory == null) {
final PsiDirectory root = myParentDirectory.findOrCreateTargetDirectory();
PsiDirectory root = myParentDirectory.findOrCreateTargetDirectory();
myTargetDirectory = root.findSubdirectory(myRelativePath);
if (myTargetDirectory == null) {
myTargetDirectory = root.createSubdirectory(myRelativePath);
final String[] pathComponents = myRelativePath.split("/");
for (String component : pathComponents) {
myTargetDirectory = root.findSubdirectory(component);
if (myTargetDirectory == null) {
myTargetDirectory = root.createSubdirectory(component);
}
root = myTargetDirectory;
}
}
return myTargetDirectory;
@@ -163,6 +163,10 @@ public class RenameDialog extends RefactoringDialog {
}
protected void preselectExtension(int start, int end) {
myNameSuggestionsField.select(start, end);
}
protected void processNewNameChanged() {
validateButtons();
}
@@ -138,6 +138,19 @@ public class NameSuggestionsField extends JPanel {
}
public void select(final int start, final int end) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Editor editor = getEditor();
if (editor == null) return;
editor.getSelectionModel().setSelection(start, end);
editor.getCaretModel().moveToOffset(end);
}
});
}
public void setSuggestions(final String[] suggestions) {
if(myComboBoxModel == null) return;
JComboBox comboBox = (JComboBox) myComponent;