[cfe] Transform collections before set literals

The VM uses the collection and set literal transformations.  The set
literal transformation assumes that collections have already been
transformed.  This was not done correctly when translating a
list (e.g., constructor initializers).

Fixes https://github.com/dart-lang/sdk/issues/37027

Change-Id: If7a6bda55f8cf0efd761fd8932d3a9e2c60db19b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/103134
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
Auto-Submit: Kevin Millikin <kmillikin@google.com>
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 4c3b6c9..88e4621 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -1036,17 +1036,17 @@
 
   void transformListPostInference(List<TreeNode> list,
       bool transformSetLiterals, bool transformCollections) {
-    if (transformSetLiterals) {
-      SetLiteralTransformer transformer = setLiteralTransformer ??=
-          new SetLiteralTransformer(this,
-              transformConst: !target.enableConstantUpdate2018);
+    if (transformCollections) {
+      CollectionTransformer transformer =
+          collectionTransformer ??= new CollectionTransformer(this);
       for (int i = 0; i < list.length; ++i) {
         list[i] = list[i].accept(transformer);
       }
     }
-    if (transformCollections) {
-      CollectionTransformer transformer =
-          collectionTransformer ??= new CollectionTransformer(this);
+    if (transformSetLiterals) {
+      SetLiteralTransformer transformer = setLiteralTransformer ??=
+          new SetLiteralTransformer(this,
+              transformConst: !target.enableConstantUpdate2018);
       for (int i = 0; i < list.length; ++i) {
         list[i] = list[i].accept(transformer);
       }
diff --git a/pkg/front_end/testcases/issue37027.dart b/pkg/front_end/testcases/issue37027.dart
new file mode 100644
index 0000000..385e2a4
--- /dev/null
+++ b/pkg/front_end/testcases/issue37027.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2019, 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 C {
+  final Set<int> s;
+  C(List<int> ell) : s = {for (var e in ell) if (e.isOdd) 2 * e};
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/issue37027.dart.hierarchy.expect b/pkg/front_end/testcases/issue37027.dart.hierarchy.expect
new file mode 100644
index 0000000..d7772a1
--- /dev/null
+++ b/pkg/front_end/testcases/issue37027.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.s
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/issue37027.dart.legacy.expect b/pkg/front_end/testcases/issue37027.dart.legacy.expect
new file mode 100644
index 0000000..653b194
--- /dev/null
+++ b/pkg/front_end/testcases/issue37027.dart.legacy.expect
@@ -0,0 +1,22 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/issue37027.dart:6:46: Error: Unexpected token 'if'.
+//   C(List<int> ell) : s = {for (var e in ell) if (e.isOdd) 2 * e};
+//                                              ^^
+//
+// pkg/front_end/testcases/issue37027.dart:6:27: Error: Unexpected token 'for'.
+//   C(List<int> ell) : s = {for (var e in ell) if (e.isOdd) 2 * e};
+//                           ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  final field core::Set<core::int> s;
+  constructor •(core::List<core::int> ell) → self::C
+    : self::C::s = <dynamic, dynamic>{}, super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/issue37027.dart.legacy.transformed.expect b/pkg/front_end/testcases/issue37027.dart.legacy.transformed.expect
new file mode 100644
index 0000000..653b194
--- /dev/null
+++ b/pkg/front_end/testcases/issue37027.dart.legacy.transformed.expect
@@ -0,0 +1,22 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/issue37027.dart:6:46: Error: Unexpected token 'if'.
+//   C(List<int> ell) : s = {for (var e in ell) if (e.isOdd) 2 * e};
+//                                              ^^
+//
+// pkg/front_end/testcases/issue37027.dart:6:27: Error: Unexpected token 'for'.
+//   C(List<int> ell) : s = {for (var e in ell) if (e.isOdd) 2 * e};
+//                           ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  final field core::Set<core::int> s;
+  constructor •(core::List<core::int> ell) → self::C
+    : self::C::s = <dynamic, dynamic>{}, super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/issue37027.dart.outline.expect b/pkg/front_end/testcases/issue37027.dart.outline.expect
new file mode 100644
index 0000000..dc4999b
--- /dev/null
+++ b/pkg/front_end/testcases/issue37027.dart.outline.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  final field core::Set<core::int> s;
+  constructor •(core::List<core::int> ell) → self::C
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/issue37027.dart.strong.expect b/pkg/front_end/testcases/issue37027.dart.strong.expect
new file mode 100644
index 0000000..2387135
--- /dev/null
+++ b/pkg/front_end/testcases/issue37027.dart.strong.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+class C extends core::Object {
+  final field core::Set<core::int> s;
+  constructor •(core::List<core::int> ell) → self::C
+    : self::C::s = block {
+      final core::Set<core::int> #t1 = col::LinkedHashSet::•<core::int>();
+      for (core::int e in ell)
+        if(e.{core::int::isOdd})
+          #t1.{core::Set::add}(2.{core::num::*}(e));
+    } =>#t1, super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/issue37027.dart.strong.transformed.expect b/pkg/front_end/testcases/issue37027.dart.strong.transformed.expect
new file mode 100644
index 0000000..2387135
--- /dev/null
+++ b/pkg/front_end/testcases/issue37027.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+class C extends core::Object {
+  final field core::Set<core::int> s;
+  constructor •(core::List<core::int> ell) → self::C
+    : self::C::s = block {
+      final core::Set<core::int> #t1 = col::LinkedHashSet::•<core::int>();
+      for (core::int e in ell)
+        if(e.{core::int::isOdd})
+          #t1.{core::Set::add}(2.{core::num::*}(e));
+    } =>#t1, super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 0347606..488cbde 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -677,6 +677,7 @@
 issue34515: TextSerializationFailure
 issue34899: TypeCheckError
 issue35875: TextSerializationFailure
+issue37027: TextSerializationFailure
 literals: TextSerializationFailure # Was: Pass
 local_generic_function: TextSerializationFailure # Was: Pass
 magic_const: TextSerializationFailure # Was: Pass