do not replace diamonds without necessity (IDEA-87172)

This commit is contained in:
Anna Kozlova
2012-06-08 16:07:19 +04:00
parent c6953ea96b
commit 78cf87d2c8
9 changed files with 111 additions and 4 deletions
@@ -40,6 +40,18 @@ public class PsiDiamondTypeUtil {
public static boolean canCollapseToDiamond(final PsiNewExpression expression,
final PsiNewExpression context,
final @Nullable PsiType expectedType) {
return canCollapseToDiamond(expression, context, expectedType, false);
}
public static boolean canChangeContextForDiamond(final PsiNewExpression expression, final PsiType expectedType) {
final PsiNewExpression copy = (PsiNewExpression)expression.copy();
return canCollapseToDiamond(copy, copy, expectedType, true);
}
private static boolean canCollapseToDiamond(final PsiNewExpression expression,
final PsiNewExpression context,
final @Nullable PsiType expectedType,
boolean skipDiamonds) {
if (PsiUtil.getLanguageLevel(context).isAtLeast(LanguageLevel.JDK_1_7)) {
final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
if (classReference != null) {
@@ -47,7 +59,7 @@ public class PsiDiamondTypeUtil {
if (parameterList != null) {
final PsiTypeElement[] typeElements = parameterList.getTypeParameterElements();
if (typeElements.length > 0) {
if (typeElements.length == 1 && typeElements[0].getType() instanceof PsiDiamondType) return false;
if (!skipDiamonds && typeElements.length == 1 && typeElements[0].getType() instanceof PsiDiamondType) return false;
final PsiDiamondTypeImpl.DiamondInferenceResult inferenceResult = PsiDiamondTypeImpl.resolveInferredTypes(expression, context);
if (inferenceResult.getErrorMessage() == null) {
final List<PsiType> types = inferenceResult.getInferredTypes();
@@ -94,7 +94,9 @@ public class JavaIntroduceParameterMethodUsagesProcessor implements IntroducePar
ExpressionConverter.getExpression(data.getParameterInitializer().getExpression(), StdLanguages.JAVA, data.getProject());
assert initializer instanceof PsiExpression;
if (initializer instanceof PsiNewExpression) {
initializer = PsiDiamondTypeUtil.expandTopLevelDiamondsInside((PsiNewExpression)initializer);
if (!PsiDiamondTypeUtil.canChangeContextForDiamond((PsiNewExpression)initializer, ((PsiNewExpression)initializer).getType())) {
initializer = PsiDiamondTypeUtil.expandTopLevelDiamondsInside((PsiNewExpression)initializer);
}
}
substituteTypeParametersInInitializer(initializer, callExpression, argList, methodToSearchFor);
ChangeContextUtil.encodeContextInfo(initializer, true);
@@ -0,0 +1,22 @@
public class TestCompletion {
public static <T, V> ParallelPipeline<T, V> test(T base, V newStage, T upstream, final ParallelPipeline<T, V> anObject) {
if (base != null){
return anObject;
}
else {
return new ParallelPipeline<>(upstream, newStage);
}
}
void f() {
test(null, null, null, new ParallelPipeline<>(null, null));
}
private static class ParallelPipeline<T, V> {
public ParallelPipeline(T p0, V p1) {
}
}
}
@@ -0,0 +1,22 @@
public class TestCompletion {
public static <T, V> ParallelPipeline<T, V> test(T base, V newStage, T upstream) {
if (base != null){
return <selection>new ParallelPipeline<>(base, newStage)</selection>;
}
else {
return new ParallelPipeline<>(upstream, newStage);
}
}
void f() {
test(null, null, null);
}
private static class ParallelPipeline<T, V> {
public ParallelPipeline(T p0, V p1) {
}
}
}
@@ -275,6 +275,10 @@ public class IntroduceParameterTest extends LightRefactoringTestCase {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL, true, false, true, false);
}
public void testPreserveDiamondOccurrences() throws Exception {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL, true, false, true, false);
}
public void testSubstituteTypeParams() throws Exception {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL, true, false, true, false);
}
@@ -170,11 +170,14 @@ public class ReplaceIfWithConditionalIntention extends Intention {
PsiExpression elseValue,
PsiType requiredType) {
condition = ParenthesesUtils.stripParentheses(condition);
thenValue = PsiDiamondTypeUtil.expandTopLevelDiamondsInside(ParenthesesUtils.stripParentheses(thenValue));
thenValue = ParenthesesUtils.stripParentheses(thenValue);
elseValue = ParenthesesUtils.stripParentheses(elseValue);
thenValue = expandDiamondsWhenNeeded(thenValue, requiredType);
if (thenValue == null) {
return null;
}
elseValue = PsiDiamondTypeUtil.expandTopLevelDiamondsInside(ParenthesesUtils.stripParentheses(elseValue));
elseValue = expandDiamondsWhenNeeded(elseValue, requiredType);
if (elseValue == null) {
return null;
}
@@ -217,6 +220,15 @@ public class ReplaceIfWithConditionalIntention extends Intention {
return conditional.toString();
}
private static PsiExpression expandDiamondsWhenNeeded(PsiExpression thenValue, PsiType requiredType) {
if (thenValue instanceof PsiNewExpression) {
if (!PsiDiamondTypeUtil.canChangeContextForDiamond((PsiNewExpression)thenValue, requiredType)) {
return PsiDiamondTypeUtil.expandTopLevelDiamondsInside(thenValue);
}
}
return thenValue;
}
private static String getExpressionText(PsiExpression expression) {
if (ParenthesesUtils.getPrecedence(expression) <=
ParenthesesUtils.CONDITIONAL_PRECEDENCE) {
@@ -0,0 +1,17 @@
public class TestCompletion {
public static <T, V> ParallelPipeline<T, V> test(T base, V newStage, T upstream) {
if <caret>(base != null) {
return new ParallelPipeline<>(base, newStage);
}
else {
return new ParallelPipeline<>(upstream, newStage);
}
}
private static class ParallelPipeline<T, V> {
public ParallelPipeline(T p0, V p1) {
}
}
}
@@ -0,0 +1,12 @@
public class TestCompletion {
public static <T, V> ParallelPipeline<T, V> test(T base, V newStage, T upstream) {
return base != null ? new ParallelPipeline<>(base, newStage) : new ParallelPipeline<>(upstream, newStage);
}
private static class ParallelPipeline<T, V> {
public ParallelPipeline(T p0, V p1) {
}
}
}
@@ -28,6 +28,10 @@ public class ReplaceIfWithConditionalIntentionTest extends IPPTestCase {
doTest();
}
public void testReplaceableAssignmentsWithDiamondsLeave() {
doTest();
}
@Override
protected String getIntentionName() {
return IntentionPowerPackBundle.message("replace.if.with.conditional.intention.name");