guava type migration: type migration usages sorting algorithm changed

This commit is contained in:
Dmitry Batkovich
2015-10-02 15:24:15 +03:00
parent b7b3d67cca
commit 71c6c77578
9 changed files with 125 additions and 32 deletions
@@ -88,6 +88,7 @@ public class TypeEvaluator {
e.addFirst(type);
usageInfo.setOwnerRoot(myLabeler.getCurrentRoot());
myTypeMap.put(usageInfo, e);
return true;
}
@@ -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<PsiElement> conversionExprs = new ArrayList<PsiElement>(myConversions.keySet());
Collections.sort(conversionExprs, new Comparator<PsiElement>() {
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<TypeMigrationUsageInfo> builder = new DFSTBuilder<TypeMigrationUsageInfo>(GraphGenerator.create(
new GraphGenerator.SemiGraph<TypeMigrationUsageInfo>() {
@Override
public Collection<TypeMigrationUsageInfo> getNodes() {
final Set<TypeMigrationUsageInfo> infos = new HashSet<TypeMigrationUsageInfo>();
for (Map.Entry<TypeMigrationUsageInfo, HashSet<Pair<TypeMigrationUsageInfo, PsiType>>> entry : myRootsTree.entrySet()) {
infos.add(entry.getKey());
infos.addAll(ContainerUtil.map(entry.getValue(), new Function<Pair<TypeMigrationUsageInfo, PsiType>, TypeMigrationUsageInfo>() {
@Override
public TypeMigrationUsageInfo fun(Pair<TypeMigrationUsageInfo, PsiType> pair) {
return pair.getFirst();
}
}));
}
return infos;
}
@Override
public Iterator<TypeMigrationUsageInfo> getIn(TypeMigrationUsageInfo n) {
final HashSet<Pair<TypeMigrationUsageInfo, PsiType>> rawNodes = myRootsTree.get(n);
if (rawNodes == null) {
return Collections.<TypeMigrationUsageInfo>emptyList().iterator();
}
final List<TypeMigrationUsageInfo> in =
ContainerUtil.map(rawNodes, new Function<Pair<TypeMigrationUsageInfo, PsiType>, TypeMigrationUsageInfo>() {
@Override
public TypeMigrationUsageInfo fun(Pair<TypeMigrationUsageInfo, PsiType> pair) {
return pair.getFirst();
}
});
return in.iterator();
}
}));
final Comparator<TypeMigrationUsageInfo> cmp = builder.comparator();
Arrays.sort(infos, new Comparator<TypeMigrationUsageInfo>() {
@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<TypeMigrationUsageInfo, PsiType> 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<Pair<TypeMigrationUsageInfo, PsiType>> getMigrationRoots() {
return myMigrationRoots;
}
@@ -81,10 +81,8 @@ public class MigrationNode extends AbstractTreeNode<TypeMigrationUsageInfo> 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
@@ -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();
}
}
@@ -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();
}
@@ -1,6 +1,6 @@
import java.util.*;
public class Test {
Map<String, Integer> f = new HashMap<>();
Map<String, Integer> f = new HashMap<String, Integer>();
}
@@ -2,6 +2,6 @@ import java.util.*;
class Test {
List<Integer> l;
void foo() {
l = new ArrayList<>();
l = new ArrayList<Integer>();
}
}
@@ -1,4 +1,4 @@
import java.util.*;
class Test {
Set<? extends Integer> f = new Set<>();
Set<? extends Integer> f = new Set<Integer>();
}
@@ -1,6 +1,6 @@
import java.util.*;
public class Test {
Set<List<int[]>> f = new Set<>();
Set<List<int[]>> f = new Set<List<int[]>>();
}