type migration tries to insert diamond for new expressions at the end of changing

This commit is contained in:
Dmitry Batkovich
2015-10-02 16:24:54 +03:00
parent 15955db1b2
commit 2f73226bfe
3 changed files with 44 additions and 9 deletions
@@ -23,6 +23,7 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiDiamondTypeUtil;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.javadoc.PsiDocTagValue;
import com.intellij.psi.search.PsiSearchScopeUtil;
@@ -36,12 +37,14 @@ 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.Consumer;
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.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
@@ -245,7 +248,7 @@ public class TypeMigrationLabeler {
}
public void change(final TypeMigrationUsageInfo usageInfo) {
public void change(final TypeMigrationUsageInfo usageInfo, @NotNull Consumer<PsiNewExpression> consumer) {
final PsiElement element = usageInfo.getElement();
if (element == null) return;
final Project project = element.getProject();
@@ -255,7 +258,11 @@ public class TypeMigrationLabeler {
for (Map.Entry<TypeMigrationUsageInfo, PsiType> info : myNewExpressionTypeChange.entrySet()) {
final PsiElement expressionToReplace = info.getKey().getElement();
if (expression.equals(expressionToReplace)) {
TypeMigrationReplacementUtil.replaceNewExpressionType(project, (PsiNewExpression)expressionToReplace, info);
final PsiNewExpression newExpression =
TypeMigrationReplacementUtil.replaceNewExpressionType(project, (PsiNewExpression)expressionToReplace, info);
if (newExpression != null) {
consumer.consume(newExpression);
}
}
}
}
@@ -282,6 +289,10 @@ public class TypeMigrationLabeler {
}
}
void postProcessNewExpression(@NotNull PsiNewExpression expression) {
TypeMigrationReplacementUtil.tryToReplaceWithDiamond(expression, null);
}
@Nullable
Object getConversion(PsiElement element) {
return myConversions.get(element);
@@ -33,7 +33,9 @@ import com.intellij.ui.content.Content;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
import com.intellij.usageView.UsageViewManager;
import com.intellij.util.Consumer;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -180,6 +182,8 @@ public class TypeMigrationProcessor extends BaseRefactoringProcessor {
}
public static void change(TypeMigrationLabeler labeler, UsageInfo[] usages) {
final List<PsiNewExpression> newExpressionsToCheckDiamonds = new SmartList<PsiNewExpression>();
List<UsageInfo> nonCodeUsages = new ArrayList<UsageInfo>();
for (UsageInfo usage : usages) {
if (((TypeMigrationUsageInfo)usage).isExcluded()) continue;
@@ -188,12 +192,22 @@ public class TypeMigrationProcessor extends BaseRefactoringProcessor {
element instanceof PsiMember ||
element instanceof PsiExpression ||
element instanceof PsiReferenceParameterList) {
labeler.change((TypeMigrationUsageInfo)usage);
labeler.change((TypeMigrationUsageInfo)usage, new Consumer<PsiNewExpression>() {
@Override
public void consume(@NotNull PsiNewExpression expression) {
newExpressionsToCheckDiamonds.add(expression);
}
});
}
else {
nonCodeUsages.add(usage);
}
}
for (PsiNewExpression newExpression : newExpressionsToCheckDiamonds) {
labeler.postProcessNewExpression(newExpression);
}
for (UsageInfo usageInfo : nonCodeUsages) {
final PsiElement element = usageInfo.getElement();
if (element != null) {
@@ -25,6 +25,7 @@ import com.intellij.psi.impl.source.tree.CompositeElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
@@ -138,7 +139,7 @@ public class TypeMigrationReplacementUtil {
}
}
static void replaceNewExpressionType(final Project project, final PsiNewExpression expression, final Map.Entry<TypeMigrationUsageInfo, PsiType> info) {
static PsiNewExpression replaceNewExpressionType(final Project project, final PsiNewExpression expression, final Map.Entry<TypeMigrationUsageInfo, PsiType> info) {
final PsiType changeType = info.getValue();
if (changeType != null) {
try {
@@ -147,11 +148,8 @@ public class TypeMigrationReplacementUtil {
if (classReference != null) {
final PsiElement psiElement = replaceTypeWithClassReferenceOrKeyword(project, componentType, classReference);
final PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(psiElement, PsiNewExpression.class);
if (newExpression != null && PsiDiamondTypeUtil.canCollapseToDiamond(newExpression, newExpression, changeType)) {
final PsiJavaCodeReferenceElement anonymousClassReference = newExpression.getClassOrAnonymousClassReference();
if (anonymousClassReference != null) {
PsiDiamondTypeUtil.replaceExplicitWithDiamond(anonymousClassReference.getParameterList());
}
if (!tryToReplaceWithDiamond(newExpression, changeType)) {
return newExpression;
}
}
else {
@@ -165,6 +163,18 @@ public class TypeMigrationReplacementUtil {
LOG.error(e);
}
}
return null;
}
static boolean tryToReplaceWithDiamond(PsiNewExpression newExpression, @Nullable PsiType changeType) {
if (newExpression != null && PsiDiamondTypeUtil.canCollapseToDiamond(newExpression, newExpression, changeType)) {
final PsiJavaCodeReferenceElement anonymousClassReference = newExpression.getClassOrAnonymousClassReference();
if (anonymousClassReference != null) {
PsiDiamondTypeUtil.replaceExplicitWithDiamond(anonymousClassReference.getParameterList());
}
return true;
}
return false;
}
private static PsiElement replaceTypeWithClassReferenceOrKeyword(Project project, PsiType componentType, PsiElement typePlace) {