Version 2.14.0-232.0.dev

Merge commit '1641a4bcfb98cad48986ac33ad8fdeb9fedf31c8' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index c005a09..57905b9 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -3417,7 +3417,6 @@
       returnType: returnType,
       nullabilitySuffix:
           isNullable ? NullabilitySuffix.question : _noneOrStarSuffix,
-      element: this,
     );
   }
 
diff --git a/pkg/analyzer/test/generated/simple_resolver_test.dart b/pkg/analyzer/test/generated/simple_resolver_test.dart
index 6000f44..981d29c 100644
--- a/pkg/analyzer/test/generated/simple_resolver_test.dart
+++ b/pkg/analyzer/test/generated/simple_resolver_test.dart
@@ -311,57 +311,6 @@
 class C {}''');
   }
 
-  test_commentReference_extension_getter() async {
-    await resolveTestCode('''
-/// See [E.b]
-class A {}
-
-extension E on A {
-  String get b => '';
-}
-''');
-
-    final classA = findNode.classDeclaration('class A');
-    final reference = classA.documentationComment!.references.single;
-
-    expect(
-        reference.identifier.staticElement, findElement.getter('b', of: 'E'));
-  }
-
-  test_commentReference_extension_method() async {
-    await resolveTestCode('''
-/// See [E.b]
-class A {}
-
-extension E on A {
-  void b() {}
-}
-''');
-
-    final classA = findNode.classDeclaration('class A');
-    final reference = classA.documentationComment!.references.single;
-
-    expect(
-        reference.identifier.staticElement, findElement.method('b', of: 'E'));
-  }
-
-  test_commentReference_extension_setter() async {
-    await resolveTestCode('''
-/// See [E.b]
-class A {}
-
-extension E on A {
-  set b(String x) {}
-}
-''');
-
-    final classA = findNode.classDeclaration('class A');
-    final reference = classA.documentationComment!.references.single;
-
-    expect(
-        reference.identifier.staticElement, findElement.setter('b', of: 'E'));
-  }
-
   test_continueTarget_labeled() async {
     // Verify that the target of the label is correctly found and is recorded
     // as the unlabeled portion of the statement.
diff --git a/pkg/analyzer/test/src/dart/resolution/comment_test.dart b/pkg/analyzer/test/src/dart/resolution/comment_test.dart
index 173fa0a..d5d1255 100644
--- a/pkg/analyzer/test/src/dart/resolution/comment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/comment_test.dart
@@ -167,6 +167,174 @@
     assertElement(findNode.simple('p5]'), findElement.parameter('p5'));
   }
 
+  test_identifier_class_instanceGetter() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+
+/// [A.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+    assertElement(findNode.simple('foo]'), findElement.getter('foo'));
+  }
+
+  test_identifier_class_instanceMethod() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+
+/// [A.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+    assertElement(findNode.simple('foo]'), findElement.method('foo'));
+  }
+
+  test_identifier_class_instanceSetter() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  set foo(int _) {}
+}
+
+/// [A.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+    assertElement(findNode.simple('foo]'), findElement.setter('foo'));
+  }
+
+  test_identifier_class_staticGetter() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  static int get foo => 0;
+}
+
+/// [A.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+    assertElement(findNode.simple('foo]'), findElement.getter('foo'));
+  }
+
+  test_identifier_class_staticMethod() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  static void foo() {}
+}
+
+/// [A.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+    assertElement(findNode.simple('foo]'), findElement.method('foo'));
+  }
+
+  test_identifier_class_staticSetter() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  static set foo(int _) {}
+}
+
+/// [A.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+    assertElement(findNode.simple('foo]'), findElement.setter('foo'));
+  }
+
+  test_identifier_extension_instanceGetter() async {
+    await assertNoErrorsInCode(r'''
+extension E on int {
+  int get foo => 0;
+}
+
+/// [E.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+    assertElement(findNode.simple('foo]'), findElement.getter('foo'));
+  }
+
+  test_identifier_extension_instanceMethod() async {
+    await assertNoErrorsInCode(r'''
+extension E on int {
+  void foo() {}
+}
+
+/// [E.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+    assertElement(findNode.simple('foo]'), findElement.method('foo'));
+  }
+
+  test_identifier_extension_instanceSetter() async {
+    await assertNoErrorsInCode(r'''
+extension E on int {
+  set foo(int _) {}
+}
+
+/// [E.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+    assertElement(findNode.simple('foo]'), findElement.setter('foo'));
+  }
+
+  test_identifier_extension_staticGetter() async {
+    await assertNoErrorsInCode(r'''
+extension E on int {
+  static int get foo => 0;
+}
+
+/// [E.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+    assertElement(findNode.simple('foo]'), findElement.getter('foo'));
+  }
+
+  test_identifier_extension_staticMethod() async {
+    await assertNoErrorsInCode(r'''
+extension E on int {
+  static void foo() {}
+}
+
+/// [E.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+    assertElement(findNode.simple('foo]'), findElement.method('foo'));
+  }
+
+  test_identifier_extension_staticSetter() async {
+    await assertNoErrorsInCode(r'''
+extension E on int {
+  static set foo(int _) {}
+}
+
+/// [E.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+    assertElement(findNode.simple('foo]'), findElement.setter('foo'));
+  }
+
   test_identifier_parameter_functionTyped() async {
     await assertNoErrorsInCode(r'''
 /// [bar]
diff --git a/pkg/analyzer/test/src/pubspec/diagnostics/asset_directory_does_not_exist_test.dart b/pkg/analyzer/test/src/pubspec/diagnostics/asset_directory_does_not_exist_test.dart
new file mode 100644
index 0000000..2d1ef5e
--- /dev/null
+++ b/pkg/analyzer/test/src/pubspec/diagnostics/asset_directory_does_not_exist_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2017, 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.
+
+import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../pubspec_test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AssetDirectoryDoesNotExistTest);
+  });
+}
+
+@reflectiveTest
+class AssetDirectoryDoesNotExistTest extends PubspecDiagnosticTest {
+  test_assetDirectoryDoesExist_noError() {
+    newFolder('/sample/assets/logos');
+    assertNoErrors('''
+name: sample
+flutter:
+  assets:
+    - assets/logos/
+''');
+  }
+
+  test_assetDirectoryDoesNotExist_error() {
+    assertErrors('''
+name: sample
+flutter:
+  assets:
+    - assets/logos/
+''', [PubspecWarningCode.ASSET_DIRECTORY_DOES_NOT_EXIST]);
+  }
+}
diff --git a/pkg/analyzer/test/src/pubspec/diagnostics/asset_does_not_exist_test.dart b/pkg/analyzer/test/src/pubspec/diagnostics/asset_does_not_exist_test.dart
new file mode 100644
index 0000000..8cd2803
--- /dev/null
+++ b/pkg/analyzer/test/src/pubspec/diagnostics/asset_does_not_exist_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2017, 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.
+
+import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../pubspec_test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AssetDoesNotExistTest);
+  });
+}
+
+@reflectiveTest
+class AssetDoesNotExistTest extends PubspecDiagnosticTest {
+  test_assetDoesNotExist_path_error() {
+    assertErrors('''
+name: sample
+flutter:
+  assets:
+    - assets/my_icon.png
+''', [PubspecWarningCode.ASSET_DOES_NOT_EXIST]);
+  }
+
+  test_assetDoesNotExist_path_inRoot_noError() {
+    newFile('/sample/assets/my_icon.png');
+    assertNoErrors('''
+name: sample
+flutter:
+  assets:
+    - assets/my_icon.png
+''');
+  }
+
+  test_assetDoesNotExist_path_inSubdir_noError() {
+    newFile('/sample/assets/images/2.0x/my_icon.png');
+    assertNoErrors('''
+name: sample
+flutter:
+  assets:
+    - assets/images/my_icon.png
+''');
+  }
+
+  @failingTest
+  test_assetDoesNotExist_uri_error() {
+    assertErrors('''
+name: sample
+flutter:
+  assets:
+    - packages/icons/my_icon.png
+''', [PubspecWarningCode.ASSET_DOES_NOT_EXIST]);
+  }
+
+  test_assetDoesNotExist_uri_noError() {
+    // TODO(brianwilkerson) Create a package named `icons` that contains the
+    // referenced file, and a `.packages` file that references that package.
+    assertNoErrors('''
+name: sample
+flutter:
+  assets:
+    - packages/icons/my_icon.png
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/pubspec/diagnostics/asset_field_not_list_test.dart b/pkg/analyzer/test/src/pubspec/diagnostics/asset_field_not_list_test.dart
new file mode 100644
index 0000000..89b9c89
--- /dev/null
+++ b/pkg/analyzer/test/src/pubspec/diagnostics/asset_field_not_list_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2017, 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.
+
+import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../pubspec_test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AssetFieldNotListTest);
+  });
+}
+
+@reflectiveTest
+class AssetFieldNotListTest extends PubspecDiagnosticTest {
+  test_assetFieldNotList_error_empty() {
+    assertErrors('''
+name: sample
+flutter:
+  assets:
+''', [PubspecWarningCode.ASSET_FIELD_NOT_LIST]);
+  }
+
+  test_assetFieldNotList_error_string() {
+    assertErrors('''
+name: sample
+flutter:
+  assets: assets/my_icon.png
+''', [PubspecWarningCode.ASSET_FIELD_NOT_LIST]);
+  }
+
+  test_assetFieldNotList_noError() {
+    newFile('/sample/assets/my_icon.png');
+    assertNoErrors('''
+name: sample
+flutter:
+  assets:
+    - assets/my_icon.png
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/pubspec/diagnostics/asset_not_string_test.dart b/pkg/analyzer/test/src/pubspec/diagnostics/asset_not_string_test.dart
new file mode 100644
index 0000000..dd68fb2
--- /dev/null
+++ b/pkg/analyzer/test/src/pubspec/diagnostics/asset_not_string_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2017, 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.
+
+import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../pubspec_test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AssetNotStringTest);
+  });
+}
+
+@reflectiveTest
+class AssetNotStringTest extends PubspecDiagnosticTest {
+  test_assetNotString_error_int() {
+    assertErrors('''
+name: sample
+flutter:
+  assets:
+    - 23
+''', [PubspecWarningCode.ASSET_NOT_STRING]);
+  }
+
+  test_assetNotString_error_map() {
+    assertErrors('''
+name: sample
+flutter:
+  assets:
+    - my_icon:
+      default: assets/my_icon.png
+      large: assets/large/my_icon.png
+''', [PubspecWarningCode.ASSET_NOT_STRING]);
+  }
+
+  test_assetNotString_noError() {
+    newFile('/sample/assets/my_icon.png');
+    assertNoErrors('''
+name: sample
+flutter:
+  assets:
+    - assets/my_icon.png
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/pubspec/diagnostics/dependencies_field_not_map_test.dart b/pkg/analyzer/test/src/pubspec/diagnostics/dependencies_field_not_map_test.dart
new file mode 100644
index 0000000..4ff18ae
--- /dev/null
+++ b/pkg/analyzer/test/src/pubspec/diagnostics/dependencies_field_not_map_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2017, 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.
+
+import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../pubspec_test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(DependenciesFieldNotMapTest);
+  });
+}
+
+@reflectiveTest
+class DependenciesFieldNotMapTest extends PubspecDiagnosticTest {
+  test_dependenciesField_empty() {
+    assertNoErrors('''
+name: sample
+dependencies:
+''');
+  }
+
+  test_dependenciesFieldNotMap_error_bool() {
+    assertErrors('''
+name: sample
+dependencies: true
+''', [PubspecWarningCode.DEPENDENCIES_FIELD_NOT_MAP]);
+  }
+
+  test_dependenciesFieldNotMap_noError() {
+    assertNoErrors('''
+name: sample
+dependencies:
+  a: any
+''');
+  }
+
+  test_devDependenciesFieldNotMap_dev_error_bool() {
+    assertErrors('''
+name: sample
+dev_dependencies: true
+''', [PubspecWarningCode.DEPENDENCIES_FIELD_NOT_MAP]);
+  }
+}
diff --git a/pkg/analyzer/test/src/pubspec/diagnostics/flutter_field_not_map_test.dart b/pkg/analyzer/test/src/pubspec/diagnostics/flutter_field_not_map_test.dart
new file mode 100644
index 0000000..85f587b
--- /dev/null
+++ b/pkg/analyzer/test/src/pubspec/diagnostics/flutter_field_not_map_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2017, 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.
+
+import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../pubspec_test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(FlutterFieldNotMapTest);
+  });
+}
+
+@reflectiveTest
+class FlutterFieldNotMapTest extends PubspecDiagnosticTest {
+  test_flutterField_empty_noError() {
+    assertNoErrors('''
+name: sample
+flutter:
+''');
+
+    assertNoErrors('''
+name: sample
+flutter:
+
+''');
+  }
+
+  test_flutterFieldNotMap_error_bool() {
+    assertErrors('''
+name: sample
+flutter: true
+''', [PubspecWarningCode.FLUTTER_FIELD_NOT_MAP]);
+  }
+
+  test_flutterFieldNotMap_noError() {
+    newFile('/sample/assets/my_icon.png');
+    assertNoErrors('''
+name: sample
+flutter:
+  assets:
+    - assets/my_icon.png
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/pubspec/validators/pubspec_dependency_validator_test.dart b/pkg/analyzer/test/src/pubspec/diagnostics/invalid_dependency_test.dart
similarity index 61%
rename from pkg/analyzer/test/src/pubspec/validators/pubspec_dependency_validator_test.dart
rename to pkg/analyzer/test/src/pubspec/diagnostics/invalid_dependency_test.dart
index cb52a95..b7b851d 100644
--- a/pkg/analyzer/test/src/pubspec/validators/pubspec_dependency_validator_test.dart
+++ b/pkg/analyzer/test/src/pubspec/diagnostics/invalid_dependency_test.dart
@@ -9,34 +9,12 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(PubspecDependencyValidatorTest);
+    defineReflectiveTests(InvalidDependencyTest);
   });
 }
 
 @reflectiveTest
