| Index: tests/compiler/dart2js/semantic_visitor_test_send_data.dart
|
| diff --git a/tests/compiler/dart2js/semantic_visitor_test_send_data.dart b/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
|
| index 33edce5be6689e350271dabcd6fae2934d867297..8dc6e3d7f62c26afb2700b55f034d092bd5f1e55 100644
|
| --- a/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
|
| +++ b/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
|
| @@ -1472,6 +1472,14 @@ const Map<String, List<Test>> SEND_TESTS = const {
|
| const Test(
|
| '''
|
| class C {}
|
| + m() => C ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_SET_IF_NULL,
|
| + constant: 'C',
|
| + rhs: '42')),
|
| + const Test(
|
| + '''
|
| + class C {}
|
| m() => ++C;
|
| ''',
|
| const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_PREFIX,
|
| @@ -1534,6 +1542,14 @@ const Map<String, List<Test>> SEND_TESTS = const {
|
| const Test(
|
| '''
|
| typedef F();
|
| + m() => F ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_SET_IF_NULL,
|
| + constant: 'F',
|
| + rhs: '42')),
|
| + const Test(
|
| + '''
|
| + typedef F();
|
| m() => ++F;
|
| ''',
|
| const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,
|
| @@ -1589,6 +1605,15 @@ const Map<String, List<Test>> SEND_TESTS = const {
|
| const Test.clazz(
|
| '''
|
| class C<T> {
|
| + m() => T ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET_IF_NULL,
|
| + element: 'type_variable(C#T)',
|
| + rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class C<T> {
|
| m() => ++T;
|
| }
|
| ''',
|
| @@ -1624,12 +1649,20 @@ const Map<String, List<Test>> SEND_TESTS = const {
|
| const Test.clazz(
|
| '''
|
| class C<T> {
|
| - static m() => T += 42;
|
| + static m() => T ??= 42;
|
| }
|
| ''',
|
| - const Visit(VisitKind.ERROR_INVALID_COMPOUND,
|
| + const Visit(VisitKind.ERROR_INVALID_SET_IF_NULL,
|
| + error: MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
|
| + rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class C<T> {
|
| + static m() => T ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.ERROR_INVALID_SET_IF_NULL,
|
| error: MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
|
| - operator: '+=',
|
| rhs: '42')),
|
| const Test.clazz(
|
| '''
|
| @@ -1685,6 +1718,13 @@ const Map<String, List<Test>> SEND_TESTS = const {
|
| rhs: '42')),
|
| const Test(
|
| '''
|
| + m() => dynamic ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_SET_IF_NULL,
|
| + constant: 'dynamic',
|
| + rhs: '42')),
|
| + const Test(
|
| + '''
|
| m() => ++dynamic;
|
| ''',
|
| const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,
|
| @@ -3936,6 +3976,18 @@ const Map<String, List<Test>> SEND_TESTS = const {
|
| ]),
|
| const Test(
|
| '''
|
| + m(a) => a?.b ??= 42;
|
| + ''',
|
| + const [
|
| + const Visit(
|
| + VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_SET_IF_NULL,
|
| + receiver: 'a', name: 'b', rhs: '42'),
|
| + const Visit(
|
| + VisitKind.VISIT_PARAMETER_GET,
|
| + element: 'parameter(m#a)'),
|
| + ]),
|
| + const Test(
|
| + '''
|
| m(a, b) => a ?? b;
|
| ''',
|
| const [
|
| @@ -3953,9 +4005,8 @@ const Map<String, List<Test>> SEND_TESTS = const {
|
| m(a) => a ??= 42;
|
| ''',
|
| const Visit(
|
| - VisitKind.VISIT_PARAMETER_COMPOUND,
|
| + VisitKind.VISIT_PARAMETER_SET_IF_NULL,
|
| element: 'parameter(m#a)',
|
| - operator: '??=',
|
| rhs: '42')),
|
| const Test.prefix(
|
| '''
|
| @@ -3965,4 +4016,453 @@ const Map<String, List<Test>> SEND_TESTS = const {
|
| const Visit(VisitKind.ERROR_INVALID_GET,
|
| error: MessageKind.PREFIX_AS_EXPRESSION)),
|
| ],
|
| + 'Set if null': const [
|
| + const Test(
|
| + '''
|
| + m(a) => a.b ??= 42;
|
| + ''',
|
| + const [
|
| + const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_SET_IF_NULL,
|
| + receiver: 'a', name: 'b', rhs: '42'),
|
| + const Visit(VisitKind.VISIT_PARAMETER_GET,
|
| + element: 'parameter(m#a)')
|
| + ]),
|
| + const Test(
|
| + '''
|
| + m(a) => a ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_PARAMETER_SET_IF_NULL,
|
| + element: 'parameter(m#a)', rhs: '42')),
|
| + const Test(
|
| + '''
|
| + m(final a) => a ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_FINAL_PARAMETER_SET_IF_NULL,
|
| + element: 'parameter(m#a)', rhs: '42')),
|
| + const Test(
|
| + '''
|
| + m() {
|
| + var a;
|
| + a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_LOCAL_VARIABLE_SET_IF_NULL,
|
| + element: 'variable(m#a)', rhs: '42')),
|
| + const Test(
|
| + '''
|
| + m() {
|
| + final a = 0;
|
| + a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_SET_IF_NULL,
|
| + element: 'variable(m#a)', rhs: '42')),
|
| + const Test(
|
| + '''
|
| + m() {
|
| + a() {}
|
| + a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_LOCAL_FUNCTION_SET_IF_NULL,
|
| + element: 'function(m#a)', rhs: '42')),
|
| + const Test(
|
| + '''
|
| + var a;
|
| + m() => a ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET_IF_NULL,
|
| + element: 'field(a)', rhs: '42')),
|
| + const Test(
|
| + '''
|
| + get a => 0;
|
| + set a(_) {}
|
| + m() => a ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_SET_IF_NULL,
|
| + getter: 'getter(a)', setter: 'setter(a)',
|
| + rhs: '42')),
|
| + const Test(
|
| + '''
|
| + class C {
|
| + static var a;
|
| + }
|
| + m() => C.a ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_STATIC_FIELD_SET_IF_NULL,
|
| + element: 'field(C#a)', rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class C {
|
| + static var a;
|
| + m() => C.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_STATIC_FIELD_SET_IF_NULL,
|
| + element: 'field(C#a)', rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class C {
|
| + static var a;
|
| + m() => a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_STATIC_FIELD_SET_IF_NULL,
|
| + element: 'field(C#a)', rhs: '42')),
|
| + const Test.prefix(
|
| + '''
|
| + class C {
|
| + static var a;
|
| + }
|
| + ''',
|
| + '''
|
| + m() => p.C.a ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_STATIC_FIELD_SET_IF_NULL,
|
| + element: 'field(C#a)', rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class C {
|
| + var o;
|
| + static m() { o ??= 42; }
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.ERROR_INVALID_SET_IF_NULL,
|
| + error: MessageKind.NO_INSTANCE_AVAILABLE,
|
| + rhs: '42')),
|
| + const Test(
|
| + '''
|
| + class C {
|
| + static get a => 0;
|
| + static set a(_) {}
|
| + }
|
| + m() => C.a ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_SET_IF_NULL,
|
| + getter: 'getter(C#a)', setter: 'setter(C#a)',
|
| + rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class C {
|
| + static get a => 0;
|
| + static set a(_) {}
|
| + m() => C.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_SET_IF_NULL,
|
| + getter: 'getter(C#a)', setter: 'setter(C#a)',
|
| + rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class C {
|
| + static get a => 0;
|
| + static set a(_) {}
|
| + m() => a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_SET_IF_NULL,
|
| + getter: 'getter(C#a)', setter: 'setter(C#a)',
|
| + rhs: '42')),
|
| + const Test.prefix(
|
| + '''
|
| + class C {
|
| + static get a => 0;
|
| + static set a(_) {}
|
| + }
|
| + ''',
|
| + '''
|
| + m() => p.C.a ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_SET_IF_NULL,
|
| + getter: 'getter(C#a)', setter: 'setter(C#a)',
|
| + rhs: '42')),
|
| + // TODO(johnniwinther): Enable these when dart2js supports method and setter
|
| + // with the same name.
|
| + /*const Test(
|
| + '''
|
| + class C {
|
| + static a() {}
|
| + static set a(_) {}
|
| + }
|
| + m() => C.a ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_SET_IF_NULL,
|
| + getter: 'function(C#a)', setter: 'setter(C#a)',
|
| + rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class C {
|
| + static a() {}
|
| + static set a(_) {}
|
| + m() => C.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_SET_IF_NULL,
|
| + getter: 'function(C#a)', setter: 'setter(C#a)',
|
| + rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class C {
|
| + static a() {}
|
| + static set a(_) {}
|
| + m() => a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_SET_IF_NULL,
|
| + getter: 'function(C#a)', setter: 'setter(C#a)',
|
| + rhs: '42')),
|
| + const Test.prefix(
|
| + '''
|
| + class C {
|
| + static a() {}
|
| + static set a(_) {}
|
| + }
|
| + ''',
|
| + '''
|
| + m() => p.C.a ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_SET_IF_NULL,
|
| + getter: 'function(C#a)', setter: 'setter(C#a)',
|
| + rhs: '42')),*/
|
| + const Test.clazz(
|
| + '''
|
| + class C {
|
| + var a;
|
| + m() => a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_THIS_PROPERTY_SET_IF_NULL,
|
| + name: 'a', rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class C {
|
| + var a = 0;
|
| + m() => this.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_THIS_PROPERTY_SET_IF_NULL,
|
| + name: 'a', rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class B {
|
| + var a = 0;
|
| + }
|
| + class C extends B {
|
| + m() => super.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_SUPER_FIELD_SET_IF_NULL,
|
| + element: 'field(B#a)', rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class B {
|
| + final a = 0;
|
| + }
|
| + class C extends B {
|
| + m() => super.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_SET_IF_NULL,
|
| + element: 'field(B#a)', rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class B {
|
| + get a => 0;
|
| + set a (_) {}
|
| + }
|
| + class C extends B {
|
| + m() => super.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_SET_IF_NULL,
|
| + getter: 'getter(B#a)', setter: 'setter(B#a)',
|
| + rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class A {
|
| + get a => 0;
|
| + }
|
| + class B extends A {
|
| + set a (_) {}
|
| + }
|
| + class C extends B {
|
| + m() => super.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_SET_IF_NULL,
|
| + getter: 'getter(A#a)', setter: 'setter(B#a)',
|
| + rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class A {
|
| + var a;
|
| + }
|
| + class B extends A {
|
| + get a => 0;
|
| + }
|
| +
|
| + class C extends B {
|
| + m() => super.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_SET_IF_NULL,
|
| + getter: 'getter(B#a)', setter: 'field(A#a)',
|
| + rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class A {
|
| + var a;
|
| + }
|
| + class B extends A {
|
| + set a(_) {}
|
| + }
|
| +
|
| + class C extends B {
|
| + m() => super.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_SET_IF_NULL,
|
| + getter: 'field(A#a)', setter: 'setter(B#a)',
|
| + rhs: '42')),
|
| + // TODO(johnniwinther): Enable this when dart2js supports shadow setters.
|
| + /*const Test.clazz(
|
| + '''
|
| + class A {
|
| + var a;
|
| + }
|
| + class B extends A {
|
| + final a = 0;
|
| + }
|
| +
|
| + class C extends B {
|
| + m() => super.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_SET_IF_NULL,
|
| + getter: 'field(B#a)', setter: 'field(A#a)',
|
| + rhs: '42')),*/
|
| + const Test.clazz(
|
| + '''
|
| + class B {
|
| + a() {}
|
| + }
|
| + class C extends B {
|
| + m() => super.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_SUPER_METHOD_SET_IF_NULL,
|
| + element: 'function(B#a)',
|
| + rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class B {
|
| + }
|
| + class C extends B {
|
| + m() => super.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SET_IF_NULL,
|
| + name: 'a', rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class B {
|
| + set a(_) {}
|
| + }
|
| + class C extends B {
|
| + m() => super.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_SET_IF_NULL,
|
| + setter: 'setter(B#a)', rhs: '42')),
|
| + const Test.clazz(
|
| + '''
|
| + class B {
|
| + get a => 42;
|
| + }
|
| + class C extends B {
|
| + m() => super.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_SET_IF_NULL,
|
| + getter: 'getter(B#a)', rhs: '42')),
|
| +
|
| + const Test.clazz(
|
| + '''
|
| + class C {
|
| + static set a(var value) { }
|
| + m() => a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_SET_IF_NULL,
|
| + setter: 'setter(C#a)', rhs: '42')),
|
| +
|
| + const Test.clazz(
|
| + '''
|
| + class C {
|
| + static get a => 42;
|
| + m() => C.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_SET_IF_NULL,
|
| + getter: 'getter(C#a)', rhs: '42')),
|
| +
|
| + const Test.clazz(
|
| + '''
|
| + class C {
|
| + static final a = 42;
|
| + m() => C.a ??= 42;
|
| + }
|
| + ''',
|
| + const Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_SET_IF_NULL,
|
| + element: 'field(C#a)', rhs: '42')),
|
| +
|
| + const Test(
|
| + '''
|
| + class C {
|
| + static a(var value) { }
|
| + }
|
| + m() => C.a ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_STATIC_METHOD_SET_IF_NULL,
|
| + element: 'function(C#a)', rhs: '42')),
|
| +
|
| + const Test(
|
| + '''
|
| + set a(var value) { }
|
| + m() => a ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_SET_IF_NULL,
|
| + setter: 'setter(a)', rhs: '42')),
|
| +
|
| + const Test(
|
| + '''
|
| + get a => 42;
|
| + m() => a ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_SET_IF_NULL,
|
| + getter: 'getter(a)', rhs: '42')),
|
| +
|
| + const Test(
|
| + '''
|
| + a(var value) { }
|
| + m() => a ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_SET_IF_NULL,
|
| + element: 'function(a)', rhs: '42')),
|
| +
|
| + const Test(
|
| + '''
|
| + final a = 42;
|
| + m() => a ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_SET_IF_NULL,
|
| + element: 'field(a)', rhs: '42')),
|
| +
|
| + const Test(
|
| + '''
|
| + m() => unresolved ??= 42;
|
| + ''',
|
| + const Visit(VisitKind.VISIT_UNRESOLVED_SET_IF_NULL,
|
| + name: 'unresolved', rhs: '42')),
|
| + ],
|
| };
|
|
|