diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart index 514d2d209ff..585a1e4bb71 100644 --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart @@ -8337,6 +8337,13 @@ class BodyBuilder extends StackListenerImpl // TODO(cstefantsova): Report an error. } } + if (fields != null) { + for (int i = 0, j = fields.length - 1; i < j; i++, j--) { + NamedPattern field = fields[i]; + fields[i] = fields[j]; + fields[j] = field; + } + } push(fields ?? NullValue.PatternList); } diff --git a/pkg/front_end/testcases/patterns/fields_order.dart b/pkg/front_end/testcases/patterns/fields_order.dart new file mode 100644 index 00000000000..0e6656b60f5 --- /dev/null +++ b/pkg/front_end/testcases/patterns/fields_order.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +class A { + String get foo => "foo"; + Object? get bar => null; +} + +test(dynamic x) { + if (x case A(foo: "", bar: String y as String)) { + return y; + } else { + return null; + } +} diff --git a/pkg/front_end/testcases/patterns/fields_order.dart.strong.expect b/pkg/front_end/testcases/patterns/fields_order.dart.strong.expect new file mode 100644 index 00000000000..a5ec2b9e944 --- /dev/null +++ b/pkg/front_end/testcases/patterns/fields_order.dart.strong.expect @@ -0,0 +1,38 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; + get foo() → core::String + return "foo"; + get bar() → core::Object? + return null; +} +static method test(dynamic x) → dynamic { + final dynamic #t1 = x; + final core::bool #t2 = true; + final dynamic #t3 = #t1; + if(#t3 is self::A) { + final core::String #t4 = #t3{self::A}.{self::A::foo}{core::String}; + final core::Object? #t5 = #t3{self::A}.{self::A::bar}{core::Object?}; + if(#t4 =={core::String::==}{(core::Object) → core::bool} "") { + final core::String #t6 = #t5 as{ForNonNullableByDefault} core::String; + final core::String #t7 = #t6; + if(#t7 is core::String) { + #t2 = false; + { + core::String y = #t7{core::String}; + { + return y; + } + } + } + } + } + if(#t2) { + return null; + } +} diff --git a/pkg/front_end/testcases/patterns/fields_order.dart.strong.transformed.expect b/pkg/front_end/testcases/patterns/fields_order.dart.strong.transformed.expect new file mode 100644 index 00000000000..a5ec2b9e944 --- /dev/null +++ b/pkg/front_end/testcases/patterns/fields_order.dart.strong.transformed.expect @@ -0,0 +1,38 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; + get foo() → core::String + return "foo"; + get bar() → core::Object? + return null; +} +static method test(dynamic x) → dynamic { + final dynamic #t1 = x; + final core::bool #t2 = true; + final dynamic #t3 = #t1; + if(#t3 is self::A) { + final core::String #t4 = #t3{self::A}.{self::A::foo}{core::String}; + final core::Object? #t5 = #t3{self::A}.{self::A::bar}{core::Object?}; + if(#t4 =={core::String::==}{(core::Object) → core::bool} "") { + final core::String #t6 = #t5 as{ForNonNullableByDefault} core::String; + final core::String #t7 = #t6; + if(#t7 is core::String) { + #t2 = false; + { + core::String y = #t7{core::String}; + { + return y; + } + } + } + } + } + if(#t2) { + return null; + } +} diff --git a/pkg/front_end/testcases/patterns/fields_order.dart.textual_outline.expect b/pkg/front_end/testcases/patterns/fields_order.dart.textual_outline.expect new file mode 100644 index 00000000000..6f8b6c97b1b --- /dev/null +++ b/pkg/front_end/testcases/patterns/fields_order.dart.textual_outline.expect @@ -0,0 +1,6 @@ +class A { + String get foo => "foo"; + Object? get bar => null; +} + +test(dynamic x) {} diff --git a/pkg/front_end/testcases/patterns/fields_order.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/patterns/fields_order.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..1f902de7129 --- /dev/null +++ b/pkg/front_end/testcases/patterns/fields_order.dart.textual_outline_modelled.expect @@ -0,0 +1,6 @@ +class A { + Object? get bar => null; + String get foo => "foo"; +} + +test(dynamic x) {} diff --git a/pkg/front_end/testcases/patterns/fields_order.dart.weak.expect b/pkg/front_end/testcases/patterns/fields_order.dart.weak.expect new file mode 100644 index 00000000000..a5ec2b9e944 --- /dev/null +++ b/pkg/front_end/testcases/patterns/fields_order.dart.weak.expect @@ -0,0 +1,38 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; + get foo() → core::String + return "foo"; + get bar() → core::Object? + return null; +} +static method test(dynamic x) → dynamic { + final dynamic #t1 = x; + final core::bool #t2 = true; + final dynamic #t3 = #t1; + if(#t3 is self::A) { + final core::String #t4 = #t3{self::A}.{self::A::foo}{core::String}; + final core::Object? #t5 = #t3{self::A}.{self::A::bar}{core::Object?}; + if(#t4 =={core::String::==}{(core::Object) → core::bool} "") { + final core::String #t6 = #t5 as{ForNonNullableByDefault} core::String; + final core::String #t7 = #t6; + if(#t7 is core::String) { + #t2 = false; + { + core::String y = #t7{core::String}; + { + return y; + } + } + } + } + } + if(#t2) { + return null; + } +} diff --git a/pkg/front_end/testcases/patterns/fields_order.dart.weak.modular.expect b/pkg/front_end/testcases/patterns/fields_order.dart.weak.modular.expect new file mode 100644 index 00000000000..a5ec2b9e944 --- /dev/null +++ b/pkg/front_end/testcases/patterns/fields_order.dart.weak.modular.expect @@ -0,0 +1,38 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; + get foo() → core::String + return "foo"; + get bar() → core::Object? + return null; +} +static method test(dynamic x) → dynamic { + final dynamic #t1 = x; + final core::bool #t2 = true; + final dynamic #t3 = #t1; + if(#t3 is self::A) { + final core::String #t4 = #t3{self::A}.{self::A::foo}{core::String}; + final core::Object? #t5 = #t3{self::A}.{self::A::bar}{core::Object?}; + if(#t4 =={core::String::==}{(core::Object) → core::bool} "") { + final core::String #t6 = #t5 as{ForNonNullableByDefault} core::String; + final core::String #t7 = #t6; + if(#t7 is core::String) { + #t2 = false; + { + core::String y = #t7{core::String}; + { + return y; + } + } + } + } + } + if(#t2) { + return null; + } +} diff --git a/pkg/front_end/testcases/patterns/fields_order.dart.weak.outline.expect b/pkg/front_end/testcases/patterns/fields_order.dart.weak.outline.expect new file mode 100644 index 00000000000..9654200af23 --- /dev/null +++ b/pkg/front_end/testcases/patterns/fields_order.dart.weak.outline.expect @@ -0,0 +1,14 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + ; + get foo() → core::String + ; + get bar() → core::Object? + ; +} +static method test(dynamic x) → dynamic + ; diff --git a/pkg/front_end/testcases/patterns/fields_order.dart.weak.transformed.expect b/pkg/front_end/testcases/patterns/fields_order.dart.weak.transformed.expect new file mode 100644 index 00000000000..a5ec2b9e944 --- /dev/null +++ b/pkg/front_end/testcases/patterns/fields_order.dart.weak.transformed.expect @@ -0,0 +1,38 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; + get foo() → core::String + return "foo"; + get bar() → core::Object? + return null; +} +static method test(dynamic x) → dynamic { + final dynamic #t1 = x; + final core::bool #t2 = true; + final dynamic #t3 = #t1; + if(#t3 is self::A) { + final core::String #t4 = #t3{self::A}.{self::A::foo}{core::String}; + final core::Object? #t5 = #t3{self::A}.{self::A::bar}{core::Object?}; + if(#t4 =={core::String::==}{(core::Object) → core::bool} "") { + final core::String #t6 = #t5 as{ForNonNullableByDefault} core::String; + final core::String #t7 = #t6; + if(#t7 is core::String) { + #t2 = false; + { + core::String y = #t7{core::String}; + { + return y; + } + } + } + } + } + if(#t2) { + return null; + } +}