mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-05 01:50:56 +07:00
replace with diamonds should always check if inferred type agrees with expected type (IDEA-73944)
This commit is contained in:
@@ -86,15 +86,16 @@ public class ChangeNewOperatorTypeFix implements IntentionAction {
|
||||
else {
|
||||
final PsiAnonymousClass anonymousClass = originalExpression.getAnonymousClass();
|
||||
newExpression = (PsiNewExpression)factory.createExpressionFromText("new " + toType.getCanonicalText() + "()" + (anonymousClass != null ? "{}" : ""), originalExpression);
|
||||
PsiExpressionList argumentList = originalExpression.getArgumentList();
|
||||
if (argumentList == null) return;
|
||||
newExpression.getArgumentList().replace(argumentList);
|
||||
if (anonymousClass == null) { //just to prevent useless inference
|
||||
if (PsiDiamondTypeUtil.canCollapseToDiamond(newExpression, originalExpression, false)) {
|
||||
if (PsiDiamondTypeUtil.canCollapseToDiamond(newExpression, originalExpression, toType)) {
|
||||
final PsiElement paramList = PsiDiamondTypeUtil.replaceExplicitWithDiamond(newExpression.getClassOrAnonymousClassReference().getParameterList());
|
||||
newExpression = PsiTreeUtil.getParentOfType(paramList, PsiNewExpression.class);
|
||||
}
|
||||
}
|
||||
PsiExpressionList argumentList = originalExpression.getArgumentList();
|
||||
if (argumentList == null) return;
|
||||
newExpression.getArgumentList().replace(argumentList);
|
||||
|
||||
if (anonymousClass != null) {
|
||||
final PsiAnonymousClass newAnonymousClass = (PsiAnonymousClass)newExpression.getAnonymousClass().replace(anonymousClass);
|
||||
final PsiClass aClass = PsiUtil.resolveClassInType(toType);
|
||||
|
||||
@@ -66,7 +66,7 @@ public class ExplicitTypeCanBeDiamondInspection extends BaseJavaLocalInspectionT
|
||||
|
||||
@Override
|
||||
public void visitNewExpression(PsiNewExpression expression) {
|
||||
if (PsiDiamondTypeUtil.canCollapseToDiamond(expression, expression)) {
|
||||
if (PsiDiamondTypeUtil.canCollapseToDiamond(expression, expression, null)) {
|
||||
final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
|
||||
LOG.assertTrue(classReference != null);
|
||||
final PsiReferenceParameterList parameterList = classReference.getParameterList();
|
||||
|
||||
@@ -16,12 +16,11 @@
|
||||
package com.intellij.psi.impl;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInspection.ExplicitTypeCanBeDiamondInspection;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -34,13 +33,9 @@ public class PsiDiamondTypeUtil {
|
||||
private PsiDiamondTypeUtil() {
|
||||
}
|
||||
|
||||
public static boolean canCollapseToDiamond(PsiNewExpression expression, PsiExpression context) {
|
||||
return canCollapseToDiamond(expression, context, true);
|
||||
}
|
||||
|
||||
public static boolean canCollapseToDiamond(PsiNewExpression expression,
|
||||
PsiExpression context,
|
||||
boolean checkAssignable) {
|
||||
public static boolean canCollapseToDiamond(final PsiNewExpression expression,
|
||||
final PsiNewExpression context,
|
||||
final @Nullable PsiType expectedType) {
|
||||
if (PsiUtil.getLanguageLevel(context).isAtLeast(LanguageLevel.JDK_1_7)) {
|
||||
final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
|
||||
if (classReference != null) {
|
||||
@@ -49,11 +44,16 @@ public class PsiDiamondTypeUtil {
|
||||
final PsiTypeElement[] typeElements = parameterList.getTypeParameterElements();
|
||||
if (typeElements.length > 0) {
|
||||
if (typeElements.length == 1 && typeElements[0].getType() instanceof PsiDiamondType) return false;
|
||||
final PsiDiamondType.DiamondInferenceResult inferenceResult = PsiDiamondType.resolveInferredTypes(expression);
|
||||
final PsiDiamondType.DiamondInferenceResult inferenceResult = PsiDiamondType.resolveInferredTypes(expression, context);
|
||||
if (inferenceResult.getErrorMessage() == null) {
|
||||
if (!checkAssignable) return true;
|
||||
final List<PsiType> types = inferenceResult.getInferredTypes();
|
||||
final PsiType[] typeArguments = parameterList.getTypeArguments();
|
||||
PsiType[] typeArguments = null;
|
||||
if (expectedType instanceof PsiClassType) {
|
||||
typeArguments = ((PsiClassType)expectedType).getParameters();
|
||||
}
|
||||
if (typeArguments == null) {
|
||||
typeArguments = parameterList.getTypeArguments();
|
||||
}
|
||||
if (types.size() == typeArguments.length) {
|
||||
for (int i = 0, typeArgumentsLength = typeArguments.length; i < typeArgumentsLength; i++) {
|
||||
PsiType typeArgument = typeArguments[i];
|
||||
|
||||
@@ -749,7 +749,9 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
|
||||
.createVariableDeclarationStatement("x", expectedType, initializer).getDeclaredElements()[0])
|
||||
.getInitializer();
|
||||
if (tryToDetectDiamondNewExpr instanceof PsiNewExpression &&
|
||||
PsiDiamondTypeUtil.canCollapseToDiamond((PsiNewExpression)tryToDetectDiamondNewExpr, initializer)) {
|
||||
PsiDiamondTypeUtil.canCollapseToDiamond((PsiNewExpression)tryToDetectDiamondNewExpr,
|
||||
(PsiNewExpression)tryToDetectDiamondNewExpr,
|
||||
expectedType)) {
|
||||
final PsiElement paramList = PsiDiamondTypeUtil
|
||||
.replaceExplicitWithDiamond(newExpression.getClassOrAnonymousClassReference().getParameterList());
|
||||
return PsiTreeUtil.getParentOfType(paramList, PsiNewExpression.class);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Change 'new Foo<Integer>()' to 'new Foo<Number>()'" "true"
|
||||
|
||||
class Foo<T> {
|
||||
Foo(T t) {}
|
||||
Foo() {}
|
||||
}
|
||||
|
||||
class Constructors {
|
||||
public static void main(String[] args) {
|
||||
Foo<Number> foo2 = new Foo<>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Change 'new Foo<Integer>(...)' to 'new Foo<Number>()'" "true"
|
||||
|
||||
class Foo<T> {
|
||||
Foo(T t) {}
|
||||
Foo() {}
|
||||
}
|
||||
|
||||
class Constructors {
|
||||
public static void main(String[] args) {
|
||||
Foo<Number> foo2 = new Foo<Number>(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Change 'new Foo<Integer>()' to 'new Foo<Number>()'" "true"
|
||||
|
||||
class Foo<T> {
|
||||
Foo(T t) {}
|
||||
Foo() {}
|
||||
}
|
||||
|
||||
class Constructors {
|
||||
public static void main(String[] args) {
|
||||
Foo<Number> foo2 = new Foo<Int<caret>eger>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Change 'new Foo<Integer>(...)' to 'new Foo<Number>()'" "true"
|
||||
|
||||
class Foo<T> {
|
||||
Foo(T t) {}
|
||||
Foo() {}
|
||||
}
|
||||
|
||||
class Constructors {
|
||||
public static void main(String[] args) {
|
||||
Foo<Number> foo2 = new Foo<Int<caret>eger>(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class Test {
|
||||
void foo() {
|
||||
final Foo<Number> a = new Foo<Number>(1);
|
||||
}
|
||||
}
|
||||
|
||||
class Foo<T> {
|
||||
Foo(T t) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class Test {
|
||||
void foo() {
|
||||
new Foo<Num<caret>ber>(1);
|
||||
}
|
||||
}
|
||||
|
||||
class Foo<T> {
|
||||
Foo(T t) {
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.daemon;
|
||||
|
||||
import com.intellij.codeInsight.daemon.quickFix.ChangeNewOperatorTypeTest;
|
||||
import com.intellij.codeInsight.daemon.quickFix.Simplify2DiamondInspectionsTest;
|
||||
import com.intellij.refactoring.*;
|
||||
import junit.framework.Test;
|
||||
@@ -33,6 +34,8 @@ public class DiamondSuite {
|
||||
testSuite.addTestSuite(LightAdvHighlightingJdk7Test.class);
|
||||
testSuite.addTestSuite(Simplify2DiamondInspectionsTest.class);
|
||||
testSuite.addTestSuite(IntroduceParameterTest.class);
|
||||
testSuite.addTestSuite(IntroduceVariableTest.class);
|
||||
testSuite.addTestSuite(ChangeNewOperatorTypeTest.class);
|
||||
return testSuite;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.intellij.util.containers.MultiMap;
|
||||
import junit.framework.Assert;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
@@ -253,6 +254,10 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase {
|
||||
doTest(new MockIntroduceVariableHandler("a", true, true, true, "java.util.ArrayList<java.lang.String>"));
|
||||
}
|
||||
|
||||
public void testCantCollapsedToDiamond() throws Exception {
|
||||
doTest(new MockIntroduceVariableHandler("a", true, true, true, "Foo<java.lang.Number>"));
|
||||
}
|
||||
|
||||
public void testSiblingInnerClassType() throws Exception {
|
||||
doTest(new MockIntroduceVariableHandler("vari", true, false, false, "A.B") {
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user