-class PubspecDependencyValidatorTest extends BasePubspecValidatorTest {
-  test_dependenciesField_empty() {
-    assertNoErrors('''
-name: sample
-dependencies:
-''');
-  }
-
-  test_dependenciesFieldNotMap_error_bool() {
-    assertErrors('''
-name: sample
-dependencies: true
-''', [PubspecWarningCode.DEPENDENCIES_FIELD_NOT_MAP]);
-  }
-
-  test_dependenciesFieldNotMap_noError() {
-    assertNoErrors('''
-name: sample
-dependencies:
-  a: any
-''');
-  }
-
+class InvalidDependencyTest extends PubspecDiagnosticTest {
   test_dependencyGit_malformed_empty() {
     // todo (pq): consider validating.
     assertNoErrors('''
@@ -150,29 +128,6 @@
 ''');
   }
 
-  test_dependencyPath_pubspecDoesNotExist() {
-    newFolder('/foo');
-    assertErrors('''
-name: sample
-dependencies:
-  foo:
-    path: /foo
-''', [PubspecWarningCode.PATH_PUBSPEC_DOES_NOT_EXIST]);
-  }
-
-  test_dependencyPath_pubspecExists() {
-    newFolder('/foo');
-    newPubspecYamlFile('/foo', '''
-name: foo
-''');
-    assertNoErrors('''
-name: sample
-dependencies:
-  foo:
-    path: /foo
-''');
-  }
-
   test_dependencyPath_valid_absolute() {
     newFolder('/foo');
     newPubspecYamlFile('/foo', '''
@@ -228,15 +183,6 @@
 ''');
   }
 
-  test_dependencyPathDoesNotExist_path_error() {
-    assertErrors('''
-name: sample
-dependencies:
-  foo:
-    path: does/not/exist
-''', [PubspecWarningCode.PATH_DOES_NOT_EXIST]);
-  }
-
   test_devDependenciesField_empty() {
     assertNoErrors('''
 name: sample
@@ -244,13 +190,6 @@
 ''');
   }
 
-  test_devDependenciesFieldNotMap_dev_error_bool() {
-    assertErrors('''
-name: sample
-dev_dependencies: true
-''', [PubspecWarningCode.DEPENDENCIES_FIELD_NOT_MAP]);
-  }
-
   test_devDependenciesFieldNotMap_dev_noError() {
     assertNoErrors('''
 name: sample
@@ -271,63 +210,4 @@
       path: path/to/foo
 ''');
   }
-
-  test_devDependencyPathDoesNotExist_path_error() {
-    assertErrors('''
-name: sample
-dev_dependencies:
-  foo:
-    path: does/not/exist
-''', [PubspecWarningCode.PATH_DOES_NOT_EXIST]);
-  }
-
-  test_devDependencyPathExists() {
-    newFolder('/foo');
-    newPubspecYamlFile('/foo', '''
-name: foo
-''');
-    assertNoErrors('''
-name: sample
-dev_dependencies:
-  foo:
-    path: /foo
-''');
-  }
-
-  test_pathNotPosix_error() {
-    newFolder('/foo');
-    newPubspecYamlFile('/foo', '''
-name: foo
-''');
-    assertErrors(r'''
-name: sample
-version: 0.1.0
-publish_to: none
-dependencies:
-  foo:
-    path: \foo
-''', [
-      PubspecWarningCode.PATH_NOT_POSIX,
-    ]);
-  }
-
-  test_unnecessaryDevDependency_error() {
-    assertErrors('''
-name: sample
-dependencies:
-  a: any
-dev_dependencies:
-  a: any
-''', [PubspecWarningCode.UNNECESSARY_DEV_DEPENDENCY]);
-  }
-
-  test_unnecessaryDevDependency_noError() {
-    assertNoErrors('''
-name: sample
-dependencies:
-  a: any
-dev_dependencies:
-  b: any
-''');
-  }
 }
diff --git a/pkg/analyzer/test/src/pubspec/validators/pubspec_name_validator_test.dart b/pkg/analyzer/test/src/pubspec/diagnostics/missing_name_test.dart
similarity index 66%
copy from pkg/analyzer/test/src/pubspec/validators/pubspec_name_validator_test.dart
copy to pkg/analyzer/test/src/pubspec/diagnostics/missing_name_test.dart
index 71a7b97..9879c54 100644
--- a/pkg/analyzer/test/src/pubspec/validators/pubspec_name_validator_test.dart
+++ b/pkg/analyzer/test/src/pubspec/diagnostics/missing_name_test.dart
@@ -9,12 +9,12 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(PubspecNameValidatorTest);
+    defineReflectiveTests(MissingNameTest);
   });
 }
 
 @reflectiveTest
