diff options
author | Stephan Herrmann | 2013-12-05 23:21:59 +0000 |
---|---|---|
committer | Stephan Herrmann | 2013-12-06 00:04:42 +0000 |
commit | c36ded7a15e1a7629b6d662c785c512a4b88882c (patch) | |
tree | b3a3917fb718ff1139eadaa7c827ddd00dc305f6 | |
parent | 160d5d061fcfc93582f0fe36646007e32719bbb7 (diff) | |
download | eclipse.jdt.core-c36ded7a15e1a7629b6d662c785c512a4b88882c.tar.gz eclipse.jdt.core-c36ded7a15e1a7629b6d662c785c512a4b88882c.tar.xz eclipse.jdt.core-c36ded7a15e1a7629b6d662c785c512a4b88882c.zip |
Initial support for poly conditional expressions
4 files changed, 72 insertions, 5 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java index db77634f3a..d0ecfa6b2a 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java @@ -19,7 +19,7 @@ import junit.framework.Test; public class GenericsRegressionTest_1_8 extends AbstractRegressionTest { static { -// TESTS_NAMES = new String[] { "test0056c" }; +// TESTS_NAMES = new String[] { "testConditionalExpression2" }; // TESTS_NUMBERS = new int[] { 40, 41, 43, 45, 63, 64 }; // TESTS_RANGE = new int[] { 11, -1 }; } @@ -70,4 +70,47 @@ public void testBug423070() { "}", }); } + +public void testConditionalExpression1() { + runConformTest( + new String[] { + "X.java", + "class A {}\n" + + "class B extends A {}\n" + + "public class X {\n" + + " <T> T combine(T x, T y) { return x; }\n" + + " A test(A a, B b, boolean flag) {\n" + + " return combine(flag ? a : b, a);\n" + + " }\n" + + "}\n" + }); +} + +public void _testConditionalExpression2() { + runConformTest( + new String[] { + "X.java", + "class A{/**/}\n" + + "class B extends A {/**/}\n" + + "class C extends B {/**/}\n" + + "class G<T> {/**/}\n" + + "\n" + + "public class X {\n" + + "G<A> ga=null;\n" + + "G<B> gb=null;\n" + + "G<C> gc=null;\n" + + "G<? super A> gsa=null;\n" + + "G<? super B> gsb=null;\n" + + "G<? super C> gsc=null;\n" + + "\n" + + "@SuppressWarnings(\"unused\")\n" + + " public void test(boolean f) {\n" + + " G<? super B> l1 = (f) ? gsa : gb;\n" + + " G<? super B> l2 = (f) ? gsb : gb;\n" + + " G<? super C> l3 = (f) ? gsc : gb;\n" + + " G<? super B> l4 = (f) ? gsb : gsb;\n" + + " }\n" + + "}" + }); +} } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java index 7de8492124..4247c2a504 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java @@ -658,7 +658,22 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, if (this.expressionContext != ASSIGNMENT_CONTEXT && this.expressionContext != INVOCATION_CONTEXT) return false; - return this.isPolyExpression; + if (this.isPolyExpression) // TODO(stephan): is this still needed? + return true; + + // ... unless both operands produce primitives (or boxed primitives): + TypeBinding opType = this.valueIfTrue.resolvedType; + if (opType != null) { + if (opType.isBaseType() || (opType.id >= TypeIds.T_JavaLangByte && opType.id <= TypeIds.T_JavaLangBoolean)) + return false; + } + opType = this.valueIfFalse.resolvedType; + if (opType != null) { + if (opType.isBaseType() || (opType.id >= TypeIds.T_JavaLangByte && opType.id <= TypeIds.T_JavaLangBoolean)) + return false; + } + + return true; } public boolean isCompatibleWith(TypeBinding left, Scope scope) { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExceptionFormula.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExceptionFormula.java index df7d992b35..cf3238b034 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExceptionFormula.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExceptionFormula.java @@ -43,7 +43,7 @@ public class ConstraintExceptionFormula extends ConstraintFormula { } public Object reduce(InferenceContext18 inferenceContext) { - // JSL 18.2.5 + // JLS 18.2.5 if (this.left instanceof LambdaExpression || this.left instanceof ReferenceExpression) { Scope scope = inferenceContext.scope; if (!this.right.isFunctionalInterface(scope)) @@ -100,8 +100,13 @@ public class ConstraintExceptionFormula extends ConstraintFormula { } } else if (this.left.isPolyExpression()) { // parenthesized: transparent in our AST + if (this.left instanceof ConditionalExpression) { - InferenceContext18.missingImplementation("NYI"); + ConditionalExpression conditional = (ConditionalExpression) this.left; + return new ConstraintFormula[] { + new ConstraintExceptionFormula(conditional.valueIfTrue, this.right), + new ConstraintExceptionFormula(conditional.valueIfFalse, this.right) + }; } } return TRUE; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java index 6c5b11af93..b75db0851c 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java @@ -87,7 +87,11 @@ class ConstraintExpressionFormula extends ConstraintFormula { inferenceContext.leavePolyInvocation(prevInvocation); } } else if (this.left instanceof ConditionalExpression) { - InferenceContext18.missingImplementation("NYI"); + ConditionalExpression conditional = (ConditionalExpression) this.left; + return new ConstraintFormula[] { + new ConstraintExpressionFormula(conditional.valueIfTrue, this.right, this.relation), + new ConstraintExpressionFormula(conditional.valueIfFalse, this.right, this.relation) + }; } else if (this.left instanceof LambdaExpression) { LambdaExpression lambda = (LambdaExpression) this.left; Scope scope = inferenceContext.scope; |