mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
rename: balloon notification about filtered unresolvable collisions (IDEA-56611)
This commit is contained in:
@@ -17,12 +17,18 @@
|
||||
package com.intellij.refactoring.rename;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.IdeFrame;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
import com.intellij.openapi.wm.ex.StatusBarEx;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import com.intellij.psi.impl.light.LightElement;
|
||||
@@ -39,6 +45,7 @@ import com.intellij.refactoring.util.RelatedUsageInfo;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.usageView.UsageViewDescriptor;
|
||||
import com.intellij.usageView.UsageViewUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
@@ -46,6 +53,8 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import java.util.*;
|
||||
|
||||
public class RenameProcessor extends BaseRefactoringProcessor {
|
||||
@@ -65,6 +74,7 @@ public class RenameProcessor extends BaseRefactoringProcessor {
|
||||
private NonCodeUsageInfo[] myNonCodeUsages = new NonCodeUsageInfo[0];
|
||||
private final List<AutomaticRenamerFactory> myRenamerFactories = new ArrayList<AutomaticRenamerFactory>();
|
||||
private final List<AutomaticRenamer> myRenamers = new ArrayList<AutomaticRenamer>();
|
||||
private final List<UnresolvableCollisionUsageInfo> mySkippedUsages = new ArrayList<UnresolvableCollisionUsageInfo>();
|
||||
|
||||
public RenameProcessor(Project project,
|
||||
PsiElement element,
|
||||
@@ -139,8 +149,6 @@ public class RenameProcessor extends BaseRefactoringProcessor {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Set<UsageInfo> usagesSet = new HashSet<UsageInfo>(Arrays.asList(usagesIn));
|
||||
RenameUtil.removeConflictUsages(usagesSet);
|
||||
|
||||
final List<UsageInfo> variableUsages = new ArrayList<UsageInfo>();
|
||||
if (!myRenamers.isEmpty()) {
|
||||
@@ -174,10 +182,13 @@ public class RenameProcessor extends BaseRefactoringProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
if (!variableUsages.isEmpty()) {
|
||||
usagesSet.addAll(variableUsages);
|
||||
refUsages.set(usagesSet.toArray(new UsageInfo[usagesSet.size()]));
|
||||
final Set<UsageInfo> usagesSet = new HashSet<UsageInfo>(Arrays.asList(usagesIn));
|
||||
usagesSet.addAll(variableUsages);
|
||||
final List<UnresolvableCollisionUsageInfo> conflictUsages = RenameUtil.removeConflictUsages(usagesSet);
|
||||
if (conflictUsages != null) {
|
||||
mySkippedUsages.addAll(conflictUsages);
|
||||
}
|
||||
refUsages.set(usagesSet.toArray(new UsageInfo[usagesSet.size()]));
|
||||
|
||||
prepareSuccessful();
|
||||
return true;
|
||||
@@ -192,7 +203,7 @@ public class RenameProcessor extends BaseRefactoringProcessor {
|
||||
final Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
for (final AutomaticRenamer renamer : myRenamers) {
|
||||
renamer.findUsages(variableUsages, mySearchInComments, mySearchTextOccurrences);
|
||||
renamer.findUsages(variableUsages, mySearchInComments, mySearchTextOccurrences, mySkippedUsages);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -326,6 +337,32 @@ public class RenameProcessor extends BaseRefactoringProcessor {
|
||||
}
|
||||
}
|
||||
myNonCodeUsages = nonCodeUsages.toArray(new NonCodeUsageInfo[nonCodeUsages.size()]);
|
||||
if (!mySkippedUsages.isEmpty()) {
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode() && !ApplicationManager.getApplication().isHeadlessEnvironment()) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
final IdeFrame ideFrame = WindowManager.getInstance().getIdeFrame(myProject);
|
||||
if (ideFrame != null) {
|
||||
|
||||
StatusBarEx statusBar = (StatusBarEx)ideFrame.getStatusBar();
|
||||
HyperlinkListener listener = new HyperlinkListener() {
|
||||
public void hyperlinkUpdate(HyperlinkEvent e) {
|
||||
if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED) return;
|
||||
Messages.showMessageDialog("<html>" +
|
||||
StringUtil.join(mySkippedUsages, new Function<UnresolvableCollisionUsageInfo, String>() {
|
||||
public String fun(UnresolvableCollisionUsageInfo unresolvableCollisionUsageInfo) {
|
||||
return unresolvableCollisionUsageInfo.getDescription();
|
||||
}
|
||||
}, "<br>") +
|
||||
"</html>", "Don't panic! They are safe to skip", null);
|
||||
}
|
||||
};
|
||||
statusBar.notifyProgressByBalloon(MessageType.WARNING, "<html><body>Unable to rename certain usages. <a href=\"\">Browse</a></body></html>", null, listener);
|
||||
}
|
||||
}
|
||||
}, ModalityState.NON_MODAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void performPsiSpoilingRefactoring() {
|
||||
|
||||
@@ -239,13 +239,17 @@ public class RenameUtil {
|
||||
ref.handleElementRename(newName);
|
||||
}
|
||||
|
||||
public static void removeConflictUsages(Set<UsageInfo> usages) {
|
||||
@Nullable
|
||||
public static List<UnresolvableCollisionUsageInfo> removeConflictUsages(Set<UsageInfo> usages) {
|
||||
final List<UnresolvableCollisionUsageInfo> result = new ArrayList<UnresolvableCollisionUsageInfo>();
|
||||
for (Iterator<UsageInfo> iterator = usages.iterator(); iterator.hasNext();) {
|
||||
UsageInfo usageInfo = iterator.next();
|
||||
if (usageInfo instanceof UnresolvableCollisionUsageInfo) {
|
||||
result.add((UnresolvableCollisionUsageInfo)usageInfo);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
return result.isEmpty() ? null : result;
|
||||
}
|
||||
|
||||
public static void addConflictDescriptions(UsageInfo[] usages, MultiMap<PsiElement, String> conflicts) {
|
||||
|
||||
+15
-3
@@ -47,9 +47,16 @@ public abstract class AutomaticRenamer {
|
||||
}
|
||||
|
||||
public void findUsages(List<UsageInfo> result, final boolean searchInStringsAndComments, final boolean searchInNonJavaFiles) {
|
||||
findUsages(result, searchInStringsAndComments, searchInNonJavaFiles, null);
|
||||
}
|
||||
|
||||
public void findUsages(List<UsageInfo> result,
|
||||
final boolean searchInStringsAndComments,
|
||||
final boolean searchInNonJavaFiles,
|
||||
List<UnresolvableCollisionUsageInfo> unresolvedUsages) {
|
||||
for (Iterator<PsiNamedElement> iterator = myElements.iterator(); iterator.hasNext();) {
|
||||
final PsiNamedElement variable = iterator.next();
|
||||
final boolean success = findUsagesForElement(variable, result, searchInStringsAndComments, searchInNonJavaFiles);
|
||||
final boolean success = findUsagesForElement(variable, result, searchInStringsAndComments, searchInNonJavaFiles, unresolvedUsages);
|
||||
if (!success) {
|
||||
iterator.remove();
|
||||
}
|
||||
@@ -59,12 +66,17 @@ public abstract class AutomaticRenamer {
|
||||
private boolean findUsagesForElement(PsiNamedElement element,
|
||||
List<UsageInfo> result,
|
||||
final boolean searchInStringsAndComments,
|
||||
final boolean searchInNonJavaFiles) {
|
||||
final boolean searchInNonJavaFiles, List<UnresolvableCollisionUsageInfo> unresolvedUsages) {
|
||||
final String newName = getNewName(element);
|
||||
if (newName != null) {
|
||||
final UsageInfo[] usages = RenameUtil.findUsages(element, newName, searchInStringsAndComments, searchInNonJavaFiles, myRenames);
|
||||
for (final UsageInfo usage : usages) {
|
||||
if (usage instanceof UnresolvableCollisionUsageInfo) return false;
|
||||
if (usage instanceof UnresolvableCollisionUsageInfo) {
|
||||
if (unresolvedUsages != null) {
|
||||
unresolvedUsages.add((UnresolvableCollisionUsageInfo)usage);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ContainerUtil.addAll(result, usages);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user