diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeEvaluator.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeEvaluator.java index 1435dc1f2271..4e4f078c8944 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeEvaluator.java +++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeEvaluator.java @@ -88,6 +88,7 @@ public class TypeEvaluator { e.addFirst(type); + usageInfo.setOwnerRoot(myLabeler.getCurrentRoot()); myTypeMap.put(usageInfo, e); return true; } diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java index d381a958191d..a157daa9946a 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java +++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java @@ -36,13 +36,19 @@ import com.intellij.refactoring.typeMigration.usageInfo.OverridenUsageInfo; import com.intellij.refactoring.typeMigration.usageInfo.OverriderUsageInfo; import com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo; import com.intellij.usageView.UsageInfo; +import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; import com.intellij.util.Query; +import com.intellij.util.containers.*; +import com.intellij.util.graph.DFSTBuilder; +import com.intellij.util.graph.GraphGenerator; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import javax.swing.*; import java.util.*; +import java.util.HashMap; +import java.util.HashSet; /** * @author db @@ -132,15 +138,8 @@ public class TypeMigrationLabeler { int j = 0; - List conversionExprs = new ArrayList(myConversions.keySet()); - Collections.sort(conversionExprs, new Comparator() { - public int compare(final PsiElement e1, final PsiElement e2) { - return e2.getTextRange().getStartOffset() - e1.getTextRange().getStartOffset(); - } - }); - for (final PsiElement element : conversionExprs) { + for (final PsiElement element : myConversions.keySet()) { final Object conv = myConversions.get(element); - usages[j++] = new TypeMigrationUsageInfo(element) { public String getTooltipText() { if (conv instanceof String) { //todo @@ -157,6 +156,11 @@ public class TypeMigrationLabeler { if (conv instanceof TypeConversionDescriptorBase) return ((TypeConversionDescriptorBase)conv).getRoot().isExcluded(); return super.isExcluded(); } + + @Override + public TypeMigrationUsageInfo getOwnerRoot() { + return conv instanceof TypeConversionDescriptorBase ? ((TypeConversionDescriptorBase)conv).getRoot() : null; + } }; } @@ -172,9 +176,75 @@ public class TypeMigrationLabeler { for (final TypeMigrationUsageInfo expr : myNewExpressionTypeChange.keySet()) { usages[j++] = expr; } - return usages; + return sortMigratedUsages(usages); } + private TypeMigrationUsageInfo[] sortMigratedUsages(TypeMigrationUsageInfo[] infos) { + final DFSTBuilder builder = new DFSTBuilder(GraphGenerator.create( + new GraphGenerator.SemiGraph() { + @Override + public Collection getNodes() { + final Set infos = new HashSet(); + for (Map.Entry>> entry : myRootsTree.entrySet()) { + infos.add(entry.getKey()); + infos.addAll(ContainerUtil.map(entry.getValue(), new Function, TypeMigrationUsageInfo>() { + @Override + public TypeMigrationUsageInfo fun(Pair pair) { + return pair.getFirst(); + } + })); + } + return infos; + } + + @Override + public Iterator getIn(TypeMigrationUsageInfo n) { + final HashSet> rawNodes = myRootsTree.get(n); + if (rawNodes == null) { + return Collections.emptyList().iterator(); + } + final List in = + ContainerUtil.map(rawNodes, new Function, TypeMigrationUsageInfo>() { + @Override + public TypeMigrationUsageInfo fun(Pair pair) { + return pair.getFirst(); + } + }); + return in.iterator(); + } + })); + final Comparator cmp = builder.comparator(); + + Arrays.sort(infos, new Comparator() { + @Override + public int compare(final TypeMigrationUsageInfo info1, final TypeMigrationUsageInfo info2) { + final TypeMigrationUsageInfo i1 = info1.getOwnerRoot(); + final TypeMigrationUsageInfo i2 = info2.getOwnerRoot(); + if (i1 == null && i2 == null) { + return 0; + } + if (i1 == null) { + return 1; + } + if (i2 == null) { + return -1; + } + + final int res = cmp.compare(i1, i2); + if (res != 0) { + return res; + } + final PsiElement element1 = info1.getElement(); + final PsiElement element2 = info2.getElement(); + LOG.assertTrue(element1 != null && element2 != null); + return element2.getTextRange().getStartOffset() - element1.getTextRange().getStartOffset(); + } + }); + + return infos; + } + + public void change(final TypeMigrationUsageInfo usageInfo) { final PsiElement element = usageInfo.getElement(); if (element == null) return; @@ -310,7 +380,9 @@ public class TypeMigrationLabeler { return; } - myNewExpressionTypeChange.put(new TypeMigrationUsageInfo(expr), migrationType); + final TypeMigrationUsageInfo usageInfo = new TypeMigrationUsageInfo(expr); + usageInfo.setOwnerRoot(myCurrentRoot); + myNewExpressionTypeChange.put(usageInfo, migrationType); getTypeEvaluator().setType(new TypeMigrationUsageInfo(expr), migrationType); return; } else { @@ -322,7 +394,9 @@ public class TypeMigrationLabeler { final PsiType type = TypeEvaluator.substituteType(migrationType, originalType, true, ((PsiClassType)originalType).resolveGenerics().getElement(), JavaPsiFacade.getElementFactory(expr.getProject()).createType(((PsiClassType)originalType).resolve(), PsiSubstitutor.EMPTY)); if (type != null){ - myNewExpressionTypeChange.put(new TypeMigrationUsageInfo(expr), type); + final TypeMigrationUsageInfo usageInfo = new TypeMigrationUsageInfo(expr); + usageInfo.setOwnerRoot(myCurrentRoot); + myNewExpressionTypeChange.put(usageInfo, type); getTypeEvaluator().setType(new TypeMigrationUsageInfo(expr), type); return; } @@ -384,9 +458,6 @@ public class TypeMigrationLabeler { return false; } - //TODO dmitry batkovich - //type = JavaPsiFacade.getElementFactory(element.getProject()).createTypeFromText(type.getCanonicalText(true), element); - if (resolved instanceof PsiMethod) { final PsiMethod method = ((PsiMethod)resolved); final PsiMethod[] methods = OverridingMethodsSearch.search(method, true).toArray(PsiMethod.EMPTY_ARRAY); @@ -610,18 +681,24 @@ public class TypeMigrationLabeler { return validReferences.toArray(new PsiReference[validReferences.size()]); } - public void migrateRoot(final PsiElement root, final PsiType migrationType, final PsiReference[] usages) { + public void setRootAndMigrate(final TypeMigrationUsageInfo newRootUsageInfo, final PsiType migrationType, final PsiReference[] usages) { + final TypeMigrationUsageInfo oldRoot = getCurrentRoot(); + setCurrentRoot(newRootUsageInfo); + PsiElement root = newRootUsageInfo.getElement(); if (root instanceof PsiMethod) { migrateMethodReturnExpression(migrationType, (PsiMethod)root); } else if (root instanceof PsiParameter && ((PsiParameter)root).getDeclarationScope() instanceof PsiMethod) { migrateMethodCallExpressions(migrationType, (PsiParameter)root, null); } - else if (root instanceof PsiVariable || root instanceof PsiExpression){ + else if (root instanceof PsiVariable || root instanceof PsiExpression) { final PsiElement element = getContainingStatement(root); element.accept(new TypeMigrationStatementProcessor(element, this)); - } else if (root instanceof PsiReferenceParameterList) { - myClassTypeArgumentsChange.put(new TypeMigrationUsageInfo(root), (PsiClassType)migrationType); + } + else if (root instanceof PsiReferenceParameterList) { + final TypeMigrationUsageInfo info = new TypeMigrationUsageInfo(root); + info.setOwnerRoot(oldRoot); + myClassTypeArgumentsChange.put(info, (PsiClassType)migrationType); new ClassTypeArgumentMigrationProcessor(this).migrateClassTypeParameter((PsiReferenceParameterList)root, migrationType); } @@ -726,8 +803,7 @@ public class TypeMigrationLabeler { j = 0; for (final Pair root : roots) { - myCurrentRoot = root.getFirst(); - migrateRoot(root.getFirst().getElement(), root.getSecond(), cachedUsages[j++]); + setRootAndMigrate(root.getFirst(), root.getSecond(), cachedUsages[j++]); } } @@ -760,6 +836,10 @@ public class TypeMigrationLabeler { myCurrentRoot = currentRoot; } + TypeMigrationUsageInfo getCurrentRoot() { + return myCurrentRoot; + } + public LinkedList> getMigrationRoots() { return myMigrationRoots; } diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/ui/MigrationNode.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/ui/MigrationNode.java index 70acb48def6c..08b1679db0d1 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeMigration/ui/MigrationNode.java +++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/ui/MigrationNode.java @@ -81,10 +81,8 @@ public class MigrationNode extends AbstractTreeNode impl final PsiElement element = myInfo.getElement(); if (element != null) { - myLabeler.setCurrentRoot(myInfo); - try { - myLabeler.migrateRoot(element, myMigrationType, myLabeler.markRootUsages(element, myMigrationType)); + myLabeler.setRootAndMigrate(myInfo, myMigrationType, myLabeler.markRootUsages(element, myMigrationType)); } catch (TypeMigrationLabeler.MigrateException e) { //skip warning diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/usageInfo/TypeMigrationUsageInfo.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/usageInfo/TypeMigrationUsageInfo.java index b1a87354df0c..120838a7ce25 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeMigration/usageInfo/TypeMigrationUsageInfo.java +++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/usageInfo/TypeMigrationUsageInfo.java @@ -18,6 +18,7 @@ package com.intellij.refactoring.typeMigration.usageInfo; import com.intellij.psi.PsiElement; import com.intellij.usageView.UsageInfo; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author anna @@ -25,6 +26,7 @@ import org.jetbrains.annotations.NotNull; */ public class TypeMigrationUsageInfo extends UsageInfo { private boolean myExcluded; + private TypeMigrationUsageInfo myOwnerRoot; public TypeMigrationUsageInfo(@NotNull PsiElement element) { @@ -39,4 +41,16 @@ public class TypeMigrationUsageInfo extends UsageInfo { return myExcluded; } + public TypeMigrationUsageInfo getOwnerRoot() { + return myOwnerRoot; + } + + public void setOwnerRoot(TypeMigrationUsageInfo ownerRoot) { + myOwnerRoot = ownerRoot; + } + + @Override + public String toString() { + return getClass().getSimpleName() + ":" + getElement(); + } } diff --git a/java/typeMigration/test/com/intellij/codeInsight/inspections/GuavaInspectionTest.java b/java/typeMigration/test/com/intellij/codeInsight/inspections/GuavaInspectionTest.java index ca47339be872..8afd272fb25a 100644 --- a/java/typeMigration/test/com/intellij/codeInsight/inspections/GuavaInspectionTest.java +++ b/java/typeMigration/test/com/intellij/codeInsight/inspections/GuavaInspectionTest.java @@ -47,19 +47,19 @@ public class GuavaInspectionTest extends JavaCodeInsightFixtureTestCase { moduleBuilder.addJdk(IdeaTestUtil.getMockJdk18Path().getPath()); } - public void _testOptional() { + public void testOptional() { doTest(); } - public void _testOptional2() { + public void testOptional2() { doTest(); } - public void _testSimpleFluentIterable() { + public void testSimpleFluentIterable() { doTest(); } - public void _testChainedFluentIterable() { + public void testChainedFluentIterable() { doTest(); } @@ -67,7 +67,7 @@ public class GuavaInspectionTest extends JavaCodeInsightFixtureTestCase { doTest(); } - public void _testChainedFluentIterableWithChainedInitializer() { + public void testChainedFluentIterableWithChainedInitializer() { doTest(); } diff --git a/java/typeMigration/testData/refactoring/typeMigration/t100/after/test.java b/java/typeMigration/testData/refactoring/typeMigration/t100/after/test.java index b2917c86149e..5204fd518622 100644 --- a/java/typeMigration/testData/refactoring/typeMigration/t100/after/test.java +++ b/java/typeMigration/testData/refactoring/typeMigration/t100/after/test.java @@ -1,6 +1,6 @@ import java.util.*; public class Test { - Map f = new HashMap<>(); + Map f = new HashMap(); } diff --git a/java/typeMigration/testData/refactoring/typeMigration/t33/after/test.java b/java/typeMigration/testData/refactoring/typeMigration/t33/after/test.java index 126292ad9322..34eed3867745 100644 --- a/java/typeMigration/testData/refactoring/typeMigration/t33/after/test.java +++ b/java/typeMigration/testData/refactoring/typeMigration/t33/after/test.java @@ -2,6 +2,6 @@ import java.util.*; class Test { List l; void foo() { - l = new ArrayList<>(); + l = new ArrayList(); } } \ No newline at end of file diff --git a/java/typeMigration/testData/refactoring/typeMigration/t54/after/test.java b/java/typeMigration/testData/refactoring/typeMigration/t54/after/test.java index 11cbc3fe7520..b6edbd7a5eb2 100644 --- a/java/typeMigration/testData/refactoring/typeMigration/t54/after/test.java +++ b/java/typeMigration/testData/refactoring/typeMigration/t54/after/test.java @@ -1,4 +1,4 @@ import java.util.*; class Test { - Set f = new Set<>(); + Set f = new Set(); } \ No newline at end of file diff --git a/java/typeMigration/testData/refactoring/typeMigration/t99/after/test.java b/java/typeMigration/testData/refactoring/typeMigration/t99/after/test.java index 1f7b49a490d9..dea674d39645 100644 --- a/java/typeMigration/testData/refactoring/typeMigration/t99/after/test.java +++ b/java/typeMigration/testData/refactoring/typeMigration/t99/after/test.java @@ -1,6 +1,6 @@ import java.util.*; public class Test { - Set> f = new Set<>(); + Set> f = new Set>(); }