Version 2.14.0-384.0.dev

Merge commit '58d917e7573c359580ade43845004dbbc62220d5' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 8ede85a..5644191 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
     "constraint, update this by running tools/generate_package_config.dart."
   ],
   "configVersion": 2,
-  "generated": "2021-07-30T20:37:49.663747",
+  "generated": "2021-08-04T21:18:41.561058",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
@@ -151,6 +151,12 @@
       "languageVersion": "2.12"
     },
     {
+      "name": "characters",
+      "rootUri": "../third_party/pkg/characters",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
       "name": "charcode",
       "rootUri": "../third_party/pkg/charcode",
       "packageUri": "lib/",
diff --git a/DEPS b/DEPS
index 613addf..8b2457d 100644
--- a/DEPS
+++ b/DEPS
@@ -81,6 +81,7 @@
   "boringssl_rev" : "1607f54fed72c6589d560254626909a64124f091",
   "browser-compat-data_tag": "v1.0.22",
   "browser_launcher_rev": "c6cc1025d6901926cf022e144ba109677e3548f1",
+  "characters_rev": "6ec389c4dfa8fce14820dc5cbf6e693202e7e052",
   "charcode_rev": "84ea427711e24abf3b832923959caa7dd9a8514b",
   "chrome_rev" : "19997",
   "cli_util_rev" : "8c504de5deb08fe32ecf51f9662bb37d8c708e57",
@@ -329,6 +330,8 @@
   Var("dart_root") + "/third_party/pkg/boolean_selector":
       Var("dart_git") + "boolean_selector.git" +
       "@" + Var("boolean_selector_rev"),
+  Var("dart_root") + "/third_party/pkg/characters":
+      Var("dart_git") + "characters.git" + "@" + Var("characters_rev"),
   Var("dart_root") + "/third_party/pkg/charcode":
       Var("dart_git") + "charcode.git" + "@" + Var("charcode_rev"),
   Var("dart_root") + "/third_party/pkg/cli_util":
diff --git a/pkg/front_end/lib/src/api_unstable/vm.dart b/pkg/front_end/lib/src/api_unstable/vm.dart
index 7bb6bef..f592c51 100644
--- a/pkg/front_end/lib/src/api_unstable/vm.dart
+++ b/pkg/front_end/lib/src/api_unstable/vm.dart
@@ -87,5 +87,7 @@
         serializeComponent,
         serializeProcedure;
 
+export 'package:_fe_analyzer_shared/src/util/options.dart';
+
 export 'package:_fe_analyzer_shared/src/util/resolve_input_uri.dart'
     show resolveInputUri;
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 727bb3f..b35320c 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -149,8 +149,6 @@
         StdioProcess;
 
 import 'package:vm/target/vm.dart' show VmTarget;
-import 'package:vm/transformations/type_flow/transformer.dart' as type_flow;
-import 'package:vm/transformations/pragma.dart' as type_flow;
 
 import '../../testing_utils.dart' show checkEnvironment;
 
@@ -856,11 +854,10 @@
         }
         return new Result<ComponentResult>(
             result, runResult.outcome, runResult.error);
-      case "aot":
       case "none":
       case "dart2js":
       case "dartdevc":
-        // TODO(johnniwinther): Support running vm aot, dart2js and/or dartdevc.
+        // TODO(johnniwinther): Support running dart2js and/or dartdevc.
         return pass(result);
       default:
         throw new ArgumentError(
@@ -1704,9 +1701,6 @@
     case "vm":
       target = new TestVmTarget(targetFlags);
       break;
-    case "aot":
-      target = new TestVmAotTarget(targetFlags);
-      break;
     case "none":
       target = new NoneTarget(targetFlags);
       break;
@@ -2048,22 +2042,6 @@
   TestVmTarget(TargetFlags flags) : super(flags);
 }
 
