Casts in ternary condition

This commit is contained in:
Clément Fournier committed 2021-04-29 00:13:24 +02:00
1 parent 46f7c77507
commit 9bbe60f269
4 files changed
+57 -6

No files matched your search

@@ -105,6 +105,7 @@ public abstract class ExprContext {
static ExprContext newNumericContext(JTypeMirror targetType) {
if (targetType.isPrimitive()) {
assert targetType.isNumeric() : targetType;
return new RegularCtx(targetType, CtxKind.Numeric);
}
return RegularCtx.NO_CTX; // error
@@ -463,11 +463,17 @@ final class PolyResolution {
return booleanCtx; // condition
} else if (papa instanceof ASTConditionalExpression && node.getIndexInParent() != 0) {
assert ((ASTConditionalExpression) papa).isStandalone()
: "Expected standalone ternary, otherwise doesCascadeContext(..) would have returned true";
} else if (papa instanceof ASTConditionalExpression) {
return ExprContext.newStandaloneTernaryCtx(((ASTConditionalExpression) papa).getTypeMirror());
if (node.getIndexInParent() == 0) {
return booleanCtx; // the condition
} else {
// a branch
assert ((ASTConditionalExpression) papa).isStandalone()
: "Expected standalone ternary, otherwise doesCascadeContext(..) would have returned true";
return ExprContext.newStandaloneTernaryCtx(((ASTConditionalExpression) papa).getTypeMirror());
}
} else if (papa instanceof ASTInfixExpression) {
// numeric contexts, maybe
@@ -521,7 +527,10 @@ final class PolyResolution {
if (child.getParent() != node) {
// means the "node" is a "stop recursion because no context" result in contextOf
return false;
} else if (!internalUse && node instanceof ASTConditionalExpression) {
} else if (!internalUse
&& node instanceof ASTConditionalExpression
&& child.getIndexInParent() != 0) {
// conditional branch
((ASTConditionalExpression) node).getTypeMirror(); // force resolution
return !((ASTConditionalExpression) node).isStandalone();
}
@@ -165,6 +165,23 @@ class ConversionContextTests : ProcessorTestSpec({
}
}
parserTest("Test context of ternary condition") {
val (acu, spy) = parser.parseWithTypeInferenceSpy("""
class Scratch {
static void m(Boolean boxedBool, boolean bool, String str, int[] ints) {
str = (boolean) boxedBool ? "a" : "b";
}
}
""")
val (booleanCast) = acu.descendants(ASTCastExpression::class.java).toList()
spy.shouldBeOk {
booleanCast.conversionContext::getTargetType shouldBe boolean
}
}
parserTest("Test numeric context") {
val (acu, spy) = parser.parseWithTypeInferenceSpy("""
@@ -618,7 +618,7 @@ class Scratch {
]]></code>
</test-code>
<test-code>
<description>Loops</description>
<description>Conditionals and loop statements</description>
<expected-problems>5</expected-problems>
<code><![CDATA[
class Scratch {
@@ -632,6 +632,30 @@ class Scratch {
}
]]></code>
</test-code>
<test-code>
<description>Conditional expr condition</description>
<expected-problems>1</expected-problems>
<code><![CDATA[
class Scratch {
static void m(Boolean boxedBool, boolean bool, String str, int[] ints) {
str = (boolean) boxedBool ? "a" : "b";
}
}
]]></code>
</test-code>
<test-code>
<description>Necessary cast for condition</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
class Scratch {
static void m(Object obj) {
// both are necessary
if ((Boolean) obj
|| (boolean) obj);
}
}
]]></code>
</test-code>
<test-code>
<description>Missing context identity cast</description>
<expected-problems>2</expected-problems>