OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 // Verify that the static type of a ??= b is the least upper bound of the |
| 6 // static types of a and b. |
| 7 |
| 8 import "package:expect/expect.dart"; |
| 9 |
| 10 bad() { |
| 11 Expect.fail('Should not be executed'); |
| 12 } |
| 13 |
| 14 /// Actually of type B so that the implicit downcasts below succeed at runtime. |
| 15 A theA = new B(); |
| 16 B theB = new B(); |
| 17 |
| 18 class A { |
| 19 String a; |
| 20 } |
| 21 |
| 22 class B extends A { |
| 23 String b; |
| 24 } |
| 25 |
| 26 class C extends A { |
| 27 String c; |
| 28 } |
| 29 |
| 30 A get a => null; |
| 31 |
| 32 void set a(A value) {} |
| 33 |
| 34 B get b => null; |
| 35 |
| 36 void set b(B value) {} |
| 37 |
| 38 class ClassWithStaticGetters { |
| 39 static A get a => null; |
| 40 |
| 41 static void set a(A value) {} |
| 42 |
| 43 static B get b => null; |
| 44 |
| 45 static void set b(B value) {} |
| 46 } |
| 47 |
| 48 class ClassWithInstanceGetters { |
| 49 A get a => null; |
| 50 |
| 51 void set a(A value) {} |
| 52 |
| 53 B get b => null; |
| 54 |
| 55 void set b(B value) {} |
| 56 } |
| 57 |
| 58 class DerivedClass extends ClassWithInstanceGetters { |
| 59 A get a => bad(); |
| 60 |
| 61 void set a(A value) { |
| 62 bad(); |
| 63 } |
| 64 |
| 65 B get b => bad(); |
| 66 |
| 67 void set b(B value) { |
| 68 bad(); |
| 69 } |
| 70 |
| 71 void derivedTest() { |
| 72 // The static type of super.v ??= e is the LUB of the static types of |
| 73 // super.v and e. |
| 74 (super.a ??= theA).a; //# 01: ok |
| 75 (super.a ??= theA).b; //# 02: compile-time error |
| 76 (super.a ??= theB).a; //# 03: ok |
| 77 (super.a ??= theB).b; //# 04: compile-time error |
| 78 (super.b ??= theA).a; //# 05: ok |
| 79 (super.b ??= theA).b; //# 06: compile-time error |
| 80 |
| 81 // Exactly the same static errors that would be caused by super.v = e |
| 82 // are also generated in the case of super.v ??= e. |
| 83 super.b ??= new C(); //# 07: compile-time error |
| 84 } |
| 85 } |
| 86 |
| 87 main() { |
| 88 new DerivedClass().derivedTest(); |
| 89 |
| 90 // The static type of v ??= e is the LUB of the static types of v and e. |
| 91 (a ??= theA).a; //# 08: ok |
| 92 (a ??= theA).b; //# 09: compile-time error |
| 93 (a ??= theB).a; //# 10: ok |
| 94 (a ??= theB).b; //# 11: compile-time error |
| 95 (b ??= theA).a; //# 12: ok |
| 96 (b ??= theA).b; //# 13: compile-time error |
| 97 |
| 98 // Exactly the same static errors that would be caused by v = e are also |
| 99 // generated in the case of v ??= e. |
| 100 b ??= new C(); //# 14: compile-time error |
| 101 |
| 102 // The static type of C.v ??= e is the LUB of the static types of C.v and e. |
| 103 (ClassWithStaticGetters.a ??= theA).a; //# 15: ok |
| 104 (ClassWithStaticGetters.a ??= theA).b; //# 16: compile-time error |
| 105 (ClassWithStaticGetters.a ??= theB).a; //# 17: ok |
| 106 (ClassWithStaticGetters.a ??= theB).b; //# 18: compile-time error |
| 107 (ClassWithStaticGetters.b ??= theA).a; //# 19: ok |
| 108 (ClassWithStaticGetters.b ??= theA).b; //# 20: compile-time error |
| 109 |
| 110 // Exactly the same static errors that would be caused by C.v = e are |
| 111 // also generated in the case of C.v ??= e. |
| 112 ClassWithStaticGetters.b ??= new C(); //# 21: compile-time error |
| 113 |
| 114 // The static type of e1.v ??= e2 is the LUB of the static types of e1.v and |
| 115 // e2. |
| 116 (new ClassWithInstanceGetters().a ??= theA).a; //# 22: ok |
| 117 (new ClassWithInstanceGetters().a ??= theA).b; //# 23: compile-time error |
| 118 (new ClassWithInstanceGetters().a ??= theB).a; //# 24: ok |
| 119 (new ClassWithInstanceGetters().a ??= theB).b; //# 25: compile-time error |
| 120 (new ClassWithInstanceGetters().b ??= theA).a; //# 26: ok |
| 121 (new ClassWithInstanceGetters().b ??= theA).b; //# 27: compile-time error |
| 122 |
| 123 // Exactly the same static errors that would be caused by e1.v = e2 are |
| 124 // also generated in the case of e1.v ??= e2. |
| 125 new ClassWithInstanceGetters().b ??= new C(); //# 28: compile-time error |
| 126 |
| 127 // The static type of e1[e2] ??= e3 is the LUB of the static types of e1[e2] |
| 128 // and e3. |
| 129 ((<A>[null])[0] ??= theA).a; //# 29: ok |
| 130 ((<A>[null])[0] ??= theA).b; //# 30: compile-time error |
| 131 ((<A>[null])[0] ??= theB).a; //# 31: ok |
| 132 ((<A>[null])[0] ??= theB).b; //# 32: compile-time error |
| 133 ((<B>[null])[0] ??= theA).a; //# 33: ok |
| 134 ((<B>[null])[0] ??= theA).b; //# 34: compile-time error |
| 135 |
| 136 // Exactly the same static errors that would be caused by e1[e2] = e3 are |
| 137 // also generated in the case of e1[e2] ??= e3. |
| 138 (<B>[null])[0] ??= new C(); //# 35: compile-time error |
| 139 |
| 140 // The static type of e1?.v op= e2 is the static type of e1.v op e2, |
| 141 // therefore the static type of e1?.v ??= e2 is the static type of |
| 142 // e1.v ?? e2, which is the LUB of the static types of e1?.v and e2. |
| 143 (new ClassWithInstanceGetters()?.a ??= theA).a; //# 36: ok |
| 144 (new ClassWithInstanceGetters()?.a ??= theA).b; //# 37: compile-time error |
| 145 (new ClassWithInstanceGetters()?.a ??= theB).a; //# 38: ok |
| 146 (new ClassWithInstanceGetters()?.a ??= theB).b; //# 39: compile-time error |
| 147 (new ClassWithInstanceGetters()?.b ??= theA).a; //# 40: ok |
| 148 (new ClassWithInstanceGetters()?.b ??= theA).b; //# 41: compile-time error |
| 149 |
| 150 // Exactly the same static errors that would be caused by e1.v ??= e2 are |
| 151 // also generated in the case of e1?.v ??= e2. |
| 152 new ClassWithInstanceGetters()?.b ??= new C(); //# 42: compile-time error |
| 153 } |
OLD | NEW |