-class TestVmAotTarget extends TestVmTarget {
-  TestVmAotTarget(TargetFlags flags) : super(flags);
-
-  @override
-  bool get hasGlobalTransformation => true;
-
-  @override
-  Component performGlobalTransformations(
-      KernelTarget kernelTarget, Component component) {
-    return type_flow.transformComponent(
-        this, kernelTarget.loader.coreTypes, component,
-        matcher: new type_flow.ConstantPragmaAnnotationParser(
-            kernelTarget.loader.coreTypes));
-  }
-}
-
 class EnsureNoErrors
     extends Step<ComponentResult, ComponentResult, FastaContext> {
   const EnsureNoErrors();
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.strong.expect b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.strong.expect
deleted file mode 100644
index a52e3ca..0000000
--- a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.strong.expect
+++ /dev/null
@@ -1,49 +0,0 @@
-library /*isNonNullableByDefault*/;
-import self as self;
-import "dart:core" as core;
-import "main_lib.dart" as mai;
-
-import "org-dartlang-testcase:///main_lib.dart";
-
-static method main() → dynamic {
-  core::List<dynamic> list = <dynamic>[];
-  if(list.{core::Iterable::isNotEmpty}{core::bool}) {
-    new mai::Class::•().{mai::Class::method}((null as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} mai::Enum){(mai::Enum) → core::int};
-  }
-}
-
-library /*isNonNullableByDefault*/;
-import self as mai;
-import "dart:core" as core;
-
-class Enum extends core::Object implements core::Enum /*isEnum*/  {
-  final field core::int index;
-  final field core::String _name;
-  static const field core::List<mai::Enum> values = #C4;
-  static const field mai::Enum a = #C3;
-  const constructor •(core::int index, core::String _name) → mai::Enum
-    : mai::Enum::index = index, mai::Enum::_name = _name, super core::Object::•()
-    ;
-  method toString() → core::String
-    return this.{mai::Enum::_name}{core::String};
-}
-class Class extends core::Object {
-  synthetic constructor •() → mai::Class
-    : super core::Object::•()
-    ;
-  method method(mai::Enum e) → core::int
-    return e.{mai::Enum::index}{core::int};
-}
-
-constants  {
-  #C1 = 0
-  #C2 = "Enum.a"
-  #C3 = mai::Enum {index:#C1, _name:#C2}
-  #C4 = <mai::Enum>[#C3]
-}
-
-
-Constructor coverage from constants:
-org-dartlang-testcase:///main_lib.dart:
-- Enum. (from org-dartlang-testcase:///main_lib.dart:5:6)
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.strong.transformed.expect b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.strong.transformed.expect
deleted file mode 100644
index a821c4b..0000000
--- a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.strong.transformed.expect
+++ /dev/null
@@ -1,35 +0,0 @@
-library /*isNonNullableByDefault*/;
-import self as self;
-import "dart:core" as core;
-import "main_lib.dart" as mai;
-import "dart:_internal" as _in;
-
-import "org-dartlang-testcase:///main_lib.dart";
-
-static method main() → dynamic {
-  core::List<dynamic> list = core::_GrowableList::•<dynamic>(0);
-  if(list.{core::Iterable::isNotEmpty}{core::bool}) {
-    block {
-      new mai::Class::•();
-      _in::unsafeCast<dynamic>(null) as{TypeError,ForDynamic,ForNonNullableByDefault} mai::Enum;
-    } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
-  }
-}
-
-library /*isNonNullableByDefault*/;
-import self as mai;
-import "dart:core" as core;
-
-abstract class Enum extends core::Object implements core::Enum {
-}
-class Class extends core::Object {
-  synthetic constructor •() → mai::Class
-    : super core::Object::•()
-    ;
-}
-
-
-
-Constructor coverage from constants:
-org-dartlang-testcase:///main_lib.dart:
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.textual_outline.expect b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.textual_outline.expect
deleted file mode 100644
index 82be6bb..0000000
--- a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.textual_outline.expect
+++ /dev/null
@@ -1,3 +0,0 @@
-import 'main_lib.dart';
-
-main() {}
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.textual_outline_modelled.expect
deleted file mode 100644
index 82be6bb..0000000
--- a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.textual_outline_modelled.expect
+++ /dev/null
@@ -1,3 +0,0 @@
-import 'main_lib.dart';
-
-main() {}
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.expect b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.expect
deleted file mode 100644
index c05364c..0000000
--- a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.expect
+++ /dev/null
@@ -1,49 +0,0 @@
-library /*isNonNullableByDefault*/;
-import self as self;
-import "dart:core" as core;
-import "main_lib.dart" as mai;
-
-import "org-dartlang-testcase:///main_lib.dart";
-
-static method main() → dynamic {
-  core::List<dynamic> list = <dynamic>[];
-  if(list.{core::Iterable::isNotEmpty}{core::bool}) {
-    new mai::Class::•().{mai::Class::method}((null as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} mai::Enum){(mai::Enum) → core::int};
-  }
-}
-
-library /*isNonNullableByDefault*/;
-import self as mai;
-import "dart:core" as core;
-
-class Enum extends core::Object implements core::Enum /*isEnum*/  {
-  final field core::int index;
-  final field core::String _name;
-  static const field core::List<mai::Enum> values = #C4;
-  static const field mai::Enum a = #C3;
-  const constructor •(core::int index, core::String _name) → mai::Enum
-    : mai::Enum::index = index, mai::Enum::_name = _name, super core::Object::•()
-    ;
-  method toString() → core::String
-    return this.{mai::Enum::_name}{core::String};
-}
-class Class extends core::Object {
-  synthetic constructor •() → mai::Class
-    : super core::Object::•()
-    ;
-  method method(mai::Enum e) → core::int
-    return e.{mai::Enum::index}{core::int};
-}
-
-constants  {
-  #C1 = 0
-  #C2 = "Enum.a"
-  #C3 = mai::Enum {index:#C1, _name:#C2}
-  #C4 = <mai::Enum*>[#C3]
-}
-
-
-Constructor coverage from constants:
-org-dartlang-testcase:///main_lib.dart:
-- Enum. (from org-dartlang-testcase:///main_lib.dart:5:6)
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.outline.expect b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.outline.expect
deleted file mode 100644
index 1dd0498..0000000
--- a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.outline.expect
+++ /dev/null
@@ -1,42 +0,0 @@
-library /*isNonNullableByDefault*/;
-import self as self;
-
-import "org-dartlang-testcase:///main_lib.dart";
-
-static method main() → dynamic
-  ;
-
-library /*isNonNullableByDefault*/;
-import self as self2;
-import "dart:core" as core;
-
-class Enum extends core::Object implements core::Enum /*isEnum*/  {
-  final field core::int index;
-  final field core::String _name;
-  static const field core::List<self2::Enum> values = #C4;
-  static const field self2::Enum a = #C3;
-  const constructor •(core::int index, core::String _name) → self2::Enum
-    : self2::Enum::index = index, self2::Enum::_name = _name, super core::Object::•()
-    ;
-  method toString() → core::String
-    return this.{self2::Enum::_name}{core::String};
-}
-class Class extends core::Object {
-  synthetic constructor •() → self2::Class
-    ;
-  method method(self2::Enum e) → core::int
-    ;
-}
-
-constants  {
-  #C1 = 0
-  #C2 = "Enum.a"
-  #C3 = self2::Enum {index:#C1, _name:#C2}
-  #C4 = <self2::Enum*>[#C3]
-}
-
-
-Constructor coverage from constants:
-org-dartlang-testcase:///main_lib.dart:
-- Enum. (from org-dartlang-testcase:///main_lib.dart:5:6)
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.transformed.expect b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.transformed.expect
deleted file mode 100644
index 33ef7bc..0000000
--- a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.transformed.expect
+++ /dev/null
@@ -1,35 +0,0 @@
-library /*isNonNullableByDefault*/;
-import self as self;
-import "dart:core" as core;
-import "main_lib.dart" as mai;
-import "dart:_internal" as _in;
-
-import "org-dartlang-testcase:///main_lib.dart";
-
-static method main() → dynamic {
-  core::List<dynamic> list = core::_GrowableList::•<dynamic>(0);
-  if(list.{core::Iterable::isNotEmpty}{core::bool}) {
-    new mai::Class::•().{mai::Class::method}(_in::unsafeCast<mai::Enum>(_in::unsafeCast<dynamic>(null))){(mai::Enum) → core::int};
-  }
-}
-
-library /*isNonNullableByDefault*/;
-import self as mai;
-import "dart:core" as core;
-
-abstract class Enum extends core::Object implements core::Enum {
-  abstract get /*isLegacy*/ index() → core::int;
-}
-class Class extends core::Object {
-  synthetic constructor •() → mai::Class
-    : super core::Object::•()
-    ;
-  method method(mai::Enum e) → core::int
-    return e.{mai::Enum::index}{core::int};
-}
-
-
-
-Constructor coverage from constants:
-org-dartlang-testcase:///main_lib.dart:
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/test.options b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/test.options
deleted file mode 100644
index bfe6dc8..0000000
--- a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/test.options
+++ /dev/null
@@ -1 +0,0 @@
-main_lib.dart
\ No newline at end of file
diff --git a/pkg/front_end/testcases/aot/folder.options b/pkg/front_end/testcases/aot/folder.options
deleted file mode 100644
index a8a8650..0000000
--- a/pkg/front_end/testcases/aot/folder.options
+++ /dev/null
@@ -1 +0,0 @@
---target=aot
\ No newline at end of file
diff --git a/pkg/front_end/testcases/aot/tree_shake/main.dart.strong.expect b/pkg/front_end/testcases/aot/tree_shake/main.dart.strong.expect
deleted file mode 100644
index 961f514..0000000
--- a/pkg/front_end/testcases/aot/tree_shake/main.dart.strong.expect
+++ /dev/null
@@ -1,116 +0,0 @@
-library /*isNonNullableByDefault*/;
-import self as self;
-import "dart:core" as core;
-import "main_lib.dart" as mai;
-
-import "org-dartlang-testcase:///main_lib.dart";
-
-class UnusedEnum extends core::Object implements core::Enum /*isEnum*/  {
-  final field core::int index;
-  final field core::String _name;
-  static const field core::List<self::UnusedEnum> values = #C7;
-  static const field self::UnusedEnum a = #C3;
-  static const field self::UnusedEnum b = #C6;
-  const constructor •(core::int index, core::String _name) → self::UnusedEnum
-    : self::UnusedEnum::index = index, self::UnusedEnum::_name = _name, super core::Object::•()
-    ;
-  method toString() → core::String
-    return this.{self::UnusedEnum::_name}{core::String};
-}
-class UsedEnum extends core::Object implements core::Enum /*isEnum*/  {
-  final field core::int index;
-  final field core::String _name;
-  static const field core::List<self::UsedEnum> values = #C12;
-  static const field self::UsedEnum unusedValue = #C9;
-  static const field self::UsedEnum usedValue = #C11;
-  const constructor •(core::int index, core::String _name) → self::UsedEnum
-    : self::UsedEnum::index = index, self::UsedEnum::_name = _name, super core::Object::•()
-    ;
-  method toString() → core::String
-    return this.{self::UsedEnum::_name}{core::String};
-}
-class UnusedInterface extends core::Object {
-  field core::int? usedInterfaceField;
-  constructor •(core::int? usedInterfaceField) → self::UnusedInterface
-    : self::UnusedInterface::usedInterfaceField = usedInterfaceField, super core::Object::•()
-    ;
-}
-class UsedClass extends core::Object implements self::UnusedInterface {
-  field core::int? unusedField = null;
-  field core::int? usedField = null;
-  field core::int? usedInterfaceField = null;
-  synthetic constructor •() → self::UsedClass
-    : super core::Object::•()
-    ;
-}
-class UnusedClass extends core::Object {
-  synthetic constructor •() → self::UnusedClass
-    : super core::Object::•()
-    ;
-}
-static method usedMethod(self::UnusedInterface c) → dynamic {
-  c.{self::UnusedInterface::usedInterfaceField} = c.{self::UnusedInterface::usedInterfaceField}{core::int?};
-}
-static method unusedMethod() → dynamic {}
-static method main() → dynamic {
-  self::usedMethod(let final self::UsedClass #t1 = new self::UsedClass::•() in block {
-    #t1.{self::UsedClass::usedField}{core::int?};
-  } =>#t1);
-  #C11;
-  core::List<self::UnusedEnum> list = <self::UnusedEnum>[];
-  if(list.{core::Iterable::isNotEmpty}{core::bool}) {
-    new mai::ConstClass::•().{mai::ConstClass::method}((null as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} mai::ConstEnum){(mai::ConstEnum) → core::int};
-  }
-}
-
-library /*isNonNullableByDefault*/;
-import self as mai;
-import "dart:core" as core;
-
-class ConstEnum extends core::Object implements core::Enum /*isEnum*/  {
-  final field core::int index;
-  final field core::String _name;
-  static const field core::List<mai::ConstEnum> values = #C15;
-  static const field mai::ConstEnum value = #C14;
-  const constructor •(core::int index, core::String _name) → mai::ConstEnum
-    : mai::ConstEnum::index = index, mai::ConstEnum::_name = _name, super core::Object::•()
-    ;
-  method toString() → core::String
-    return this.{mai::ConstEnum::_name}{core::String};
-}
-class ConstClass extends core::Object {
-  synthetic constructor •() → mai::ConstClass
-    : super core::Object::•()
-    ;
-  method method(mai::ConstEnum e) → core::int
-    return e.{mai::ConstEnum::index}{core::int};
-}
-
-constants  {
-  #C1 = 0
-  #C2 = "UnusedEnum.a"
-  #C3 = self::UnusedEnum {index:#C1, _name:#C2}
-  #C4 = 1
-  #C5 = "UnusedEnum.b"
-  #C6 = self::UnusedEnum {index:#C4, _name:#C5}
-  #C7 = <self::UnusedEnum>[#C3, #C6]
-  #C8 = "UsedEnum.unusedValue"
-  #C9 = self::UsedEnum {index:#C1, _name:#C8}
-  #C10 = "UsedEnum.usedValue"
-  #C11 = self::UsedEnum {index:#C4, _name:#C10}
-  #C12 = <self::UsedEnum>[#C9, #C11]
-  #C13 = "ConstEnum.value"
-  #C14 = mai::ConstEnum {index:#C1, _name:#C13}
-  #C15 = <mai::ConstEnum>[#C14]
-}
-
-
-Constructor coverage from constants:
-org-dartlang-testcase:///main_lib.dart:
-- ConstEnum. (from org-dartlang-testcase:///main_lib.dart:5:6)
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
-
-org-dartlang-testcase:///main.dart:
-- UnusedEnum. (from org-dartlang-testcase:///main.dart:7:6)
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
-- UsedEnum. (from org-dartlang-testcase:///main.dart:8:6)
diff --git a/pkg/front_end/testcases/aot/tree_shake/main.dart.strong.transformed.expect b/pkg/front_end/testcases/aot/tree_shake/main.dart.strong.transformed.expect
deleted file mode 100644
index 0aaa3a0..0000000
--- a/pkg/front_end/testcases/aot/tree_shake/main.dart.strong.transformed.expect
+++ /dev/null
@@ -1,69 +0,0 @@
-library /*isNonNullableByDefault*/;
-import self as self;
-import "dart:core" as core;
-import "main_lib.dart" as mai;
-import "dart:_internal" as _in;
-
-import "org-dartlang-testcase:///main_lib.dart";
-
-abstract class UnusedEnum extends core::Object implements core::Enum {
-}
-class UsedEnum extends core::Object implements core::Enum /*isEnum*/  {
-  final field core::int index;
-  final field core::String _name;
-  method toString() → core::String
-    return this.{self::UsedEnum::_name}{core::String};
-}
-abstract class UnusedInterface extends core::Object {
-  abstract get /*isLegacy*/ usedInterfaceField() → core::int?;
-  abstract set /*isLegacy*/ usedInterfaceField(core::int? value) → void;
-}
-class UsedClass extends core::Object implements self::UnusedInterface {
-  field core::int? usedField = null;
-  field core::int? usedInterfaceField = null;
-  synthetic constructor •() → self::UsedClass
-    : super core::Object::•()
-    ;
-}
-static method usedMethod(self::UnusedInterface c) → dynamic {
-  c.{self::UnusedInterface::usedInterfaceField} = c.{self::UnusedInterface::usedInterfaceField}{core::int?};
-}
-static method main() → dynamic {
-  self::usedMethod(let final self::UsedClass #t1 = new self::UsedClass::•() in block {
-    #t1.{self::UsedClass::usedField}{core::int?};
-  } =>#t1);
-  #C3;
-  core::List<self::UnusedEnum> list = core::_GrowableList::•<self::UnusedEnum>(0);
-  if(list.{core::Iterable::isNotEmpty}{core::bool}) {
-    block {
-      new mai::ConstClass::•();
-      _in::unsafeCast<dynamic>(null) as{TypeError,ForDynamic,ForNonNullableByDefault} mai::ConstEnum;
-    } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
-  }
-}
-
-library /*isNonNullableByDefault*/;
-import self as mai;
-import "dart:core" as core;
-
-abstract class ConstEnum extends core::Object implements core::Enum {
-}
-class ConstClass extends core::Object {
-  synthetic constructor •() → mai::ConstClass
-    : super core::Object::•()
-    ;
-}
-
-constants  {
-  #C1 = 1
-  #C2 = "UsedEnum.usedValue"
-  #C3 = self::UsedEnum {index:#C1, _name:#C2}
-}
-
-
-Constructor coverage from constants:
-org-dartlang-testcase:///main_lib.dart:
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
-
-org-dartlang-testcase:///main.dart:
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/aot/tree_shake/main.dart.textual_outline.expect b/pkg/front_end/testcases/aot/tree_shake/main.dart.textual_outline.expect
deleted file mode 100644
index 97f788b..0000000
--- a/pkg/front_end/testcases/aot/tree_shake/main.dart.textual_outline.expect
+++ /dev/null
@@ -1,24 +0,0 @@
-import 'main_lib.dart';
-
-enum UnusedEnum { a, b }
-enum UsedEnum {
-  unusedValue,
-  usedValue,
-}
-usedMethod(UnusedInterface c) {}
-unusedMethod() {}
-
-class UnusedInterface {
-  int? usedInterfaceField;
-  UnusedInterface(this.usedInterfaceField);
-}
-
-class UsedClass implements UnusedInterface {
-  int? unusedField;
-  int? usedField;
-  int? usedInterfaceField;
-}
-
-class UnusedClass {}
-
-main() {}
diff --git a/pkg/front_end/testcases/aot/tree_shake/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/aot/tree_shake/main.dart.textual_outline_modelled.expect
deleted file mode 100644
index a10c6f3..0000000
--- a/pkg/front_end/testcases/aot/tree_shake/main.dart.textual_outline_modelled.expect
+++ /dev/null
@@ -1,23 +0,0 @@
-import 'main_lib.dart';
-
-class UnusedClass {}
-
-class UnusedInterface {
-  UnusedInterface(this.usedInterfaceField);
-  int? usedInterfaceField;
-}
-
-class UsedClass implements UnusedInterface {
-  int? unusedField;
-  int? usedField;
-  int? usedInterfaceField;
-}
-
-enum UnusedEnum { a, b }
-enum UsedEnum {
-  unusedValue,
-  usedValue,
-}
-main() {}
-unusedMethod() {}
-usedMethod(UnusedInterface c) {}
diff --git a/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.expect b/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.expect
deleted file mode 100644
index cd3c2b4..0000000
--- a/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.expect
+++ /dev/null
@@ -1,116 +0,0 @@
-library /*isNonNullableByDefault*/;
-import self as self;
-import "dart:core" as core;
-import "main_lib.dart" as mai;
-
-import "org-dartlang-testcase:///main_lib.dart";
-
-class UnusedEnum extends core::Object implements core::Enum /*isEnum*/  {
-  final field core::int index;
-  final field core::String _name;
-  static const field core::List<self::UnusedEnum> values = #C7;
-  static const field self::UnusedEnum a = #C3;
-  static const field self::UnusedEnum b = #C6;
-  const constructor •(core::int index, core::String _name) → self::UnusedEnum
-    : self::UnusedEnum::index = index, self::UnusedEnum::_name = _name, super core::Object::•()
-    ;
-  method toString() → core::String
-    return this.{self::UnusedEnum::_name}{core::String};
-}
-class UsedEnum extends core::Object implements core::Enum /*isEnum*/  {
-  final field core::int index;
-  final field core::String _name;
-  static const field core::List<self::UsedEnum> values = #C12;
-  static const field self::UsedEnum unusedValue = #C9;
-  static const field self::UsedEnum usedValue = #C11;
-  const constructor •(core::int index, core::String _name) → self::UsedEnum
-    : self::UsedEnum::index = index, self::UsedEnum::_name = _name, super core::Object::•()
-    ;
-  method toString() → core::String
-    return this.{self::UsedEnum::_name}{core::String};
-}
-class UnusedInterface extends core::Object {
-  field core::int? usedInterfaceField;
-  constructor •(core::int? usedInterfaceField) → self::UnusedInterface
-    : self::UnusedInterface::usedInterfaceField = usedInterfaceField, super core::Object::•()
-    ;
-}
-class UsedClass extends core::Object implements self::UnusedInterface {
-  field core::int? unusedField = null;
-  field core::int? usedField = null;
-  field core::int? usedInterfaceField = null;
-  synthetic constructor •() → self::UsedClass
-    : super core::Object::•()
-    ;
-}
-class UnusedClass extends core::Object {
-  synthetic constructor •() → self::UnusedClass
-    : super core::Object::•()
-    ;
-}
-static method usedMethod(self::UnusedInterface c) → dynamic {
-  c.{self::UnusedInterface::usedInterfaceField} = c.{self::UnusedInterface::usedInterfaceField}{core::int?};
-}
-static method unusedMethod() → dynamic {}
-static method main() → dynamic {
-  self::usedMethod(let final self::UsedClass #t1 = new self::UsedClass::•() in block {
-    #t1.{self::UsedClass::usedField}{core::int?};
-  } =>#t1);
-  #C11;
-  core::List<self::UnusedEnum> list = <self::UnusedEnum>[];
-  if(list.{core::Iterable::isNotEmpty}{core::bool}) {
-    new mai::ConstClass::•().{mai::ConstClass::method}((null as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} mai::ConstEnum){(mai::ConstEnum) → core::int};
-  }
-}
-
-library /*isNonNullableByDefault*/;
-import self as mai;
-import "dart:core" as core;
-
-class ConstEnum extends core::Object implements core::Enum /*isEnum*/  {
-  final field core::int index;
-  final field core::String _name;
-  static const field core::List<mai::ConstEnum> values = #C15;
-  static const field mai::ConstEnum value = #C14;
-  const constructor •(core::int index, core::String _name) → mai::ConstEnum
-    : mai::ConstEnum::index = index, mai::ConstEnum::_name = _name, super core::Object::•()
-    ;
-  method toString() → core::String
-    return this.{mai::ConstEnum::_name}{core::String};
-}
-class ConstClass extends core::Object {
-  synthetic constructor •() → mai::ConstClass
-    : super core::Object::•()
-    ;
-  method method(mai::ConstEnum e) → core::int
-    return e.{mai::ConstEnum::index}{core::int};
-}
-
-constants  {
-  #C1 = 0
-  #C2 = "UnusedEnum.a"
-  #C3 = self::UnusedEnum {index:#C1, _name:#C2}
-  #C4 = 1
-  #C5 = "UnusedEnum.b"
-  #C6 = self::UnusedEnum {index:#C4, _name:#C5}
-  #C7 = <self::UnusedEnum*>[#C3, #C6]
-  #C8 = "UsedEnum.unusedValue"
-  #C9 = self::UsedEnum {index:#C1, _name:#C8}
-  #C10 = "UsedEnum.usedValue"
-  #C11 = self::UsedEnum {index:#C4, _name:#C10}
-  #C12 = <self::UsedEnum*>[#C9, #C11]
-  #C13 = "ConstEnum.value"
-  #C14 = mai::ConstEnum {index:#C1, _name:#C13}
-  #C15 = <mai::ConstEnum*>[#C14]
-}
-
-
-Constructor coverage from constants:
-org-dartlang-testcase:///main_lib.dart:
-- ConstEnum. (from org-dartlang-testcase:///main_lib.dart:5:6)
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
-
-org-dartlang-testcase:///main.dart:
-- UnusedEnum. (from org-dartlang-testcase:///main.dart:7:6)
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
-- UsedEnum. (from org-dartlang-testcase:///main.dart:8:6)
diff --git a/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.outline.expect b/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.outline.expect
deleted file mode 100644
index a041682..0000000
--- a/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.outline.expect
+++ /dev/null
@@ -1,96 +0,0 @@
-library /*isNonNullableByDefault*/;
-import self as self;
-import "dart:core" as core;
-
-import "org-dartlang-testcase:///main_lib.dart";
-
-class UnusedEnum extends core::Object implements core::Enum /*isEnum*/  {
-  final field core::int index;
-  final field core::String _name;
-  static const field core::List<self::UnusedEnum> values = const <self::UnusedEnum>[self::UnusedEnum::a, self::UnusedEnum::b];
-  static const field self::UnusedEnum a = const self::UnusedEnum::•(0, "UnusedEnum.a");
-  static const field self::UnusedEnum b = const self::UnusedEnum::•(1, "UnusedEnum.b");
-  const constructor •(core::int index, core::String _name) → self::UnusedEnum
-    : self::UnusedEnum::index = index, self::UnusedEnum::_name = _name, super core::Object::•()
-    ;
-  method toString() → core::String
-    return this.{self::UnusedEnum::_name}{core::String};
-}
-class UsedEnum extends core::Object implements core::Enum /*isEnum*/  {
-  final field core::int index;
-  final field core::String _name;
-  static const field core::List<self::UsedEnum> values = const <self::UsedEnum>[self::UsedEnum::unusedValue, self::UsedEnum::usedValue];
-  static const field self::UsedEnum unusedValue = const self::UsedEnum::•(0, "UsedEnum.unusedValue");
-  static const field self::UsedEnum usedValue = const self::UsedEnum::•(1, "UsedEnum.usedValue");
-  const constructor •(core::int index, core::String _name) → self::UsedEnum
-    : self::UsedEnum::index = index, self::UsedEnum::_name = _name, super core::Object::•()
-    ;
-  method toString() → core::String
-    return this.{self::UsedEnum::_name}{core::String};
-}
-class UnusedInterface extends core::Object {
-  field core::int? usedInterfaceField;
-  constructor •(core::int? usedInterfaceField) → self::UnusedInterface
-    ;
-}
-class UsedClass extends core::Object implements self::UnusedInterface {
-  field core::int? unusedField;
-  field core::int? usedField;
-  field core::int? usedInterfaceField;
-  synthetic constructor •() → self::UsedClass
-    ;
-}
-class UnusedClass extends core::Object {
-  synthetic constructor •() → self::UnusedClass
-    ;
-}
-static method usedMethod(self::UnusedInterface c) → dynamic
-  ;
-static method unusedMethod() → dynamic
-  ;
-static method main() → dynamic
-  ;
-
-library /*isNonNullableByDefault*/;
-import self as self2;
-import "dart:core" as core;
-
-class ConstEnum extends core::Object implements core::Enum /*isEnum*/  {
-  final field core::int index;
-  final field core::String _name;
-  static const field core::List<self2::ConstEnum> values = #C4;
-  static const field self2::ConstEnum value = #C3;
-  const constructor •(core::int index, core::String _name) → self2::ConstEnum
-    : self2::ConstEnum::index = index, self2::ConstEnum::_name = _name, super core::Object::•()
-    ;
-  method toString() → core::String
-    return this.{self2::ConstEnum::_name}{core::String};
-}
-class ConstClass extends core::Object {
-  synthetic constructor •() → self2::ConstClass
-    ;
-  method method(self2::ConstEnum e) → core::int
-    ;
-}
-
-constants  {
-  #C1 = 0
-  #C2 = "ConstEnum.value"
-  #C3 = self2::ConstEnum {index:#C1, _name:#C2}
-  #C4 = <self2::ConstEnum*>[#C3]
-}
-
-Extra constant evaluation status:
-Evaluated: ListLiteral @ org-dartlang-testcase:///main.dart:7:6 -> ListConstant(const <UnusedEnum*>[const UnusedEnum{UnusedEnum.index: 0, UnusedEnum._name: "UnusedEnum.a"}, const UnusedEnum{UnusedEnum.index: 1, UnusedEnum._name: "UnusedEnum.b"}])
-Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:7:19 -> InstanceConstant(const UnusedEnum{UnusedEnum.index: 0, UnusedEnum._name: "UnusedEnum.a"})
-Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:7:22 -> InstanceConstant(const UnusedEnum{UnusedEnum.index: 1, UnusedEnum._name: "UnusedEnum.b"})
-Evaluated: ListLiteral @ org-dartlang-testcase:///main.dart:8:6 -> ListConstant(const <UsedEnum*>[const UsedEnum{UsedEnum.index: 0, UsedEnum._name: "UsedEnum.unusedValue"}, const UsedEnum{UsedEnum.index: 1, UsedEnum._name: "UsedEnum.usedValue"}])
-Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:9:3 -> InstanceConstant(const UsedEnum{UsedEnum.index: 0, UsedEnum._name: "UsedEnum.unusedValue"})
-Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:10:3 -> InstanceConstant(const UsedEnum{UsedEnum.index: 1, UsedEnum._name: "UsedEnum.usedValue"})
-Extra constant evaluation: evaluated: 18, effectively constant: 6
-
-
-Constructor coverage from constants:
-org-dartlang-testcase:///main_lib.dart:
-- ConstEnum. (from org-dartlang-testcase:///main_lib.dart:5:6)
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.transformed.expect b/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.transformed.expect
deleted file mode 100644
index 9382897..0000000
--- a/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.transformed.expect
+++ /dev/null
@@ -1,69 +0,0 @@
-library /*isNonNullableByDefault*/;
-import self as self;
-import "dart:core" as core;
-import "main_lib.dart" as mai;
-import "dart:_internal" as _in;
-
-import "org-dartlang-testcase:///main_lib.dart";
-
-abstract class UnusedEnum extends core::Object implements core::Enum {
-}
-class UsedEnum extends core::Object implements core::Enum /*isEnum*/  {
-  final field core::int index;
-  final field core::String _name;
-  method toString() → core::String
-    return this.{self::UsedEnum::_name}{core::String};
-}
-abstract class UnusedInterface extends core::Object {
-  abstract get /*isLegacy*/ usedInterfaceField() → core::int?;
-  abstract set /*isLegacy*/ usedInterfaceField(core::int? value) → void;
-}
-class UsedClass extends core::Object implements self::UnusedInterface {
-  field core::int? usedField = null;
-  field core::int? usedInterfaceField = null;
-  synthetic constructor •() → self::UsedClass
-    : super core::Object::•()
-    ;
-}
-static method usedMethod(self::UnusedInterface c) → dynamic {
-  c.{self::UnusedInterface::usedInterfaceField} = c.{self::UnusedInterface::usedInterfaceField}{core::int?};
-}
-static method main() → dynamic {
-  self::usedMethod(let final self::UsedClass #t1 = new self::UsedClass::•() in block {
-    #t1.{self::UsedClass::usedField}{core::int?};
-  } =>#t1);
-  #C3;
-  core::List<self::UnusedEnum> list = core::_GrowableList::•<self::UnusedEnum>(0);
-  if(list.{core::Iterable::isNotEmpty}{core::bool}) {
-    new mai::ConstClass::•().{mai::ConstClass::method}(_in::unsafeCast<mai::ConstEnum>(_in::unsafeCast<dynamic>(null))){(mai::ConstEnum) → core::int};
-  }
-}
-
-library /*isNonNullableByDefault*/;
-import self as mai;
-import "dart:core" as core;
-
-abstract class ConstEnum extends core::Object implements core::Enum {
-  abstract get /*isLegacy*/ index() → core::int;
-}
-class ConstClass extends core::Object {
-  synthetic constructor •() → mai::ConstClass
-    : super core::Object::•()
-    ;
-  method method(mai::ConstEnum e) → core::int
-    return e.{mai::ConstEnum::index}{core::int};
-}
-
-constants  {
-  #C1 = 1
-  #C2 = "UsedEnum.usedValue"
-  #C3 = self::UsedEnum {index:#C1, _name:#C2}
-}
-
-
-Constructor coverage from constants:
-org-dartlang-testcase:///main_lib.dart:
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
-
-org-dartlang-testcase:///main.dart:
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/aot/tree_shake/test.options b/pkg/front_end/testcases/aot/tree_shake/test.options
deleted file mode 100644
index bfe6dc8..0000000
--- a/pkg/front_end/testcases/aot/tree_shake/test.options
+++ /dev/null
@@ -1 +0,0 @@
-main_lib.dart
\ No newline at end of file
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.strong.expect b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.strong.expect
deleted file mode 100644
index b5c21df..0000000
--- a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.strong.expect
+++ /dev/null
@@ -1,35 +0,0 @@
-library /*isNonNullableByDefault*/;
-import self as self;
-import "dart:core" as core;
-import "main_lib.dart" as mai;
-
-import "org-dartlang-testcase:///main_lib.dart";
-
-class Class extends core::Object implements mai::Interface {
-  field core::int? field1 = null;
-  field core::int? field2 = null;
-  field core::int? field3 = null;
-  synthetic constructor •() → self::Class
-    : super core::Object::•()
-    ;
-}
-static method method(mai::Interface i) → void {
-  i.{mai::Interface::field2} = i.{mai::Interface::field1}{core::int?};
-  i.{mai::Interface::field3} = i.{mai::Interface::field3}{core::int?};
-}
-static method main() → dynamic {
-  self::method(new self::Class::•());
-}
-
-library /*isNonNullableByDefault*/;
-import self as mai;
-import "dart:core" as core;
-
-class Interface extends core::Object {
-  field core::int? field1 = null;
-  field core::int? field2 = null;
-  field core::int? field3 = null;
-  synthetic constructor •() → mai::Interface
-    : super core::Object::•()
-    ;
-}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.strong.transformed.expect b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.strong.transformed.expect
deleted file mode 100644
index 4f86a02..0000000
--- a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.strong.transformed.expect
+++ /dev/null
@@ -1,33 +0,0 @@
-library /*isNonNullableByDefault*/;
-import self as self;
-import "dart:core" as core;
-import "main_lib.dart" as mai;
-
-import "org-dartlang-testcase:///main_lib.dart";
-
-class Class extends core::Object implements mai::Interface {
-  field core::int? field1 = null;
-  field core::int? field3 = null;
-  synthetic constructor •() → self::Class
-    : super core::Object::•()
-    ;
-  set /*isLegacy*/ field2(core::int? value) → void;
-}
-static method method(mai::Interface i) → void {
-  i.{mai::Interface::field2} = i.{mai::Interface::field1}{core::int?};
-  i.{mai::Interface::field3} = i.{mai::Interface::field3}{core::int?};
-}
-static method main() → dynamic {
-  self::method(new self::Class::•());
-}
-
-library /*isNonNullableByDefault*/;
-import self as mai;
-import "dart:core" as core;
-
-abstract class Interface extends core::Object {
-  abstract get /*isLegacy*/ field1() → core::int?;
-  abstract set /*isLegacy*/ field2(core::int? value) → void;
-  abstract get /*isLegacy*/ field3() → core::int?;
-  abstract set /*isLegacy*/ field3(core::int? value) → void;
-}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.textual_outline.expect b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.textual_outline.expect
deleted file mode 100644
index 433a1aa..0000000
--- a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.textual_outline.expect
+++ /dev/null
@@ -1,10 +0,0 @@
-import 'main_lib.dart';
-
-class Class implements Interface {
-  int? field1;
-  int? field2;
-  int? field3;
-}
-
-void method(Interface i) {}
-main() {}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.textual_outline_modelled.expect
deleted file mode 100644
index 60b9b0d..0000000
--- a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.textual_outline_modelled.expect
+++ /dev/null
@@ -1,10 +0,0 @@
-import 'main_lib.dart';
-
-class Class implements Interface {
-  int? field1;
-  int? field2;
-  int? field3;
-}
-
-main() {}
-void method(Interface i) {}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.expect b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.expect
deleted file mode 100644
index b5c21df..0000000
--- a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.expect
+++ /dev/null
@@ -1,35 +0,0 @@
-library /*isNonNullableByDefault*/;
-import self as self;
-import "dart:core" as core;
-import "main_lib.dart" as mai;
-
-import "org-dartlang-testcase:///main_lib.dart";
-
-class Class extends core::Object implements mai::Interface {
-  field core::int? field1 = null;
-  field core::int? field2 = null;
-  field core::int? field3 = null;
-  synthetic constructor •() → self::Class
-    : super core::Object::•()
-    ;
-}
-static method method(mai::Interface i) → void {
-  i.{mai::Interface::field2} = i.{mai::Interface::field1}{core::int?};
-  i.{mai::Interface::field3} = i.{mai::Interface::field3}{core::int?};
-}
-static method main() → dynamic {
-  self::method(new self::Class::•());
-}
-
-library /*isNonNullableByDefault*/;
-import self as mai;
-import "dart:core" as core;
-
-class Interface extends core::Object {
-  field core::int? field1 = null;
-  field core::int? field2 = null;
-  field core::int? field3 = null;
-  synthetic constructor •() → mai::Interface
-    : super core::Object::•()
-    ;
-}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.outline.expect b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.outline.expect
deleted file mode 100644
index 7018a21..0000000
--- a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.outline.expect
+++ /dev/null
@@ -1,30 +0,0 @@
-library /*isNonNullableByDefault*/;
-import self as self;
-import "dart:core" as core;
-import "main_lib.dart" as mai;
-
-import "org-dartlang-testcase:///main_lib.dart";
-
-class Class extends core::Object implements mai::Interface {
-  field core::int? field1;
-  field core::int? field2;
-  field core::int? field3;
-  synthetic constructor •() → self::Class
-    ;
-}
-static method method(mai::Interface i) → void
-  ;
-static method main() → dynamic
-  ;
-
-library /*isNonNullableByDefault*/;
-import self as mai;
-import "dart:core" as core;
-
-class Interface extends core::Object {
-  field core::int? field1;
-  field core::int? field2;
-  field core::int? field3;
-  synthetic constructor •() → mai::Interface
-    ;
-}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.transformed.expect b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.transformed.expect
deleted file mode 100644
index 4f86a02..0000000
--- a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.transformed.expect
+++ /dev/null
@@ -1,33 +0,0 @@
-library /*isNonNullableByDefault*/;
-import self as self;
-import "dart:core" as core;
-import "main_lib.dart" as mai;
-
-import "org-dartlang-testcase:///main_lib.dart";
-
-class Class extends core::Object implements mai::Interface {
-  field core::int? field1 = null;
-  field core::int? field3 = null;
-  synthetic constructor •() → self::Class
-    : super core::Object::•()
-    ;
-  set /*isLegacy*/ field2(core::int? value) → void;
-}
-static method method(mai::Interface i) → void {
-  i.{mai::Interface::field2} = i.{mai::Interface::field1}{core::int?};
-  i.{mai::Interface::field3} = i.{mai::Interface::field3}{core::int?};
-}
-static method main() → dynamic {
-  self::method(new self::Class::•());
-}
-
-library /*isNonNullableByDefault*/;
-import self as mai;
-import "dart:core" as core;
-
-abstract class Interface extends core::Object {
-  abstract get /*isLegacy*/ field1() → core::int?;
-  abstract set /*isLegacy*/ field2(core::int? value) → void;
-  abstract get /*isLegacy*/ field3() → core::int?;
-  abstract set /*isLegacy*/ field3(core::int? value) → void;
-}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/test.options b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/test.options
deleted file mode 100644
index bfe6dc8..0000000
--- a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/test.options
+++ /dev/null
@@ -1 +0,0 @@
-main_lib.dart
\ No newline at end of file
diff --git a/pkg/vm/test/common_test_utils.dart b/pkg/vm/test/common_test_utils.dart
index 1ff586a..ed5b3f5 100644
--- a/pkg/vm/test/common_test_utils.dart
+++ b/pkg/vm/test/common_test_utils.dart
@@ -10,6 +10,7 @@
         CompilerOptions,
         DiagnosticMessage,
         computePlatformBinariesLocation,
+        kernelForModule,
         kernelForProgram,
         parseExperimentalArguments,
         parseExperimentalFlags;
@@ -39,34 +40,53 @@
     bool enableSuperMixins = false,
     List<String>? experimentalFlags,
     Map<String, String>? environmentDefines,
-    Uri? packagesFileUri}) async {
-  final platformKernel =
-      computePlatformBinariesLocation().resolve('vm_platform_strong.dill');
-  target ??= new TestingVmTarget(new TargetFlags())
-    ..enableSuperMixins = enableSuperMixins;
-  environmentDefines ??= <String, String>{};
-  final options = new CompilerOptions()
-    ..target = target
-    ..additionalDills = <Uri>[platformKernel]
-    ..environmentDefines = environmentDefines
-    ..packagesFileUri = packagesFileUri
-    ..explicitExperimentalFlags =
-        parseExperimentalFlags(parseExperimentalArguments(experimentalFlags),
-            onError: (String message) {
-      throw message;
-    })
-    ..onDiagnostic = (DiagnosticMessage message) {
-      fail("Compilation error: ${message.plainTextFormatted.join('\n')}");
-    };
+    Uri? packagesFileUri,
+    List<Uri>? linkedDependencies}) async {
+  Directory? tempDirectory;
+  try {
+    final platformKernel =
+        computePlatformBinariesLocation().resolve('vm_platform_strong.dill');
+    target ??= new TestingVmTarget(new TargetFlags())
+      ..enableSuperMixins = enableSuperMixins;
+    environmentDefines ??= <String, String>{};
+    final options = new CompilerOptions()
+      ..target = target
+      ..additionalDills = <Uri>[platformKernel]
+      ..environmentDefines = environmentDefines
+      ..packagesFileUri = packagesFileUri
+      ..explicitExperimentalFlags =
+          parseExperimentalFlags(parseExperimentalArguments(experimentalFlags),
+              onError: (String message) {
+        throw message;
+      })
+      ..onDiagnostic = (DiagnosticMessage message) {
+        fail("Compilation error: ${message.plainTextFormatted.join('\n')}");
+      };
+    if (linkedDependencies != null) {
+      final Component component =
+          (await kernelForModule(linkedDependencies, options)).component!;
+      tempDirectory = await Directory.systemTemp.createTemp();
+      Uri uri = tempDirectory.uri.resolve("generated.dill");
+      File generated = new File.fromUri(uri);
+      IOSink sink = generated.openWrite();
+      try {
+        new BinaryPrinter(sink).writeComponentFile(component);
+      } finally {
+        await sink.close();
+      }
+      options..additionalDills = <Uri>[platformKernel, uri];
+    }
 
-  final Component component =
-      (await kernelForProgram(sourceUri, options))!.component!;
+    final Component component =
+        (await kernelForProgram(sourceUri, options))!.component!;
 
-  // Make sure the library name is the same and does not depend on the order
-  // of test cases.
-  component.mainMethod!.enclosingLibrary.name = '#lib';
-
-  return component;
+    // Make sure the library name is the same and does not depend on the order
+    // of test cases.
+    component.mainMethod!.enclosingLibrary.name = '#lib';
+    return component;
+  } finally {
+    await tempDirectory?.delete(recursive: true);
+  }
 }
 
 String kernelLibraryToString(Library library) {
diff --git a/pkg/vm/test/transformations/type_flow/transformer_test.dart b/pkg/vm/test/transformations/type_flow/transformer_test.dart
index 0fee483..f52fb1f 100644
--- a/pkg/vm/test/transformations/type_flow/transformer_test.dart
+++ b/pkg/vm/test/transformations/type_flow/transformer_test.dart
@@ -8,6 +8,7 @@
 import 'package:kernel/ast.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/kernel.dart';
+import 'package:front_end/src/api_unstable/vm.dart';
 import 'package:test/test.dart';
 import 'package:vm/transformations/pragma.dart'
     show ConstantPragmaAnnotationParser;
@@ -16,13 +17,14 @@
 
 import '../../common_test_utils.dart';
 
-final String pkgVmDir = Platform.script.resolve('../../..').toFilePath();
+final Uri pkgVmDir = Platform.script.resolve('../../..');
 
-runTestCase(Uri source, bool enableNullSafety) async {
+runTestCase(
+    Uri source, bool enableNullSafety, List<Uri>? linkedDependencies) async {
   final target =
       new TestingVmTarget(new TargetFlags(enableNullSafety: enableNullSafety));
-  Component component =
-      await compileTestCaseToKernelProgram(source, target: target);
+  Component component = await compileTestCaseToKernelProgram(source,
+      target: target, linkedDependencies: linkedDependencies);
 
   final coreTypes = new CoreTypes(component);
 
@@ -32,6 +34,8 @@
 
   String actual = kernelLibraryToString(component.mainMethod!.enclosingLibrary);
 
+  Set<Library> dependencies = {};
+
   // Tests in /protobuf_handler consist of multiple libraries.
   // Include libraries with protobuf generated messages into the result.
   if (source.toString().contains('/protobuf_handler/')) {
@@ -39,12 +43,23 @@
       if (lib.importUri
           .toString()
           .contains('/protobuf_handler/lib/generated/')) {
-        lib.name ??= lib.importUri.pathSegments.last;
-        actual += kernelLibraryToString(lib);
+        dependencies.add(lib);
       }
     }
+  }
+  for (var lib in component.libraries) {
+    if (lib.fileUri.path.endsWith('.lib.dart')) {
+      dependencies.add(lib);
+    }
+  }
+
+  if (dependencies.isNotEmpty) {
+    for (var lib in dependencies) {
+      lib.name ??= lib.importUri.pathSegments.last;
+      actual += kernelLibraryToString(lib);
+    }
     // Remove library paths.
-    actual = actual.replaceAll(Uri.file(pkgVmDir).toString(), 'file:pkg/vm');
+    actual = actual.replaceAll(pkgVmDir.toString(), 'file:pkg/vm/');
   }
 
   compareResultWithExpectationsFile(source, actual);
@@ -59,21 +74,57 @@
   return null;
 }
 
+class TestOptions {
+  /// List of libraries the should be precompiled to .dill before compiling the
+  /// main library from source.
+  static const Option<List<String>?> linked =
+      Option('--linked', StringListValue());
+
+  /// If set, the test should be compiled with sound null safety.
+  static const Option<bool> nnbdStrong =
+      Option('--nnbd-strong', BoolValue(false));
+
+  static const List<Option> options = [linked, nnbdStrong];
+}
+
 main(List<String> args) {
   final testNameFilter = argsTestName(args);
 
   group('transform-component', () {
-    final testCasesDir = new Directory(
-        pkgVmDir + '/testcases/transformations/type_flow/transformer');
+    final testCasesDir = new Directory.fromUri(
+        pkgVmDir.resolve('testcases/transformations/type_flow/transformer/'));
 
     for (var entry
         in testCasesDir.listSync(recursive: true, followLinks: false)) {
       final path = entry.path;
       if (path.endsWith('.dart') &&
           !path.endsWith('.pb.dart') &&
-          (testNameFilter == null || path.contains(testNameFilter))) {
-        final bool enableNullSafety = path.endsWith('_nnbd_strong.dart');
-        test(path, () => runTestCase(entry.uri, enableNullSafety));
+          !path.endsWith('.lib.dart')) {
+        String name = entry.uri.pathSegments.last;
+        if (testNameFilter != null && !path.contains(testNameFilter)) {
+          print('Skipping ${name}');
+          continue;
+        }
+        List<Uri>? linkDependencies;
+        bool enableNullSafety = path.endsWith('_nnbd_strong.dart');
+
+        File optionsFile = new File('${path}.options');
+        if (optionsFile.existsSync()) {
+          ParsedOptions parsedOptions = ParsedOptions.parse(
+              ParsedOptions.readOptionsFile(optionsFile.readAsStringSync()),
+              TestOptions.options);
+          List<String>? linked = TestOptions.linked.read(parsedOptions);
+          if (linked != null) {
+            linkDependencies =
+                linked.map((String name) => entry.uri.resolve(name)).toList();
+          }
+          if (TestOptions.nnbdStrong.read(parsedOptions)) {
+            enableNullSafety = true;
+          }
+        }
+
+        test(path,
+            () => runTestCase(entry.uri, enableNullSafety, linkDependencies));
       }
     }
   }, timeout: Timeout.none);
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart b/pkg/vm/testcases/transformations/type_flow/transformer/const_default.dart
similarity index 66%
copy from pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart
copy to pkg/vm/testcases/transformations/type_flow/transformer/const_default.dart
index d2ee09c..bec8996 100644
--- a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/const_default.dart
@@ -2,11 +2,13 @@
 // 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.
 
-import 'main_lib.dart';
+import 'const_default.lib.dart';
+
+test(Class c) {
+  c.method2();
+}
 
 main() {
-  List list = [];
-  if (list.isNotEmpty) {
-    new Class().method(null as dynamic);
-  }
+  dynamic dyn = null;
+  //test(dyn);
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/const_default.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/const_default.dart.expect
new file mode 100644
index 0000000..15faad67
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/const_default.dart.expect
@@ -0,0 +1,11 @@
+library #lib /*isNonNullableByDefault*/;
+import self as self;
+
+import "file:pkg/vm/testcases/transformations/type_flow/transformer/const_default.lib.dart";
+
+static method main() → dynamic {
+  dynamic dyn = null;
+}
+library const_default.lib.dart /*isNonNullableByDefault*/;
+import self as self;
+
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/const_default.dart.options b/pkg/vm/testcases/transformations/type_flow/transformer/const_default.dart.options
new file mode 100644
index 0000000..4b185bc
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/const_default.dart.options
@@ -0,0 +1 @@
+--linked=const_default.lib.dart
\ No newline at end of file
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/const_default.lib.dart b/pkg/vm/testcases/transformations/type_flow/transformer/const_default.lib.dart
new file mode 100644
index 0000000..53f72f0
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/const_default.lib.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2021, 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 Constant {
+  final int _field;
+
+  const Constant._(this._field);
+
+  static const Constant a = const Constant._(0);
+}
+
+abstract class Interface {
+  Future<void> method({Constant c: Constant.a});
+  Future<void> method2();
+}
+
+class Class implements Interface {
+  Future<void> method({c: Constant.a}) async {}
+  Future<void> method2() async {}
+}
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart
similarity index 86%
rename from pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart
rename to pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart
index d2ee09c..602299f 100644
--- a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart
@@ -2,11 +2,11 @@
 // 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.
 
-import 'main_lib.dart';
+import 'enum_from_lib_used_as_type.lib.dart';
 
 main() {
   List list = [];
   if (list.isNotEmpty) {
     new Class().method(null as dynamic);
   }
-}
+}
\ No newline at end of file
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
new file mode 100644
index 0000000..0e15b41
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
@@ -0,0 +1,28 @@
+library #lib /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "enum_from_lib_used_as_type.lib.dart" as lib;
+import "dart:_internal" as _in;
+
+import "file:pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.lib.dart";
+
+static method main() → dynamic {
+  core::List<dynamic> list = [@vm.inferred-type.metadata=dart.core::_GrowableList<dynamic>] core::_GrowableList::•<dynamic>(0);
+  if([@vm.direct-call.metadata=dart.core::_GrowableList.isNotEmpty] [@vm.inferred-type.metadata=dart.core::bool] list.{core::Iterable::isNotEmpty}{core::bool}) {
+    [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.lib.dart::Class.method] [@vm.inferred-type.metadata=!? (skip check)] new lib::Class::•().{lib::Class::method}(_in::unsafeCast<lib::Enum>(_in::unsafeCast<dynamic>(null))){(lib::Enum) → core::int};
+  }
+}
+library enum_from_lib_used_as_type.lib.dart /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class Enum extends core::Object implements core::Enum {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3267]  abstract get /*isLegacy*/ index() → core::int;
+}
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3268,getterSelectorId:3269]  method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::Enum e) → core::int
+    return [@vm.inferred-type.metadata=!] e.{self::Enum::index}{core::int};
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.options b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.options
new file mode 100644
index 0000000..86efd12
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.options
@@ -0,0 +1 @@
+--linked=enum_from_lib_used_as_type.lib.dart
\ No newline at end of file
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main_lib.dart b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.lib.dart
similarity index 98%
rename from pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main_lib.dart
rename to pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.lib.dart
index e5600e4..951e2e9 100644
--- a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main_lib.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.lib.dart
@@ -6,4 +6,4 @@
 
 class Class {
   int method(Enum e) => e.index;
-}
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/aot/tree_shake/main.dart b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart
similarity index 93%
rename from pkg/front_end/testcases/aot/tree_shake/main.dart
rename to pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart
index 8958414..1abc669 100644
--- a/pkg/front_end/testcases/aot/tree_shake/main.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart
@@ -2,7 +2,7 @@
 // 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.
 
-import 'main_lib.dart';
+import 'tree_shake_enum_from_lib.lib.dart';
 
 enum UnusedEnum { a, b }
 enum UsedEnum {
@@ -37,4 +37,4 @@
   if (list.isNotEmpty) {
     new ConstClass().method(null as dynamic);
   }
-}
+}
\ No newline at end of file
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
new file mode 100644
index 0000000..1f84d00
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
@@ -0,0 +1,59 @@
+library #lib /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "tree_shake_enum_from_lib.lib.dart" as lib;
+import "dart:_internal" as _in;
+
+import "file:pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.lib.dart";
+
+abstract class UnusedEnum extends core::Object implements core::Enum {
+}
+class UsedEnum extends core::Object implements core::Enum /*isEnum*/  {
+[@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] [@vm.unboxing-info.metadata=()->i]  final field core::int index;
+[@vm.inferred-type.metadata=dart.core::_OneByteString (value: "UsedEnum.usedValue")] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2]  final field core::String _name;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method toString() → core::String
+    return [@vm.direct-call.metadata=#lib::UsedEnum._name] [@vm.inferred-type.metadata=dart.core::_OneByteString (value: "UsedEnum.usedValue")] this.{self::UsedEnum::_name}{core::String};
+}
+abstract class UnusedInterface extends core::Object {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  abstract get /*isLegacy*/ usedInterfaceField() → core::int?;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  abstract set /*isLegacy*/ usedInterfaceField(core::int? value) → void;
+}
+class UsedClass extends core::Object implements self::UnusedInterface {
+[@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  field core::int? usedField = null;
+[@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  field core::int? usedInterfaceField = null;
+  synthetic constructor •() → self::UsedClass
+    : super core::Object::•()
+    ;
+}
+static method usedMethod([@vm.inferred-type.metadata=#lib::UsedClass] self::UnusedInterface c) → dynamic {
+  [@vm.direct-call.metadata=#lib::UsedClass.usedInterfaceField] [@vm.inferred-type.metadata=!? (skip check)] c.{self::UnusedInterface::usedInterfaceField} = [@vm.direct-call.metadata=#lib::UsedClass.usedInterfaceField] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] c.{self::UnusedInterface::usedInterfaceField}{core::int?};
+}
+static method main() → dynamic {
+  self::usedMethod(let final self::UsedClass #t1 = new self::UsedClass::•() in block {
+    [@vm.direct-call.metadata=#lib::UsedClass.usedField] #t1.{self::UsedClass::usedField}{core::int?};
+  } =>#t1);
+  #C3;
+  core::List<self::UnusedEnum> list = [@vm.inferred-type.metadata=dart.core::_GrowableList<#lib::UnusedEnum>] core::_GrowableList::•<self::UnusedEnum>(0);
+  if([@vm.direct-call.metadata=dart.core::_GrowableList.isNotEmpty] [@vm.inferred-type.metadata=dart.core::bool] list.{core::Iterable::isNotEmpty}{core::bool}) {
+    [@vm.direct-call.metadata=library file:pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.lib.dart::ConstClass.method] [@vm.inferred-type.metadata=!? (skip check)] new lib::ConstClass::•().{lib::ConstClass::method}(_in::unsafeCast<lib::ConstEnum>(_in::unsafeCast<dynamic>(null))){(lib::ConstEnum) → core::int};
+  }
+}
+constants  {
+  #C1 = 1
+  #C2 = "UsedEnum.usedValue"
+  #C3 = self::UsedEnum {index:#C1, _name:#C2}
+}
+library tree_shake_enum_from_lib.lib.dart /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class ConstEnum extends core::Object implements core::Enum {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3273]  abstract get /*isLegacy*/ index() → core::int;
+}
+class ConstClass extends core::Object {
+  synthetic constructor •() → self::ConstClass
+    : super core::Object::•()
+    ;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3274,getterSelectorId:3275]  method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::ConstEnum e) → core::int
+    return [@vm.inferred-type.metadata=!] e.{self::ConstEnum::index}{core::int};
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.options b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.options
new file mode 100644
index 0000000..ea4f34c
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.options
@@ -0,0 +1 @@
+--linked=tree_shake_enum_from_lib.lib.dart
\ No newline at end of file
diff --git a/pkg/front_end/testcases/aot/tree_shake/main_lib.dart b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.lib.dart
similarity index 98%
rename from pkg/front_end/testcases/aot/tree_shake/main_lib.dart
rename to pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.lib.dart
index bc873dc..af82d68 100644
--- a/pkg/front_end/testcases/aot/tree_shake/main_lib.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.lib.dart
@@ -6,4 +6,4 @@
 
 class ConstClass {
   int method(ConstEnum e) => e.index;
-}
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field.dart
similarity index 91%
rename from pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart
rename to pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field.dart
index 53ab22e..28a4c67 100644
--- a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field.dart
@@ -2,7 +2,7 @@
 // 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.
 
-import 'main_lib.dart';
+import 'tree_shake_field.lib.dart';
 
 class Class implements Interface {
   int? field1;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field.dart.expect
new file mode 100644
index 0000000..92a3b9a
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field.dart.expect
@@ -0,0 +1,32 @@
+library #lib /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "tree_shake_field.lib.dart" as lib;
+
+import "file:pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field.lib.dart";
+
+class Class extends core::Object implements lib::Interface {
+[@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  field core::int? field1 = null;
+[@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  field core::int? field3 = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5]  set /*isLegacy*/ field2(core::int? value) → void;
+}
+static method method([@vm.inferred-type.metadata=#lib::Class] lib::Interface i) → void {
+  [@vm.direct-call.metadata=#lib::Class.field2] [@vm.inferred-type.metadata=!? (skip check)] i.{lib::Interface::field2} = [@vm.direct-call.metadata=#lib::Class.field1] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] i.{lib::Interface::field1}{core::int?};
+  [@vm.direct-call.metadata=#lib::Class.field3] [@vm.inferred-type.metadata=!? (skip check)] i.{lib::Interface::field3} = [@vm.direct-call.metadata=#lib::Class.field3] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] i.{lib::Interface::field3}{core::int?};
+}
+static method main() → dynamic {
+  self::method(new self::Class::•());
+}
+library tree_shake_field.lib.dart /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class Interface extends core::Object {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2]  abstract get /*isLegacy*/ field1() → core::int?;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5]  abstract set /*isLegacy*/ field2(core::int? value) → void;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  abstract get /*isLegacy*/ field3() → core::int?;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  abstract set /*isLegacy*/ field3(core::int? value) → void;
+}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main_lib.dart b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field.lib.dart
similarity index 100%
rename from pkg/front_end/testcases/aot/tree_shake_field_from_lib/main_lib.dart
rename to pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field.lib.dart
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field_linked.dart
similarity index 91%
copy from pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart
copy to pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field_linked.dart
index 53ab22e..28a4c67 100644
--- a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field_linked.dart
@@ -2,7 +2,7 @@
 // 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.
 
-import 'main_lib.dart';
+import 'tree_shake_field.lib.dart';
 
 class Class implements Interface {
   int? field1;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field_linked.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field_linked.dart.expect
new file mode 100644
index 0000000..92a3b9a
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field_linked.dart.expect
@@ -0,0 +1,32 @@
+library #lib /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "tree_shake_field.lib.dart" as lib;
+
+import "file:pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field.lib.dart";
+
+class Class extends core::Object implements lib::Interface {
+[@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  field core::int? field1 = null;
+[@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  field core::int? field3 = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5]  set /*isLegacy*/ field2(core::int? value) → void;
+}
+static method method([@vm.inferred-type.metadata=#lib::Class] lib::Interface i) → void {
+  [@vm.direct-call.metadata=#lib::Class.field2] [@vm.inferred-type.metadata=!? (skip check)] i.{lib::Interface::field2} = [@vm.direct-call.metadata=#lib::Class.field1] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] i.{lib::Interface::field1}{core::int?};
+  [@vm.direct-call.metadata=#lib::Class.field3] [@vm.inferred-type.metadata=!? (skip check)] i.{lib::Interface::field3} = [@vm.direct-call.metadata=#lib::Class.field3] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] i.{lib::Interface::field3}{core::int?};
+}
+static method main() → dynamic {
+  self::method(new self::Class::•());
+}
+library tree_shake_field.lib.dart /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class Interface extends core::Object {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:2]  abstract get /*isLegacy*/ field1() → core::int?;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5]  abstract set /*isLegacy*/ field2(core::int? value) → void;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  abstract get /*isLegacy*/ field3() → core::int?;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  abstract set /*isLegacy*/ field3(core::int? value) → void;
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field_linked.dart.options b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field_linked.dart.options
new file mode 100644
index 0000000..6e1fb8f
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_field_linked.dart.options
@@ -0,0 +1 @@
+--linked=tree_shake_field.lib.dart
\ No newline at end of file
diff --git a/tools/VERSION b/tools/VERSION
index 8c5ab71..7ff6d89 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 383
+PRERELEASE 384
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/spec_parser/Dart.g b/tools/spec_parser/Dart.g
index e1d7db2..465b18a 100644
--- a/tools/spec_parser/Dart.g
+++ b/tools/spec_parser/Dart.g
@@ -4,6 +4,23 @@
 
 // CHANGES:
 //
+// v0.17 Correct `uri` to allow multi-line strings (raw and non-raw).
+//
+// v0.16 (284695f1937c262523a9a11b9084213f889c83e0) Correct instance variable
+// declaration syntax such that `covariant late final` is allowed.
+//
+// v0.15 (6facd6dfdafa2953e8523348220d3129ea884678) Add support for
+// constructor tearoffs and explicitly instantiated function tearoffs and
+// type literals.
+//
+// v0.14 (f65c20124edd9e04f7b3a6f014f40c16f51052f6) Correct `partHeader`
+// to allow uri syntax in a `PART OF` directive.
+//
+// v0.13 (bb5cb79a2fd57d6a480b922bc650d5cd15948753) Introduce non-terminals
+// `builtinIdentifier` and `reservedWord`; update `typeAlias` to enable
+// non-function type aliases; add missing `metadata` to formal parameter
+// declarations; correct `symbolLiteral` to allow `VOID`;
+
 // v0.12 (82403371ac00ddf004be60fa7b705474d2864509) Cf. language issue #1341:
 // correct `metadata`. Change `qualifiedName` such that it only includes the
 // cases with a '.'; the remaining case is added where `qualifiedName` is used.
@@ -559,7 +576,7 @@
 
 // Not used in the specification (needed here for <uri>).
 stringLiteralWithoutInterpolation
-    :    singleLineStringWithoutInterpolation+
+    :    singleStringWithoutInterpolation+
     ;
 
 setOrMapLiteral
@@ -1266,10 +1283,13 @@
     ;
 
 // Not used in the specification (needed here for <uri>).
-singleLineStringWithoutInterpolation
+singleStringWithoutInterpolation
     :    RAW_SINGLE_LINE_STRING
+    |    RAW_MULTI_LINE_STRING
     |    SINGLE_LINE_STRING_DQ_BEGIN_END
     |    SINGLE_LINE_STRING_SQ_BEGIN_END
+    |    MULTI_LINE_STRING_DQ_BEGIN_END
+    |    MULTI_LINE_STRING_SQ_BEGIN_END
     ;
 
 singleLineString