java conditional: set type null if one of sides is null and exp is poly expressions (IDEA-244854)

GitOrigin-RevId: d073f5a7bf01d347614ab290e1242016d71bfc46
This commit is contained in:
Anna Kozlova
2020-07-01 18:43:01 +00:00
committed by intellij-monorepo-bot
parent 83cb3d2793
commit ee5541dec3
6 changed files with 28 additions and 13 deletions
@@ -498,6 +498,9 @@ public final class HighlightMethodUtil {
if (mismatchedExpressions.size() == 1) {
toolTip = createOneArgMismatchTooltip(candidateInfo, mismatchedExpressions, expressions, parameters);
}
else if (mismatchedExpressions.isEmpty()) {
toolTip = description;
}
if (toolTip == null) {
toolTip = createMismatchedArgumentsHtmlTooltip(candidateInfo, list);
}
@@ -1899,13 +1899,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
public void visitConditionalExpression(PsiConditionalExpression expression) {
super.visitConditionalExpression(expression);
if (myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) && PsiPolyExpressionUtil.isPolyExpression(expression)) {
PsiElement element = PsiUtil.skipParenthesizedExprUp(expression.getParent());
if (element instanceof PsiExpressionList) {
PsiElement parent = element.getParent();
if (parent instanceof PsiCall && !((PsiCall)parent).resolveMethodGenerics().isValidResult()) {
return;
}
}
final PsiExpression thenExpression = expression.getThenExpression();
final PsiExpression elseExpression = expression.getElseExpression();
if (thenExpression != null && elseExpression != null) {
@@ -32,6 +32,8 @@ import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
public class PsiConditionalExpressionImpl extends ExpressionPsiElement implements PsiConditionalExpression {
private static final Logger LOG = Logger.getInstance(PsiConditionalExpressionImpl.class);
@@ -64,18 +66,17 @@ public class PsiConditionalExpressionImpl extends ExpressionPsiElement implement
PsiExpression expr2 = getElseExpression();
PsiType type1 = expr1 == null ? null : expr1.getType();
PsiType type2 = expr2 == null ? null : expr2.getType();
if (type1 == null) return type2;
if (type2 == null) return type1;
if (type1.equals(type2)) return type1;
if (Objects.equals(type1, type2)) return type1;
if (PsiUtil.isLanguageLevel8OrHigher(this) &&
PsiPolyExpressionUtil.isPolyExpression(this)) {
//15.25.3 Reference Conditional Expressions
// The type of a poly reference conditional expression is the same as its target type.
PsiType targetType = InferenceSession.getTargetType(this);
if (MethodCandidateInfo.isOverloadCheck(PsiUtil.skipParenthesizedExprUp(this.getParent()))) {
if (MethodCandidateInfo.isOverloadCheck()) {
return targetType != null &&
type1 != null &&
type2 != null &&
targetType.isAssignableFrom(type1) &&
targetType.isAssignableFrom(type2) ? targetType : null;
}
@@ -85,6 +86,9 @@ public class PsiConditionalExpressionImpl extends ExpressionPsiElement implement
}
}
if (type1 == null) return type2;
if (type2 == null) return type1;
final int typeRank1 = TypeConversionUtil.getTypeRank(type1);
final int typeRank2 = TypeConversionUtil.getTypeRank(type2);
@@ -0,0 +1,14 @@
class MyTest {
static void n(boolean f) {
m(f ? (f ? 0 : "-") : "");
m(f ? 0 : "");
m1(f ? (f ? <error descr="Incompatible types. Found: 'int', required: 'java.lang.String'">0</error> : "-") : "");
m1(f ? <error descr="Incompatible types. Found: 'int', required: 'java.lang.String'">0</error> : "");
}
static void m(String s) {}
static void m(Object o) {}
static void m1(String o) {}
}
@@ -3,6 +3,6 @@ class X {
void foo(String str) {}
void test(Object obj, boolean b) {
foo((<warning descr="Casting '(b ? obj : ())' to 'Object' is redundant">Object</warning>)(b ? obj : (<error descr="Expression expected">)</error>));
foo((Object)(b ? obj : (<error descr="Expression expected">)</error>));
}
}
@@ -53,4 +53,5 @@ public class LightAdvHighlightingJdk8Test extends LightDaemonAnalyzerTestCase {
}
public void testNoArraySuperType() { doTest(true, true);}
public void testCaptureItself() { doTest(true, true); }
public void testNestedConditionalWithOverloads() { doTest(true, true); }
}