automatic variables renaming when turning refs to super and extracting supers

This commit is contained in:
Eugene Vigdorchik
2005-02-25 17:40:44 +03:00
parent 5add012faa
commit a0cacbc5e7
6 changed files with 107 additions and 40 deletions
@@ -25,7 +25,6 @@ public abstract class ExtractSuperBaseProcessor extends TurnRefsToSuperProcessor
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.extractSuperclass.ExtractSuperClassProcessor");
protected PsiDirectory myTargetDirectory;
protected final String myNewClassName;
protected PsiClass myClass;
protected MemberInfo[] myMemberInfos;
protected final JavaDocPolicy myJavaDocPolicy;
@@ -35,7 +34,7 @@ public abstract class ExtractSuperBaseProcessor extends TurnRefsToSuperProcessor
PsiDirectory targetDirectory,
String newClassName,
PsiClass aClass, MemberInfo[] memberInfos, JavaDocPolicy javaDocPolicy) {
super(project, replaceInstanceOf);
super(project, replaceInstanceOf, newClassName);
myTargetDirectory = targetDirectory;
myNewClassName = newClassName;
myClass = aClass;
@@ -99,7 +98,7 @@ public abstract class ExtractSuperBaseProcessor extends TurnRefsToSuperProcessor
result.add(new BindToOldUsageInfo(element, ref, myClass));
}
}
UsageInfo[] usageInfos = (UsageInfo[]) result.toArray(new UsageInfo[result.size()]);
UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]);
return UsageViewUtil.removeDuplicatedUsages(usageInfos);
}
@@ -125,6 +124,8 @@ public abstract class ExtractSuperBaseProcessor extends TurnRefsToSuperProcessor
catch (IncorrectOperationException e) {
LOG.error(e);
}
performVariablesRenaming();
}
protected abstract PsiClass extractSuper(String superClassName) throws IncorrectOperationException;
@@ -55,7 +55,7 @@ public class AutomaticRenamingDialog extends DialogWrapper {
oldNames.add(oldName);
}
}
myOldNames = (String[])oldNames.toArray(new String[oldNames.size()]);
myOldNames = oldNames.toArray(new String[oldNames.size()]);
myShouldRename = new boolean[myOldNames.length];
myNewNames = new String[myOldNames.length];
Arrays.sort(myOldNames);
@@ -53,7 +53,7 @@ public abstract class AutomaticRenamer <T extends PsiNamedElement> {
return true;
}
public List<? extends PsiNamedElement> getElements() {
public List<? extends T> getElements() {
return Collections.unmodifiableList(myElements);
}
@@ -42,10 +42,6 @@ public class AutomaticVariableRenamer extends AutomaticRenamer<PsiVariable> {
return "Variable";
}
public void findUsages(List<UsageInfo> result, boolean searchInStringsAndComments, boolean searchInNonJavaFiles) {
super.findUsages(result, searchInStringsAndComments, searchInNonJavaFiles);
}
public String nameToCanonicalName(String name, PsiVariable psiVariable) {
final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(psiVariable.getManager());
return codeStyleManager.variableNameToPropertyName(name, codeStyleManager.getVariableKind(psiVariable));
@@ -23,7 +23,7 @@ public class TurnRefsToSuperProcessor extends TurnRefsToSuperProcessorBase {
PsiClass aClass,
PsiClass aSuper,
boolean replaceInstanceOf) {
super(project, replaceInstanceOf);
super(project, replaceInstanceOf, aSuper.getName());
myClass = aClass;
mySuper = aSuper;
}
@@ -51,10 +51,8 @@ public class TurnRefsToSuperProcessor extends TurnRefsToSuperProcessorBase {
}
protected void refreshElements(final PsiElement[] elements) {
final boolean condition = elements.length == 2 && elements[0] instanceof PsiClass && elements[1] instanceof PsiClass;
LOG.assertTrue(condition);
myClass = (PsiClass) elements[0];
mySuper = (PsiClass) elements[1];
LOG.assertTrue(elements.length == 2 && elements[0] instanceof PsiClass && elements[1] instanceof PsiClass);
setClasses ((PsiClass) elements[0], (PsiClass) elements[1]);
}
protected boolean preprocessUsages(UsageInfo[][] usages) {
@@ -65,8 +63,7 @@ public class TurnRefsToSuperProcessor extends TurnRefsToSuperProcessorBase {
return false;
}
prepareSuccessful();
return true;
return super.preprocessUsages(usages);
}
protected void performRefactoring(UsageInfo[] usages) {
@@ -77,6 +74,8 @@ public class TurnRefsToSuperProcessor extends TurnRefsToSuperProcessorBase {
} catch (IncorrectOperationException e) {
LOG.error(e);
}
performVariablesRenaming();
}
protected boolean isInSuper(PsiElement member) {
@@ -2,14 +2,14 @@ package com.intellij.refactoring.turnRefsToSuper;
import com.intellij.internal.diGraph.analyzer.GlobalAnalyzer;
import com.intellij.internal.diGraph.analyzer.Mark;
import com.intellij.internal.diGraph.analyzer.OneEndFunctor;
import com.intellij.internal.diGraph.analyzer.MarkedNode;
import com.intellij.internal.diGraph.analyzer.OneEndFunctor;
import com.intellij.internal.diGraph.impl.EdgeImpl;
import com.intellij.internal.diGraph.impl.NodeImpl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.impl.search.PsiSearchHelperImpl;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.LocalSearchScope;
@@ -18,16 +18,17 @@ import com.intellij.psi.util.PsiSuperMethodUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.rename.AutomaticRenamingDialog;
import com.intellij.refactoring.rename.naming.AutomaticVariableRenamer;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.refactoring.util.MoveRenameUsageInfo;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.Queue;
import com.intellij.util.containers.HashSet;
import com.intellij.util.containers.Queue;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.*;
/**
* @author dsl
@@ -40,10 +41,76 @@ public abstract class TurnRefsToSuperProcessorBase extends BaseRefactoringProces
protected PsiSearchHelper mySearchHelper;
protected HashSet<PsiElement> myMarkedNodes = new HashSet<PsiElement>();
private Queue<PsiExpression> myExpressionsQueue;
protected HashMap<PsiElement,Node> myElementToNode = new HashMap<PsiElement, Node>();
protected HashMap<PsiElement, Node> myElementToNode = new HashMap<PsiElement, Node>();
private Map<PsiVariable, String> myVariablesRenames = new HashMap<PsiVariable, String>();
private final String mySuperClassName;
private List<UsageInfo> myVariablesUsages = new ArrayList<UsageInfo>();
public TurnRefsToSuperProcessorBase(Project project, boolean replaceInstanceOf) {
protected boolean preprocessUsages(UsageInfo[][] usagesRef) {
UsageInfo[] usages = usagesRef[0];
List<UsageInfo> filtered = new ArrayList<UsageInfo>();
for (int i = 0; i < usages.length; i++) {
UsageInfo usage = usages[i];
if (usage instanceof TurnToSuperReferenceUsageInfo) {
filtered.add(usage);
}
}
myVariableRenamer = new AutomaticVariableRenamer(myClass, mySuperClassName, filtered);
if (myVariableRenamer.hasAnythingToRename()) {
final AutomaticRenamingDialog dialog = new AutomaticRenamingDialog(myProject, myVariableRenamer);
dialog.show();
if (!dialog.isOK()) return false;
final List<? extends PsiVariable> variables = myVariableRenamer.getElements();
for (Iterator<? extends PsiVariable> iterator1 = variables.iterator(); iterator1.hasNext();) {
final PsiVariable variable = iterator1.next();
myVariablesRenames.put(variable, myVariableRenamer.getNewName(variable));
}
Runnable runnable = new Runnable() {
public void run() {
myVariableRenamer.findUsages(myVariablesUsages, false, false);
}
};
if (!ApplicationManager.getApplication().runProcessWithProgressSynchronously(
runnable, "Searching for variables", true, myProject)) {
return false;
}
}
prepareSuccessful();
return true;
}
private AutomaticVariableRenamer myVariableRenamer;
protected void performVariablesRenaming() {
try {
for (Iterator<UsageInfo> iterator = myVariablesUsages.iterator(); iterator.hasNext();) {
UsageInfo usage = iterator.next();
if (usage instanceof MoveRenameUsageInfo) {
final MoveRenameUsageInfo renameUsageInfo = ((MoveRenameUsageInfo)usage);
final String newName = myVariablesRenames.get(renameUsageInfo.referencedElement);
renameUsageInfo.reference.handleElementRename(newName);
}
}
final Iterator<Map.Entry<PsiVariable, String>> iterator = myVariablesRenames.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<PsiVariable, String> entry = iterator.next();
entry.getKey().setName(entry.getValue());
}
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
public TurnRefsToSuperProcessorBase(Project project, boolean replaceInstanceOf, String superClassName) {
super(project);
mySuperClassName = superClassName;
myManager = PsiManager.getInstance(project);
mySearchHelper = myManager.getSearchHelper();
myManager = PsiManager.getInstance(myProject);
@@ -70,14 +137,14 @@ public abstract class TurnRefsToSuperProcessorBase extends BaseRefactoringProces
HashSet<PsiFile> fileSet = new HashSet<PsiFile>();
for (int i = 0; i < usages.length; i++) {
UsageInfo usage = usages[i];
if (usage.getElement() == null || !usage.getElement().isValid()) continue;
if (!(usage instanceof TurnToSuperReferenceUsageInfo)) continue;
fileSet.add(usage.getElement().getContainingFile());
PsiElement newElement = usage.getElement().getReference().bindToElement(aSuper);
if (usage instanceof TurnToSuperReferenceUsageInfo && usage.getElement() != null) {
fileSet.add(usage.getElement().getContainingFile());
PsiElement newElement = usage.getElement().getReference().bindToElement(aSuper);
if (newElement.getParent() instanceof PsiTypeElement) {
if (newElement.getParent().getParent() instanceof PsiTypeCastExpression) {
fixPossiblyRedundantCast((PsiTypeCastExpression)newElement.getParent().getParent());
if (newElement.getParent() instanceof PsiTypeElement) {
if (newElement.getParent().getParent() instanceof PsiTypeCastExpression) {
fixPossiblyRedundantCast((PsiTypeCastExpression)newElement.getParent().getParent());
}
}
}
}
@@ -292,16 +359,18 @@ public abstract class TurnRefsToSuperProcessorBase extends BaseRefactoringProces
addLink(type, superType);
}
}
};
}
;
final PsiMethod[] superMethods = PsiSuperMethodUtil.findSuperMethods(method);
new Inner().linkInheritors(superMethods);
final PsiClass[] subClasses = mySearchHelper.findInheritors(method.getContainingClass(), GlobalSearchScope.projectScope(myProject), false);
final PsiClass[] subClasses =
mySearchHelper.findInheritors(method.getContainingClass(), GlobalSearchScope.projectScope(myProject), false);
// ??? In the theory this is non-efficient way: too many inheritors can be processed.
// ??? But in real use it seems reasonably fast. If poor performance problems emerged,
// ??? should be optimized
for (int i1 = 0; i1 != subClasses.length; ++ i1) {
final PsiMethod[] mBSs = subClasses [i1].findMethodsBySignature(method, true);
for (int i1 = 0; i1 != subClasses.length; ++i1) {
final PsiMethod[] mBSs = subClasses[i1].findMethodsBySignature(method, true);
new Inner().linkInheritors(mBSs);
}
}
@@ -340,15 +409,17 @@ public abstract class TurnRefsToSuperProcessorBase extends BaseRefactoringProces
addLink(returnType, superType);
}
}
};
}
;
new Inner().linkInheritors(superMethods);
// ??? In the theory this is non-efficient way: too many inheritors can be processed (and multiple times).
// ??? But in real use it seems reasonably fast. If poor performance problems emerged,
// ??? should be optimized
final PsiClass[] subClasses = mySearchHelper.findInheritors(method.getContainingClass(), GlobalSearchScope.projectScope(myProject), false);
for (int i1 = 0; i1 != subClasses.length; ++ i1) {
final PsiMethod[] mBSs = subClasses [i1].findMethodsBySignature(method, true);
new Inner ().linkInheritors(mBSs);
final PsiClass[] subClasses =
mySearchHelper.findInheritors(method.getContainingClass(), GlobalSearchScope.projectScope(myProject), false);
for (int i1 = 0; i1 != subClasses.length; ++i1) {
final PsiMethod[] mBSs = subClasses[i1].findMethodsBySignature(method, true);
new Inner().linkInheritors(mBSs);
}
}