diamonds: expand them on if to conditional expression replacement (IDEA-73987)

This commit is contained in:
anna
2011-09-08 19:27:52 +02:00
parent b294192ac2
commit 24fe648832
9 changed files with 130 additions and 35 deletions
@@ -17,9 +17,13 @@ package com.intellij.psi.impl;
import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Function;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -96,4 +100,49 @@ public class PsiDiamondTypeUtil {
}
return psiElement;
}
public static PsiElement replaceDiamondWithExplicitTypes(PsiElement element) {
final PsiElement parent = element.getParent();
if (!(parent instanceof PsiJavaCodeReferenceElement)) {
return parent;
}
final PsiJavaCodeReferenceElement javaCodeReferenceElement =
(PsiJavaCodeReferenceElement) parent;
final PsiReferenceParameterList referenceParameterList =
(PsiReferenceParameterList) element;
final StringBuilder text = new StringBuilder();
text.append(javaCodeReferenceElement.getQualifiedName());
text.append('<');
final PsiTypeElement[] typeElements = referenceParameterList.getTypeParameterElements();
final PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(typeElements[0], PsiNewExpression.class);
final PsiDiamondType.DiamondInferenceResult result = PsiDiamondType.resolveInferredTypesNoCheck(newExpression, newExpression);
text.append(StringUtil.join(result.getInferredTypes(), new Function<PsiType, String>() {
@Override
public String fun(PsiType psiType) {
return psiType.getCanonicalText();
}
}, ","));
text.append('>');
final PsiElementFactory elementFactory =
JavaPsiFacade.getElementFactory(element.getProject());
final PsiJavaCodeReferenceElement newReference =
elementFactory.createReferenceFromText(text.toString(), element);
return CodeStyleManager.getInstance(javaCodeReferenceElement.getProject()).reformat(javaCodeReferenceElement.replace(newReference));
}
public static PsiExpression expandTopLevelDiamondsInside(PsiExpression expr) {
if (expr instanceof PsiNewExpression) {
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)expr).getClassReference();
if (classReference != null) {
final PsiReferenceParameterList parameterList = classReference.getParameterList();
if (parameterList != null) {
final PsiTypeElement[] typeParameterElements = parameterList.getTypeParameterElements();
if (typeParameterElements.length == 1 && typeParameterElements[0].getType() instanceof PsiDiamondType) {
return (PsiExpression)replaceDiamondWithExplicitTypes(parameterList).getParent();
}
}
}
}
return expr;
}
}
@@ -16,6 +16,7 @@
<orderEntry type="module" module-name="jsp-openapi" />
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
<orderEntry type="module" module-name="lang-impl" />
<orderEntry type="module" module-name="java-impl" />
</component>
</module>
@@ -16,6 +16,7 @@
package com.siyeh.ipp.trivialif;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiDiamondTypeUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.ipp.base.Intention;
@@ -148,11 +149,11 @@ public class ReplaceIfWithConditionalIntention extends Intention {
PsiExpression elseValue,
PsiType requiredType) {
condition = ParenthesesUtils.stripParentheses(condition);
thenValue = ParenthesesUtils.stripParentheses(thenValue);
thenValue = PsiDiamondTypeUtil.expandTopLevelDiamondsInside(ParenthesesUtils.stripParentheses(thenValue));
if (thenValue == null) {
return null;
}
elseValue = ParenthesesUtils.stripParentheses(elseValue);
elseValue = PsiDiamondTypeUtil.expandTopLevelDiamondsInside(ParenthesesUtils.stripParentheses(elseValue));
if (elseValue == null) {
return null;
}
@@ -16,15 +16,12 @@
package com.siyeh.ipp.types;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.impl.PsiDiamondTypeUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.ipp.base.Intention;
import com.siyeh.ipp.base.PsiElementPredicate;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
public class ReplaceDiamondWithExplicitTypeArgumentsIntention extends Intention {
@NotNull
@@ -36,34 +33,6 @@ public class ReplaceDiamondWithExplicitTypeArgumentsIntention extends Intention
@Override
protected void processIntention(@NotNull PsiElement element)
throws IncorrectOperationException {
final PsiElement parent = element.getParent();
if (!(parent instanceof PsiJavaCodeReferenceElement)) {
return;
}
final PsiJavaCodeReferenceElement javaCodeReferenceElement =
(PsiJavaCodeReferenceElement) parent;
final PsiReferenceParameterList referenceParameterList =
(PsiReferenceParameterList) element;
final StringBuilder text = new StringBuilder();
text.append(javaCodeReferenceElement.getQualifiedName());
text.append('<');
final PsiTypeElement[] typeElements = referenceParameterList.getTypeParameterElements();
final PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(typeElements[0], PsiNewExpression.class);
final PsiDiamondType.DiamondInferenceResult result = PsiDiamondType.resolveInferredTypesNoCheck(newExpression, newExpression);
boolean first = true;
for (PsiType typeArgument : result.getInferredTypes()) {
if (first) {
first = false;
} else {
text.append(',');
}
text.append(typeArgument.getCanonicalText());
}
text.append('>');
final PsiElementFactory elementFactory =
JavaPsiFacade.getElementFactory(element.getProject());
final PsiJavaCodeReferenceElement newReference =
elementFactory.createReferenceFromText(text.toString(), element);
CodeStyleManager.getInstance(javaCodeReferenceElement.getProject()).reformat(javaCodeReferenceElement.replace(newReference));
PsiDiamondTypeUtil.replaceDiamondWithExplicitTypes(element);
}
}
@@ -0,0 +1,10 @@
import java.util.*;
class Test {
public void multiAssignment(boolean b) {
List<Integer> l;
if <caret>(b) {
l = new ArrayList<>(1);
} else l = new ArrayList<>(3);
}
}
@@ -0,0 +1,8 @@
import java.util.*;
class Test {
public void multiAssignment(boolean b) {
List<Integer> l;
l = b ? new ArrayList<Integer>(1) : new ArrayList<Integer>(3);
}
}
@@ -0,0 +1,10 @@
import java.util.*;
class Test {
public List<Integer> multiReturn(boolean b) {
if <caret>(b) {
return new ArrayList<>(1);
}
else return new ArrayList<>(3);
}
}
@@ -0,0 +1,7 @@
import java.util.*;
class Test {
public List<Integer> multiReturn(boolean b) {
return b ? new ArrayList<Integer>(1) : new ArrayList<Integer>(3);
}
}
@@ -0,0 +1,40 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ipp.trivialif;
import com.siyeh.IntentionPowerPackBundle;
import com.siyeh.ipp.IPPTestCase;
public class ReplaceIfWithConditionalIntentionTest extends IPPTestCase {
public void testReturnValueWithDiamonds() {
doTest();
}
public void testReplaceableAssignmentsWithDiamonds() {
doTest();
}
@Override
protected String getIntentionName() {
return IntentionPowerPackBundle.message("replace.if.with.conditional.intention.name");
}
@Override
protected String getRelativePath() {
return "trivialif/replaceIfWithConditional";
}
}