-class PubspecNameValidatorTest extends BasePubspecValidatorTest {
+class MissingNameTest extends PubspecDiagnosticTest {
   test_missingName_error() {
     assertErrors('', [PubspecWarningCode.MISSING_NAME]);
   }
@@ -24,16 +24,4 @@
 name: sample
 ''');
   }
-
-  test_nameNotString_error_int() {
-    assertErrors('''
-name: 42
-''', [PubspecWarningCode.NAME_NOT_STRING]);
-  }
-
-  test_nameNotString_noError() {
-    assertNoErrors('''
-name: sample
-''');
-  }
 }
diff --git a/pkg/analyzer/test/src/pubspec/validators/pubspec_name_validator_test.dart b/pkg/analyzer/test/src/pubspec/diagnostics/name_not_string_test.dart
similarity index 68%
rename from pkg/analyzer/test/src/pubspec/validators/pubspec_name_validator_test.dart
rename to pkg/analyzer/test/src/pubspec/diagnostics/name_not_string_test.dart
index 71a7b97..c58ef0a 100644
--- a/pkg/analyzer/test/src/pubspec/validators/pubspec_name_validator_test.dart
+++ b/pkg/analyzer/test/src/pubspec/diagnostics/name_not_string_test.dart
@@ -9,22 +9,12 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(PubspecNameValidatorTest);
+    defineReflectiveTests(NameNotStringTest);
   });
 }
 
 @reflectiveTest
-class PubspecNameValidatorTest extends BasePubspecValidatorTest {
-  test_missingName_error() {
-    assertErrors('', [PubspecWarningCode.MISSING_NAME]);
-  }
-
-  test_missingName_noError() {
-    assertNoErrors('''
-name: sample
-''');
-  }
-
+class NameNotStringTest extends PubspecDiagnosticTest {
   test_nameNotString_error_int() {
     assertErrors('''
 name: 42
diff --git a/pkg/analyzer/test/src/pubspec/diagnostics/path_does_not_exist_test.dart b/pkg/analyzer/test/src/pubspec/diagnostics/path_does_not_exist_test.dart
new file mode 100644
index 0000000..4afdda6
--- /dev/null
+++ b/pkg/analyzer/test/src/pubspec/diagnostics/path_does_not_exist_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2017, 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.
+
+import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../pubspec_test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(PathDoesNotExistTest);
+  });
+}
+
+@reflectiveTest
+class PathDoesNotExistTest extends PubspecDiagnosticTest {
+  test_dependencyPathDoesNotExist_path_error() {
+    assertErrors('''
+name: sample
+dependencies:
+  foo:
+    path: does/not/exist
+''', [PubspecWarningCode.PATH_DOES_NOT_EXIST]);
+  }
+
+  test_devDependencyPathDoesNotExist_path_error() {
+    assertErrors('''
+name: sample
+dev_dependencies:
+  foo:
+    path: does/not/exist
+''', [PubspecWarningCode.PATH_DOES_NOT_EXIST]);
+  }
+
+  test_devDependencyPathExists() {
+    newFolder('/foo');
+    newPubspecYamlFile('/foo', '''
+name: foo
+''');
+    assertNoErrors('''
+name: sample
+dev_dependencies:
+  foo:
+    path: /foo
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/pubspec/diagnostics/path_not_posix_test.dart b/pkg/analyzer/test/src/pubspec/diagnostics/path_not_posix_test.dart
new file mode 100644
index 0000000..2a4c3bf
--- /dev/null
+++ b/pkg/analyzer/test/src/pubspec/diagnostics/path_not_posix_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2017, 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.
+
+import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../pubspec_test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(PathNotPosixTest);
+  });
+}
+
+@reflectiveTest
+class PathNotPosixTest extends PubspecDiagnosticTest {
+  test_pathNotPosix_error() {
+    newFolder('/foo');
+    newPubspecYamlFile('/foo', '''
+name: foo
+''');
+    assertErrors(r'''
+name: sample
+version: 0.1.0
+publish_to: none
+dependencies:
+  foo:
+    path: \foo
+''', [
+      PubspecWarningCode.PATH_NOT_POSIX,
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/pubspec/diagnostics/path_pubspec_does_not_exist_test.dart b/pkg/analyzer/test/src/pubspec/diagnostics/path_pubspec_does_not_exist_test.dart
new file mode 100644
index 0000000..ea4b629
--- /dev/null
+++ b/pkg/analyzer/test/src/pubspec/diagnostics/path_pubspec_does_not_exist_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2017, 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.
+
+import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../pubspec_test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(PathPubspecDoesNotExistTest);
+  });
+}
+
+@reflectiveTest
+class PathPubspecDoesNotExistTest extends PubspecDiagnosticTest {
+  test_dependencyPath_pubspecDoesNotExist() {
+    newFolder('/foo');
+    assertErrors('''
+name: sample
+dependencies:
+  foo:
+    path: /foo
+''', [PubspecWarningCode.PATH_PUBSPEC_DOES_NOT_EXIST]);
+  }
+
+  test_dependencyPath_pubspecExists() {
+    newFolder('/foo');
+    newPubspecYamlFile('/foo', '''
+name: foo
+''');
+    assertNoErrors('''
+name: sample
+dependencies:
+  foo:
+    path: /foo
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/pubspec/diagnostics/test_all.dart b/pkg/analyzer/test/src/pubspec/diagnostics/test_all.dart
new file mode 100644
index 0000000..7b1b0ed
--- /dev/null
+++ b/pkg/analyzer/test/src/pubspec/diagnostics/test_all.dart
@@ -0,0 +1,38 @@
+// 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.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'asset_directory_does_not_exist_test.dart'
+    as asset_directory_does_not_exist;
+import 'asset_does_not_exist_test.dart' as asset_does_not_exist;
+import 'asset_field_not_list_test.dart' as asset_field_not_list;
+import 'asset_not_string_test.dart' as asset_not_string;
+import 'dependencies_field_not_map_test.dart' as dependencies_field_not_map;
+import 'flutter_field_not_map_test.dart' as flutter_field_not_map;
+import 'invalid_dependency_test.dart' as invalid_dependency;
+import 'missing_name_test.dart' as missing_name;
+import 'name_not_string_test.dart' as name_not_string;
+import 'path_does_not_exist_test.dart' as path_does_not_exist;
+import 'path_not_posix_test.dart' as path_not_posix;
+import 'path_pubspec_does_not_exist_test.dart' as path_pubspec_does_not_exist;
+import 'unnecessary_dev_dependency_test.dart' as unnecessary_dev_dependency;
+
+main() {
+  defineReflectiveSuite(() {
+    asset_directory_does_not_exist.main();
+    asset_does_not_exist.main();
+    asset_field_not_list.main();
+    asset_not_string.main();
+    dependencies_field_not_map.main();
+    flutter_field_not_map.main();
+    invalid_dependency.main();
+    missing_name.main();
+    name_not_string.main();
+    path_does_not_exist.main();
+    path_not_posix.main();
+    path_pubspec_does_not_exist.main();
+    unnecessary_dev_dependency.main();
+  }, name: 'diagnostics');
+}
diff --git a/pkg/analyzer/test/src/pubspec/diagnostics/unnecessary_dev_dependency_test.dart b/pkg/analyzer/test/src/pubspec/diagnostics/unnecessary_dev_dependency_test.dart
new file mode 100644
index 0000000..466f9d3
--- /dev/null
+++ b/pkg/analyzer/test/src/pubspec/diagnostics/unnecessary_dev_dependency_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2017, 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.
+
+import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../pubspec_test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UnnecessaryDevDependencyTest);
+  });
+}
+
+@reflectiveTest
+class UnnecessaryDevDependencyTest extends PubspecDiagnosticTest {
+  test_unnecessaryDevDependency_error() {
+    assertErrors('''
+name: sample
+dependencies:
+  a: any
+dev_dependencies:
+  a: any
+''', [PubspecWarningCode.UNNECESSARY_DEV_DEPENDENCY]);
+  }
+
+  test_unnecessaryDevDependency_noError() {
+    assertNoErrors('''
+name: sample
+dependencies:
+  a: any
+dev_dependencies:
+  b: any
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/pubspec/pubspec_test_support.dart b/pkg/analyzer/test/src/pubspec/pubspec_test_support.dart
index e2816d5..ab9365f 100644
--- a/pkg/analyzer/test/src/pubspec/pubspec_test_support.dart
+++ b/pkg/analyzer/test/src/pubspec/pubspec_test_support.dart
@@ -10,7 +10,7 @@
 
 import '../../generated/test_support.dart';
 
-class BasePubspecValidatorTest with ResourceProviderMixin {
+class PubspecDiagnosticTest with ResourceProviderMixin {
   late PubspecValidator validator;
 
   /// Assert that when the validator is used on the given [content] the
diff --git a/pkg/analyzer/test/src/pubspec/test_all.dart b/pkg/analyzer/test/src/pubspec/test_all.dart
index d5ef1de..7acfdc5 100644
--- a/pkg/analyzer/test/src/pubspec/test_all.dart
+++ b/pkg/analyzer/test/src/pubspec/test_all.dart
@@ -4,10 +4,10 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'validators/test_all.dart' as validator_tests;
+import 'diagnostics/test_all.dart' as diagnostics_tests;
 
 main() {
   defineReflectiveSuite(() {
-    validator_tests.main();
+    diagnostics_tests.main();
   }, name: 'pubspec');
 }
diff --git a/pkg/analyzer/test/src/pubspec/validators/pubspec_flutter_validator_test.dart b/pkg/analyzer/test/src/pubspec/validators/pubspec_flutter_validator_test.dart
deleted file mode 100644
index 34c9489..0000000
--- a/pkg/analyzer/test/src/pubspec/validators/pubspec_flutter_validator_test.dart
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright (c) 2017, 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.
-
-import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../pubspec_test_support.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(PubspecFlutterValidatorTest);
-  });
-}
-
-@reflectiveTest
-class PubspecFlutterValidatorTest extends BasePubspecValidatorTest {
-  test_assetDirectoryDoesExist_noError() {
-    newFolder('/sample/assets/logos');
-    assertNoErrors('''
-name: sample
-flutter:
-  assets:
-    - assets/logos/
-''');
-  }
-
-  test_assetDirectoryDoesNotExist_error() {
-    assertErrors('''
-name: sample
-flutter:
-  assets:
-    - assets/logos/
-''', [PubspecWarningCode.ASSET_DIRECTORY_DOES_NOT_EXIST]);
-  }
-
-  test_assetDoesNotExist_path_error() {
-    assertErrors('''
-name: sample
-flutter:
-  assets:
-    - assets/my_icon.png
-''', [PubspecWarningCode.ASSET_DOES_NOT_EXIST]);
-  }
-
-  test_assetDoesNotExist_path_inRoot_noError() {
-    newFile('/sample/assets/my_icon.png');
-    assertNoErrors('''
-name: sample
-flutter:
-  assets:
-    - assets/my_icon.png
-''');
-  }
-
-  test_assetDoesNotExist_path_inSubdir_noError() {
-    newFile('/sample/assets/images/2.0x/my_icon.png');
-    assertNoErrors('''
-name: sample
-flutter:
-  assets:
-    - assets/images/my_icon.png
-''');
-  }
-
-  @failingTest
-  test_assetDoesNotExist_uri_error() {
-    assertErrors('''
-name: sample
-flutter:
-  assets:
-    - packages/icons/my_icon.png
-''', [PubspecWarningCode.ASSET_DOES_NOT_EXIST]);
-  }
-
-  test_assetDoesNotExist_uri_noError() {
-    // TODO(brianwilkerson) Create a package named `icons` that contains the
-    // referenced file, and a `.packages` file that references that package.
-    assertNoErrors('''
-name: sample
-flutter:
-  assets:
-    - packages/icons/my_icon.png
-''');
-  }
-
-  test_assetFieldNotList_error_empty() {
-    assertErrors('''
-name: sample
-flutter:
-  assets:
-''', [PubspecWarningCode.ASSET_FIELD_NOT_LIST]);
-  }
-
-  test_assetFieldNotList_error_string() {
-    assertErrors('''
-name: sample
-flutter:
-  assets: assets/my_icon.png
-''', [PubspecWarningCode.ASSET_FIELD_NOT_LIST]);
-  }
-
-  test_assetFieldNotList_noError() {
-    newFile('/sample/assets/my_icon.png');
-    assertNoErrors('''
-name: sample
-flutter:
-  assets:
-    - assets/my_icon.png
-''');
-  }
-
-  test_assetNotString_error_int() {
-    assertErrors('''
-name: sample
-flutter:
-  assets:
-    - 23
-''', [PubspecWarningCode.ASSET_NOT_STRING]);
-  }
-
-  test_assetNotString_error_map() {
-    assertErrors('''
-name: sample
-flutter:
-  assets:
-    - my_icon:
-      default: assets/my_icon.png
-      large: assets/large/my_icon.png
-''', [PubspecWarningCode.ASSET_NOT_STRING]);
-  }
-
-  test_assetNotString_noError() {
-    newFile('/sample/assets/my_icon.png');
-    assertNoErrors('''
-name: sample
-flutter:
-  assets:
-    - assets/my_icon.png
-''');
-  }
-
-  test_flutterField_empty_noError() {
-    assertNoErrors('''
-name: sample
-flutter:
-''');
-
-    assertNoErrors('''
-name: sample
-flutter:
-
-''');
-  }
-
-  test_flutterFieldNotMap_error_bool() {
-    assertErrors('''
-name: sample
-flutter: true
-''', [PubspecWarningCode.FLUTTER_FIELD_NOT_MAP]);
-  }
-
-  test_flutterFieldNotMap_noError() {
-    newFile('/sample/assets/my_icon.png');
-    assertNoErrors('''
-name: sample
-flutter:
-  assets:
-    - assets/my_icon.png
-''');
-  }
-}
diff --git a/pkg/analyzer/test/src/pubspec/validators/test_all.dart b/pkg/analyzer/test/src/pubspec/validators/test_all.dart
deleted file mode 100644
index cd7a55c..0000000
--- a/pkg/analyzer/test/src/pubspec/validators/test_all.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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.
-
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'pubspec_dependency_validator_test.dart'
-    as pubspec_dependency_validator_test;
-import 'pubspec_flutter_validator_test.dart' as pubspec_flutter_validator_test;
-import 'pubspec_name_validator_test.dart' as pubspec_name_validator_test;
-
-main() {
-  defineReflectiveSuite(() {
-    pubspec_dependency_validator_test.main();
-    pubspec_flutter_validator_test.main();
-    pubspec_name_validator_test.main();
-  }, name: 'validators');
-}
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 2ddaa30..4489693 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -781,7 +781,15 @@
       _writeMetadata(e);
       _writeCodeRange(e);
       _writeTypeParameterElements(e.typeParameters);
-      _writelnWithIndent('aliasedType: ${e.aliasedType}');
+
+      var aliasedType = e.aliasedType;
+      _writeType(aliasedType, name: 'aliasedType');
+      // TODO(scheglov) https://github.com/dart-lang/sdk/issues/44629
+      // TODO(scheglov) Remove it when we stop providing it everywhere.
+      if (aliasedType is FunctionType) {
+        // ignore: deprecated_member_use_from_same_package
+        expect(aliasedType.element, isNull);
+      }
 
       var aliasedElement = e.aliasedElement;
       if (aliasedElement is GenericFunctionTypeElement) {
diff --git a/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart b/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
index f076a8a..a181567 100644
--- a/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
+++ b/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
@@ -9,7 +9,7 @@
 import '../js/js.dart' as js;
 import '../serialization/serialization.dart';
 import '../util/util.dart';
-import '../js_emitter/model.dart' show Fragment;
+import '../js_emitter/model.dart';
 
 import 'namer.dart';
 
@@ -230,7 +230,7 @@
   // Each resource has a distinct name.
   String name;
   List<Fragment> fragments;
-  Map<Entity, List<js.Property>> holderCode;
+  Map<Library, List<js.Property>> holderCode;
   js.Statement _statement;
 
   @override
@@ -507,8 +507,8 @@
   void registerHolders() {
     // Register all holders used in all [DeferredHolderResource]s.
     for (var resource in holderResources) {
-      resource.holderCode.forEach((entity, properties) {
-        String holderName = globalObjectNameForEntity(entity);
+      resource.holderCode.forEach((library, properties) {
+        String holderName = globalObjectNameForEntity(library.element);
         registerHolderUseOrUpdate(resource.name, holderName,
             properties: properties);
       });
@@ -769,7 +769,7 @@
   final List<DeferredHolderResource> holderResources = [];
   final Set<String> _uniqueHolders = {};
   final List<String> _holders = [];
-  final Map<Entity, String> _entityMap = {};
+  final Map<Library, String> _libraryMap = {};
   final JCommonElements _commonElements;
 
   LegacyDeferredHolderExpressionFinalizerImpl(this._commonElements) {
@@ -844,9 +844,9 @@
   /// Registers an [Entity] with a specific [holder].
   void registerHolderUse(String holder, Object data) {
     if (_uniqueHolders.add(holder)) _holders.add(holder);
-    if (data != null && data is Entity) {
-      assert(!_entityMap.containsKey(data) || _entityMap[data] == holder);
-      _entityMap[data] = holder;
+    if (data != null && data is Library) {
+      assert(!_libraryMap.containsKey(data) || _libraryMap[data] == holder);
+      _libraryMap[data] = holder;
     }
   }
 
@@ -890,9 +890,9 @@
 
   /// Registers all of the holders used by a given [DeferredHolderResource].
   void registerHolders(DeferredHolderResource resource) {
-    for (var entity in resource.holderCode.keys) {
-      var holder = globalObjectForEntity(entity);
-      registerHolderUse(holder, entity);
+    for (var library in resource.holderCode.keys) {
+      var holder = globalObjectForLibrary(library.element);
+      registerHolderUse(holder, library);
     }
   }
 
@@ -917,9 +917,9 @@
     }
 
     final holderCode = resource.holderCode;
-    holderCode.forEach((entity, properties) {
-      assert(_entityMap.containsKey(entity));
-      var holder = _entityMap[entity];
+    holderCode.forEach((library, properties) {
+      assert(_libraryMap.containsKey(library));
+      var holder = _libraryMap[library];
       assert(codePerHolder.containsKey(holder));
       codePerHolder[holder].addAll(properties);
     });
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index 78f3727..9f40195 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -824,7 +824,7 @@
 
   /// Adds code to a finalizer.
   void addCodeToFinalizer(void Function(js.Node) addCode, js.Node fragmentCode,
-      Map<Entity, List<js.Property>> holderCode) {
+      Map<Library, List<js.Property>> holderCode) {
     addCode(fragmentCode);
     for (var properties in holderCode.values) {
       for (var property in properties) {
@@ -836,7 +836,7 @@
   /// Finalizes the code for a fragment, and optionally finalizes holders.
   /// Finalizing holders must be the last step of the emitter.
   void finalizeCode(String resourceName, js.Node code,
-      Map<Entity, List<js.Property>> holderCode,
+      Map<Library, List<js.Property>> holderCode,
       {bool finalizeHolders: false}) {
     StringReferenceFinalizer stringFinalizer =
         StringReferenceFinalizerImpl(_options.enableMinification);
@@ -868,23 +868,21 @@
   /// into a map keyed by [Entity] because we don't yet know anything about the
   /// structure of the underlying holders and thus we cannot emit this code
   /// directly into the ast.
-  Map<Entity, List<js.Property>> emitHolderCode(List<Library> libraries) {
-    Map<Entity, List<js.Property>> holderCode = {};
+  Map<Library, List<js.Property>> emitHolderCode(List<Library> libraries) {
+    Map<Library, List<js.Property>> holderCode = {};
     for (Library library in libraries) {
       for (StaticMethod method in library.statics) {
         Map<js.Name, js.Expression> propertyMap = emitStaticMethod(method);
         propertyMap.forEach((js.Name key, js.Expression value) {
           var property = new js.Property(js.quoteName(key), value);
-          Entity holderKey =
-              method is StaticStubMethod ? method.library : method.element;
-          (holderCode[holderKey] ??= []).add(property);
+          (holderCode[library] ??= []).add(property);
           registerEntityAst(method.element, property, library: library.element);
         });
       }
       for (Class cls in library.classes) {
         js.Expression constructor = emitConstructor(cls);
         var property = new js.Property(js.quoteName(cls.name), constructor);
-        (holderCode[cls.element] ??= []).add(property);
+        (holderCode[library] ??= []).add(property);
         registerEntityAst(cls.element, property, library: library.element);
       }
     }
diff --git a/pkg/dartdev/lib/src/commands/compile.dart b/pkg/dartdev/lib/src/commands/compile.dart
index 3b476e4..5027f18 100644
--- a/pkg/dartdev/lib/src/commands/compile.dart
+++ b/pkg/dartdev/lib/src/commands/compile.dart
@@ -5,6 +5,7 @@
 import 'dart:async';
 import 'dart:io';
 
+import 'package:args/args.dart';
 import 'package:dart2native/generate.dart';
 import 'package:front_end/src/api_prototype/compiler_options.dart'
     show Verbosity;
@@ -66,89 +67,28 @@
 class CompileJSCommand extends CompileSubcommandCommand {
   static const String cmdName = 'js';
 
-  CompileJSCommand({bool verbose})
-      : super(cmdName, 'Compile Dart to JavaScript.', verbose) {
-    argParser
-      ..addOption(
-        commonOptions['outputFile'].flag,
-        help: commonOptions['outputFile'].help,
-        abbr: commonOptions['outputFile'].abbr,
-        defaultsTo: commonOptions['outputFile'].defaultsTo,
-      )
-      ..addOption(
-        commonOptions['verbosity'].flag,
-        help: commonOptions['verbosity'].help,
-        abbr: commonOptions['verbosity'].abbr,
-        defaultsTo: commonOptions['verbosity'].defaultsTo,
-        allowed: commonOptions['verbosity'].allowed,
-        allowedHelp: commonOptions['verbosity'].allowedHelp,
-      )
-      ..addFlag(
-        'minified',
-        help: 'Generate minified output.',
-        abbr: 'm',
-        negatable: false,
-      )
-      ..addMultiOption('define', abbr: 'D', valueHelp: 'key=value', help: '''
-Define an environment declaration. To specify multiple declarations, use multiple options or use commas to separate key-value pairs.
-For example: dart compile $cmdName -Da=1,b=2 main.dart''');
+  /// Accept all flags so we can delegate arg parsing to dart2js internally.
+  @override
+  final ArgParser argParser = ArgParser.allowAnything();
 
-    addExperimentalFlags(argParser, verbose);
-  }
+  CompileJSCommand({bool verbose})
+      : super(cmdName, 'Compile Dart to JavaScript.', verbose);
 
   @override
   String get invocation => '${super.invocation} <dart entry point>';
 
   @override
   FutureOr<int> run() async {
-    if (!Sdk.checkArtifactExists(sdk.dart2jsSnapshot)) {
-      return 255;
-    }
-    final String librariesPath = path.absolute(
-      sdk.sdkPath,
-      'lib',
-      'libraries.json',
-    );
+    if (!Sdk.checkArtifactExists(sdk.dart2jsSnapshot)) return 255;
 
-    if (!Sdk.checkArtifactExists(librariesPath)) {
-      return 255;
-    }
+    final librariesPath = path.absolute(sdk.sdkPath, 'lib', 'libraries.json');
 
-    // We expect a single rest argument; the dart entry point.
-    if (argResults.rest.length != 1) {
-      // This throws.
-      usageException('Missing Dart entry point.');
-    }
-
-    final String sourcePath = argResults.rest[0];
-    if (!checkFile(sourcePath)) {
-      return 1;
-    }
-    final args = <String>[
-      '--libraries-spec=$librariesPath',
-      if (argResults.enabledExperiments.isNotEmpty)
-        "--enable-experiment=${argResults.enabledExperiments.join(',')}",
-      if (argResults.wasParsed(commonOptions['outputFile'].flag))
-        "-o${argResults[commonOptions['outputFile'].flag]}",
-      if (argResults.wasParsed('minified')) '-m',
-    ];
-
-    if (argResults.wasParsed('define')) {
-      for (final define in argResults['define']) {
-        args.add('-D$define');
-      }
-    }
-
-    // Add any args that weren't parsed to the end. This will likely only ever
-    // be the script name.
-    args.addAll(argResults.rest);
+    if (!Sdk.checkArtifactExists(librariesPath)) return 255;
 
     VmInteropHandler.run(
         sdk.dart2jsSnapshot,
         [
           '--libraries-spec=$librariesPath',
-          if (argResults.enabledExperiments.isNotEmpty)
-            "--enable-experiment=${argResults.enabledExperiments.join(',')}",
           '--cfe-invocation-modes=compile',
           ...argResults.arguments,
         ],
@@ -357,9 +297,7 @@
   static const String cmdName = 'compile';
   CompileCommand({bool verbose = false})
       : super(cmdName, 'Compile Dart to various formats.', verbose) {
-    addSubcommand(CompileJSCommand(
-      verbose: verbose,
-    ));
+    addSubcommand(CompileJSCommand(verbose: verbose));
     addSubcommand(CompileSnapshotCommand(
       commandName: CompileSnapshotCommand.jitSnapshotCmdName,
       help: 'to a JIT snapshot.',
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index c5e44a7..4675cb9 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -4,7 +4,6 @@
 
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/diagnostic/diagnostic.dart';
-import 'package:analyzer/error/error.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:test/test.dart';
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 0cec1c2..9040385 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -5011,20 +5011,7 @@
   void Trace(Serializer* s, ObjectPtr object) {
     LinkedHashMapPtr map = LinkedHashMap::RawCast(object);
     objects_.Add(map);
-
-    s->Push(map->untag()->type_arguments_);
-
-    intptr_t used_data = Smi::Value(map->untag()->used_data_);
-    ArrayPtr data_array = map->untag()->data_;
-    ObjectPtr* data_elements = data_array->untag()->data();
-    for (intptr_t i = 0; i < used_data; i += 2) {
-      ObjectPtr key = data_elements[i];
-      if (key != data_array) {
-        ObjectPtr value = data_elements[i + 1];
-        s->Push(key);
-        s->Push(value);
-      }
-    }
+    PushFromTo(map);
   }
 
   void WriteAlloc(Serializer* s) {
@@ -5041,26 +5028,7 @@
     for (intptr_t i = 0; i < count; i++) {
       LinkedHashMapPtr map = objects_[i];
       AutoTraceObject(map);
-
-      WriteField(map, type_arguments_);
-
-      const intptr_t used_data = Smi::Value(map->untag()->used_data_);
-      ASSERT((used_data & 1) == 0);  // Keys + values, so must be even.
-      const intptr_t deleted_keys = Smi::Value(map->untag()->deleted_keys_);
-
-      // Write out the number of (not deleted) key/value pairs that will follow.
-      s->Write<int32_t>((used_data >> 1) - deleted_keys);
-
-      ArrayPtr data_array = map->untag()->data_;
-      ObjectPtr* data_elements = data_array->untag()->data();
-      for (intptr_t i = 0; i < used_data; i += 2) {
-        ObjectPtr key = data_elements[i];
-        if (key != data_array) {
-          ObjectPtr value = data_elements[i + 1];
-          s->WriteElementRef(key, i);
-          s->WriteElementRef(value, i + 1);
-        }
-      }
+      WriteFromTo(map);
     }
   }
 
@@ -5081,41 +5049,12 @@
   }
 
   void ReadFill(Deserializer* d, bool primary) {
-    PageSpace* old_space = d->heap()->old_space();
-
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       LinkedHashMapPtr map = static_cast<LinkedHashMapPtr>(d->Ref(id));
       Deserializer::InitializeHeader(map, kLinkedHashMapCid,
                                      LinkedHashMap::InstanceSize(),
                                      primary && is_canonical());
-
-      map->untag()->type_arguments_ =
-          static_cast<TypeArgumentsPtr>(d->ReadRef());
-
-      // TODO(rmacnak): Reserve ref ids and co-allocate in ReadAlloc.
-      intptr_t pairs = d->Read<int32_t>();
-      intptr_t used_data = pairs << 1;
-      intptr_t data_size = Utils::Maximum(
-          Utils::RoundUpToPowerOfTwo(used_data),
-          static_cast<uintptr_t>(LinkedHashMap::kInitialIndexSize));
-
-      ArrayPtr data = static_cast<ArrayPtr>(
-          old_space->AllocateSnapshot(Array::InstanceSize(data_size)));
-      data->untag()->type_arguments_ = TypeArguments::null();
-      data->untag()->length_ = Smi::New(data_size);
-      intptr_t i;
-      for (i = 0; i < used_data; i++) {
-        data->untag()->data()[i] = d->ReadRef();
-      }
-      for (; i < data_size; i++) {
-        data->untag()->data()[i] = Object::null();
-      }
-
-      map->untag()->index_ = TypedData::null();
-      map->untag()->hash_mask_ = Smi::New(0);
-      map->untag()->data_ = data;
-      map->untag()->used_data_ = Smi::New(used_data);
-      map->untag()->deleted_keys_ = Smi::New(0);
+      ReadFromTo(map);
     }
   }
 };
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 7c75e83..19e2383 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -3097,6 +3097,7 @@
   POINTER_FIELD(SmiPtr, used_data)
   POINTER_FIELD(SmiPtr, deleted_keys)
   VISIT_TO(deleted_keys)
+  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   friend class SnapshotReader;
 };
diff --git a/tools/VERSION b/tools/VERSION
index 45803c1d..b336d1d 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 231
+PRERELEASE 232
 PRERELEASE_PATCH 0
\ No newline at end of file