Version 2.15.0-75.0.dev

Merge commit '00f20a07323664dfeb9f3e109f2f63883c1be3ac' into 'dev'
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 38529f2..97e8276 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -615,6 +615,10 @@
   /// Base path where to cache data.
   String? cacheFolder;
 
+  /// The path to the package config file override.
+  /// If `null`, then the default discovery mechanism is used.
+  String? packagesFile;
+
   /// The analytics instance; note, this object can be `null`, and should be
   /// accessed via a null-aware operator.
   telemetry.Analytics? analytics;
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index 538236d..5bd16c2 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -221,6 +221,7 @@
     contextManager = ContextManagerImpl(
       resourceProvider,
       sdkManager,
+      options.packagesFile,
       byteStore,
       fileContentCache,
       analysisPerformanceLogger,
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index fa2fae2..10acd68 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -142,6 +142,10 @@
   /// particular context.
   final DartSdkManager sdkManager;
 
+  /// The path to the package config file override.
+  /// If `null`, then the default discovery mechanism is used.
+  final String? packagesFile;
+
   /// The storage for cached results.
   final ByteStore _byteStore;
 
@@ -213,6 +217,7 @@
   ContextManagerImpl(
       this.resourceProvider,
       this.sdkManager,
+      this.packagesFile,
       this._byteStore,
       this._fileContentCache,
       this._performanceLog,
@@ -428,6 +433,7 @@
       resourceProvider: resourceProvider,
       scheduler: _scheduler,
       sdkPath: sdkManager.defaultSdkDirectory,
+      packagesFile: packagesFile,
       fileContentCache: _fileContentCache,
     );
 
diff --git a/pkg/analysis_server/lib/src/lsp/client_capabilities.dart b/pkg/analysis_server/lib/src/lsp/client_capabilities.dart
index 9a0b40a..bac248e 100644
--- a/pkg/analysis_server/lib/src/lsp/client_capabilities.dart
+++ b/pkg/analysis_server/lib/src/lsp/client_capabilities.dart
@@ -59,6 +59,7 @@
   final bool documentChanges;
   final bool configuration;
   final bool createResourceOperations;
+  final bool renameResourceOperations;
   final bool completionDeprecatedFlag;
   final bool applyEdit;
   final bool workDoneProgress;
@@ -102,6 +103,10 @@
                 .workspace?.workspaceEdit?.resourceOperations
                 ?.contains(ResourceOperationKind.Create) ??
             false,
+        renameResourceOperations = raw
+                .workspace?.workspaceEdit?.resourceOperations
+                ?.contains(ResourceOperationKind.Rename) ??
+            false,
         definitionLocationLink =
             raw.textDocument?.definition?.linkSupport ?? false,
         completionItemTags = _listToSet(
diff --git a/pkg/analysis_server/lib/src/lsp/client_configuration.dart b/pkg/analysis_server/lib/src/lsp/client_configuration.dart
index d5786cc..83b987b 100644
--- a/pkg/analysis_server/lib/src/lsp/client_configuration.dart
+++ b/pkg/analysis_server/lib/src/lsp/client_configuration.dart
@@ -170,4 +170,12 @@
   /// If null, the formatters default will be used.
   int? get lineLength =>
       _settings['lineLength'] as int? ?? _fallback?.lineLength;
+
+  /// Whether to rename files when renaming classes inside them where the file
+  /// and class name match.
+  ///
+  /// Values are "always", "prompt", "never". Any other values should be treated
+  /// like "never".
+  String get renameFilesWithClasses =>
+      _settings['renameFilesWithClasses'] as String? ?? 'never';
 }
diff --git a/pkg/analysis_server/lib/src/lsp/constants.dart b/pkg/analysis_server/lib/src/lsp/constants.dart
index 9f46f71..ca213ec 100644
--- a/pkg/analysis_server/lib/src/lsp/constants.dart
+++ b/pkg/analysis_server/lib/src/lsp/constants.dart
@@ -218,6 +218,8 @@
 
 /// Strings used in user prompts (window/showMessageRequest).
 abstract class UserPromptActions {
+  static const String yes = 'Yes';
+  static const String no = 'No';
   static const String cancel = 'Cancel';
   static const String renameAnyway = 'Rename Anyway';
 }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
index 6773974..9a92867 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
@@ -4,11 +4,14 @@
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/client_configuration.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
+import 'package:analysis_server/src/services/refactoring/rename_unit_member.dart';
+import 'package:analyzer/dart/element/element.dart';
 
 class PrepareRenameHandler
     extends MessageHandler<TextDocumentPositionParams, RangeAndPlaceholder?> {
@@ -75,14 +78,25 @@
 }
 
 class RenameHandler extends MessageHandler<RenameParams, WorkspaceEdit?> {
+  final _upperCasePattern = RegExp('[A-Z]');
+
   RenameHandler(LspAnalysisServer server) : super(server);
 
+  LspGlobalClientConfiguration get config => server.clientConfiguration.global;
+
   @override
   Method get handlesMessage => Method.textDocument_rename;
 
   @override
   LspJsonHandler<RenameParams> get jsonHandler => RenameParams.jsonHandler;
 
+  /// Checks whether a client supports Rename resource operations.
+  bool get _clientSupportsRename {
+    final capabilities = server.clientCapabilities;
+    return (capabilities?.documentChanges ?? false) &&
+        (capabilities?.renameResourceOperations ?? false);
+  }
+
   @override
   Future<ErrorOr<WorkspaceEdit?>> handle(
       RenameParams params, CancellationToken token) async {
@@ -128,12 +142,6 @@
         return success(null);
       }
 
-      // TODO(dantup): Consider using window/showMessageRequest to prompt
-      // the user to see if they'd like to proceed with a rename if there
-      // are non-fatal errors or warnings. For now we will reject all errors
-      // (fatal and not) as this seems like the most logical behaviour when
-      // without a prompt.
-
       // Check the rename is valid here.
       final initStatus = await refactoring.checkInitialConditions();
       if (token.isCancellationRequested) {
@@ -195,8 +203,72 @@
         return fileModifiedError;
       }
 
-      final workspaceEdit = createWorkspaceEdit(server, change);
+      var workspaceEdit = createWorkspaceEdit(server, change);
+
+      // Check whether we should handle renaming the file to match the class.
+      if (_clientSupportsRename && _isClassRename(refactoring)) {
+        final pathContext = server.resourceProvider.pathContext;
+        // The rename must always be performed on the file that defines the
+        // class which is not necessarily the one where the rename was invoked.
+        final declaringFile = (refactoring as RenameUnitMemberRefactoringImpl)
+            .element
+            .declaration
+            ?.source
+            ?.fullName;
+        if (declaringFile != null) {
+          final folder = pathContext.dirname(declaringFile);
+          final actualFilename = pathContext.basename(declaringFile);
+          final oldComputedFilename =
+              _fileNameForClassName(refactoring.oldName);
+          final newFilename = _fileNameForClassName(params.newName);
+
+          // Only if the existing filename matches exactly what we'd expect for
+          // the original class name will we consider renaming.
+          if (actualFilename == oldComputedFilename) {
+            final renameConfig = config.renameFilesWithClasses;
+            final shouldRename = renameConfig == 'always' ||
+                (renameConfig == 'prompt' &&
+                    await _promptToRenameFile(actualFilename, newFilename));
+            if (shouldRename) {
+              final newPath = pathContext.join(folder, newFilename);
+              final renameEdit = createRenameEdit(declaringFile, newPath);
+              workspaceEdit = mergeWorkspaceEdits([workspaceEdit, renameEdit]);
+            }
+          }
+        }
+      }
+
       return success(workspaceEdit);
     });
   }
+
+  /// Computes a filename for a given class name (convert from PascalCase to
+  /// snake_case).
+  String _fileNameForClassName(String className) {
+    final fileName = className
+        .replaceAllMapped(_upperCasePattern,
+            (match) => match.start == 0 ? match[0]! : '_${match[0]}')
+        .toLowerCase();
+    return '$fileName.dart';
+  }
+
+  bool _isClassRename(RenameRefactoring refactoring) =>
+      refactoring is RenameUnitMemberRefactoringImpl &&
+      refactoring.element is ClassElement;
+
+  /// Asks the user whether they would like to rename the file along with the
+  /// class.
+  Future<bool> _promptToRenameFile(
+      String oldFilename, String newFilename) async {
+    final userChoice = await server.showUserPrompt(
+      MessageType.Info,
+      "Rename '$oldFilename' to '$newFilename'?",
+      [
+        MessageActionItem(title: UserPromptActions.yes),
+        MessageActionItem(title: UserPromptActions.no),
+      ],
+    );
+
+    return userChoice.title == UserPromptActions.yes;
+  }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index 795b45e..3a3e421 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -132,6 +132,30 @@
           .toList());
 }
 
+/// Create a [WorkspaceEdit] that renames [oldPath] to [newPath].
+WorkspaceEdit createRenameEdit(String oldPath, String newPath) {
+  final changes =
+      <Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>[];
+
+  final rename = RenameFile(
+    oldUri: Uri.file(oldPath).toString(),
+    newUri: Uri.file(newPath).toString(),
+  );
+
+  final renameUnion =
+      Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t3(rename);
+
+  changes.add(renameUnion);
+
+  final edit = WorkspaceEdit(
+      documentChanges: Either2<
+          List<TextDocumentEdit>,
+          List<
+              Either4<TextDocumentEdit, CreateFile, RenameFile,
+                  DeleteFile>>>.t2(changes));
+  return edit;
+}
+
 /// Creates a [lsp.WorkspaceEdit] from a [server.SourceChange] that can include
 /// experimental [server.SnippetTextEdit]s if the client has indicated support
 /// for these in the experimental section of their client capabilities.
@@ -655,6 +679,33 @@
 bool isDartDocument(lsp.TextDocumentIdentifier? doc) =>
     doc?.uri.endsWith('.dart') ?? false;
 
+/// Merges two [WorkspaceEdit]s into a single one.
+///
+/// Will throw if given [WorkspaceEdit]s that do not use documentChanges.
+WorkspaceEdit mergeWorkspaceEdits(List<WorkspaceEdit> edits) {
+  // TODO(dantup): This method (and much other code here) should be
+  // significantly tidied up when nonfunction-type-aliases is available here.
+  final changes =
+      <Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>[];
+
+  for (final edit in edits) {
+    // Flatten the Either into just the Union side to get a flat list.
+    final flatResourceChanges = edit.documentChanges!.map(
+      (edits) => edits.map((e) =>
+          Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t1(e)),
+      (resources) => resources,
+    );
+    changes.addAll(flatResourceChanges);
+  }
+
+  return WorkspaceEdit(
+      documentChanges: Either2<
+          List<TextDocumentEdit>,
+          List<
+              Either4<TextDocumentEdit, CreateFile, RenameFile,
+                  DeleteFile>>>.t2(changes));
+}
+
 lsp.Location navigationTargetToLocation(
   String targetFilePath,
   server.NavigationTarget target,
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 2fb7918..025eb5b 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -98,6 +98,9 @@
   /// The path to the data cache.
   static const String CACHE_FOLDER = 'cache';
 
+  /// The path to the package config file override.
+  static const String PACKAGES_FILE = 'packages';
+
   /// The name of the flag specifying the server protocol to use.
   static const String SERVER_PROTOCOL = 'protocol';
   static const String PROTOCOL_ANALYZER = 'analyzer';
@@ -156,6 +159,7 @@
 
     analysisServerOptions.clientVersion = results[CLIENT_VERSION];
     analysisServerOptions.cacheFolder = results[CACHE_FOLDER];
+    analysisServerOptions.packagesFile = results[PACKAGES_FILE];
 
     // Read in any per-SDK overrides specified in <sdk>/config/settings.json.
     var sdkConfig = SdkConfiguration.readFromSdk();
@@ -602,6 +606,12 @@
     parser.addOption(CACHE_FOLDER,
         valueHelp: 'path',
         help: 'Override the location of the analysis server\'s cache.');
+    parser.addOption(
+      PACKAGES_FILE,
+      valueHelp: 'path',
+      help: 'The path to the package resolution configuration file, which '
+          'supplies a mapping of package names\ninto paths.',
+    );
 
     parser.addOption(
       SERVER_PROTOCOL,
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index 3e9ead3..4da1f25 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -213,8 +213,9 @@
     // closure cannot have parameters
     if (_selectionFunctionExpression != null && _parameters.isNotEmpty) {
       var message = format(
-          'Cannot extract closure as method, it references {0} external variable(s).',
-          _parameters.length);
+          'Cannot extract closure as method, it references {0} external variable{1}.',
+          _parameters.length,
+          _parameters.length == 1 ? '' : 's');
       return RefactoringStatus.fatal(message);
     }
     return result;
diff --git a/pkg/analysis_server/test/integration/server/command_line_options_test.dart b/pkg/analysis_server/test/integration/server/command_line_options_test.dart
new file mode 100644
index 0000000..0b085ea
--- /dev/null
+++ b/pkg/analysis_server/test/integration/server/command_line_options_test.dart
@@ -0,0 +1,66 @@
+// 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 'dart:async';
+
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../support/integration_tests.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(OptionsPackagesIntegrationTest);
+  });
+}
+
+@reflectiveTest
+class OptionsPackagesIntegrationTest
+    extends AbstractAnalysisServerIntegrationTest {
+  @override
+  Future startServer({int? diagnosticPort, int? servicesPort}) {
+    var fooPath = sourcePath('foo');
+    writeFile(
+      path.join(fooPath, 'lib', 'foo.dart'),
+      'var my_foo = 0;',
+    );
+
+    var packagesPath = sourcePath('my_packages.json');
+    writeFile(packagesPath, '''
+{
+  "configVersion": 2,
+  "packages": [
+    {
+      "name": "foo",
+      "rootUri": "${path.toUri(fooPath)}",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    }
+  ]
+}
+''');
+
+    return server.start(
+      diagnosticPort: diagnosticPort,
+      servicesPort: servicesPort,
+      packagesFile: packagesPath,
+    );
+  }
+
+  Future<void> test_it() {
+    var pathname = sourcePath('test.dart');
+    writeFile(pathname, '''
+import 'package:foo/foo.dart';
+void main() {
+  my_foo;
+}
+''');
+    standardAnalysisSetup();
+    return analysisFinished.then((_) {
+      var errors = existingErrorsForFile(pathname);
+      expect(errors, isEmpty);
+    });
+  }
+}
diff --git a/pkg/analysis_server/test/integration/server/test_all.dart b/pkg/analysis_server/test/integration/server/test_all.dart
index 92ae2b1..1239990 100644
--- a/pkg/analysis_server/test/integration/server/test_all.dart
+++ b/pkg/analysis_server/test/integration/server/test_all.dart
@@ -5,6 +5,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'bazel_changes_test.dart' as bazel_changes_test;
+import 'command_line_options_test.dart' as command_line_options_test;
 import 'get_version_test.dart' as get_version_test;
 import 'set_subscriptions_invalid_service_test.dart'
     as set_subscriptions_invalid_service_test;
@@ -15,6 +16,7 @@
 void main() {
   defineReflectiveSuite(() {
     bazel_changes_test.main();
+    command_line_options_test.main();
     get_version_test.main();
     set_subscriptions_test.main();
     set_subscriptions_invalid_service_test.main();
diff --git a/pkg/analysis_server/test/integration/support/integration_tests.dart b/pkg/analysis_server/test/integration/support/integration_tests.dart
index dd30a55..6ca048e 100644
--- a/pkg/analysis_server/test/integration/support/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/support/integration_tests.dart
@@ -236,7 +236,9 @@
     int? servicesPort,
   }) {
     return server.start(
-        diagnosticPort: diagnosticPort, servicesPort: servicesPort);
+      diagnosticPort: diagnosticPort,
+      servicesPort: servicesPort,
+    );
   }
 
   /// After every test, the server is stopped and [sourceDirectory] is deleted.
@@ -606,6 +608,7 @@
   Future start({
     int? diagnosticPort,
     String? instrumentationLogFile,
+    String? packagesFile,
     bool profileServer = false,
     String? sdkPath,
     int? servicesPort,
@@ -676,6 +679,9 @@
     if (instrumentationLogFile != null) {
       arguments.add('--instrumentation-log-file=$instrumentationLogFile');
     }
+    if (packagesFile != null) {
+      arguments.add('--packages=$packagesFile');
+    }
     if (sdkPath != null) {
       arguments.add('--sdk=$sdkPath');
     }
diff --git a/pkg/analysis_server/test/lsp/rename_test.dart b/pkg/analysis_server/test/lsp/rename_test.dart
index 27be436..f62944d 100644
--- a/pkg/analysis_server/test/lsp/rename_test.dart
+++ b/pkg/analysis_server/test/lsp/rename_test.dart
@@ -118,7 +118,162 @@
         content, 'MyNewClass', expectedContent);
   }
 
-  Future<void> test_rename_classNewKeyword() async {
+  Future<void> test_rename_class_doesNotRenameFileIfDisabled() async {
+    const content = '''
+    class Main {}
+    final a = new [[Ma^in]]();
+    ''';
+    const expectedContent = '''
+    class MyNewMain {}
+    final a = new MyNewMain();
+    ''';
+    final contents = await _test_rename_withDocumentChanges(
+        content, 'MyNewMain', expectedContent);
+    // Ensure the only file is still called main.dart.
+    expect(contents.keys.single, equals(mainFilePath));
+  }
+
+  Future<void> test_rename_class_doesRenameFileAfterPrompt() async {
+    const content = '''
+    class Main {}
+    final a = new [[Ma^in]]();
+    ''';
+    const expectedContent = '''
+    class MyNewMain {}
+    final a = new MyNewMain();
+    ''';
+    final newMainFilePath = join(projectFolderPath, 'lib', 'my_new_main.dart');
+
+    /// Helper that performs the rename and tests the results. Passed below to
+    /// provideConfig() so we can wrap this with handlers to provide the
+    /// required config.
+    Future<void> testRename() async {
+      final contents = await _test_rename_withDocumentChanges(
+        content,
+        'MyNewMain',
+        expectedContent,
+        expectedFilePath: newMainFilePath,
+        workspaceCapabilities: withConfigurationSupport(
+            withResourceOperationKinds(emptyWorkspaceClientCapabilities,
+                [ResourceOperationKind.Rename])),
+      );
+      // Ensure we now only have the newly-renamed file and not the old one
+      // (its contents will have been checked by the function above).
+      expect(contents.keys.single, equals(newMainFilePath));
+    }
+
+    /// Helper that will respond to the window/showMessageRequest request from
+    /// the server when prompted about renaming the file.
+    Future<MessageActionItem> promptHandler(
+        ShowMessageRequestParams params) async {
+      // Ensure the prompt is as expected.
+      expect(params.type, equals(MessageType.Info));
+      expect(
+          params.message, equals("Rename 'main.dart' to 'my_new_main.dart'?"));
+      expect(params.actions, hasLength(2));
+      expect(params.actions![0],
+          equals(MessageActionItem(title: UserPromptActions.yes)));
+      expect(params.actions![1],
+          equals(MessageActionItem(title: UserPromptActions.no)));
+
+      // Respond to the request with the required action.
+      return params.actions!.first;
+    }
+
+    // Run the test and provide the config + prompt handling function.
+    return handleExpectedRequest(
+      Method.window_showMessageRequest,
+      ShowMessageRequestParams.fromJson,
+      () => provideConfig(
+        testRename,
+        {'renameFilesWithClasses': 'prompt'},
+      ),
+      handler: promptHandler,
+    );
+  }
+
+  Future<void> test_rename_class_doesRenameFileIfAlwaysEnabled() async {
+    const content = '''
+    class Main {}
+    final a = new [[Ma^in]]();
+    ''';
+    const expectedContent = '''
+    class MyNewMain {}
+    final a = new MyNewMain();
+    ''';
+    final newMainFilePath = join(projectFolderPath, 'lib', 'my_new_main.dart');
+    await provideConfig(
+      () async {
+        final contents = await _test_rename_withDocumentChanges(
+          content,
+          'MyNewMain',
+          expectedContent,
+          expectedFilePath: newMainFilePath,
+          workspaceCapabilities: withConfigurationSupport(
+              withResourceOperationKinds(emptyWorkspaceClientCapabilities,
+                  [ResourceOperationKind.Rename])),
+        );
+        // Ensure we now only have the newly-renamed file and not the old one
+        // (its contents will have been checked by the function above).
+        expect(contents.keys.single, equals(newMainFilePath));
+      },
+      {'renameFilesWithClasses': 'always'},
+    );
+  }
+
+  Future<void> test_rename_class_doesRenameFileIfRenamedFromAnother() async {
+    const mainContent = '''
+    class Main {}
+    ''';
+    const otherContent = '''
+    import 'main.dart';
+
+    final a = Ma^in();
+    ''';
+    const expectedContent = '''
+    class MyNewMain {}
+    ''';
+    // Since we don't actually perform the file rename (we only include an
+    // instruction for the client to do so), the import will not be updated
+    // by us. Instead, the client will send the rename event back to the server
+    // and it would be handled normally as if the user had done it locally.
+    const expectedOtherContent = '''
+    import 'main.dart';
+
+    final a = MyNewMain();
+    ''';
+    final otherFilePath = join(projectFolderPath, 'lib', 'other.dart');
+    final newMainFilePath = join(projectFolderPath, 'lib', 'my_new_main.dart');
+    newFile(mainFilePath, content: withoutMarkers(mainContent));
+    await pumpEventQueue(times: 5000);
+    await provideConfig(
+      () async {
+        final contents = await _test_rename_withDocumentChanges(
+          otherContent,
+          'MyNewMain',
+          expectedOtherContent,
+          filePath: otherFilePath,
+          contents: {
+            otherFilePath: otherContent,
+            mainFilePath: mainContent,
+          },
+          workspaceCapabilities: withConfigurationSupport(
+              withResourceOperationKinds(emptyWorkspaceClientCapabilities,
+                  [ResourceOperationKind.Rename])),
+        );
+        // Expect that main was renamed to my_new_main and the other file was
+        // updated.
+        expect(contents.containsKey(mainFilePath), isFalse);
+        expect(contents.containsKey(newMainFilePath), isTrue);
+        expect(contents.containsKey(otherFilePath), isTrue);
+        expect(contents[newMainFilePath], expectedContent);
+        expect(contents[otherFilePath], expectedOtherContent);
+      },
+      {'renameFilesWithClasses': 'always'},
+    );
+  }
+
+  Future<void> test_rename_classNewKeyword() {
     const content = '''
     class MyClass {}
     final a = n^ew MyClass();
@@ -308,6 +463,30 @@
     expect(contents[referencedFilePath], equals(expectedReferencedContent));
   }
 
+  Future<void> test_rename_nonClass_doesNotRenameFile() async {
+    const content = '''
+    final Ma^in = 'test';
+    ''';
+    const expectedContent = '''
+    final MyNewMain = 'test';
+    ''';
+    await provideConfig(
+      () async {
+        final contents = await _test_rename_withDocumentChanges(
+          content,
+          'MyNewMain',
+          expectedContent,
+          workspaceCapabilities: withConfigurationSupport(
+              withResourceOperationKinds(emptyWorkspaceClientCapabilities,
+                  [ResourceOperationKind.Rename])),
+        );
+        // Ensure the only file is still called main.dart.
+        expect(contents.keys.single, equals(mainFilePath));
+      },
+      {'renameFilesWithClasses': 'always'},
+    );
+  }
+
   Future<void> test_rename_rejectedForBadName() async {
     const content = '''
     class MyClass {}
@@ -533,44 +712,56 @@
     );
   }
 
-  Future<void> _test_rename_withDocumentChanges(
+  Future<Map<String, String>> _test_rename_withDocumentChanges(
     String content,
     String newName,
     String? expectedContent, {
-    sendRenameVersion = true,
+    String? filePath,
+    String? expectedFilePath,
+    bool sendRenameVersion = true,
+    ClientCapabilitiesWorkspace? workspaceCapabilities,
+    Map<String, String>? contents,
   }) async {
+    contents ??= {};
+    filePath ??= mainFilePath;
+    expectedFilePath ??= filePath;
+    final fileUri = Uri.file(filePath);
+
     // The specific number doesn't matter here, it's just a placeholder to confirm
     // the values match.
     final documentVersion = 222;
+    contents[filePath] = withoutMarkers(content);
+    final documentVersions = {
+      filePath: documentVersion,
+    };
+
+    final initialAnalysis = waitForAnalysisComplete();
     await initialize(
-      workspaceCapabilities:
-          withDocumentChangesSupport(emptyWorkspaceClientCapabilities),
+      workspaceCapabilities: withDocumentChangesSupport(
+          workspaceCapabilities ?? emptyWorkspaceClientCapabilities),
     );
-    await openFile(mainFileUri, withoutMarkers(content),
-        version: documentVersion);
+    await openFile(fileUri, withoutMarkers(content), version: documentVersion);
+    await initialAnalysis;
 
     final result = await rename(
-      mainFileUri,
+      fileUri,
       sendRenameVersion ? documentVersion : null,
       positionFromMarker(content),
       newName,
     );
+
     if (expectedContent == null) {
       expect(result, isNull);
     } else {
       // Ensure applying the changes will give us the expected content.
-      final contents = {
-        mainFilePath: withoutMarkers(content),
-      };
-      final documentVersions = {
-        mainFilePath: documentVersion,
-      };
       applyDocumentChanges(
         contents,
         result!.documentChanges!,
         expectedVersions: documentVersions,
       );
-      expect(contents[mainFilePath], equals(expectedContent));
+      expect(contents[expectedFilePath], equals(expectedContent));
     }
+
+    return contents;
   }
 }
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index 2e49ae5..45b8b3f 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -679,7 +679,7 @@
       change.map(
         (textDocEdit) => applyTextDocumentEdits(oldFileContent, [textDocEdit]),
         (create) => applyResourceCreate(oldFileContent, create),
-        (rename) => throw 'applyResourceChanges:Delete not currently supported',
+        (rename) => applyResourceRename(oldFileContent, rename),
         (delete) => throw 'applyResourceChanges:Delete not currently supported',
       );
     }
@@ -694,6 +694,17 @@
     oldFileContent[path] = '';
   }
 
+  void applyResourceRename(
+      Map<String, String> oldFileContent, RenameFile rename) {
+    final oldPath = Uri.parse(rename.oldUri).toFilePath();
+    final newPath = Uri.parse(rename.newUri).toFilePath();
+    if (!oldFileContent.containsKey(oldPath)) {
+      throw 'Recieved rename instruction for $oldPath which did not exist.';
+    }
+    oldFileContent[newPath] = oldFileContent[oldPath]!;
+    oldFileContent.remove(oldPath);
+  }
+
   String applyTextDocumentEdit(String content, TextDocumentEdit edit) {
     return edit.edits.fold(content, applyTextEdit);
   }
@@ -1474,12 +1485,12 @@
 
   /// Calls the supplied function and responds to any `workspace/configuration`
   /// request with the supplied config.
-  Future<ResponseMessage> provideConfig(
-    Future<ResponseMessage> Function() f,
+  Future<T> provideConfig<T>(
+    Future<T> Function() f,
     FutureOr<Map<String, Object?>> globalConfig, {
     FutureOr<Map<String, Map<String, Object?>>>? folderConfig,
   }) {
-    return handleExpectedRequest<ResponseMessage, ConfigurationParams,
+    return handleExpectedRequest<T, ConfigurationParams,
         List<Map<String, Object?>>>(
       Method.workspace_configuration,
       ConfigurationParams.fromJson,
diff --git a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
index 66861c0..6e99c97 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
@@ -948,7 +948,7 @@
     var status = await refactoring.checkInitialConditions();
     assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL,
         expectedMessage:
-            'Cannot extract closure as method, it references 1 external variable(s).');
+            'Cannot extract closure as method, it references 1 external variable.');
   }
 
   Future<void> test_closure_bad_referencesParameter() async {
@@ -963,7 +963,7 @@
     var status = await refactoring.checkInitialConditions();
     assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL,
         expectedMessage:
-            'Cannot extract closure as method, it references 1 external variable(s).');
+            'Cannot extract closure as method, it references 1 external variable.');
   }
 
   Future<void> test_fromTopLevelVariableInitializerClosure() async {
diff --git a/pkg/analysis_server/tool/lsp_spec/README.md b/pkg/analysis_server/tool/lsp_spec/README.md
index bac9b69..cc61b66 100644
--- a/pkg/analysis_server/tool/lsp_spec/README.md
+++ b/pkg/analysis_server/tool/lsp_spec/README.md
@@ -38,6 +38,7 @@
 - `dart.lineLength`: The number of characters the formatter should wrap code at. If unspecified, code will be wrapped at `80` characters.
 - `dart.completeFunctionCalls`: Completes functions/methods with their required parameters.
 - `dart.showTodos`: Whether to generate diagnostics for TODO comments. If unspecified, diagnostics will not be generated.
+- `dart.renameFilesWithClasses`: When set to `"always"`, will rename files when classes are renamed if the filename matches the class name (but in snake_form). When set to `"prompt"`, a prompt will be shown on each class rename asking to confirm the file rename. Otherwise, files will not be renamed. Renames are performed using LSP's ResourceOperation edits - that means the rename is simply included in the resulting `WorkspaceEdit` and must be handled by the client.
 
 ## Method Status
 
diff --git a/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart b/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
index d1e6db7..62c8072 100644
--- a/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
+++ b/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
@@ -351,7 +351,8 @@
       if (node is TypeName) {
         var element = node.name.staticElement;
         if (element is TypeParameterElement) {
-          return true;
+          var enclosing = element.enclosingElement;
+          return enclosing is ClassElement && !enclosing.isMixin;
         }
       }
     }
diff --git a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
index 8328c57..e3aaab4 100644
--- a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
@@ -12,7 +12,6 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(IsConstantTypeExpressionTest);
-    defineReflectiveTests(IsPotentiallyConstantTypeExpressionTest);
     defineReflectiveTests(PotentiallyConstantTest);
     defineReflectiveTests(PotentiallyConstantWithoutNullSafetyTest);
   });
@@ -104,16 +103,58 @@
 ''');
   }
 
-  test_typeParameter() async {
+  test_typeParameter_ofClass() async {
     await _assertPotentiallyConst(r'''
 class A<T> {
-  m() {
+  T x;
+}
+''');
+  }
+
+  test_typeParameter_ofClass_nested() async {
+    await _assertPotentiallyConst(r'''
+class A<T> {
+  List<T> x;
+}
+''');
+  }
+
+  test_typeParameter_ofExtension() async {
+    await _assertNeverConst(r'''
+extension E<T> on int {
+  void foo() {
     T x;
   }
 }
 ''');
   }
 
+  test_typeParameter_ofFunction() async {
+    await _assertNeverConst(r'''
+void foo<T>() {
+  T x;
+}
+''');
+  }
+
+  test_typeParameter_ofMethod() async {
+    await _assertNeverConst(r'''
+class A {
+  void foo<T>() {
+    T x;
+  }
+}
+''');
+  }
+
+  test_typeParameter_ofMixin() async {
+    await _assertNeverConst(r'''
+mixin M<T> {
+  T x;
+}
+''');
+  }
+
   test_void() async {
     await _assertConst(r'''
 void x;
@@ -123,62 +164,26 @@
   Future<void> _assertConst(String code) async {
     await resolveTestCode(code);
     var type = findNode.variableDeclarationList('x;').type!;
+    expect(isPotentiallyConstantTypeExpression(type), isTrue);
     expect(isConstantTypeExpression(type), isTrue);
   }
 
   Future<void> _assertNeverConst(String code) async {
     await resolveTestCode(code);
     var type = findNode.variableDeclarationList('x;').type!;
+    expect(isPotentiallyConstantTypeExpression(type), isFalse);
     expect(isConstantTypeExpression(type), isFalse);
   }
 
   Future<void> _assertPotentiallyConst(String code) async {
     await resolveTestCode(code);
     var type = findNode.variableDeclarationList('x;').type!;
+    expect(isPotentiallyConstantTypeExpression(type), isTrue);
     expect(isConstantTypeExpression(type), isFalse);
   }
 }
 
 @reflectiveTest
-class IsPotentiallyConstantTypeExpressionTest
-    extends IsConstantTypeExpressionTest {
-  @override
-  test_typeParameter() async {
-    await _assertConst(r'''
-class A<T> {
-  m() {
-    T x;
-  }
-}
-''');
-  }
-
-  test_typeParameter_nested() async {
-    await _assertConst(r'''
-class A<T> {
-  m() {
-    List<T> x;
-  }
-}
-''');
-  }
-
-  @override
-  Future<void> _assertConst(String code) async {
-    await resolveTestCode(code);
-    var type = findNode.variableDeclarationList('x;').type!;
-    expect(isPotentiallyConstantTypeExpression(type), isTrue);
-  }
-
-  @override
-  Future<void> _assertPotentiallyConst(String code) async {
-    await resolveTestCode(code);
-    var type = findNode.variableDeclarationList('x;').type!;
-    expect(isPotentiallyConstantTypeExpression(type), isTrue);
-  }
-}
-
-@reflectiveTest
 class PotentiallyConstantTest extends PubPackageResolutionTest {
   test_adjacentStrings() async {
     await _assertConst(r'''
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index 7ec27d6..fa01214 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -397,7 +397,7 @@
         hide: hide);
     parser.addOption(_packagesOption,
         help: 'The path to the package resolution configuration file, which '
-            'supplies a mapping of package names\nto paths.',
+            'supplies a mapping of package names\ninto paths.',
         hide: ddc);
     parser.addFlag(_enableInitializingFormalAccessFlag,
         help:
diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
index 57b488b..3a7a7f3 100644
--- a/pkg/compiler/lib/src/common/codegen.dart
+++ b/pkg/compiler/lib/src/common/codegen.dart
@@ -43,7 +43,7 @@
       _CodegenImpact.readFromDataSource;
 
   void writeToDataSink(DataSink sink) {
-    throw new UnsupportedError('CodegenImpact.writeToDataSink');
+    throw UnsupportedError('CodegenImpact.writeToDataSink');
   }
 
   Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks {
@@ -123,7 +123,7 @@
         ?.toSet();
     Set<Pair<DartType, DartType>> typeVariableBoundsSubtypeChecks =
         source.readList(() {
-      return new Pair(source.readDartType(), source.readDartType());
+      return Pair(source.readDartType(), source.readDartType());
     }, emptyAsNull: true)?.toSet();
     Set<String> constSymbols = source.readStrings(emptyAsNull: true)?.toSet();
     List<Set<ClassEntity>> specializedGetInterceptors = source.readList(() {
@@ -131,9 +131,8 @@
     }, emptyAsNull: true);
     bool usesInterceptor = source.readBool();
     int asyncMarkersValue = source.readIntOrNull();
-    EnumSet<AsyncMarker> asyncMarkers = asyncMarkersValue != null
-        ? new EnumSet.fromValue(asyncMarkersValue)
-        : null;
+    EnumSet<AsyncMarker> asyncMarkers =
+        asyncMarkersValue != null ? EnumSet.fromValue(asyncMarkersValue) : null;
     Set<GenericInstantiation> genericInstantiations = source
         .readList(() => GenericInstantiation.readFromDataSource(source),
             emptyAsNull: true)
@@ -147,7 +146,7 @@
         .readList(() => Selector.readFromDataSource(source), emptyAsNull: true)
         ?.toSet();
     source.end(tag);
-    return new _CodegenImpact.internal(
+    return _CodegenImpact.internal(
         member,
         dynamicUses,
         staticUses,
@@ -214,7 +213,7 @@
       DartType subtype, DartType supertype) {
     _typeVariableBoundsSubtypeChecks ??= {};
     _typeVariableBoundsSubtypeChecks
-        .add(new Pair<DartType, DartType>(subtype, supertype));
+        .add(Pair<DartType, DartType>(subtype, supertype));
   }
 
   @override
@@ -254,7 +253,7 @@
   bool get usesInterceptor => _usesInterceptor;
 
   void registerAsyncMarker(AsyncMarker asyncMarker) {
-    _asyncMarkers ??= new EnumSet<AsyncMarker>();
+    _asyncMarkers ??= EnumSet<AsyncMarker>();
     _asyncMarkers.add(asyncMarker);
   }
 
@@ -307,7 +306,7 @@
 
   @override
   String toString() {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     sb.write('CodegenImpact:');
     WorldImpact.printOn(sb, this);
 
@@ -344,7 +343,7 @@
   List<ModularExpression> _expressions;
 
   CodegenRegistry(this._elementEnvironment, this._currentElement)
-      : this._worldImpact = new _CodegenImpact(_currentElement);
+      : this._worldImpact = _CodegenImpact(_currentElement);
 
   @override
   String toString() => 'CodegenRegistry for $_currentElement';
@@ -376,7 +375,7 @@
   }
 
   void registerInstantiatedClosure(FunctionEntity element) {
-    _worldImpact.registerStaticUse(new StaticUse.callMethod(element));
+    _worldImpact.registerStaticUse(StaticUse.callMethod(element));
   }
 
   void registerConstSymbol(String name) {
@@ -396,7 +395,7 @@
   }
 
   void registerInstantiation(InterfaceType type) {
-    registerTypeUse(new TypeUse.instantiation(type));
+    registerTypeUse(TypeUse.instantiation(type));
   }
 
   void registerAsyncMarker(AsyncMarker asyncMarker) {
@@ -426,7 +425,7 @@
   }
 
   CodegenResult close(js.Fun code) {
-    return new CodegenResult(
+    return CodegenResult(
         code, _worldImpact, _names ?? const [], _expressions ?? const []);
   }
 }
@@ -598,7 +597,7 @@
 
   @override
   String toString() {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     sb.write('CodegenResult(code=');
     sb.write(code != null ? js.DebugPrint(code) : '<null>,');
     sb.write('impact=$impact,');
@@ -678,7 +677,7 @@
         break;
     }
     source.end(tag);
-    return new ModularName(kind, data: data, set: set);
+    return ModularName(kind, data: data, set: set);
   }
 
   void writeToDataSink(DataSink sink) {
@@ -805,7 +804,7 @@
         break;
     }
     source.end(tag);
-    return new ModularExpression(kind, data);
+    return ModularExpression(kind, data);
   }
 
   void writeToDataSink(DataSink sink) {
@@ -857,7 +856,7 @@
 
   @override
   String toString() {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     sb.write('ModularExpression(kind=$kind,data=');
     if (data is ConstantValue) {
       sb.write((data as ConstantValue).toStructuredText(null));
@@ -1009,12 +1008,12 @@
 
   static void writeToDataSink(DataSink sink, js.Node node) {
     sink.begin(JsNodeTags.tag);
-    JsNodeSerializer serializer = new JsNodeSerializer._(sink);
+    JsNodeSerializer serializer = JsNodeSerializer._(sink);
     serializer.visit(node);
     sink.end(JsNodeTags.tag);
   }
 
-  void visit(js.Node node, {bool allowNull: false}) {
+  void visit(js.Node node, {bool allowNull = false}) {
     if (allowNull) {
       sink.writeBool(node != null);
       if (node != null) {
@@ -1038,32 +1037,32 @@
 
   @override
   void visitInterpolatedDeclaration(js.InterpolatedDeclaration node) {
-    throw new UnsupportedError('JsNodeSerializer.visitInterpolatedDeclaration');
+    throw UnsupportedError('JsNodeSerializer.visitInterpolatedDeclaration');
   }
 
   @override
   void visitInterpolatedStatement(js.InterpolatedStatement node) {
-    throw new UnsupportedError('JsNodeSerializer.visitInterpolatedStatement');
+    throw UnsupportedError('JsNodeSerializer.visitInterpolatedStatement');
   }
 
   @override
   void visitInterpolatedSelector(js.InterpolatedSelector node) {
-    throw new UnsupportedError('JsNodeSerializer.visitInterpolatedDeclaration');
+    throw UnsupportedError('JsNodeSerializer.visitInterpolatedDeclaration');
   }
 
   @override
   void visitInterpolatedParameter(js.InterpolatedParameter node) {
-    throw new UnsupportedError('JsNodeSerializer.visitInterpolatedParameter');
+    throw UnsupportedError('JsNodeSerializer.visitInterpolatedParameter');
   }
 
   @override
   void visitInterpolatedLiteral(js.InterpolatedLiteral node) {
-    throw new UnsupportedError('JsNodeSerializer.visitInterpolatedLiteral');
+    throw UnsupportedError('JsNodeSerializer.visitInterpolatedLiteral');
   }
 
   @override
   void visitInterpolatedExpression(js.InterpolatedExpression node) {
-    throw new UnsupportedError('JsNodeSerializer.visitInterpolatedExpression');
+    throw UnsupportedError('JsNodeSerializer.visitInterpolatedExpression');
   }
 
   @override
@@ -1171,7 +1170,7 @@
       sink.end(JsNodeTags.stringBackedName);
       _writeInfo(node);
     } else {
-      throw new UnsupportedError(
+      throw UnsupportedError(
           'Unexpected deferred expression: ${node.runtimeType}.');
     }
   }
@@ -1229,17 +1228,17 @@
 
   @override
   void visitDeferredString(js.DeferredString node) {
-    throw new UnsupportedError('JsNodeSerializer.visitDeferredString');
+    throw UnsupportedError('JsNodeSerializer.visitDeferredString');
   }
 
   @override
   void visitDeferredStatement(js.DeferredStatement node) {
-    throw new UnsupportedError('JsNodeSerializer.visitDeferredStatement');
+    throw UnsupportedError('JsNodeSerializer.visitDeferredStatement');
   }
 
   @override
   void visitDeferredNumber(js.DeferredNumber node) {
-    throw new UnsupportedError('JsNodeSerializer.visitDeferredNumber');
+    throw UnsupportedError('JsNodeSerializer.visitDeferredNumber');
   }
 
   @override
@@ -1269,7 +1268,7 @@
       sink.end(JsNodeTags.deferredHolderExpression);
       _writeInfo(node);
     } else {
-      throw new UnsupportedError(
+      throw UnsupportedError(
           'Unexpected deferred expression: ${node.runtimeType}.');
     }
   }
@@ -1686,13 +1685,13 @@
       List<ModularExpression> modularExpressions) {
     source.begin(JsNodeTags.tag);
     JsNodeDeserializer deserializer =
-        new JsNodeDeserializer._(source, modularNames, modularExpressions);
+        JsNodeDeserializer._(source, modularNames, modularExpressions);
     js.Node node = deserializer.read();
     source.end(JsNodeTags.tag);
     return node;
   }
 
-  T read<T extends js.Node>({bool allowNull: false}) {
+  T read<T extends js.Node>({bool allowNull = false}) {
     if (allowNull) {
       bool hasValue = source.readBool();
       if (!hasValue) return null;
@@ -1702,54 +1701,54 @@
     switch (kind) {
       case JsNodeKind.comment:
         source.begin(JsNodeTags.comment);
-        node = new js.Comment(source.readString());
+        node = js.Comment(source.readString());
         source.end(JsNodeTags.comment);
         break;
       case JsNodeKind.await:
         source.begin(JsNodeTags.await);
-        node = new js.Await(read());
+        node = js.Await(read());
         source.end(JsNodeTags.await);
         break;
       case JsNodeKind.regExpLiteral:
         source.begin(JsNodeTags.regExpLiteral);
-        node = new js.RegExpLiteral(source.readString());
+        node = js.RegExpLiteral(source.readString());
         source.end(JsNodeTags.regExpLiteral);
         break;
       case JsNodeKind.property:
         source.begin(JsNodeTags.property);
         js.Expression name = read();
         js.Expression value = read();
-        node = new js.Property(name, value);
+        node = js.Property(name, value);
         source.end(JsNodeTags.property);
         break;
       case JsNodeKind.methodDefinition:
         source.begin(JsNodeTags.methodDefinition);
         js.Expression name = read();
         js.Expression function = read();
-        node = new js.MethodDefinition(name, function);
+        node = js.MethodDefinition(name, function);
         source.end(JsNodeTags.methodDefinition);
         break;
       case JsNodeKind.objectInitializer:
         source.begin(JsNodeTags.objectInitializer);
         List<js.Property> properties = readList();
         bool isOneLiner = source.readBool();
-        node = new js.ObjectInitializer(properties, isOneLiner: isOneLiner);
+        node = js.ObjectInitializer(properties, isOneLiner: isOneLiner);
         source.end(JsNodeTags.objectInitializer);
         break;
       case JsNodeKind.arrayHole:
         source.begin(JsNodeTags.arrayHole);
-        node = new js.ArrayHole();
+        node = js.ArrayHole();
         source.end(JsNodeTags.arrayHole);
         break;
       case JsNodeKind.arrayInitializer:
         source.begin(JsNodeTags.arrayInitializer);
         List<js.Expression> elements = readList();
-        node = new js.ArrayInitializer(elements);
+        node = js.ArrayInitializer(elements);
         source.end(JsNodeTags.arrayInitializer);
         break;
       case JsNodeKind.parentheses:
         source.begin(JsNodeTags.parentheses);
-        node = new js.Parentheses(read());
+        node = js.Parentheses(read());
         source.end(JsNodeTags.parentheses);
         break;
       case JsNodeKind.modularName:
@@ -1763,44 +1762,44 @@
         source.begin(JsNodeTags.asyncName);
         js.Name prefix = read();
         js.Name base = read();
-        node = new AsyncName(prefix, base);
+        node = AsyncName(prefix, base);
         source.end(JsNodeTags.asyncName);
         break;
       case JsNodeKind.stringBackedName:
         source.begin(JsNodeTags.stringBackedName);
-        node = new StringBackedName(source.readString());
+        node = StringBackedName(source.readString());
         source.end(JsNodeTags.stringBackedName);
         break;
       case JsNodeKind.stringConcatenation:
         source.begin(JsNodeTags.stringConcatenation);
         List<js.Literal> parts = readList();
-        node = new js.StringConcatenation(parts);
+        node = js.StringConcatenation(parts);
         source.end(JsNodeTags.stringConcatenation);
         break;
       case JsNodeKind.literalNull:
         source.begin(JsNodeTags.literalNull);
-        node = new js.LiteralNull();
+        node = js.LiteralNull();
         source.end(JsNodeTags.literalNull);
         break;
       case JsNodeKind.literalNumber:
         source.begin(JsNodeTags.literalNumber);
-        node = new js.LiteralNumber(source.readString());
+        node = js.LiteralNumber(source.readString());
         source.end(JsNodeTags.literalNumber);
         break;
       case JsNodeKind.literalString:
         source.begin(JsNodeTags.literalString);
-        node = new js.LiteralString(source.readString());
+        node = js.LiteralString(source.readString());
         source.end(JsNodeTags.literalString);
         break;
       case JsNodeKind.literalStringFromName:
         source.begin(JsNodeTags.literalStringFromName);
         js.Name name = read();
-        node = new js.LiteralStringFromName(name);
+        node = js.LiteralStringFromName(name);
         source.end(JsNodeTags.literalStringFromName);
         break;
       case JsNodeKind.literalBool:
         source.begin(JsNodeTags.literalBool);
-        node = new js.LiteralBool(source.readBool());
+        node = js.LiteralBool(source.readBool());
         source.end(JsNodeTags.literalBool);
         break;
       case JsNodeKind.modularExpression:
@@ -1817,7 +1816,7 @@
         js.Block body = read();
         js.AsyncModifier asyncModifier =
             source.readEnum(js.AsyncModifier.values);
-        node = new js.Fun(params, body, asyncModifier: asyncModifier);
+        node = js.Fun(params, body, asyncModifier: asyncModifier);
         source.end(JsNodeTags.function);
         break;
       case JsNodeKind.arrowFunction:
@@ -1826,57 +1825,57 @@
         js.Block body = read();
         js.AsyncModifier asyncModifier =
             source.readEnum(js.AsyncModifier.values);
-        node = new js.ArrowFunction(params, body, asyncModifier: asyncModifier);
+        node = js.ArrowFunction(params, body, asyncModifier: asyncModifier);
         source.end(JsNodeTags.arrowFunction);
         break;
       case JsNodeKind.namedFunction:
         source.begin(JsNodeTags.namedFunction);
         js.Declaration name = read();
         js.Fun function = read();
-        node = new js.NamedFunction(name, function);
+        node = js.NamedFunction(name, function);
         source.end(JsNodeTags.namedFunction);
         break;
       case JsNodeKind.access:
         source.begin(JsNodeTags.access);
         js.Expression receiver = read();
         js.Expression selector = read();
-        node = new js.PropertyAccess(receiver, selector);
+        node = js.PropertyAccess(receiver, selector);
         source.end(JsNodeTags.access);
         break;
       case JsNodeKind.parameter:
         source.begin(JsNodeTags.parameter);
-        node = new js.Parameter(source.readString());
+        node = js.Parameter(source.readString());
         source.end(JsNodeTags.parameter);
         break;
       case JsNodeKind.variableDeclaration:
         source.begin(JsNodeTags.variableDeclaration);
         String name = source.readString();
         bool allowRename = source.readBool();
-        node = new js.VariableDeclaration(name, allowRename: allowRename);
+        node = js.VariableDeclaration(name, allowRename: allowRename);
         source.end(JsNodeTags.variableDeclaration);
         break;
       case JsNodeKind.thisExpression:
         source.begin(JsNodeTags.thisExpression);
-        node = new js.This();
+        node = js.This();
         source.end(JsNodeTags.thisExpression);
         break;
       case JsNodeKind.variableUse:
         source.begin(JsNodeTags.variableUse);
-        node = new js.VariableUse(source.readString());
+        node = js.VariableUse(source.readString());
         source.end(JsNodeTags.variableUse);
         break;
       case JsNodeKind.postfix:
         source.begin(JsNodeTags.postfix);
         String op = source.readString();
         js.Expression argument = read();
-        node = new js.Postfix(op, argument);
+        node = js.Postfix(op, argument);
         source.end(JsNodeTags.postfix);
         break;
       case JsNodeKind.prefix:
         source.begin(JsNodeTags.prefix);
         String op = source.readString();
         js.Expression argument = read();
-        node = new js.Prefix(op, argument);
+        node = js.Prefix(op, argument);
         source.end(JsNodeTags.prefix);
         break;
       case JsNodeKind.binary:
@@ -1884,21 +1883,21 @@
         String op = source.readString();
         js.Expression left = read();
         js.Expression right = read();
-        node = new js.Binary(op, left, right);
+        node = js.Binary(op, left, right);
         source.end(JsNodeTags.binary);
         break;
       case JsNodeKind.callExpression:
         source.begin(JsNodeTags.callExpression);
         js.Expression target = read();
         List<js.Expression> arguments = readList();
-        node = new js.Call(target, arguments);
+        node = js.Call(target, arguments);
         source.end(JsNodeTags.callExpression);
         break;
       case JsNodeKind.newExpression:
         source.begin(JsNodeTags.newExpression);
         js.Expression cls = read();
         List<js.Expression> arguments = readList();
-        node = new js.New(cls, arguments);
+        node = js.New(cls, arguments);
         source.end(JsNodeTags.newExpression);
         break;
       case JsNodeKind.conditional:
@@ -1906,14 +1905,14 @@
         js.Expression condition = read();
         js.Expression then = read();
         js.Expression otherwise = read();
-        node = new js.Conditional(condition, then, otherwise);
+        node = js.Conditional(condition, then, otherwise);
         source.end(JsNodeTags.conditional);
         break;
       case JsNodeKind.variableInitialization:
         source.begin(JsNodeTags.variableInitialization);
         js.Declaration declaration = read();
         js.Expression value = source.readValueOrNull(read);
-        node = new js.VariableInitialization(declaration, value);
+        node = js.VariableInitialization(declaration, value);
         source.end(JsNodeTags.variableInitialization);
         break;
       case JsNodeKind.assignment:
@@ -1921,73 +1920,73 @@
         js.Expression leftHandSide = read();
         String op = source.readStringOrNull();
         js.Expression value = read();
-        node = new js.Assignment.compound(leftHandSide, op, value);
+        node = js.Assignment.compound(leftHandSide, op, value);
         source.end(JsNodeTags.assignment);
         break;
       case JsNodeKind.variableDeclarationList:
         source.begin(JsNodeTags.variableDeclarationList);
         List<js.VariableInitialization> declarations = readList();
         bool indentSplits = source.readBool();
-        node = new js.VariableDeclarationList(declarations,
+        node = js.VariableDeclarationList(declarations,
             indentSplits: indentSplits);
         source.end(JsNodeTags.variableDeclarationList);
         break;
       case JsNodeKind.literalExpression:
         source.begin(JsNodeTags.literalExpression);
-        node = new js.LiteralExpression(source.readString());
+        node = js.LiteralExpression(source.readString());
         source.end(JsNodeTags.literalExpression);
         break;
       case JsNodeKind.dartYield:
         source.begin(JsNodeTags.dartYield);
         js.Expression expression = read();
         bool hasStar = source.readBool();
-        node = new js.DartYield(expression, hasStar);
+        node = js.DartYield(expression, hasStar);
         source.end(JsNodeTags.dartYield);
         break;
       case JsNodeKind.literalStatement:
         source.begin(JsNodeTags.literalStatement);
-        node = new js.LiteralStatement(source.readString());
+        node = js.LiteralStatement(source.readString());
         source.end(JsNodeTags.literalStatement);
         break;
       case JsNodeKind.labeledStatement:
         source.begin(JsNodeTags.labeledStatement);
         String label = source.readString();
         js.Statement body = read();
-        node = new js.LabeledStatement(label, body);
+        node = js.LabeledStatement(label, body);
         source.end(JsNodeTags.labeledStatement);
         break;
       case JsNodeKind.functionDeclaration:
         source.begin(JsNodeTags.functionDeclaration);
         js.Declaration name = read();
         js.Fun function = read();
-        node = new js.FunctionDeclaration(name, function);
+        node = js.FunctionDeclaration(name, function);
         source.end(JsNodeTags.functionDeclaration);
         break;
       case JsNodeKind.switchDefault:
         source.begin(JsNodeTags.switchDefault);
         js.Block body = read();
-        node = new js.Default(body);
+        node = js.Default(body);
         source.end(JsNodeTags.switchDefault);
         break;
       case JsNodeKind.switchCase:
         source.begin(JsNodeTags.switchCase);
         js.Expression expression = read();
         js.Block body = read();
-        node = new js.Case(expression, body);
+        node = js.Case(expression, body);
         source.end(JsNodeTags.switchCase);
         break;
       case JsNodeKind.switchStatement:
         source.begin(JsNodeTags.switchStatement);
         js.Expression key = read();
         List<js.SwitchClause> cases = readList();
-        node = new js.Switch(key, cases);
+        node = js.Switch(key, cases);
         source.end(JsNodeTags.switchStatement);
         break;
       case JsNodeKind.catchClause:
         source.begin(JsNodeTags.catchClause);
         js.Declaration declaration = read();
         js.Block body = read();
-        node = new js.Catch(declaration, body);
+        node = js.Catch(declaration, body);
         source.end(JsNodeTags.catchClause);
         break;
       case JsNodeKind.tryStatement:
@@ -1995,45 +1994,45 @@
         js.Block body = read();
         js.Catch catchPart = source.readValueOrNull(read);
         js.Block finallyPart = source.readValueOrNull(read);
-        node = new js.Try(body, catchPart, finallyPart);
+        node = js.Try(body, catchPart, finallyPart);
         source.end(JsNodeTags.tryStatement);
         break;
       case JsNodeKind.throwStatement:
         source.begin(JsNodeTags.throwStatement);
         js.Expression expression = read();
-        node = new js.Throw(expression);
+        node = js.Throw(expression);
         source.end(JsNodeTags.throwStatement);
         break;
       case JsNodeKind.returnStatement:
         source.begin(JsNodeTags.returnStatement);
         js.Expression value = source.readValueOrNull(read);
-        node = new js.Return(value);
+        node = js.Return(value);
         source.end(JsNodeTags.returnStatement);
         break;
       case JsNodeKind.breakStatement:
         source.begin(JsNodeTags.breakStatement);
         String targetLabel = source.readStringOrNull();
-        node = new js.Break(targetLabel);
+        node = js.Break(targetLabel);
         source.end(JsNodeTags.breakStatement);
         break;
       case JsNodeKind.continueStatement:
         source.begin(JsNodeTags.continueStatement);
         String targetLabel = source.readStringOrNull();
-        node = new js.Continue(targetLabel);
+        node = js.Continue(targetLabel);
         source.end(JsNodeTags.continueStatement);
         break;
       case JsNodeKind.doStatement:
         source.begin(JsNodeTags.doStatement);
         js.Statement body = read();
         js.Expression condition = read();
-        node = new js.Do(body, condition);
+        node = js.Do(body, condition);
         source.end(JsNodeTags.doStatement);
         break;
       case JsNodeKind.whileStatement:
         source.begin(JsNodeTags.whileStatement);
         js.Expression condition = read();
         js.Statement body = read();
-        node = new js.While(condition, body);
+        node = js.While(condition, body);
         source.end(JsNodeTags.whileStatement);
         break;
       case JsNodeKind.forInStatement:
@@ -2041,7 +2040,7 @@
         js.Expression leftHandSide = read();
         js.Expression object = read();
         js.Statement body = read();
-        node = new js.ForIn(leftHandSide, object, body);
+        node = js.ForIn(leftHandSide, object, body);
         source.end(JsNodeTags.forInStatement);
         break;
       case JsNodeKind.forStatement:
@@ -2050,7 +2049,7 @@
         js.Expression condition = read(allowNull: true);
         js.Expression update = read(allowNull: true);
         js.Statement body = read();
-        node = new js.For(init, condition, update, body);
+        node = js.For(init, condition, update, body);
         source.end(JsNodeTags.forStatement);
         break;
       case JsNodeKind.ifStatement:
@@ -2058,29 +2057,29 @@
         js.Expression condition = read();
         js.Statement then = read();
         js.Statement otherwise = read();
-        node = new js.If(condition, then, otherwise);
+        node = js.If(condition, then, otherwise);
         source.end(JsNodeTags.ifStatement);
         break;
       case JsNodeKind.emptyStatement:
         source.begin(JsNodeTags.emptyStatement);
-        node = new js.EmptyStatement();
+        node = js.EmptyStatement();
         source.end(JsNodeTags.emptyStatement);
         break;
       case JsNodeKind.expressionStatement:
         source.begin(JsNodeTags.expressionStatement);
-        node = new js.ExpressionStatement(read());
+        node = js.ExpressionStatement(read());
         source.end(JsNodeTags.expressionStatement);
         break;
       case JsNodeKind.block:
         source.begin(JsNodeTags.block);
         List<js.Statement> statements = readList();
-        node = new js.Block(statements);
+        node = js.Block(statements);
         source.end(JsNodeTags.block);
         break;
       case JsNodeKind.program:
         source.begin(JsNodeTags.program);
         List<js.Statement> body = readList();
-        node = new js.Program(body);
+        node = js.Program(body);
         source.end(JsNodeTags.program);
         break;
       case JsNodeKind.stringReference:
@@ -2109,7 +2108,7 @@
     return node;
   }
 
-  List<T> readList<T extends js.Node>({bool emptyAsNull: false}) {
+  List<T> readList<T extends js.Node>({bool emptyAsNull = false}) {
     return source.readList(read, emptyAsNull: emptyAsNull);
   }
 }
diff --git a/pkg/compiler/lib/src/common/names.dart b/pkg/compiler/lib/src/common/names.dart
index 5abee00..74804d7 100644
--- a/pkg/compiler/lib/src/common/names.dart
+++ b/pkg/compiler/lib/src/common/names.dart
@@ -69,89 +69,89 @@
 /// [Name]s commonly used.
 class Names {
   /// The name of the call operator.
-  static const Name call = const PublicName(Identifiers.call);
+  static const Name call = PublicName(Identifiers.call);
 
   /// The name of the current element property used on iterators in for-each
   /// loops.
-  static const Name current = const PublicName(Identifiers.current);
+  static const Name current = PublicName(Identifiers.current);
 
   /// The name of the dynamic type.
-  static const Name dynamic_ = const PublicName('dynamic');
+  static const Name dynamic_ = PublicName('dynamic');
 
   /// The name of the iterator property used in for-each loops.
-  static const Name iterator = const PublicName(Identifiers.iterator);
+  static const Name iterator = PublicName(Identifiers.iterator);
 
   /// The name of the move next method used on iterators in for-each loops.
-  static const Name moveNext = const PublicName('moveNext');
+  static const Name moveNext = PublicName('moveNext');
 
   /// The name of the no such method handler on 'Object'.
-  static const Name noSuchMethod_ = const PublicName(Identifiers.noSuchMethod_);
+  static const Name noSuchMethod_ = PublicName(Identifiers.noSuchMethod_);
 
   /// The name of the to-string method on 'Object'.
-  static const Name toString_ = const PublicName('toString');
+  static const Name toString_ = PublicName('toString');
 
-  static const Name INDEX_NAME = const PublicName("[]");
-  static const Name INDEX_SET_NAME = const PublicName("[]=");
+  static const Name INDEX_NAME = PublicName("[]");
+  static const Name INDEX_SET_NAME = PublicName("[]=");
   static const Name CALL_NAME = Names.call;
 
-  static const Name length = const PublicName(Identifiers.length);
+  static const Name length = PublicName(Identifiers.length);
 
-  static const Name runtimeType_ = const PublicName(Identifiers.runtimeType_);
+  static const Name runtimeType_ = PublicName(Identifiers.runtimeType_);
 
-  static const Name genericInstantiation = const PublicName('instantiate');
+  static const Name genericInstantiation = PublicName('instantiate');
 
   /// The name of the signature function in closure classes.
-  static const Name signature = const PublicName(Identifiers.signature);
+  static const Name signature = PublicName(Identifiers.signature);
 }
 
 /// [Selector]s commonly used.
 class Selectors {
   /// The selector for calling the cancel method on 'StreamIterator'.
   static final Selector cancel =
-      new Selector.call(const PublicName('cancel'), CallStructure.NO_ARGS);
+      Selector.call(const PublicName('cancel'), CallStructure.NO_ARGS);
 
   /// The selector for getting the current element property used in for-each
   /// loops.
-  static final Selector current = new Selector.getter(Names.current);
+  static final Selector current = Selector.getter(Names.current);
 
   /// The selector for getting the iterator property used in for-each loops.
-  static final Selector iterator = new Selector.getter(Names.iterator);
+  static final Selector iterator = Selector.getter(Names.iterator);
 
   /// The selector for calling the move next method used in for-each loops.
   static final Selector moveNext =
-      new Selector.call(Names.moveNext, CallStructure.NO_ARGS);
+      Selector.call(Names.moveNext, CallStructure.NO_ARGS);
 
   /// The selector for calling the no such method handler on 'Object'.
   static final Selector noSuchMethod_ =
-      new Selector.call(Names.noSuchMethod_, CallStructure.ONE_ARG);
+      Selector.call(Names.noSuchMethod_, CallStructure.ONE_ARG);
 
   /// The selector for tearing off noSuchMethod.
   static final Selector noSuchMethodGetter =
-      new Selector.getter(Names.noSuchMethod_);
+      Selector.getter(Names.noSuchMethod_);
 
   /// The selector for calling the to-string method on 'Object'.
   static final Selector toString_ =
-      new Selector.call(Names.toString_, CallStructure.NO_ARGS);
+      Selector.call(Names.toString_, CallStructure.NO_ARGS);
 
   /// The selector for tearing off toString.
-  static final Selector toStringGetter = new Selector.getter(Names.toString_);
+  static final Selector toStringGetter = Selector.getter(Names.toString_);
 
   static final Selector hashCode_ =
-      new Selector.getter(const PublicName('hashCode'));
+      Selector.getter(const PublicName('hashCode'));
 
   static final Selector compareTo =
-      new Selector.call(const PublicName("compareTo"), CallStructure.ONE_ARG);
+      Selector.call(const PublicName("compareTo"), CallStructure.ONE_ARG);
 
-  static final Selector equals = new Selector.binaryOperator('==');
+  static final Selector equals = Selector.binaryOperator('==');
 
-  static final Selector length = new Selector.getter(Names.length);
+  static final Selector length = Selector.getter(Names.length);
 
   static final Selector codeUnitAt =
-      new Selector.call(const PublicName('codeUnitAt'), CallStructure.ONE_ARG);
+      Selector.call(const PublicName('codeUnitAt'), CallStructure.ONE_ARG);
 
-  static final Selector index = new Selector.index();
+  static final Selector index = Selector.index();
 
-  static final Selector runtimeType_ = new Selector.getter(Names.runtimeType_);
+  static final Selector runtimeType_ = Selector.getter(Names.runtimeType_);
 
   /// List of all the selectors held in static fields.
   ///
@@ -179,89 +179,84 @@
 /// [Uri]s commonly used.
 class Uris {
   /// The URI for 'dart:async'.
-  static final Uri dart_async = new Uri(scheme: 'dart', path: 'async');
+  static final Uri dart_async = Uri(scheme: 'dart', path: 'async');
 
   /// The URI for 'dart:collection'.
-  static final Uri dart_collection =
-      new Uri(scheme: 'dart', path: 'collection');
+  static final Uri dart_collection = Uri(scheme: 'dart', path: 'collection');
 
   /// The URI for 'dart:core'.
-  static final Uri dart_core = new Uri(scheme: 'dart', path: 'core');
+  static final Uri dart_core = Uri(scheme: 'dart', path: 'core');
 
   /// The URI for 'dart:html'.
-  static final Uri dart_html = new Uri(scheme: 'dart', path: 'html');
+  static final Uri dart_html = Uri(scheme: 'dart', path: 'html');
 
   /// The URI for 'dart:html_common'.
-  static final Uri dart_html_common =
-      new Uri(scheme: 'dart', path: 'html_common');
+  static final Uri dart_html_common = Uri(scheme: 'dart', path: 'html_common');
 
   /// The URI for 'dart:indexed_db'.
-  static final Uri dart_indexed_db =
-      new Uri(scheme: 'dart', path: 'indexed_db');
+  static final Uri dart_indexed_db = Uri(scheme: 'dart', path: 'indexed_db');
 
   /// The URI for 'dart:isolate'.
-  static final Uri dart_isolate = new Uri(scheme: 'dart', path: 'isolate');
+  static final Uri dart_isolate = Uri(scheme: 'dart', path: 'isolate');
 
   /// The URI for 'dart:math'.
-  static final Uri dart_math = new Uri(scheme: 'dart', path: 'math');
+  static final Uri dart_math = Uri(scheme: 'dart', path: 'math');
 
   /// The URI for 'dart:mirrors'.
-  static final Uri dart_mirrors = new Uri(scheme: 'dart', path: 'mirrors');
+  static final Uri dart_mirrors = Uri(scheme: 'dart', path: 'mirrors');
 
   /// The URI for 'dart:_internal'.
-  static final Uri dart__internal = new Uri(scheme: 'dart', path: '_internal');
+  static final Uri dart__internal = Uri(scheme: 'dart', path: '_internal');
 
   /// The URI for 'dart:_native_typed_data'.
   static final Uri dart__native_typed_data =
-      new Uri(scheme: 'dart', path: '_native_typed_data');
+      Uri(scheme: 'dart', path: '_native_typed_data');
 
   /// The URI for 'dart:typed_data'.
-  static final Uri dart_typed_data =
-      new Uri(scheme: 'dart', path: 'typed_data');
+  static final Uri dart_typed_data = Uri(scheme: 'dart', path: 'typed_data');
 
   /// The URI for 'dart:svg'.
-  static final Uri dart_svg = new Uri(scheme: 'dart', path: 'svg');
+  static final Uri dart_svg = Uri(scheme: 'dart', path: 'svg');
 
   /// The URI for 'dart:web_audio'.
-  static final Uri dart_web_audio = new Uri(scheme: 'dart', path: 'web_audio');
+  static final Uri dart_web_audio = Uri(scheme: 'dart', path: 'web_audio');
 
   /// The URI for 'dart:web_gl'.
-  static final Uri dart_web_gl = new Uri(scheme: 'dart', path: 'web_gl');
+  static final Uri dart_web_gl = Uri(scheme: 'dart', path: 'web_gl');
 
   /// The URI for 'dart:web_sql'.
-  static final Uri dart_web_sql = new Uri(scheme: 'dart', path: 'web_sql');
+  static final Uri dart_web_sql = Uri(scheme: 'dart', path: 'web_sql');
 
   /// The URI for 'dart:_js_helper'.
-  static final Uri dart__js_helper =
-      new Uri(scheme: 'dart', path: '_js_helper');
+  static final Uri dart__js_helper = Uri(scheme: 'dart', path: '_js_helper');
 
   /// The URI for 'dart:_late_helper'.
   static final Uri dart__late_helper =
       Uri(scheme: 'dart', path: '_late_helper');
 
   /// The URI for 'dart:_rti'.
-  static final Uri dart__rti = new Uri(scheme: 'dart', path: '_rti');
+  static final Uri dart__rti = Uri(scheme: 'dart', path: '_rti');
 
   /// The URI for 'dart:_interceptors'.
   static final Uri dart__interceptors =
-      new Uri(scheme: 'dart', path: '_interceptors');
+      Uri(scheme: 'dart', path: '_interceptors');
 
   /// The URI for 'dart:_foreign_helper'.
   static final Uri dart__foreign_helper =
-      new Uri(scheme: 'dart', path: '_foreign_helper');
+      Uri(scheme: 'dart', path: '_foreign_helper');
 
   /// The URI for 'dart:_js_names'.
-  static final Uri dart__js_names = new Uri(scheme: 'dart', path: '_js_names');
+  static final Uri dart__js_names = Uri(scheme: 'dart', path: '_js_names');
 
   /// The URI for 'dart:_js_embedded_names'.
   static final Uri dart__js_embedded_names =
-      new Uri(scheme: 'dart', path: '_js_embedded_names');
+      Uri(scheme: 'dart', path: '_js_embedded_names');
 
   /// The URI for 'dart:js'.
   static final Uri dart_js = Uri(scheme: 'dart', path: 'js');
 
   /// The URI for 'package:js'.
-  static final Uri package_js = new Uri(scheme: 'package', path: 'js/js.dart');
+  static final Uri package_js = Uri(scheme: 'package', path: 'js/js.dart');
 
   /// The URI for 'dart:_js_annotations'.
   static final Uri dart__js_annotations =
@@ -269,5 +264,5 @@
 
   /// The URI for 'package:meta/dart2js.dart'.
   static final Uri package_meta_dart2js =
-      new Uri(scheme: 'package', path: 'meta/dart2js.dart');
+      Uri(scheme: 'package', path: 'meta/dart2js.dart');
 }
diff --git a/pkg/compiler/lib/src/common/tasks.dart b/pkg/compiler/lib/src/common/tasks.dart
index 6022b50..35aff31 100644
--- a/pkg/compiler/lib/src/common/tasks.dart
+++ b/pkg/compiler/lib/src/common/tasks.dart
@@ -28,7 +28,7 @@
   Map _zoneValues;
 
   CompilerTask(this._measurer)
-      : _watch = _measurer.enableTaskMeasurements ? new Stopwatch() : null;
+      : _watch = _measurer.enableTaskMeasurements ? Stopwatch() : null;
 
   /// Whether measurement is disabled. The functions [measure] and [measureIo]
   /// only measure time if measurements are enabled.
@@ -107,7 +107,7 @@
 
     return runZoned(action,
         zoneValues: _zoneValues ??= {_measurer: this},
-        zoneSpecification: _zoneSpecification ??= new ZoneSpecification(
+        zoneSpecification: _zoneSpecification ??= ZoneSpecification(
             run: _run, runUnary: _runUnary, runBinary: _runBinary));
   }
 
@@ -183,7 +183,7 @@
     // Use a nested CompilerTask for the measurement to ensure nested [measure]
     // calls work correctly. The subtasks will never themselves have nested
     // subtasks because they are not accessible outside.
-    GenericTask subtask = _subtasks[name] ??= new GenericTask(name, _measurer);
+    GenericTask subtask = _subtasks[name] ??= GenericTask(name, _measurer);
     return subtask.measure(action);
   }
 
@@ -200,7 +200,7 @@
     // Use a nested CompilerTask for the measurement to ensure nested [measure]
     // calls work correctly. The subtasks will never themselves have nested
     // subtasks because they are not accessible outside.
-    GenericTask subtask = _subtasks[name] ??= new GenericTask(name, _measurer);
+    GenericTask subtask = _subtasks[name] ??= GenericTask(name, _measurer);
     return subtask.measureIo(action);
   }
 
@@ -225,12 +225,12 @@
   ///
   /// Note: MUST be the first field of this class to ensure [wallclock] is
   /// started before other computations.
-  final Stopwatch _wallClock = new Stopwatch()..start();
+  final Stopwatch _wallClock = Stopwatch()..start();
 
   Duration get elapsedWallClock => _wallClock.elapsed;
 
   /// Measures gaps between zoned closures due to asynchronicity.
-  final Stopwatch _asyncWallClock = new Stopwatch();
+  final Stopwatch _asyncWallClock = Stopwatch();
 
   Duration get elapsedAsyncWallClock => _asyncWallClock.elapsed;
 
@@ -241,7 +241,7 @@
   @override
   final int hashCode = _hashCodeGenerator++;
 
-  Measurer({this.enableTaskMeasurements: false});
+  Measurer({this.enableTaskMeasurements = false});
 
   /// The currently running task, that is, the task whose [Stopwatch] is
   /// currently running.
diff --git a/pkg/compiler/lib/src/deferred_load/deferred_load.dart b/pkg/compiler/lib/src/deferred_load/deferred_load.dart
index 1d21d68..38da9db 100644
--- a/pkg/compiler/lib/src/deferred_load/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load/deferred_load.dart
@@ -314,6 +314,10 @@
   /// The OutputUnit that will be loaded when the program starts.
   OutputUnit _mainOutputUnit;
 
+  /// A sentinel used only by the [ImportSet] corresponding to the
+  /// [_mainOutputUnit].
+  final ImportEntity _mainImport = ImportEntity(true, 'main#main', null, null);
+
   /// A set containing (eventually) all output units that will result from the
   /// program.
   final List<OutputUnit> _allOutputUnits = [];
@@ -350,7 +354,6 @@
 
   DeferredLoadTask(this.compiler, this._elementMap) : super(compiler.measurer) {
     _mainOutputUnit = OutputUnit(true, 'main', {});
-    importSets.mainSet.unit = _mainOutputUnit;
     _allOutputUnits.add(_mainOutputUnit);
   }
 
@@ -535,6 +538,10 @@
         var transitions = builder.buildTransitionsMap(_allDeferredImports);
         importSets.buildInitialSets(transitions);
       }
+
+      // Build the [ImportSet] representing the [_mainOutputUnit].
+      importSets.buildMainSet(
+          _mainImport, _mainOutputUnit, _allDeferredImports);
     });
   }
 
diff --git a/pkg/compiler/lib/src/deferred_load/import_set.dart b/pkg/compiler/lib/src/deferred_load/import_set.dart
index 0327d27..984f7cb 100644
--- a/pkg/compiler/lib/src/deferred_load/import_set.dart
+++ b/pkg/compiler/lib/src/deferred_load/import_set.dart
@@ -41,9 +41,12 @@
   /// The canonical instance representing the empty import set.
   ImportSet _emptySet = ImportSet.empty();
 
-  /// The import set representing the main output unit, which happens to be
-  /// implemented as an empty set in our algorithm.
-  ImportSet get mainSet => _emptySet;
+  /// The [ImportSet] representing the main output unit.
+  ImportSet _mainSet;
+  ImportSet get mainSet {
+    assert(_mainSet != null && _mainSet.unit != null);
+    return _mainSet;
+  }
 
   /// Get the smallest [ImportSet] that contains [import]. When
   /// unconstrained, this [ImportSet] is a singleton [ImportSet] containing
@@ -59,17 +62,31 @@
     return _emptySet._add(_wrap(import));
   }
 
+  /// A helper method to convert a [Set<ImportEntity>] to an [ImportSet].
+  ImportSet setOfImportsToImportSet(Set<ImportEntity> setOfImports) {
+    List<_DeferredImport> imports = setOfImports.map(_wrap).toList();
+    imports.sort((a, b) => a.index - b.index);
+    var result = _emptySet;
+    for (var import in imports) {
+      result = result._add(import);
+    }
+    return result;
+  }
+
+  /// Builds the [mainSet] which contains transitions for all other deferred
+  /// imports as well as [mainImport].
+  void buildMainSet(ImportEntity mainImport, OutputUnit mainOutputUnit,
+      Iterable<ImportEntity> allDeferredImports) {
+    _mainSet = setOfImportsToImportSet({mainImport, ...allDeferredImports});
+    _mainSet.unit = mainOutputUnit;
+    initialSets[mainImport] = _mainSet;
+  }
+
   /// Initializes the [initialSet] map.
   void buildInitialSets(
       Map<ImportEntity, Set<ImportEntity>> initialTransitions) {
     initialTransitions.forEach((import, setOfImports) {
-      List<_DeferredImport> imports = setOfImports.map(_wrap).toList();
-      imports.sort((a, b) => a.index - b.index);
-      var result = _emptySet;
-      for (var import in imports) {
-        result = result._add(import);
-      }
-      initialSets[import] = result;
+      initialSets[import] = setOfImportsToImportSet(setOfImports);
     });
   }
 
diff --git a/pkg/compiler/lib/src/js_backend/type_reference.dart b/pkg/compiler/lib/src/js_backend/type_reference.dart
index a845b95..eca01c8 100644
--- a/pkg/compiler/lib/src/js_backend/type_reference.dart
+++ b/pkg/compiler/lib/src/js_backend/type_reference.dart
@@ -663,9 +663,7 @@
 
   @override
   void visitTypeVariableType(covariant TypeVariableType type, DartType parent) {
-    if (parent != type.element.typeDeclaration) {
-      _identifier(type.element.typeDeclaration.name);
-    }
+    _identifier(type.element.typeDeclaration.name);
     _identifier(type.element.name);
   }
 
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart
index 0457090..788d79e 100644
--- a/pkg/compiler/lib/src/native/behavior.dart
+++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -14,8 +14,8 @@
 import '../universe/side_effects.dart' show SideEffects;
 import 'js.dart';
 
-typedef dynamic /*DartType|SpecialType*/ TypeLookup(String typeString,
-    {bool required});
+typedef TypeLookup = dynamic /*DartType|SpecialType*/
+    Function(String typeString, {bool required});
 
 /// This class is a temporary work-around until we get a more powerful DartType.
 class SpecialType {
@@ -23,7 +23,7 @@
   const SpecialType._(this.name);
 
   /// The type Object, but no subtypes:
-  static const JsObject = const SpecialType._('=Object');
+  static const JsObject = SpecialType._('=Object');
 
   @override
   int get hashCode => name.hashCode;
@@ -35,7 +35,7 @@
     if (name == '=Object') {
       return JsObject;
     } else {
-      throw new UnsupportedError("Unknown SpecialType '$name'.");
+      throw UnsupportedError("Unknown SpecialType '$name'.");
     }
   }
 }
@@ -189,7 +189,7 @@
   static NativeBehavior get CHANGES_OTHER => NativeBehavior._makeChangesOther();
   static NativeBehavior get DEPENDS_OTHER => NativeBehavior._makeDependsOther();
 
-  NativeBehavior() : sideEffects = new SideEffects.empty();
+  NativeBehavior() : sideEffects = SideEffects.empty();
 
   NativeBehavior.internal(this.sideEffects);
 
@@ -211,13 +211,13 @@
     List typesReturned = readTypes();
     List typesInstantiated = readTypes();
     String codeTemplateText = source.readStringOrNull();
-    SideEffects sideEffects = new SideEffects.readFromDataSource(source);
+    SideEffects sideEffects = SideEffects.readFromDataSource(source);
     int throwBehavior = source.readInt();
     bool isAllocation = source.readBool();
     bool useGvn = source.readBool();
     source.end(tag);
 
-    NativeBehavior behavior = new NativeBehavior.internal(sideEffects);
+    NativeBehavior behavior = NativeBehavior.internal(sideEffects);
     behavior.typesReturned.addAll(typesReturned);
     behavior.typesInstantiated.addAll(typesInstantiated);
     if (codeTemplateText != null) {
@@ -274,8 +274,8 @@
         ')';
   }
 
-  static NativeBehavior _makePure({bool isAllocation: false}) {
-    NativeBehavior behavior = new NativeBehavior();
+  static NativeBehavior _makePure({bool isAllocation = false}) {
+    NativeBehavior behavior = NativeBehavior();
     behavior.sideEffects.clearAllDependencies();
     behavior.sideEffects.clearAllSideEffects();
     behavior.throwBehavior = NativeThrowBehavior.NEVER;
@@ -384,7 +384,7 @@
           spannable, MessageKind.GENERIC, {'text': message});
     }
 
-    const List<String> knownTags = const [
+    const List<String> knownTags = [
       'creates',
       'returns',
       'depends',
@@ -538,7 +538,7 @@
       return null;
     }
 
-    SideEffects sideEffects = new SideEffects();
+    SideEffects sideEffects = SideEffects();
     if (effects == "none") {
       sideEffects.clearAllSideEffects();
     } else if (effects == "all") {
@@ -609,7 +609,7 @@
     //  'Type1|Type2'.  A union type.
     //  '=Object'.      A JavaScript Object, no subtype.
 
-    NativeBehavior behavior = new NativeBehavior();
+    NativeBehavior behavior = NativeBehavior();
 
     behavior.codeTemplateText = codeString;
     behavior.codeTemplate = js.js.parseForeignJS(behavior.codeTemplateText);
@@ -647,12 +647,11 @@
         nullType: commonElements.nullType);
 
     if (!sideEffectsAreEncodedInSpecString) {
-      new SideEffectsVisitor(behavior.sideEffects)
-          .visit(behavior.codeTemplate.ast);
+      SideEffectsVisitor(behavior.sideEffects).visit(behavior.codeTemplate.ast);
     }
     if (!throwBehaviorFromSpecString) {
       behavior.throwBehavior =
-          new ThrowBehaviorVisitor().analyze(behavior.codeTemplate.ast);
+          ThrowBehaviorVisitor().analyze(behavior.codeTemplate.ast);
     }
 
     return behavior;
@@ -686,8 +685,8 @@
       Spannable spannable,
       DiagnosticReporter reporter,
       CommonElements commonElements) {
-    NativeBehavior behavior = new NativeBehavior();
-    behavior.sideEffects.setTo(new SideEffects());
+    NativeBehavior behavior = NativeBehavior();
+    behavior.sideEffects.setTo(SideEffects());
     _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal(
         behavior, spannable, specString, lookupType, reporter, commonElements);
     return behavior;
@@ -699,11 +698,11 @@
       Spannable spannable,
       DiagnosticReporter reporter,
       CommonElements commonElements) {
-    NativeBehavior behavior = new NativeBehavior();
+    NativeBehavior behavior = NativeBehavior();
     // TODO(sra): Allow the use site to override these defaults.
     // Embedded globals are usually pre-computed data structures or JavaScript
     // functions that never change.
-    behavior.sideEffects.setTo(new SideEffects.empty());
+    behavior.sideEffects.setTo(SideEffects.empty());
     behavior.throwBehavior = NativeThrowBehavior.NEVER;
     _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal(
         behavior, spannable, specString, lookupType, reporter, commonElements,
@@ -857,7 +856,7 @@
       Iterable<String> returnsAnnotations,
       TypeLookup lookupType,
       {bool isJsInterop}) {
-    _behavior = new NativeBehavior();
+    _behavior = NativeBehavior();
     // TODO(sigmund,sra): consider doing something better for numeric types.
     _addReturnType(!isJsInterop ? type : commonElements.dynamicType);
     _capture(type, isJsInterop);
@@ -868,7 +867,7 @@
   }
 
   NativeBehavior buildFieldStoreBehavior(DartType type) {
-    _behavior = new NativeBehavior();
+    _behavior = NativeBehavior();
     _escape(type, false);
     // We don't override the default behaviour - the annotations apply to
     // loading the field.
@@ -882,7 +881,7 @@
       Iterable<String> returnsAnnotations,
       TypeLookup lookupType,
       {bool isJsInterop}) {
-    _behavior = new NativeBehavior();
+    _behavior = NativeBehavior();
     DartType returnType = type.returnType;
     // Note: For dart:html and other internal libraries we maintain, we can
     // trust the return type and use it to limit what we enqueue. We have to
diff --git a/pkg/compiler/lib/src/native/enqueue.dart b/pkg/compiler/lib/src/native/enqueue.dart
index e08baad..9f97703 100644
--- a/pkg/compiler/lib/src/native/enqueue.dart
+++ b/pkg/compiler/lib/src/native/enqueue.dart
@@ -37,8 +37,8 @@
 }
 
 abstract class NativeEnqueuerBase implements NativeEnqueuer {
-  final Set<ClassEntity> _registeredClasses = new Set<ClassEntity>();
-  final Set<ClassEntity> _unusedClasses = new Set<ClassEntity>();
+  final Set<ClassEntity> _registeredClasses = Set<ClassEntity>();
+  final Set<ClassEntity> _unusedClasses = Set<ClassEntity>();
 
   @override
   bool get hasInstantiatedNativeClasses => !_registeredClasses.isEmpty;
@@ -75,7 +75,7 @@
         continue;
       }
       impactBuilder.registerTypeUse(
-          new TypeUse.nativeInstantiation(_elementEnvironment.getRawType(cls)));
+          TypeUse.nativeInstantiation(_elementEnvironment.getRawType(cls)));
     }
   }
 
@@ -88,11 +88,11 @@
   void _processNativeBehavior(
       WorldImpactBuilder impactBuilder, NativeBehavior behavior, cause) {
     void registerInstantiation(InterfaceType type) {
-      impactBuilder.registerTypeUse(new TypeUse.nativeInstantiation(type));
+      impactBuilder.registerTypeUse(TypeUse.nativeInstantiation(type));
     }
 
     int unusedBefore = _unusedClasses.length;
-    Set<ClassEntity> matchingClasses = new Set<ClassEntity>();
+    Set<ClassEntity> matchingClasses = Set<ClassEntity>();
     for (var type in behavior.typesInstantiated) {
       if (type is SpecialType) {
         if (type == SpecialType.JsObject) {
@@ -182,7 +182,7 @@
 
   /// The set of all native classes.  Each native class is in [nativeClasses]
   /// and exactly one of [unusedClasses] and [registeredClasses].
-  final Set<ClassEntity> _nativeClasses = new Set<ClassEntity>();
+  final Set<ClassEntity> _nativeClasses = Set<ClassEntity>();
 
   NativeResolutionEnqueuer(
       CompilerOptions options,
@@ -200,7 +200,7 @@
 
   @override
   WorldImpact processNativeClasses(Iterable<Uri> libraries) {
-    WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
+    WorldImpactBuilderImpl impactBuilder = WorldImpactBuilderImpl();
     Iterable<ClassEntity> nativeClasses =
         _nativeClassFinder.computeNativeClasses(libraries);
     _nativeClasses.addAll(nativeClasses);
@@ -224,7 +224,7 @@
   final Iterable<ClassEntity> _nativeClasses;
   final NativeData _nativeData;
 
-  final Set<ClassEntity> _doneAddSubtypes = new Set<ClassEntity>();
+  final Set<ClassEntity> _doneAddSubtypes = Set<ClassEntity>();
 
   NativeCodegenEnqueuer(
       CompilerOptions options,
@@ -238,7 +238,7 @@
 
   @override
   WorldImpact processNativeClasses(Iterable<Uri> libraries) {
-    WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
+    WorldImpactBuilderImpl impactBuilder = WorldImpactBuilderImpl();
     _unusedClasses.addAll(_nativeClasses);
 
     if (!enableLiveTypeAnalysis) {
@@ -246,7 +246,7 @@
     }
 
     // HACK HACK - add all the resolved classes.
-    Set<ClassEntity> matchingClasses = new Set<ClassEntity>();
+    Set<ClassEntity> matchingClasses = Set<ClassEntity>();
     for (ClassEntity classElement in _nativeClasses) {
       if (_unusedClasses.contains(classElement)) {
         matchingClasses.add(classElement);
diff --git a/pkg/compiler/lib/src/native/js.dart b/pkg/compiler/lib/src/native/js.dart
index e984dc6..166fc6a 100644
--- a/pkg/compiler/lib/src/native/js.dart
+++ b/pkg/compiler/lib/src/native/js.dart
@@ -10,7 +10,7 @@
   HasCapturedPlaceholders._();
 
   static bool check(js.Node node) {
-    HasCapturedPlaceholders visitor = new HasCapturedPlaceholders._();
+    HasCapturedPlaceholders visitor = HasCapturedPlaceholders._();
     node.accept(visitor);
     return visitor.found;
   }
diff --git a/pkg/compiler/lib/src/native/resolver.dart b/pkg/compiler/lib/src/native/resolver.dart
index 10b0f3f..b20f6d8 100644
--- a/pkg/compiler/lib/src/native/resolver.dart
+++ b/pkg/compiler/lib/src/native/resolver.dart
@@ -28,13 +28,13 @@
   final KElementEnvironment _elementEnvironment;
   final NativeBasicData _nativeBasicData;
 
-  Map<String, ClassEntity> _tagOwner = new Map<String, ClassEntity>();
+  Map<String, ClassEntity> _tagOwner = Map<String, ClassEntity>();
 
   BaseNativeClassFinder(this._elementEnvironment, this._nativeBasicData);
 
   @override
   Iterable<ClassEntity> computeNativeClasses(Iterable<Uri> libraries) {
-    Set<ClassEntity> nativeClasses = new Set<ClassEntity>();
+    Set<ClassEntity> nativeClasses = Set<ClassEntity>();
     libraries.forEach((uri) => _processNativeClassesInLibrary(
         _elementEnvironment.lookupLibrary(uri), nativeClasses));
     _processSubclassesOfNativeClasses(libraries, nativeClasses);
@@ -84,7 +84,7 @@
   /// [nativeClasses].
   void _processSubclassesOfNativeClasses(
       Iterable<Uri> libraries, Set<ClassEntity> nativeClasses) {
-    Set<ClassEntity> nativeClassesAndSubclasses = new Set<ClassEntity>();
+    Set<ClassEntity> nativeClassesAndSubclasses = Set<ClassEntity>();
     // Collect potential subclasses, e.g.
     //
     //     class B extends foo.A {}
@@ -100,7 +100,7 @@
         String extendsName = _findExtendsNameOfClass(cls);
         if (extendsName != null) {
           Set<ClassEntity> potentialSubclasses = potentialExtends.putIfAbsent(
-              extendsName, () => new Set<ClassEntity>());
+              extendsName, () => Set<ClassEntity>());
           potentialSubclasses.add(cls);
         }
       });
diff --git a/pkg/compiler/lib/src/universe/call_structure.dart b/pkg/compiler/lib/src/universe/call_structure.dart
index 45603b8..7cae519 100644
--- a/pkg/compiler/lib/src/universe/call_structure.dart
+++ b/pkg/compiler/lib/src/universe/call_structure.dart
@@ -19,11 +19,11 @@
   /// data stream.
   static const String tag = 'call-structure';
 
-  static const CallStructure NO_ARGS = const CallStructure.unnamed(0);
-  static const CallStructure ONE_ARG = const CallStructure.unnamed(1);
-  static const CallStructure TWO_ARGS = const CallStructure.unnamed(2);
-  static const CallStructure THREE_ARGS = const CallStructure.unnamed(3);
-  static const CallStructure FOUR_ARGS = const CallStructure.unnamed(4);
+  static const CallStructure NO_ARGS = CallStructure.unnamed(0);
+  static const CallStructure ONE_ARG = CallStructure.unnamed(1);
+  static const CallStructure TWO_ARGS = CallStructure.unnamed(2);
+  static const CallStructure THREE_ARGS = CallStructure.unnamed(3);
+  static const CallStructure FOUR_ARGS = CallStructure.unnamed(4);
 
   /// The number of type arguments of the call.
   final int typeArgumentCount;
@@ -42,10 +42,9 @@
   factory CallStructure(int argumentCount,
       [List<String> namedArguments, int typeArgumentCount = 0]) {
     if (namedArguments == null || namedArguments.isEmpty) {
-      return new CallStructure.unnamed(argumentCount, typeArgumentCount);
+      return CallStructure.unnamed(argumentCount, typeArgumentCount);
     }
-    return new NamedCallStructure(
-        argumentCount, namedArguments, typeArgumentCount);
+    return NamedCallStructure(argumentCount, namedArguments, typeArgumentCount);
   }
 
   /// Deserializes a [CallStructure] object from [source].
@@ -55,7 +54,7 @@
     List<String> namedArguments = source.readStrings();
     int typeArgumentCount = source.readInt();
     source.end(tag);
-    return new CallStructure(argumentCount, namedArguments, typeArgumentCount);
+    return CallStructure(argumentCount, namedArguments, typeArgumentCount);
   }
 
   /// Serializes this [CallStructure] to [sink].
@@ -77,7 +76,7 @@
   CallStructure toNormalized() => this;
 
   CallStructure withTypeArgumentCount(int typeArgumentCount) =>
-      new CallStructure(argumentCount, namedArguments, typeArgumentCount);
+      CallStructure(argumentCount, namedArguments, typeArgumentCount);
 
   /// `true` if this call has named arguments.
   bool get isNamed => false;
@@ -93,11 +92,11 @@
 
   CallStructure get nonGeneric => typeArgumentCount == 0
       ? this
-      : new CallStructure(argumentCount, namedArguments);
+      : CallStructure(argumentCount, namedArguments);
 
   /// Short textual representation use for testing.
   String get shortText {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     sb.write('(');
     sb.write(positionalArgumentCount);
     if (namedArgumentCount > 0) {
@@ -110,7 +109,7 @@
 
   /// A description of the argument structure.
   String structureToString() {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     sb.write('arity=$argumentCount');
     if (typeArgumentCount != 0) {
       sb.write(', types=$typeArgumentCount');
@@ -121,7 +120,7 @@
   @override
   String toString() => 'CallStructure(${structureToString()})';
 
-  Selector get callSelector => new Selector.call(Names.call, this);
+  Selector get callSelector => Selector.call(Names.call, this);
 
   bool match(CallStructure other) {
     if (identical(this, other)) return true;
@@ -234,7 +233,7 @@
   bool get isNormalized => namedArguments == _orderedNamedArguments;
 
   @override
-  CallStructure toNormalized() => new NamedCallStructure.internal(
+  CallStructure toNormalized() => NamedCallStructure.internal(
       argumentCount,
       getOrderedNamedArguments(),
       typeArgumentCount,
@@ -253,7 +252,7 @@
 
   @override
   String structureToString() {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     sb.write('arity=$argumentCount, named=[${namedArguments.join(', ')}]');
     if (typeArgumentCount != 0) {
       sb.write(', types=$typeArgumentCount');
diff --git a/pkg/compiler/lib/src/universe/class_hierarchy.dart b/pkg/compiler/lib/src/universe/class_hierarchy.dart
index d4a17ee..6ea468a 100644
--- a/pkg/compiler/lib/src/universe/class_hierarchy.dart
+++ b/pkg/compiler/lib/src/universe/class_hierarchy.dart
@@ -172,23 +172,22 @@
       DataSource source, CommonElements commonElements) {
     source.begin(tag);
     Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes =
-        new ClassHierarchyNodesMap();
+        ClassHierarchyNodesMap();
     int classCount = source.readInt();
     for (int i = 0; i < classCount; i++) {
-      ClassHierarchyNode node = new ClassHierarchyNode.readFromDataSource(
-          source, classHierarchyNodes);
+      ClassHierarchyNode node =
+          ClassHierarchyNode.readFromDataSource(source, classHierarchyNodes);
       classHierarchyNodes[node.cls] = node;
     }
     Map<ClassEntity, ClassSet> classSets = {};
     for (int i = 0; i < classCount; i++) {
       ClassSet classSet =
-          new ClassSet.readFromDataSource(source, classHierarchyNodes);
+          ClassSet.readFromDataSource(source, classHierarchyNodes);
       classSets[classSet.cls] = classSet;
     }
 
     source.end(tag);
-    return new ClassHierarchyImpl(
-        commonElements, classHierarchyNodes, classSets);
+    return ClassHierarchyImpl(commonElements, classHierarchyNodes, classSets);
   }
 
   @override
@@ -483,7 +482,7 @@
         }
         return IterationStep.CONTINUE;
       });
-      return new SubclassResult(classes);
+      return SubclassResult(classes);
     } else if (query2 == ClassQuery.SUBCLASS) {
       if (isSubtypeOf(cls2, cls1)) {
         // The subclasses of [cls2] are all subtypes of [cls1].
@@ -505,7 +504,7 @@
         }
         return IterationStep.CONTINUE;
       });
-      return new SubclassResult(classes);
+      return SubclassResult(classes);
     } else {
       if (cls1 == cls2 || isSubtypeOf(cls1, cls2)) {
         // The subtypes of [cls1] are contained within the subtypes of [cls2].
@@ -539,7 +538,7 @@
         }
         return IterationStep.CONTINUE;
       });
-      return new SubclassResult(classes);
+      return SubclassResult(classes);
     }
   }
 
@@ -555,7 +554,7 @@
 
   @override
   String dump([ClassEntity cls]) {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     if (cls != null) {
       sb.write("Classes in the closed world related to $cls:\n");
     } else {
@@ -574,7 +573,7 @@
       <ClassEntity, ClassHierarchyNode>{};
   final Map<ClassEntity, ClassSet> _classSets = <ClassEntity, ClassSet>{};
   final Map<ClassEntity, Set<ClassEntity>> mixinUses =
-      new Map<ClassEntity, Set<ClassEntity>>();
+      Map<ClassEntity, Set<ClassEntity>>();
 
   final CommonElements _commonElements;
   final ClassQueries _classQueries;
@@ -587,7 +586,7 @@
         "ClassHierarchyNode/ClassSet mismatch: "
         "${_classHierarchyNodes} vs "
         "${_classSets}");
-    return new ClassHierarchyImpl(
+    return ClassHierarchyImpl(
         _commonElements, _classHierarchyNodes, _classSets);
   }
 
@@ -602,7 +601,7 @@
       if (superclass != null) {
         parentNode = _ensureClassHierarchyNode(superclass);
       }
-      return new ClassHierarchyNode(
+      return ClassHierarchyNode(
           parentNode, cls, _classQueries.getHierarchyDepth(cls));
     });
   }
@@ -610,7 +609,7 @@
   ClassSet _ensureClassSet(ClassEntity cls) {
     return _classSets.putIfAbsent(cls, () {
       ClassHierarchyNode node = _ensureClassHierarchyNode(cls);
-      ClassSet classSet = new ClassSet(node);
+      ClassSet classSet = ClassSet(node);
 
       for (InterfaceType type in _classQueries.getSupertypes(cls)) {
         // TODO(johnniwinther): Optimization: Avoid adding [cls] to
@@ -654,7 +653,8 @@
   }
 
   void updateClassHierarchyNodeForClass(ClassEntity cls,
-      {bool directlyInstantiated: false, bool abstractlyInstantiated: false}) {
+      {bool directlyInstantiated = false,
+      bool abstractlyInstantiated = false}) {
     ClassHierarchyNode node = _ensureClassSet(cls).node;
     _updateSuperClassHierarchyNodeForClass(node);
     if (directlyInstantiated) {
@@ -669,7 +669,7 @@
     // TODO(johnniwinther): Add map restricted to live classes.
     // We don't support patch classes as mixin.
     Set<ClassEntity> users =
-        mixinUses.putIfAbsent(mixin, () => new Set<ClassEntity>());
+        mixinUses.putIfAbsent(mixin, () => Set<ClassEntity>());
     users.add(mixinApplication);
   }
 
@@ -719,7 +719,7 @@
       ClassEntity memberHoldingClass, ClassEntity thisClass) {
     _InheritedInThisClassCache cache =
         _inheritedInThisClassCacheMap[memberHoldingClass] ??=
-            new _InheritedInThisClassCache();
+            _InheritedInThisClassCache();
     return cache.isInheritedInThisClassOf(this, memberHoldingClass, thisClass);
   }
 
@@ -727,7 +727,7 @@
 
   bool isInheritedInSubtypeOf(ClassEntity x, ClassEntity y) {
     _InheritedInSubtypeCache cache =
-        _inheritedInSubtypeCacheMap[x] ??= new _InheritedInSubtypeCache();
+        _inheritedInSubtypeCacheMap[x] ??= _InheritedInSubtypeCache();
     return cache.isInheritedInSubtypeOf(this, x, y);
   }
 }
@@ -764,7 +764,7 @@
         builder._classHierarchyNodes[memberHoldingClass];
 
     if (_inheritingClasses == null) {
-      _inheritingClasses = new Set<ClassEntity>();
+      _inheritingClasses = Set<ClassEntity>();
       _inheritingClasses.addAll(memberHoldingClassNode
           .subclassesByMask(ClassHierarchyNode.ALL, strict: false));
       for (ClassHierarchyNode mixinApplication
@@ -774,7 +774,7 @@
       }
     }
 
-    Set<ClassEntity> validatingSet = new Set<ClassEntity>();
+    Set<ClassEntity> validatingSet = Set<ClassEntity>();
 
     void processHierarchy(ClassHierarchyNode mixerNode) {
       for (ClassEntity inheritingClass in _inheritingClasses) {
@@ -804,7 +804,7 @@
       processHierarchy(mixinApplication);
     }
 
-    return new _LiveSet(validatingSet);
+    return _LiveSet(validatingSet);
   }
 }
 
@@ -839,7 +839,7 @@
         failedAt(
             x, "No ClassSet for $x (${x.runtimeType}): ${builder._classSets}"));
 
-    Set<ClassEntity> classes = new Set<ClassEntity>();
+    Set<ClassEntity> classes = Set<ClassEntity>();
 
     if (builder._isSubtypeOf(x, y)) {
       // [x] implements [y] itself, possible through supertypes.
@@ -865,7 +865,7 @@
       subclassImplements(mixinApplication, strict: false);
     }
 
-    return new _LiveSet(classes);
+    return _LiveSet(classes);
   }
 }
 
@@ -990,19 +990,19 @@
   const SubclassResult.internal(this.kind) : classes = null;
 
   static const SubclassResult EMPTY =
-      const SubclassResult.internal(SubclassResultKind.EMPTY);
+      SubclassResult.internal(SubclassResultKind.EMPTY);
   static const SubclassResult EXACT1 =
-      const SubclassResult.internal(SubclassResultKind.EXACT1);
+      SubclassResult.internal(SubclassResultKind.EXACT1);
   static const SubclassResult EXACT2 =
-      const SubclassResult.internal(SubclassResultKind.EXACT2);
+      SubclassResult.internal(SubclassResultKind.EXACT2);
   static const SubclassResult SUBCLASS1 =
-      const SubclassResult.internal(SubclassResultKind.SUBCLASS1);
+      SubclassResult.internal(SubclassResultKind.SUBCLASS1);
   static const SubclassResult SUBCLASS2 =
-      const SubclassResult.internal(SubclassResultKind.SUBCLASS2);
+      SubclassResult.internal(SubclassResultKind.SUBCLASS2);
   static const SubclassResult SUBTYPE1 =
-      const SubclassResult.internal(SubclassResultKind.SUBTYPE1);
+      SubclassResult.internal(SubclassResultKind.SUBTYPE1);
   static const SubclassResult SUBTYPE2 =
-      const SubclassResult.internal(SubclassResultKind.SUBTYPE2);
+      SubclassResult.internal(SubclassResultKind.SUBTYPE2);
 
   @override
   String toString() => 'SubclassResult($kind,classes=$classes)';
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart
index a2eaee0..3a3c138 100644
--- a/pkg/compiler/lib/src/universe/class_set.dart
+++ b/pkg/compiler/lib/src/universe/class_set.dart
@@ -53,7 +53,7 @@
   /// [ClassHierarchyNode.subclassesByMask],
   /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
   static final EnumSet<Instantiation> INSTANTIATED =
-      new EnumSet<Instantiation>.fromValues(const <Instantiation>[
+      EnumSet<Instantiation>.fromValues(const <Instantiation>[
     Instantiation.DIRECTLY_INSTANTIATED,
     Instantiation.INDIRECTLY_INSTANTIATED,
     Instantiation.ABSTRACTLY_INSTANTIATED,
@@ -63,7 +63,7 @@
   /// [ClassHierarchyNode.subclassesByMask],
   /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
   static final EnumSet<Instantiation> EXPLICITLY_INSTANTIATED =
-      new EnumSet<Instantiation>.fromValues(const <Instantiation>[
+      EnumSet<Instantiation>.fromValues(const <Instantiation>[
     Instantiation.DIRECTLY_INSTANTIATED,
     Instantiation.ABSTRACTLY_INSTANTIATED
   ], fixed: true);
@@ -72,17 +72,17 @@
   /// [ClassHierarchyNode.subclassesByMask],
   /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
   static final EnumSet<Instantiation> ALL =
-      new EnumSet<Instantiation>.fromValues(Instantiation.values, fixed: true);
+      EnumSet<Instantiation>.fromValues(Instantiation.values, fixed: true);
 
   /// Creates an enum set for selecting the returned classes in
   /// [ClassHierarchyNode.subclassesByMask],
   /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
   static EnumSet<Instantiation> createMask(
-      {bool includeDirectlyInstantiated: true,
-      bool includeIndirectlyInstantiated: true,
-      bool includeUninstantiated: true,
-      bool includeAbstractlyInstantiated: true}) {
-    EnumSet<Instantiation> mask = new EnumSet<Instantiation>();
+      {bool includeDirectlyInstantiated = true,
+      bool includeIndirectlyInstantiated = true,
+      bool includeUninstantiated = true,
+      bool includeAbstractlyInstantiated = true}) {
+    EnumSet<Instantiation> mask = EnumSet<Instantiation>();
     if (includeDirectlyInstantiated) {
       mask.add(Instantiation.DIRECTLY_INSTANTIATED);
     }
@@ -99,7 +99,7 @@
   }
 
   final ClassHierarchyNode parentNode;
-  final EnumSet<Instantiation> _mask = new EnumSet<Instantiation>.fromValues(
+  final EnumSet<Instantiation> _mask = EnumSet<Instantiation>.fromValues(
       const <Instantiation>[Instantiation.UNINSTANTIATED]);
   final IndexedClass cls;
 
@@ -228,7 +228,7 @@
     int hierarchyDepth = source.readInt();
     int instantiatedSubclassCount = source.readInt();
     source.end(tag);
-    return new ClassHierarchyNode(parentNode, cls, hierarchyDepth)
+    return ClassHierarchyNode(parentNode, cls, hierarchyDepth)
       .._instantiatedSubclassCount = instantiatedSubclassCount
       .._mask.value = maskValue;
   }
@@ -279,8 +279,8 @@
   /// their corresponding [Instantiation] values in [mask]. If [strict] is
   /// `true`, [cls] itself is _not_ returned.
   Iterable<ClassEntity> subclassesByMask(EnumSet<Instantiation> mask,
-      {bool strict: false}) {
-    return new ClassHierarchyNodeIterable(this, mask, includeRoot: !strict);
+      {bool strict = false}) {
+    return ClassHierarchyNodeIterable(this, mask, includeRoot: !strict);
   }
 
   /// Applies [predicate] to each subclass of [cls] matching the criteria
@@ -291,7 +291,7 @@
   /// intersect with their corresponding [Instantiation] values in [mask]. If
   /// [strict] is `true`, [predicate] is _not_ called on [cls] itself.
   bool anySubclass(bool predicate(ClassEntity cls), EnumSet<Instantiation> mask,
-      {bool strict: false}) {
+      {bool strict = false}) {
     IterationStep wrapper(ClassEntity cls) {
       return predicate(cls) ? IterationStep.STOP : IterationStep.CONTINUE;
     }
@@ -314,7 +314,7 @@
   /// visitation was stopped, or [ForEach.CONTINUE] if visitation continued to
   /// the end.
   IterationStep forEachSubclass(ForEachFunction f, EnumSet<Instantiation> mask,
-      {bool strict: false}) {
+      {bool strict = false}) {
     IterationStep nextStep;
     if (!strict && mask.intersects(_mask)) {
       nextStep = f(cls);
@@ -374,8 +374,8 @@
   }
 
   void printOn(StringBuffer sb, String indentation,
-      {bool instantiatedOnly: false,
-      bool sorted: true,
+      {bool instantiatedOnly = false,
+      bool sorted = true,
       ClassEntity withRespectTo}) {
     bool isRelatedTo(ClassEntity _subclass) {
       return true;
@@ -439,10 +439,10 @@
   }
 
   String dump(
-      {String indentation: '',
-      bool instantiatedOnly: false,
+      {String indentation = '',
+      bool instantiatedOnly = false,
       ClassEntity withRespectTo}) {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     printOn(sb, indentation,
         instantiatedOnly: instantiatedOnly, withRespectTo: withRespectTo);
     return sb.toString();
@@ -552,7 +552,7 @@
       return nodeMap[source.readClass()];
     }, emptyAsNull: true);
     source.end(tag);
-    return new ClassSet(node)
+    return ClassSet(node)
       .._subtypes = subtypes
       .._mixinApplications = mixinApplications;
   }
@@ -633,7 +633,7 @@
   /// their corresponding [Instantiation] values in [mask]. If [strict] is
   /// `true`, [cls] itself is _not_ returned.
   Iterable<ClassEntity> subclassesByMask(EnumSet<Instantiation> mask,
-      {bool strict: false}) {
+      {bool strict = false}) {
     return node.subclassesByMask(mask, strict: strict);
   }
 
@@ -644,10 +644,10 @@
   /// [includeIndirectlyInstantiated], and [includeUninstantiated] are `true`,
   /// respectively. If [strict] is `true`, [cls] itself is _not_ returned.
   Iterable<ClassEntity> subtypes(
-      {bool includeDirectlyInstantiated: true,
-      bool includeIndirectlyInstantiated: true,
-      bool includeUninstantiated: true,
-      bool strict: false}) {
+      {bool includeDirectlyInstantiated = true,
+      bool includeIndirectlyInstantiated = true,
+      bool includeUninstantiated = true,
+      bool strict = false}) {
     EnumSet<Instantiation> mask = ClassHierarchyNode.createMask(
         includeDirectlyInstantiated: includeDirectlyInstantiated,
         includeIndirectlyInstantiated: includeIndirectlyInstantiated,
@@ -661,13 +661,12 @@
   /// their corresponding [Instantiation] values in [mask]. If [strict] is
   /// `true`, [cls] itself is _not_ returned.
   Iterable<ClassEntity> subtypesByMask(EnumSet<Instantiation> mask,
-      {bool strict: false}) {
+      {bool strict = false}) {
     if (_subtypes == null) {
       return node.subclassesByMask(mask, strict: strict);
     }
 
-    return new SubtypesIterable.SubtypesIterator(this, mask,
-        includeRoot: !strict);
+    return SubtypesIterable.SubtypesIterator(this, mask, includeRoot: !strict);
   }
 
   /// Applies [predicate] to each subclass of [cls] matching the criteria
@@ -678,7 +677,7 @@
   /// intersect with their corresponding [Instantiation] values in [mask]. If
   /// [strict] is `true`, [predicate] is _not_ called on [cls] itself.
   bool anySubclass(bool predicate(ClassEntity cls), EnumSet<Instantiation> mask,
-      {bool strict: false}) {
+      {bool strict = false}) {
     return node.anySubclass(predicate, mask, strict: strict);
   }
 
@@ -697,7 +696,7 @@
   /// visitation was stopped, or [ForEach.CONTINUE] if visitation continued to
   /// the end.
   IterationStep forEachSubclass(ForEachFunction f, EnumSet<Instantiation> mask,
-      {bool strict: false}) {
+      {bool strict = false}) {
     return node.forEachSubclass(f, mask, strict: strict);
   }
 
@@ -709,7 +708,7 @@
   /// intersect with their corresponding [Instantiation] values in [mask]. If
   /// [strict] is `true`, [predicate] is _not_ called on [cls] itself.
   bool anySubtype(bool predicate(ClassEntity cls), EnumSet<Instantiation> mask,
-      {bool strict: false}) {
+      {bool strict = false}) {
     IterationStep wrapper(ClassEntity cls) {
       return predicate(cls) ? IterationStep.STOP : IterationStep.CONTINUE;
     }
@@ -732,7 +731,7 @@
   /// visitation was stopped, or [ForEach.CONTINUE] if visitation continued to
   /// the end.
   IterationStep forEachSubtype(ForEachFunction f, EnumSet<Instantiation> mask,
-      {bool strict: false}) {
+      {bool strict = false}) {
     IterationStep nextStep =
         node.forEachSubclass(f, mask, strict: strict) ?? IterationStep.CONTINUE;
     if (nextStep == IterationStep.CONTINUE && _subtypes != null) {
@@ -844,7 +843,7 @@
 
   @override
   String toString() {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     sb.write('[\n');
     node.printOn(sb, '  ');
     sb.write('\n');
@@ -873,13 +872,13 @@
   final EnumSet<Instantiation> mask;
   final bool includeRoot;
 
-  ClassHierarchyNodeIterable(this.root, this.mask, {this.includeRoot: true}) {
-    if (root == null) throw new StateError("No root for iterable.");
+  ClassHierarchyNodeIterable(this.root, this.mask, {this.includeRoot = true}) {
+    if (root == null) throw StateError("No root for iterable.");
   }
 
   @override
   Iterator<ClassEntity> get iterator {
-    return new ClassHierarchyNodeIterator(this);
+    return ClassHierarchyNodeIterator(this);
   }
 }
 
@@ -970,10 +969,10 @@
   final bool includeRoot;
 
   SubtypesIterable.SubtypesIterator(this.subtypeSet, this.mask,
-      {this.includeRoot: true});
+      {this.includeRoot = true});
 
   @override
-  Iterator<ClassEntity> get iterator => new SubtypesIterator(this);
+  Iterator<ClassEntity> get iterator => SubtypesIterator(this);
 }
 
 /// Iterator for the subtypes in a [ClassSet].
@@ -1038,7 +1037,7 @@
 /// Visiting function used for the `forEachX` functions of [ClassHierarchyNode]
 /// and [ClassSet]. The return value controls the continued iteration. If `null`
 /// is returned, iteration continues to the end.
-typedef IterationStep ForEachFunction(ClassEntity cls);
+typedef ForEachFunction = IterationStep Function(ClassEntity cls);
 
 /// Singleton map implemented as a field on the key.
 class ClassHierarchyNodesMap extends MapBase<ClassEntity, ClassHierarchyNode> {
@@ -1048,7 +1047,7 @@
     if (cls is ClassHierarchyNodesMapKey) {
       return cls._classHierarchyNode;
     }
-    throw new UnimplementedError('ClassHierarchyNodesMap for $cls');
+    throw UnimplementedError('ClassHierarchyNodesMap for $cls');
   }
 
   @override
@@ -1058,7 +1057,7 @@
       cls._classHierarchyNode = node;
       return;
     }
-    throw new UnimplementedError('ClassHierarchyNodesMap for $cls');
+    throw UnimplementedError('ClassHierarchyNodesMap for $cls');
   }
 
   @override
@@ -1069,17 +1068,17 @@
 
   @override
   Iterable<ClassEntity> get keys {
-    throw new UnimplementedError('ClassHierarchyNodesMap.keys');
+    throw UnimplementedError('ClassHierarchyNodesMap.keys');
   }
 
   @override
   ClassHierarchyNode remove(Object key) {
-    throw new UnimplementedError('ClassHierarchyNodesMap.remove');
+    throw UnimplementedError('ClassHierarchyNodesMap.remove');
   }
 
   @override
   void clear() {
-    throw new UnimplementedError('ClassHierarchyNodesMap.clear');
+    throw UnimplementedError('ClassHierarchyNodesMap.clear');
   }
 }
 
diff --git a/pkg/compiler/lib/src/universe/codegen_world_builder.dart b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
index b63141d..d960d16 100644
--- a/pkg/compiler/lib/src/universe/codegen_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
@@ -409,7 +409,7 @@
   }
 
   void processClassMembers(ClassEntity cls, MemberUsedCallback memberUsed,
-      {bool checkEnqueuerConsistency: false}) {
+      {bool checkEnqueuerConsistency = false}) {
     _elementEnvironment.forEachClassMember(cls,
         (ClassEntity cls, MemberEntity member) {
       _processInstantiatedClassMember(cls, member, memberUsed,
@@ -419,7 +419,7 @@
 
   void _processInstantiatedClassMember(
       ClassEntity cls, MemberEntity member, MemberUsedCallback memberUsed,
-      {bool checkEnqueuerConsistency: false}) {
+      {bool checkEnqueuerConsistency = false}) {
     if (!member.isInstanceMember) return;
     EnumSet<MemberUse> useSet = EnumSet<MemberUse>();
     MemberUsage usage = _getMemberUsage(member, useSet);
@@ -434,7 +434,7 @@
   }
 
   MemberUsage _getMemberUsage(MemberEntity member, EnumSet<MemberUse> useSet,
-      {bool checkEnqueuerConsistency: false}) {
+      {bool checkEnqueuerConsistency = false}) {
     // TODO(johnniwinther): Change [TypeMask] to not apply to a superclass
     // member unless the class has been instantiated. Similar to
     // [StrongModeConstraint].
diff --git a/pkg/compiler/lib/src/universe/feature.dart b/pkg/compiler/lib/src/universe/feature.dart
index 8d8d9ba..1e1dd45 100644
--- a/pkg/compiler/lib/src/universe/feature.dart
+++ b/pkg/compiler/lib/src/universe/feature.dart
@@ -93,7 +93,7 @@
   final bool isConstant;
   final bool isEmpty;
 
-  MapLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false});
+  MapLiteralUse(this.type, {this.isConstant = false, this.isEmpty = false});
 
   @override
   int get hashCode {
@@ -123,7 +123,7 @@
   final bool isConstant;
   final bool isEmpty;
 
-  SetLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false});
+  SetLiteralUse(this.type, {this.isConstant = false, this.isEmpty = false});
 
   @override
   int get hashCode =>
@@ -149,7 +149,7 @@
   final bool isConstant;
   final bool isEmpty;
 
-  ListLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false});
+  ListLiteralUse(this.type, {this.isConstant = false, this.isEmpty = false});
 
   @override
   int get hashCode {
@@ -203,7 +203,7 @@
 
   /// Short textual representation use for testing.
   String get shortText {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     switch (kind) {
       case RuntimeTypeUseKind.string:
         sb.write('string:');
@@ -246,7 +246,7 @@
     DartType functionType = source.readDartType();
     List<DartType> typeArguments = source.readDartTypes();
     source.end(tag);
-    return new GenericInstantiation(functionType, typeArguments);
+    return GenericInstantiation(functionType, typeArguments);
   }
 
   void writeToDataSink(DataSink sink) {
diff --git a/pkg/compiler/lib/src/universe/function_set.dart b/pkg/compiler/lib/src/universe/function_set.dart
index e19991a..7c934bf 100644
--- a/pkg/compiler/lib/src/universe/function_set.dart
+++ b/pkg/compiler/lib/src/universe/function_set.dart
@@ -17,12 +17,12 @@
   final Map<String, FunctionSetNode> _nodes;
 
   factory FunctionSet(Iterable<MemberEntity> liveInstanceMembers) {
-    Map<String, FunctionSetNode> nodes = new Map<String, FunctionSetNode>();
+    Map<String, FunctionSetNode> nodes = Map<String, FunctionSetNode>();
     for (MemberEntity member in liveInstanceMembers) {
       String name = member.name;
-      (nodes[name] ??= new FunctionSetNode(name)).add(member);
+      (nodes[name] ??= FunctionSetNode(name)).add(member);
     }
-    return new FunctionSet.internal(nodes);
+    return FunctionSet.internal(nodes);
   }
 
   FunctionSet.internal(this._nodes);
@@ -58,8 +58,8 @@
   SelectorMask _createSelectorMask(
       Selector selector, AbstractValue receiver, AbstractValueDomain domain) {
     return receiver != null
-        ? new SelectorMask(selector, receiver)
-        : new SelectorMask(selector, domain.dynamicType);
+        ? SelectorMask(selector, receiver)
+        : SelectorMask(selector, domain.dynamicType);
   }
 
   /// Returns the set of functions that can be the target of a call to
@@ -70,7 +70,7 @@
     String name = selector.name;
     SelectorMask selectorMask = _createSelectorMask(selector, receiver, domain);
     SelectorMask noSuchMethodMask =
-        new SelectorMask(Selectors.noSuchMethod_, selectorMask.receiver);
+        SelectorMask(Selectors.noSuchMethod_, selectorMask.receiver);
     FunctionSetNode node = _nodes[name];
     FunctionSetNode noSuchMethods = _nodes[Identifiers.noSuchMethod_];
     if (node != null) {
@@ -215,7 +215,7 @@
           // Defer the allocation of the functions set until we are
           // sure we need it. This allows us to return immutable empty
           // lists when the filtering produced no results.
-          functions = new Setlet<MemberEntity>();
+          functions = Setlet<MemberEntity>();
         }
         functions.add(element);
       }
@@ -230,22 +230,21 @@
           noSuchMethods.query(noSuchMethodMask, domain);
       if (!noSuchMethodQuery.functions.isEmpty) {
         if (functions == null) {
-          functions =
-              new Setlet<MemberEntity>.from(noSuchMethodQuery.functions);
+          functions = Setlet<MemberEntity>.from(noSuchMethodQuery.functions);
         } else {
           functions.addAll(noSuchMethodQuery.functions);
         }
       }
     }
     cache[selectorMask] = result = (functions != null)
-        ? new FullFunctionSetQuery(functions)
+        ? FullFunctionSetQuery(functions)
         : const EmptyFunctionSetQuery();
     return result;
   }
 
   @override
   String toString() {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     sb.write('FunctionSetNode(');
     String comma = '';
     cache.forEach((mask, query) {
diff --git a/pkg/compiler/lib/src/universe/member_usage.dart b/pkg/compiler/lib/src/universe/member_usage.dart
index de26a23..591b05a 100644
--- a/pkg/compiler/lib/src/universe/member_usage.dart
+++ b/pkg/compiler/lib/src/universe/member_usage.dart
@@ -17,7 +17,7 @@
 
   AbstractUsage.cloned(this._pendingUse);
 
-  AbstractUsage() : this._pendingUse = new EnumSet<T>() {
+  AbstractUsage() : this._pendingUse = EnumSet<T>() {
     _pendingUse.addAll(_originalUse);
   }
 
@@ -41,7 +41,7 @@
 abstract class MemberUsage extends AbstractUsage<MemberUse> {
   /// Constant empty access set used as the potential access set for impossible
   /// accesses, for instance writing to a final field or invoking a setter.
-  static const EnumSet<Access> emptySet = const EnumSet.fixed(0);
+  static const EnumSet<Access> emptySet = EnumSet.fixed(0);
 
   final MemberEntity entity;
 
@@ -60,12 +60,12 @@
       }
       if (member.isTopLevel || member.isStatic || member.isConstructor) {
         // TODO(johnniwinther): Track super constructor invocations?
-        return new EnumSet.fromValues([Access.staticAccess]);
+        return EnumSet.fromValues([Access.staticAccess]);
       } else if (member.isInstanceMember) {
-        return new EnumSet.fromValues(Access.values);
+        return EnumSet.fromValues(Access.values);
       } else {
         assert(member is JRecordField, "Unexpected member: $member");
-        return new EnumSet();
+        return EnumSet();
       }
     }
 
@@ -89,33 +89,33 @@
 
     if (member.isField) {
       if (member.isAssignable) {
-        return new FieldUsage(member,
+        return FieldUsage(member,
             potentialReads: createPotentialReads(),
             potentialWrites: createPotentialWrites(),
             potentialInvokes: createPotentialInvokes());
       } else {
-        return new FieldUsage(member,
+        return FieldUsage(member,
             potentialReads: createPotentialReads(),
             potentialWrites: emptySet,
             potentialInvokes: createPotentialInvokes());
       }
     } else if (member.isGetter) {
-      return new PropertyUsage(member,
+      return PropertyUsage(member,
           potentialReads: createPotentialReads(),
           potentialWrites: emptySet,
           potentialInvokes: createPotentialInvokes());
     } else if (member.isSetter) {
-      return new PropertyUsage(member,
+      return PropertyUsage(member,
           potentialReads: emptySet,
           potentialWrites: createPotentialWrites(),
           potentialInvokes: emptySet);
     } else if (member.isConstructor) {
-      return new MethodUsage(member,
+      return MethodUsage(member,
           potentialReads: emptySet, potentialInvokes: createPotentialInvokes());
     } else {
       assert(member is FunctionEntity,
           failedAt(member, "Unexpected member: $member"));
-      return new MethodUsage(member,
+      return MethodUsage(member,
           potentialReads: createPotentialReads(),
           potentialInvokes: createPotentialInvokes());
     }
@@ -293,9 +293,9 @@
 
   PropertyUsage(MemberEntity member,
       {this.potentialReads, this.potentialWrites, this.potentialInvokes})
-      : reads = new EnumSet(),
-        writes = new EnumSet(),
-        invokes = new EnumSet(),
+      : reads = EnumSet(),
+        writes = EnumSet(),
+        invokes = EnumSet(),
         assert(potentialReads != null),
         assert(potentialWrites != null),
         assert(potentialInvokes != null),
@@ -338,7 +338,7 @@
 
   @override
   MemberUsage clone() {
-    return new PropertyUsage.cloned(entity, _pendingUse.clone(),
+    return PropertyUsage.cloned(entity, _pendingUse.clone(),
         potentialReads: potentialReads.clone(),
         potentialWrites: potentialWrites.clone(),
         potentialInvokes: potentialInvokes.clone(),
@@ -403,9 +403,9 @@
   FieldUsage(FieldEntity field,
       {this.potentialReads, this.potentialWrites, this.potentialInvokes})
       : hasInit = false,
-        reads = new EnumSet(),
-        writes = new EnumSet(),
-        invokes = new EnumSet(),
+        reads = EnumSet(),
+        writes = EnumSet(),
+        invokes = EnumSet(),
         assert(potentialReads != null),
         assert(potentialWrites != null),
         assert(potentialInvokes != null),
@@ -473,7 +473,7 @@
 
   @override
   MemberUsage clone() {
-    return new FieldUsage.cloned(entity, _pendingUse.clone(),
+    return FieldUsage.cloned(entity, _pendingUse.clone(),
         potentialReads: potentialReads.clone(),
         potentialWrites: potentialWrites.clone(),
         potentialInvokes: potentialInvokes.clone(),
@@ -522,9 +522,9 @@
 
   MethodUsage(FunctionEntity function,
       {this.potentialReads, this.potentialInvokes})
-      : reads = new EnumSet(),
-        invokes = new EnumSet(),
-        parameterUsage = new ParameterUsage(function.parameterStructure),
+      : reads = EnumSet(),
+        invokes = EnumSet(),
+        parameterUsage = ParameterUsage(function.parameterStructure),
         assert(potentialReads != null),
         assert(potentialInvokes != null),
         super.internal(function);
@@ -583,7 +583,7 @@
 
   @override
   MemberUsage clone() {
-    return new MethodUsage.cloned(
+    return MethodUsage.cloned(
         entity, parameterUsage.clone(), _pendingUse.clone(),
         reads: reads.clone(),
         potentialReads: potentialReads.clone(),
@@ -615,20 +615,18 @@
 
 /// Common [EnumSet]s used for [MemberUse].
 class MemberUses {
-  static const EnumSet<MemberUse> NONE = const EnumSet<MemberUse>.fixed(0);
-  static const EnumSet<MemberUse> NORMAL_ONLY =
-      const EnumSet<MemberUse>.fixed(1);
+  static const EnumSet<MemberUse> NONE = EnumSet<MemberUse>.fixed(0);
+  static const EnumSet<MemberUse> NORMAL_ONLY = EnumSet<MemberUse>.fixed(1);
   static const EnumSet<MemberUse> CLOSURIZE_INSTANCE_ONLY =
-      const EnumSet<MemberUse>.fixed(2);
+      EnumSet<MemberUse>.fixed(2);
   static const EnumSet<MemberUse> CLOSURIZE_STATIC_ONLY =
-      const EnumSet<MemberUse>.fixed(4);
-  static const EnumSet<MemberUse> ALL_INSTANCE =
-      const EnumSet<MemberUse>.fixed(3);
-  static const EnumSet<MemberUse> ALL_STATIC =
-      const EnumSet<MemberUse>.fixed(5);
+      EnumSet<MemberUse>.fixed(4);
+  static const EnumSet<MemberUse> ALL_INSTANCE = EnumSet<MemberUse>.fixed(3);
+  static const EnumSet<MemberUse> ALL_STATIC = EnumSet<MemberUse>.fixed(5);
 }
 
-typedef void MemberUsedCallback(MemberEntity member, EnumSet<MemberUse> useSet);
+typedef MemberUsedCallback = void Function(
+    MemberEntity member, EnumSet<MemberUse> useSet);
 
 /// Registry for the observed use of a class [entity] in the open world.
 // TODO(johnniwinther): Merge this with [InstantiationInfo].
@@ -668,15 +666,14 @@
 
 /// Common [EnumSet]s used for [ClassUse].
 class ClassUses {
-  static const EnumSet<ClassUse> NONE = const EnumSet<ClassUse>.fixed(0);
-  static const EnumSet<ClassUse> INSTANTIATED_ONLY =
-      const EnumSet<ClassUse>.fixed(1);
-  static const EnumSet<ClassUse> IMPLEMENTED_ONLY =
-      const EnumSet<ClassUse>.fixed(2);
-  static const EnumSet<ClassUse> ALL = const EnumSet<ClassUse>.fixed(3);
+  static const EnumSet<ClassUse> NONE = EnumSet<ClassUse>.fixed(0);
+  static const EnumSet<ClassUse> INSTANTIATED_ONLY = EnumSet<ClassUse>.fixed(1);
+  static const EnumSet<ClassUse> IMPLEMENTED_ONLY = EnumSet<ClassUse>.fixed(2);
+  static const EnumSet<ClassUse> ALL = EnumSet<ClassUse>.fixed(3);
 }
 
-typedef void ClassUsedCallback(ClassEntity cls, EnumSet<ClassUse> useSet);
+typedef ClassUsedCallback = void Function(
+    ClassEntity cls, EnumSet<ClassUse> useSet);
 
 /// Object used for tracking parameter use in constructor and method
 /// invocations.
@@ -712,7 +709,7 @@
         : 0;
     if (!_parameterStructure.namedParameters.isEmpty) {
       _unprovidedNamedParameters =
-          new Set<String>.from(_parameterStructure.namedParameters);
+          Set<String>.from(_parameterStructure.namedParameters);
     }
   }
 
@@ -776,7 +773,7 @@
   ParameterStructure get invokedParameters {
     if (!_hasInvoke) return null;
     if (isFullyUsed) return _parameterStructure;
-    return new ParameterStructure(
+    return ParameterStructure(
         _parameterStructure.requiredPositionalParameters,
         _providedPositionalParameters ??
             _parameterStructure.positionalParameters,
@@ -790,7 +787,7 @@
   }
 
   ParameterUsage clone() {
-    return new ParameterUsage.cloned(_parameterStructure,
+    return ParameterUsage.cloned(_parameterStructure,
         hasInvoke: _hasInvoke,
         providedPositionalParameters: _providedPositionalParameters,
         areAllTypeParametersProvided: _areAllTypeParametersProvided,
@@ -823,15 +820,15 @@
 /// Access sets used for registration of member usage.
 class Accesses {
   /// Statically bound access of a member.
-  static const EnumSet<Access> staticAccess = const EnumSet<Access>.fixed(1);
+  static const EnumSet<Access> staticAccess = EnumSet<Access>.fixed(1);
 
   /// Dynamically bound access of a member. This implies the statically bound
   /// access of the member.
-  static const EnumSet<Access> dynamicAccess = const EnumSet<Access>.fixed(3);
+  static const EnumSet<Access> dynamicAccess = EnumSet<Access>.fixed(3);
 
   /// Direct access of a super class member. This implies the statically bound
   /// access of the member.
-  static const EnumSet<Access> superAccess = const EnumSet<Access>.fixed(5);
+  static const EnumSet<Access> superAccess = EnumSet<Access>.fixed(5);
 }
 
 /// The accesses of a member collected during closed world computation.
@@ -846,11 +843,11 @@
 
   factory MemberAccess.readFromDataSource(DataSource source) {
     source.begin(tag);
-    EnumSet<Access> reads = new EnumSet.fixed(source.readInt());
-    EnumSet<Access> writes = new EnumSet.fixed(source.readInt());
-    EnumSet<Access> invokes = new EnumSet.fixed(source.readInt());
+    EnumSet<Access> reads = EnumSet.fixed(source.readInt());
+    EnumSet<Access> writes = EnumSet.fixed(source.readInt());
+    EnumSet<Access> invokes = EnumSet.fixed(source.readInt());
     source.end(tag);
-    return new MemberAccess(reads, writes, invokes);
+    return MemberAccess(reads, writes, invokes);
   }
 
   void writeToDataSink(DataSink sink) {
diff --git a/pkg/compiler/lib/src/universe/resolution_world_builder.dart b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
index 6e23c07..bd6cdc2 100644
--- a/pkg/compiler/lib/src/universe/resolution_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
@@ -71,7 +71,7 @@
   /// usage can be found. This check is performed without changing the already
   /// collected member usage.
   void processClassMembers(ClassEntity cls, MemberUsedCallback memberUsed,
-      {bool checkEnqueuerConsistency: false});
+      {bool checkEnqueuerConsistency = false});
 
   /// Applies the [dynamicUse] to applicable instance members. Calls
   /// [membersUsed] with the usage changes for each member.
@@ -119,7 +119,7 @@
 
   @override
   String toString() {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     sb.write(type);
     if (kind == Instantiation.DIRECTLY_INSTANTIATED) {
       sb.write(' directly');
@@ -201,8 +201,8 @@
       ConstructorEntity constructor, InterfaceType type, Instantiation kind) {
     instantiationMap ??= <ConstructorEntity, Set<Instance>>{};
     instantiationMap
-        .putIfAbsent(constructor, () => new Set<Instance>())
-        .add(new Instance(type, kind));
+        .putIfAbsent(constructor, () => Set<Instance>())
+        .add(Instance(type, kind));
     switch (kind) {
       case Instantiation.DIRECTLY_INSTANTIATED:
         isDirectlyInstantiated = true;
@@ -213,7 +213,7 @@
       case Instantiation.UNINSTANTIATED:
         break;
       default:
-        throw new StateError("Instantiation $kind is not allowed.");
+        throw StateError("Instantiation $kind is not allowed.");
     }
   }
 
@@ -229,7 +229,7 @@
 
   @override
   String toString() {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     sb.write('InstantiationInfo[');
     if (instantiationMap != null) {
       bool needsComma = false;
@@ -263,18 +263,17 @@
       <ClassEntity, InstantiationInfo>{};
 
   /// Classes implemented by directly instantiated classes.
-  final Set<ClassEntity> _implementedClasses = new Set<ClassEntity>();
+  final Set<ClassEntity> _implementedClasses = Set<ClassEntity>();
 
   /// The set of all referenced static fields.
   ///
   /// Invariant: Elements are declaration elements.
-  final Set<FieldEntity> _allReferencedStaticFields = new Set<FieldEntity>();
+  final Set<FieldEntity> _allReferencedStaticFields = Set<FieldEntity>();
 
   /// Documentation wanted -- johnniwinther
   ///
   /// Invariant: Elements are declaration elements.
-  final Set<FunctionEntity> _methodsNeedingSuperGetter =
-      new Set<FunctionEntity>();
+  final Set<FunctionEntity> _methodsNeedingSuperGetter = Set<FunctionEntity>();
   final Map<String, Map<Selector, SelectorConstraints>> _invokedNames =
       <String, Map<Selector, SelectorConstraints>>{};
   final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters =
@@ -311,17 +310,17 @@
   final Map<String, Set<MemberUsage>> _writableInstanceMembersByName =
       <String, Set<MemberUsage>>{};
 
-  final Set<FieldEntity> _fieldSetters = new Set<FieldEntity>();
+  final Set<FieldEntity> _fieldSetters = Set<FieldEntity>();
 
-  final Set<DartType> _isChecks = new Set<DartType>();
+  final Set<DartType> _isChecks = Set<DartType>();
   final Set<TypeVariableType> _namedTypeVariablesNewRti = {};
 
   /// Set of all closures in the program. Used by the mirror tracking system
   /// to find all live closure instances.
-  final Set<Local> _localFunctions = new Set<Local>();
+  final Set<Local> _localFunctions = Set<Local>();
 
   final Set<FunctionEntity> _closurizedMembersWithFreeTypeVariables =
-      new Set<FunctionEntity>();
+      Set<FunctionEntity>();
 
   final CompilerOptions _options;
   final ElementEnvironment _elementEnvironment;
@@ -344,13 +343,13 @@
 
   bool _closed = false;
   KClosedWorld _closedWorldCache;
-  final Set<MemberEntity> _liveInstanceMembers = new Set<MemberEntity>();
+  final Set<MemberEntity> _liveInstanceMembers = Set<MemberEntity>();
 
-  final Set<ConstantValue> _constantValues = new Set<ConstantValue>();
+  final Set<ConstantValue> _constantValues = Set<ConstantValue>();
 
-  final Set<Local> _genericLocalFunctions = new Set<Local>();
+  final Set<Local> _genericLocalFunctions = Set<Local>();
 
-  Set<MemberEntity> _processedMembers = new Set<MemberEntity>();
+  Set<MemberEntity> _processedMembers = Set<MemberEntity>();
 
   bool get isClosed => _closed;
 
@@ -403,7 +402,7 @@
   // TODO(johnniwinther): Improve semantic precision.
   @override
   Iterable<ClassEntity> get directlyInstantiatedClasses {
-    Set<ClassEntity> classes = new Set<ClassEntity>();
+    Set<ClassEntity> classes = Set<ClassEntity>();
     getInstantiationMap().forEach((ClassEntity cls, InstantiationInfo info) {
       if (info.hasInstantiation) {
         classes.add(cls);
@@ -429,7 +428,7 @@
       {ConstructorEntity constructor}) {
     ClassEntity cls = type.element;
     InstantiationInfo info =
-        _instantiationInfo.putIfAbsent(cls, () => new InstantiationInfo());
+        _instantiationInfo.putIfAbsent(cls, () => InstantiationInfo());
     Instantiation kind = Instantiation.UNINSTANTIATED;
     bool isNative = _nativeBasicData.isNativeClass(cls);
     // We can't use the closed-world assumption with native abstract
@@ -472,7 +471,7 @@
       if (selector.appliesUnnamed(member)) {
         SelectorConstraints masks = selectors[selector];
         if (masks.canHit(member, selector.memberName, this)) {
-          callStructures ??= new Set<CallStructure>();
+          callStructures ??= Set<CallStructure>();
           callStructures.add(selector.callStructure);
         }
       }
@@ -579,7 +578,7 @@
     String name = selector.name;
     Object constraint = dynamicUse.receiverConstraint;
     Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent(
-        name, () => new Maplet<Selector, SelectorConstraints>());
+        name, () => Maplet<Selector, SelectorConstraints>());
     UniverseSelectorConstraints constraints = selectors[selector];
     if (constraints == null) {
       selectors[selector] = _selectorConstraintsStrategy
@@ -618,14 +617,14 @@
     } else if (staticUse.kind == StaticUseKind.CLOSURE_CALL) {
       if (staticUse.typeArguments?.isNotEmpty ?? false) {
         registerDynamicInvocation(
-            new Selector.call(Names.call, staticUse.callStructure),
+            Selector.call(Names.call, staticUse.callStructure),
             staticUse.typeArguments);
       }
       return;
     }
 
     MemberEntity element = staticUse.element;
-    EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
+    EnumSet<MemberUse> useSet = EnumSet<MemberUse>();
     MemberUsage usage = _getMemberUsage(element, useSet);
 
     if ((element.isStatic || element.isTopLevel) && element.isField) {
@@ -706,8 +705,7 @@
   /// Called to create a [ClassUsage] for [cls].
   ///
   /// Subclasses override this to ensure needed invariants on [cls].
-  ClassUsage _createClassUsage(covariant ClassEntity cls) =>
-      new ClassUsage(cls);
+  ClassUsage _createClassUsage(covariant ClassEntity cls) => ClassUsage(cls);
 
   /// Return the canonical [ClassUsage] for [cls].
   ClassUsage _getClassUsage(ClassEntity cls) {
@@ -737,7 +735,7 @@
 
   @override
   void processClassMembers(ClassEntity cls, MemberUsedCallback memberUsed,
-      {bool checkEnqueuerConsistency: false}) {
+      {bool checkEnqueuerConsistency = false}) {
     _elementEnvironment.forEachClassMember(cls,
         (ClassEntity cls, MemberEntity member) {
       _processInstantiatedClassMember(cls, member, memberUsed,
@@ -755,8 +753,8 @@
     // [f] might add elements to [: map[memberName] :] during the loop below
     // so we create a new list for [: map[memberName] :] and prepend the
     // [remaining] members after the loop.
-    map[memberName] = new Set<MemberUsage>();
-    Set<MemberUsage> remaining = new Set<MemberUsage>();
+    map[memberName] = Set<MemberUsage>();
+    Set<MemberUsage> remaining = Set<MemberUsage>();
     for (MemberUsage usage in members) {
       if (!updateUsage(usage)) {
         remaining.add(usage);
@@ -766,7 +764,7 @@
   }
 
   MemberUsage _getMemberUsage(MemberEntity member, EnumSet<MemberUse> useSet,
-      {bool checkEnqueuerConsistency: false}) {
+      {bool checkEnqueuerConsistency = false}) {
     MemberUsage usage = _memberUsage[member];
     if (usage == null) {
       if (member.isInstanceMember) {
@@ -782,7 +780,7 @@
         // Note: this assumes that there are no non-native fields on native
         // classes, which may not be the case when a native class is subclassed.
         bool isNative = _nativeBasicData.isNativeClass(cls);
-        usage = new MemberUsage(member);
+        usage = MemberUsage(member);
         if (member.isField && !isNative) {
           useSet.addAll(usage.init());
         }
@@ -832,7 +830,7 @@
           }
         }
       } else {
-        usage = new MemberUsage(member);
+        usage = MemberUsage(member);
         if (member.isField) {
           useSet.addAll(usage.init());
         }
@@ -846,18 +844,18 @@
 
   void _processInstantiatedClassMember(
       ClassEntity cls, MemberEntity member, MemberUsedCallback memberUsed,
-      {bool checkEnqueuerConsistency: false}) {
+      {bool checkEnqueuerConsistency = false}) {
     if (!member.isInstanceMember) return;
     String memberName = member.name;
 
     MemberUsage usage = _memberUsage[member];
     if (usage == null) {
-      EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
+      EnumSet<MemberUse> useSet = EnumSet<MemberUse>();
       usage = _getMemberUsage(member, useSet,
           checkEnqueuerConsistency: checkEnqueuerConsistency);
       if (useSet.isNotEmpty) {
         if (checkEnqueuerConsistency) {
-          throw new SpannableAssertionFailure(member,
+          throw SpannableAssertionFailure(member,
               'Unenqueued usage of $member: \nbefore: <none>\nafter : $usage');
         } else {
           memberUsed(usage.entity, useSet);
@@ -869,7 +867,7 @@
         usage = usage.clone();
       }
       if (usage.hasPendingDynamicUse) {
-        EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
+        EnumSet<MemberUse> useSet = EnumSet<MemberUse>();
         if (usage.hasPendingDynamicRead && _hasInvokedGetter(member)) {
           useSet.addAll(usage.read(Accesses.dynamicAccess));
         }
@@ -922,7 +920,7 @@
 
   Map<ClassEntity, Set<ClassEntity>> populateHierarchyNodes() {
     Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses =
-        new Map<ClassEntity, Set<ClassEntity>>();
+        Map<ClassEntity, Set<ClassEntity>>();
 
     // Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated`
     // properties of the [ClassHierarchyNode] for [cls].
@@ -941,7 +939,7 @@
       while (superclass != null) {
         Set<ClassEntity> typesImplementedBySubclassesOfCls =
             typesImplementedBySubclasses.putIfAbsent(
-                superclass, () => new Set<ClassEntity>());
+                superclass, () => Set<ClassEntity>());
         for (InterfaceType current in _classQueries.getSupertypes(cls)) {
           typesImplementedBySubclassesOfCls.add(current.element);
         }
@@ -959,7 +957,7 @@
   }
 
   Iterable<MemberEntity> computeAssignedInstanceMembers() {
-    Set<MemberEntity> assignedInstanceMembers = new Set<MemberEntity>();
+    Set<MemberEntity> assignedInstanceMembers = Set<MemberEntity>();
     for (MemberEntity instanceMember in _liveInstanceMembers) {
       if (_hasInvokedSetter(instanceMember)) {
         assignedInstanceMembers.add(instanceMember);
@@ -1000,7 +998,7 @@
         return _classHierarchyBuilder.isInheritedInSubtypeOf(
             memberHoldingClass, type);
     }
-    throw new UnsupportedError("Unexpected ClassRelation $relation.");
+    throw UnsupportedError("Unexpected ClassRelation $relation.");
   }
 
   @override
@@ -1027,7 +1025,7 @@
           "Member $member is processed but has not usage.");
     }
 
-    Set<InterfaceType> instantiatedTypes = new Set<InterfaceType>();
+    Set<InterfaceType> instantiatedTypes = Set<InterfaceType>();
     getInstantiationMap().forEach((_, InstantiationInfo info) {
       if (info.instantiationMap != null) {
         for (Set<Instance> instances in info.instantiationMap.values) {
@@ -1038,7 +1036,7 @@
       }
     });
 
-    KClosedWorld closedWorld = new KClosedWorldImpl(_elementMap,
+    KClosedWorld closedWorld = KClosedWorldImpl(_elementMap,
         options: _options,
         elementEnvironment: _elementEnvironment,
         dartTypes: _dartTypes,
diff --git a/pkg/compiler/lib/src/universe/selector.dart b/pkg/compiler/lib/src/universe/selector.dart
index 20f8391..b66d87c 100644
--- a/pkg/compiler/lib/src/universe/selector.dart
+++ b/pkg/compiler/lib/src/universe/selector.dart
@@ -21,12 +21,12 @@
   final int hashCode;
   const SelectorKind(this.name, this.hashCode);
 
-  static const SelectorKind GETTER = const SelectorKind('getter', 0);
-  static const SelectorKind SETTER = const SelectorKind('setter', 1);
-  static const SelectorKind CALL = const SelectorKind('call', 2);
-  static const SelectorKind OPERATOR = const SelectorKind('operator', 3);
-  static const SelectorKind INDEX = const SelectorKind('index', 4);
-  static const SelectorKind SPECIAL = const SelectorKind('special', 5);
+  static const SelectorKind GETTER = SelectorKind('getter', 0);
+  static const SelectorKind SETTER = SelectorKind('setter', 1);
+  static const SelectorKind CALL = SelectorKind('call', 2);
+  static const SelectorKind OPERATOR = SelectorKind('operator', 3);
+  static const SelectorKind INDEX = SelectorKind('index', 4);
+  static const SelectorKind SPECIAL = SelectorKind('special', 5);
 
   int get index => hashCode;
 
@@ -104,7 +104,7 @@
 
   // TODO(johnniwinther): Extract caching.
   static Map<int, List<Selector>> canonicalizedValues =
-      new Map<int, List<Selector>>();
+      Map<int, List<Selector>>();
 
   factory Selector(SelectorKind kind, Name name, CallStructure callStructure) {
     // TODO(johnniwinther): Maybe use equality instead of implicit hashing.
@@ -118,8 +118,7 @@
         return existing;
       }
     }
-    Selector result =
-        new Selector.internal(kind, name, callStructure, hashCode);
+    Selector result = Selector.internal(kind, name, callStructure, hashCode);
     list.add(result);
     return result;
   }
@@ -129,77 +128,76 @@
     if (element.isFunction) {
       FunctionEntity function = element;
       if (name == Names.INDEX_NAME) {
-        return new Selector.index();
+        return Selector.index();
       } else if (name == Names.INDEX_SET_NAME) {
-        return new Selector.indexSet();
+        return Selector.indexSet();
       }
       CallStructure callStructure = function.parameterStructure.callStructure;
       if (isOperatorName(element.name)) {
         // Operators cannot have named arguments, however, that doesn't prevent
         // a user from declaring such an operator.
-        return new Selector(SelectorKind.OPERATOR, name, callStructure);
+        return Selector(SelectorKind.OPERATOR, name, callStructure);
       } else {
-        return new Selector.call(name, callStructure);
+        return Selector.call(name, callStructure);
       }
     } else if (element.isSetter) {
-      return new Selector.setter(name);
+      return Selector.setter(name);
     } else if (element.isGetter) {
-      return new Selector.getter(name);
+      return Selector.getter(name);
     } else if (element.isField) {
-      return new Selector.getter(name);
+      return Selector.getter(name);
     } else if (element.isConstructor) {
-      return new Selector.callConstructor(name);
+      return Selector.callConstructor(name);
     } else {
       throw failedAt(element, "Can't get selector from $element");
     }
   }
 
   factory Selector.getter(Name name) =>
-      new Selector(SelectorKind.GETTER, name.getter, CallStructure.NO_ARGS);
+      Selector(SelectorKind.GETTER, name.getter, CallStructure.NO_ARGS);
 
   factory Selector.setter(Name name) =>
-      new Selector(SelectorKind.SETTER, name.setter, CallStructure.ONE_ARG);
+      Selector(SelectorKind.SETTER, name.setter, CallStructure.ONE_ARG);
 
-  factory Selector.unaryOperator(String name) => new Selector(
+  factory Selector.unaryOperator(String name) => Selector(
       SelectorKind.OPERATOR,
-      new PublicName(utils.constructOperatorName(name, true)),
+      PublicName(utils.constructOperatorName(name, true)),
       CallStructure.NO_ARGS);
 
-  factory Selector.binaryOperator(String name) => new Selector(
+  factory Selector.binaryOperator(String name) => Selector(
       SelectorKind.OPERATOR,
-      new PublicName(utils.constructOperatorName(name, false)),
+      PublicName(utils.constructOperatorName(name, false)),
       CallStructure.ONE_ARG);
 
   factory Selector.index() =>
-      new Selector(SelectorKind.INDEX, Names.INDEX_NAME, CallStructure.ONE_ARG);
+      Selector(SelectorKind.INDEX, Names.INDEX_NAME, CallStructure.ONE_ARG);
 
-  factory Selector.indexSet() => new Selector(
+  factory Selector.indexSet() => Selector(
       SelectorKind.INDEX, Names.INDEX_SET_NAME, CallStructure.TWO_ARGS);
 
   factory Selector.call(Name name, CallStructure callStructure) =>
-      new Selector(SelectorKind.CALL, name, callStructure);
+      Selector(SelectorKind.CALL, name, callStructure);
 
   factory Selector.callClosure(int arity,
           [List<String> namedArguments, int typeArgumentCount = 0]) =>
-      new Selector(SelectorKind.CALL, Names.call,
-          new CallStructure(arity, namedArguments, typeArgumentCount));
+      Selector(SelectorKind.CALL, Names.call,
+          CallStructure(arity, namedArguments, typeArgumentCount));
 
   factory Selector.callClosureFrom(Selector selector) =>
-      new Selector(SelectorKind.CALL, Names.call, selector.callStructure);
+      Selector(SelectorKind.CALL, Names.call, selector.callStructure);
 
   factory Selector.callConstructor(Name name,
           [int arity = 0, List<String> namedArguments]) =>
-      new Selector(
-          SelectorKind.CALL, name, new CallStructure(arity, namedArguments));
+      Selector(SelectorKind.CALL, name, CallStructure(arity, namedArguments));
 
-  factory Selector.callDefaultConstructor() => new Selector(
-      SelectorKind.CALL, const PublicName(''), CallStructure.NO_ARGS);
+  factory Selector.callDefaultConstructor() =>
+      Selector(SelectorKind.CALL, const PublicName(''), CallStructure.NO_ARGS);
 
   // TODO(31953): Remove this if we can implement via static calls.
-  factory Selector.genericInstantiation(int typeArguments) => new Selector(
+  factory Selector.genericInstantiation(int typeArguments) => Selector(
       SelectorKind.SPECIAL,
       Names.genericInstantiation,
-      new CallStructure(0, null, typeArguments));
+      CallStructure(0, null, typeArguments));
 
   /// Deserializes a [Selector] object from [source].
   factory Selector.readFromDataSource(DataSource source) {
@@ -208,10 +206,10 @@
     bool isSetter = source.readBool();
     LibraryEntity library = source.readLibraryOrNull();
     String text = source.readString();
-    CallStructure callStructure = new CallStructure.readFromDataSource(source);
+    CallStructure callStructure = CallStructure.readFromDataSource(source);
     source.end(tag);
-    return new Selector(
-        kind, new Name(text, library, isSetter: isSetter), callStructure);
+    return Selector(
+        kind, Name(text, library, isSetter: isSetter), callStructure);
   }
 
   /// Serializes this [Selector] to [sink].
@@ -322,14 +320,14 @@
   // especially where selectors are used in sets or as keys in maps.
   Selector toNormalized() => callStructure.isNormalized
       ? this
-      : new Selector(kind, memberName, callStructure.toNormalized());
+      : Selector(kind, memberName, callStructure.toNormalized());
 
-  Selector toCallSelector() => new Selector.callClosureFrom(this);
+  Selector toCallSelector() => Selector.callClosureFrom(this);
 
   /// Returns the non-generic [Selector] corresponding to this selector.
   Selector toNonGeneric() {
     return callStructure.typeArgumentCount > 0
-        ? new Selector(kind, memberName, callStructure.nonGeneric)
+        ? Selector(kind, memberName, callStructure.nonGeneric)
         : this;
   }
 }
diff --git a/pkg/compiler/lib/src/universe/side_effects.dart b/pkg/compiler/lib/src/universe/side_effects.dart
index 2a63070..963b52c 100644
--- a/pkg/compiler/lib/src/universe/side_effects.dart
+++ b/pkg/compiler/lib/src/universe/side_effects.dart
@@ -47,7 +47,7 @@
     source.begin(tag);
     int flags = source.readInt();
     source.end(tag);
-    return new SideEffects.fromFlags(flags);
+    return SideEffects.fromFlags(flags);
   }
 
   /// Serializes this [SideEffects] to [sink].
@@ -61,7 +61,7 @@
   bool operator ==(other) => _flags == other._flags;
 
   @override
-  int get hashCode => throw new UnsupportedError('SideEffects.hashCode');
+  int get hashCode => throw UnsupportedError('SideEffects.hashCode');
 
   bool _getFlag(int position) {
     return (_flags & (1 << position)) != 0;
@@ -204,7 +204,7 @@
 
   @override
   String toString() {
-    StringBuffer buffer = new StringBuffer();
+    StringBuffer buffer = StringBuffer();
     buffer.write('SideEffects(reads');
     if (!dependsOnSomething()) {
       buffer.write(' nothing');
@@ -254,7 +254,7 @@
 
 class SideEffectsBuilder {
   final MemberEntity _member;
-  final SideEffects _sideEffects = new SideEffects.empty();
+  final SideEffects _sideEffects = SideEffects.empty();
   final bool _free;
   Set<SideEffectsBuilder> _depending;
 
@@ -295,7 +295,7 @@
 
   void addInput(SideEffectsBuilder input) {
     if (_free) return;
-    (input._depending ??= new Set<SideEffectsBuilder>()).add(this);
+    (input._depending ??= Set<SideEffectsBuilder>()).add(this);
   }
 
   bool add(SideEffects input) {
@@ -312,7 +312,7 @@
 
   @override
   String toString() {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     sb.write('SideEffectsBuilder(member=$member,');
     sb.write('free=$_free,');
     sb.write('sideEffects=$sideEffects,');
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index 3480869..f213d7a 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -69,7 +69,7 @@
     }
     List<DartType> typeArguments = source.readDartTypes(emptyAsNull: true);
     source.end(tag);
-    return new DynamicUse(selector, receiverConstraint, typeArguments);
+    return DynamicUse(selector, receiverConstraint, typeArguments);
   }
 
   void writeToDataSink(DataSink sink) {
@@ -80,7 +80,7 @@
       if (receiverConstraint is AbstractValue) {
         sink.writeAbstractValue(receiverConstraint);
       } else {
-        throw new UnsupportedError(
+        throw UnsupportedError(
             "Unsupported receiver constraint: ${receiverConstraint}");
       }
     }
@@ -90,7 +90,7 @@
 
   /// Short textual representation use for testing.
   String get shortText {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     if (receiverConstraint != null) {
       var constraint = receiverConstraint;
       if (constraint is StrongModeConstraint) {
@@ -226,7 +226,7 @@
     ConstantValue constant = source.readConstantOrNull();
     List<DartType> typeArguments = source.readDartTypes(emptyAsNull: true);
     source.end(tag);
-    return new StaticUse.internal(element, kind,
+    return StaticUse.internal(element, kind,
         type: type,
         callStructure: callStructure,
         deferredImport: deferredImport,
@@ -250,7 +250,7 @@
 
   /// Short textual representation use for testing.
   String get shortText {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     switch (kind) {
       case StaticUseKind.INSTANCE_FIELD_SET:
       case StaticUseKind.SUPER_FIELD_SET:
@@ -322,7 +322,7 @@
         failedAt(element,
             "Not CallStructure for static invocation of element $element."));
 
-    StaticUse staticUse = new StaticUse.internal(
+    StaticUse staticUse = StaticUse.internal(
         element, StaticUseKind.STATIC_INVOKE,
         callStructure: callStructure,
         typeArguments: typeArguments,
@@ -342,7 +342,7 @@
             "or static method."));
     assert(element.isFunction,
         failedAt(element, "Static get element $element must be a function."));
-    return new StaticUse.internal(element, StaticUseKind.STATIC_TEAR_OFF,
+    return StaticUse.internal(element, StaticUseKind.STATIC_TEAR_OFF,
         deferredImport: deferredImport);
   }
 
@@ -359,7 +359,7 @@
         element.isField || element.isGetter,
         failedAt(element,
             "Static get element $element must be a field or a getter."));
-    return new StaticUse.internal(element, StaticUseKind.STATIC_GET,
+    return StaticUse.internal(element, StaticUseKind.STATIC_GET,
         deferredImport: deferredImport);
   }
 
@@ -376,7 +376,7 @@
         (element.isField && element.isAssignable) || element.isSetter,
         failedAt(element,
             "Static set element $element must be a field or a setter."));
-    return new StaticUse.internal(element, StaticUseKind.STATIC_SET,
+    return StaticUse.internal(element, StaticUseKind.STATIC_SET,
         deferredImport: deferredImport);
   }
 
@@ -391,7 +391,7 @@
             "or static method."));
     assert(element.isField,
         failedAt(element, "Static init element $element must be a field."));
-    return new StaticUse.internal(element, StaticUseKind.FIELD_INIT);
+    return StaticUse.internal(element, StaticUseKind.FIELD_INIT);
   }
 
   /// Invocation of a super method [element] with the given [callStructure].
@@ -406,7 +406,7 @@
         callStructure != null,
         failedAt(element,
             "Not CallStructure for super invocation of element $element."));
-    StaticUse staticUse = new StaticUse.internal(
+    StaticUse staticUse = StaticUse.internal(
         element, StaticUseKind.SUPER_INVOKE,
         callStructure: callStructure, typeArguments: typeArguments);
     assert(staticUse._checkGenericInvariants());
@@ -423,7 +423,7 @@
         element.isField || element.isGetter,
         failedAt(element,
             "Super get element $element must be a field or a getter."));
-    return new StaticUse.internal(element, StaticUseKind.SUPER_GET);
+    return StaticUse.internal(element, StaticUseKind.SUPER_GET);
   }
 
   /// Write access of a super field [element].
@@ -434,7 +434,7 @@
             element, "Super set element $element must be an instance method."));
     assert(element.isField,
         failedAt(element, "Super set element $element must be a field."));
-    return new StaticUse.internal(element, StaticUseKind.SUPER_FIELD_SET);
+    return StaticUse.internal(element, StaticUseKind.SUPER_FIELD_SET);
   }
 
   /// Write access of a super setter [element].
@@ -445,7 +445,7 @@
             element, "Super set element $element must be an instance method."));
     assert(element.isSetter,
         failedAt(element, "Super set element $element must be a setter."));
-    return new StaticUse.internal(element, StaticUseKind.SUPER_SETTER_SET);
+    return StaticUse.internal(element, StaticUseKind.SUPER_SETTER_SET);
   }
 
   /// Closurization of a super method [element].
@@ -454,7 +454,7 @@
         element.isInstanceMember && element.isFunction,
         failedAt(element,
             "Super invoke element $element must be an instance method."));
-    return new StaticUse.internal(element, StaticUseKind.SUPER_TEAR_OFF);
+    return StaticUse.internal(element, StaticUseKind.SUPER_TEAR_OFF);
   }
 
   /// Invocation of a constructor [element] through a this or super
@@ -473,7 +473,7 @@
             element,
             "Not CallStructure for super constructor invocation of element "
             "$element."));
-    return new StaticUse.internal(element, StaticUseKind.STATIC_INVOKE,
+    return StaticUse.internal(element, StaticUseKind.STATIC_INVOKE,
         callStructure: callStructure);
   }
 
@@ -487,14 +487,14 @@
             element,
             "Not CallStructure for constructor body invocation of element "
             "$element."));
-    return new StaticUse.internal(element, StaticUseKind.STATIC_INVOKE,
+    return StaticUse.internal(element, StaticUseKind.STATIC_INVOKE,
         callStructure: callStructure);
   }
 
   /// Direct invocation of a generator (body) [element], as a static call or
   /// through a this or super constructor call.
   factory StaticUse.generatorBodyInvoke(FunctionEntity element) {
-    return new StaticUse.internal(element, StaticUseKind.STATIC_INVOKE,
+    return StaticUse.internal(element, StaticUseKind.STATIC_INVOKE,
         callStructure: CallStructure.NO_ARGS);
   }
 
@@ -507,7 +507,7 @@
             "Direct invoke element $element must be an instance member."));
     assert(element.isFunction,
         failedAt(element, "Direct invoke element $element must be a method."));
-    StaticUse staticUse = new StaticUse.internal(
+    StaticUse staticUse = StaticUse.internal(
         element, StaticUseKind.DIRECT_INVOKE,
         callStructure: callStructure, typeArguments: typeArguments);
     assert(staticUse._checkGenericInvariants());
@@ -524,7 +524,7 @@
         element.isField || element.isGetter,
         failedAt(element,
             "Direct get element $element must be a field or a getter."));
-    return new StaticUse.internal(element, StaticUseKind.STATIC_GET);
+    return StaticUse.internal(element, StaticUseKind.STATIC_GET);
   }
 
   /// Direct write access of a field [element].
@@ -535,7 +535,7 @@
             "Direct set element $element must be an instance member."));
     assert(element.isField,
         failedAt(element, "Direct set element $element must be a field."));
-    return new StaticUse.internal(element, StaticUseKind.STATIC_SET);
+    return StaticUse.internal(element, StaticUseKind.STATIC_SET);
   }
 
   /// Constructor invocation of [element] with the given [callStructure].
@@ -551,7 +551,7 @@
             element,
             "Not CallStructure for constructor invocation of element "
             "$element."));
-    return new StaticUse.internal(element, StaticUseKind.STATIC_INVOKE,
+    return StaticUse.internal(element, StaticUseKind.STATIC_INVOKE,
         callStructure: callStructure);
   }
 
@@ -570,7 +570,7 @@
             element,
             "Typed constructor invocation element $element "
             "must be a constructor."));
-    return new StaticUse.internal(element, StaticUseKind.CONSTRUCTOR_INVOKE,
+    return StaticUse.internal(element, StaticUseKind.CONSTRUCTOR_INVOKE,
         type: type,
         callStructure: callStructure,
         deferredImport: deferredImport);
@@ -591,8 +591,7 @@
             element,
             "Const constructor invocation element $element "
             "must be a constructor."));
-    return new StaticUse.internal(
-        element, StaticUseKind.CONST_CONSTRUCTOR_INVOKE,
+    return StaticUse.internal(element, StaticUseKind.CONST_CONSTRUCTOR_INVOKE,
         type: type,
         callStructure: callStructure,
         deferredImport: deferredImport);
@@ -604,7 +603,7 @@
         element.isInstanceMember,
         failedAt(
             element, "Field init element $element must be an instance field."));
-    return new StaticUse.internal(element, StaticUseKind.FIELD_INIT);
+    return StaticUse.internal(element, StaticUseKind.FIELD_INIT);
   }
 
   /// Constant initialization of an instance field [element].
@@ -614,7 +613,7 @@
         element.isInstanceMember,
         failedAt(
             element, "Field init element $element must be an instance field."));
-    return new StaticUse.internal(element, StaticUseKind.FIELD_CONSTANT_INIT,
+    return StaticUse.internal(element, StaticUseKind.FIELD_CONSTANT_INIT,
         constant: constant);
   }
 
@@ -624,7 +623,7 @@
         element.isInstanceMember || element is JRecordField,
         failedAt(element,
             "Field init element $element must be an instance or boxed field."));
-    return new StaticUse.internal(element, StaticUseKind.INSTANCE_FIELD_GET);
+    return StaticUse.internal(element, StaticUseKind.INSTANCE_FIELD_GET);
   }
 
   /// Write access of an instance field or boxed field [element].
@@ -633,19 +632,19 @@
         element.isInstanceMember || element is JRecordField,
         failedAt(element,
             "Field init element $element must be an instance or boxed field."));
-    return new StaticUse.internal(element, StaticUseKind.INSTANCE_FIELD_SET);
+    return StaticUse.internal(element, StaticUseKind.INSTANCE_FIELD_SET);
   }
 
   /// Read of a local function [element].
   factory StaticUse.closure(Local element) {
-    return new StaticUse.internal(element, StaticUseKind.CLOSURE);
+    return StaticUse.internal(element, StaticUseKind.CLOSURE);
   }
 
   /// An invocation of a local function [element] with the provided
   /// [callStructure] and [typeArguments].
   factory StaticUse.closureCall(Local element, CallStructure callStructure,
       List<DartType> typeArguments) {
-    StaticUse staticUse = new StaticUse.internal(
+    StaticUse staticUse = StaticUse.internal(
         element, StaticUseKind.CLOSURE_CALL,
         callStructure: callStructure, typeArguments: typeArguments);
     assert(staticUse._checkGenericInvariants());
@@ -654,27 +653,27 @@
 
   /// Read of a call [method] on a closureClass.
   factory StaticUse.callMethod(FunctionEntity method) {
-    return new StaticUse.internal(method, StaticUseKind.CALL_METHOD);
+    return StaticUse.internal(method, StaticUseKind.CALL_METHOD);
   }
 
   /// Implicit method/constructor invocation of [element] created by the
   /// backend.
   factory StaticUse.implicitInvoke(FunctionEntity element) {
-    return new StaticUse.internal(element, StaticUseKind.STATIC_INVOKE,
+    return StaticUse.internal(element, StaticUseKind.STATIC_INVOKE,
         callStructure: element.parameterStructure.callStructure);
   }
 
   /// Inlining of [element].
   factory StaticUse.constructorInlining(
       ConstructorEntity element, InterfaceType instanceType) {
-    return new StaticUse.internal(element, StaticUseKind.INLINING,
+    return StaticUse.internal(element, StaticUseKind.INLINING,
         type: instanceType);
   }
 
   /// Inlining of [element].
   factory StaticUse.methodInlining(
       FunctionEntity element, List<DartType> typeArguments) {
-    return new StaticUse.internal(element, StaticUseKind.INLINING,
+    return StaticUse.internal(element, StaticUseKind.INLINING,
         typeArguments: typeArguments);
   }
 
@@ -734,7 +733,7 @@
     TypeUseKind kind = source.readEnum(TypeUseKind.values);
     ImportEntity deferredImport = source.readImportOrNull();
     source.end(tag);
-    return new TypeUse.internal(type, kind, deferredImport);
+    return TypeUse.internal(type, kind, deferredImport);
   }
 
   void writeToDataSink(DataSink sink) {
@@ -747,7 +746,7 @@
 
   /// Short textual representation use for testing.
   String get shortText {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     switch (kind) {
       case TypeUseKind.IS_CHECK:
         sb.write('is:');
@@ -803,12 +802,12 @@
 
   /// [type] used in an is check, like `e is T` or `e is! T`.
   factory TypeUse.isCheck(DartType type) {
-    return new TypeUse.internal(type, TypeUseKind.IS_CHECK);
+    return TypeUse.internal(type, TypeUseKind.IS_CHECK);
   }
 
   /// [type] used in an as cast, like `e as T`.
   factory TypeUse.asCast(DartType type) {
-    return new TypeUse.internal(type, TypeUseKind.AS_CAST);
+    return TypeUse.internal(type, TypeUseKind.AS_CAST);
   }
 
   /// [type] used as a parameter type or field type in Dart 2, like `T` in:
@@ -817,7 +816,7 @@
   ///    T field;
   ///
   factory TypeUse.parameterCheck(DartType type) {
-    return new TypeUse.internal(type, TypeUseKind.PARAMETER_CHECK);
+    return TypeUse.internal(type, TypeUseKind.PARAMETER_CHECK);
   }
 
   /// [type] used in an implicit cast in Dart 2, like `T` in
@@ -826,44 +825,44 @@
   ///    T bar = foo; // Implicitly `T bar = foo as T`.
   ///
   factory TypeUse.implicitCast(DartType type) {
-    return new TypeUse.internal(type, TypeUseKind.IMPLICIT_CAST);
+    return TypeUse.internal(type, TypeUseKind.IMPLICIT_CAST);
   }
 
   /// [type] used in a on type catch clause, like `try {} on T catch (e) {}`.
   factory TypeUse.catchType(DartType type) {
-    return new TypeUse.internal(type, TypeUseKind.CATCH_TYPE);
+    return TypeUse.internal(type, TypeUseKind.CATCH_TYPE);
   }
 
   /// [type] used as a type literal, like `foo() => T;`.
   factory TypeUse.typeLiteral(DartType type, ImportEntity deferredImport) {
-    return new TypeUse.internal(type, TypeUseKind.TYPE_LITERAL, deferredImport);
+    return TypeUse.internal(type, TypeUseKind.TYPE_LITERAL, deferredImport);
   }
 
   /// [type] used in an instantiation, like `new T();`.
   factory TypeUse.instantiation(InterfaceType type) {
-    return new TypeUse.internal(type, TypeUseKind.INSTANTIATION);
+    return TypeUse.internal(type, TypeUseKind.INSTANTIATION);
   }
 
   /// [type] used in a constant instantiation, like `const T();`.
   factory TypeUse.constInstantiation(
       InterfaceType type, ImportEntity deferredImport) {
-    return new TypeUse.internal(
+    return TypeUse.internal(
         type, TypeUseKind.CONST_INSTANTIATION, deferredImport);
   }
 
   /// [type] used in a native instantiation.
   factory TypeUse.nativeInstantiation(InterfaceType type) {
-    return new TypeUse.internal(type, TypeUseKind.NATIVE_INSTANTIATION);
+    return TypeUse.internal(type, TypeUseKind.NATIVE_INSTANTIATION);
   }
 
   /// [type] used as a direct RTI value.
   factory TypeUse.constTypeLiteral(DartType type) {
-    return new TypeUse.internal(type, TypeUseKind.RTI_VALUE);
+    return TypeUse.internal(type, TypeUseKind.RTI_VALUE);
   }
 
   /// [type] constructor used, for example in a `instanceof` check.
   factory TypeUse.constructorReference(DartType type) {
-    return new TypeUse.internal(type, TypeUseKind.CONSTRUCTOR_REFERENCE);
+    return TypeUse.internal(type, TypeUseKind.CONSTRUCTOR_REFERENCE);
   }
 
   /// [type] used directly as a type argument.
@@ -871,7 +870,7 @@
   /// The happens during optimization where a type variable can be replaced by
   /// an invariable type argument derived from a constant receiver.
   factory TypeUse.typeArgument(DartType type) {
-    return new TypeUse.internal(type, TypeUseKind.TYPE_ARGUMENT);
+    return TypeUse.internal(type, TypeUseKind.TYPE_ARGUMENT);
   }
 
   /// [type] used as a named type variable in a recipe.
@@ -905,7 +904,7 @@
     source.begin(tag);
     ConstantValue value = source.readConstant();
     source.end(tag);
-    return new ConstantUse._(value);
+    return ConstantUse._(value);
   }
 
   void writeToDataSink(DataSink sink) {
diff --git a/pkg/compiler/lib/src/universe/world_builder.dart b/pkg/compiler/lib/src/universe/world_builder.dart
index 3a91904..7ddd42e 100644
--- a/pkg/compiler/lib/src/universe/world_builder.dart
+++ b/pkg/compiler/lib/src/universe/world_builder.dart
@@ -94,7 +94,7 @@
   @override
   StrongModeWorldConstraints createSelectorConstraints(
       Selector selector, Object initialConstraint) {
-    return new StrongModeWorldConstraints()
+    return StrongModeWorldConstraints()
       ..addReceiverConstraint(initialConstraint);
   }
 
@@ -148,7 +148,7 @@
       _constraints = null;
       return true;
     }
-    _constraints ??= new Set<StrongModeConstraint>();
+    _constraints ??= Set<StrongModeConstraint>();
     return _constraints.add(constraint);
   }
 
@@ -177,7 +177,7 @@
       cls = commonElements.jsJavaScriptObjectClass;
       relation = ClassRelation.subtype;
     }
-    return new StrongModeConstraint.internal(cls, relation);
+    return StrongModeConstraint.internal(cls, relation);
   }
 
   const StrongModeConstraint.internal(this.cls, this.relation);
@@ -227,20 +227,20 @@
       <Selector, Set<DartType>>{};
 
   final Set<TypeVariableType> typeVariableTypeLiterals =
-      new Set<TypeVariableType>();
+      Set<TypeVariableType>();
 
   void _registerStaticTypeArgumentDependency(
       Entity element, List<DartType> typeArguments) {
-    staticTypeArgumentDependencies.putIfAbsent(
-        element, () => new Set<DartType>())
-      ..addAll(typeArguments);
+    staticTypeArgumentDependencies
+        .putIfAbsent(element, () => Set<DartType>())
+        .addAll(typeArguments);
   }
 
   void _registerDynamicTypeArgumentDependency(
       Selector selector, List<DartType> typeArguments) {
-    dynamicTypeArgumentDependencies.putIfAbsent(
-        selector, () => new Set<DartType>())
-      ..addAll(typeArguments);
+    dynamicTypeArgumentDependencies
+        .putIfAbsent(selector, () => Set<DartType>())
+        .addAll(typeArguments);
   }
 
   void registerStaticInvocation(StaticUse staticUse) {
diff --git a/pkg/compiler/lib/src/universe/world_impact.dart b/pkg/compiler/lib/src/universe/world_impact.dart
index b7cdac8..85b9bb0 100644
--- a/pkg/compiler/lib/src/universe/world_impact.dart
+++ b/pkg/compiler/lib/src/universe/world_impact.dart
@@ -52,7 +52,7 @@
   String toString() => dump(this);
 
   static String dump(WorldImpact worldImpact) {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     printOn(sb, worldImpact);
     return sb.toString();
   }
@@ -113,7 +113,7 @@
   @override
   void registerDynamicUse(DynamicUse dynamicUse) {
     assert(dynamicUse != null);
-    _dynamicUses ??= new Setlet<DynamicUse>();
+    _dynamicUses ??= Setlet<DynamicUse>();
     _dynamicUses.add(dynamicUse);
   }
 
@@ -125,7 +125,7 @@
   @override
   void registerTypeUse(TypeUse typeUse) {
     assert(typeUse != null);
-    _typeUses ??= new Setlet<TypeUse>();
+    _typeUses ??= Setlet<TypeUse>();
     _typeUses.add(typeUse);
   }
 
@@ -137,7 +137,7 @@
   @override
   void registerStaticUse(StaticUse staticUse) {
     assert(staticUse != null);
-    _staticUses ??= new Setlet<StaticUse>();
+    _staticUses ??= Setlet<StaticUse>();
     _staticUses.add(staticUse);
   }
 
@@ -149,7 +149,7 @@
   @override
   void registerConstantUse(ConstantUse constantUse) {
     assert(constantUse != null);
-    _constantUses ??= new Setlet<ConstantUse>();
+    _constantUses ??= Setlet<ConstantUse>();
     _constantUses.add(constantUse);
   }
 
@@ -166,11 +166,11 @@
   WorldImpactBuilderImpl _currentBuilder;
   List<WorldImpactBuilderImpl> _builders = <WorldImpactBuilderImpl>[];
 
-  StagedWorldImpactBuilder({this.collectImpacts: false});
+  StagedWorldImpactBuilder({this.collectImpacts = false});
 
   void _ensureBuilder() {
     if (_currentBuilder == null) {
-      _currentBuilder = new WorldImpactBuilderImpl();
+      _currentBuilder = WorldImpactBuilderImpl();
       if (collectImpacts) {
         _builders.add(_currentBuilder);
       }
@@ -248,7 +248,7 @@
   @override
   void registerDynamicUse(DynamicUse dynamicUse) {
     if (_dynamicUses == null) {
-      _dynamicUses = new Setlet<DynamicUse>();
+      _dynamicUses = Setlet<DynamicUse>();
       _dynamicUses.addAll(worldImpact.dynamicUses);
     }
     _dynamicUses.add(dynamicUse);
@@ -257,7 +257,7 @@
   @override
   void registerTypeUse(TypeUse typeUse) {
     if (_typeUses == null) {
-      _typeUses = new Setlet<TypeUse>();
+      _typeUses = Setlet<TypeUse>();
       _typeUses.addAll(worldImpact.typeUses);
     }
     _typeUses.add(typeUse);
@@ -271,7 +271,7 @@
   @override
   void registerStaticUse(StaticUse staticUse) {
     if (_staticUses == null) {
-      _staticUses = new Setlet<StaticUse>();
+      _staticUses = Setlet<StaticUse>();
       _staticUses.addAll(worldImpact.staticUses);
     }
     _staticUses.add(staticUse);
@@ -290,7 +290,7 @@
   @override
   void registerConstantUse(ConstantUse constantUse) {
     if (_constantUses == null) {
-      _constantUses = new Setlet<ConstantUse>();
+      _constantUses = Setlet<ConstantUse>();
       _constantUses.addAll(worldImpact.constantUses);
     }
     _constantUses.add(constantUse);
@@ -308,7 +308,7 @@
 
   @override
   String toString() {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     sb.write('TransformedWorldImpact($worldImpact)');
     WorldImpact.printOn(sb, this);
     return sb.toString();
@@ -352,7 +352,7 @@
 }
 
 // TODO(johnniwinther): Remove these when we get anonymous local classes.
-typedef void VisitUse<U>(MemberEntity member, U use);
+typedef VisitUse<U> = void Function(MemberEntity member, U use);
 
 class WorldImpactVisitorImpl implements WorldImpactVisitor {
   final VisitUse<StaticUse> _visitStaticUse;
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 5b0bb2f..65efa17 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -670,8 +670,8 @@
     void* child_isolate_data = nullptr;
     const bool success = initialize_callback(&child_isolate_data, &error);
     if (!success) {
-      Dart_ShutdownIsolate();
       FailedSpawn(error);
+      Dart_ShutdownIsolate();
       free(error);
       return;
     }
diff --git a/runtime/tests/vm/dart/isolates/fast_object_copy2_test.dart b/runtime/tests/vm/dart/isolates/fast_object_copy2_test.dart
index dc684dc..20b5557 100644
--- a/runtime/tests/vm/dart/isolates/fast_object_copy2_test.dart
+++ b/runtime/tests/vm/dart/isolates/fast_object_copy2_test.dart
@@ -19,6 +19,14 @@
 import 'fast_object_copy_test.dart'
     show UserObject, SendReceiveTestBase, notAllocatableInTLAB;
 
+topLevelClosure(a, b) {}
+topLevelClosureG<T>(T a, T b) {}
+Type getType<T>() => T;
+
+class A<T> {
+  dynamic m<H>(T a, H b) => this;
+}
+
 // When running with isolate groups enabled, we can share all of the following
 // objects.
 final sharableObjects = [
@@ -32,6 +40,36 @@
     rp.close();
     return sp;
   })(),
+  () {
+    innerClosure(a, b) {}
+    return innerClosure;
+  }(),
+  () {
+    innerClosureG<T>(T a, T b) {}
+    return innerClosureG;
+  }(),
+  () {
+    innerClosureG<T>() {
+      innerClosureG2<H>(T a, H b) {}
+      return innerClosureG2;
+    }
+
+    return innerClosureG<int>();
+  }(),
+  () {
+    innerClosureG<T>(T a, T b) {}
+    final Function(int, int) partialInstantiatedInnerClosure = innerClosureG;
+    return partialInstantiatedInnerClosure;
+  }(),
+  () {
+    return topLevelClosureG;
+  }(),
+  () {
+    final Function(int, int) partialInstantiatedInnerClosure = topLevelClosureG;
+    return partialInstantiatedInnerClosure;
+  }(),
+  getType<void Function(int, double, Object)>(),
+  getType<T Function<T>(int, double, T)>(),
   const [1, 2, 3],
   const {1: 1, 2: 2, 3: 2},
   const {1, 2, 3},
@@ -40,13 +78,40 @@
   Int32x4(1, 2, 3, 4),
 ];
 
+final copyableClosures = <dynamic>[
+  () {
+    final a = A<int>();
+    final Function<T>(int, T) genericMethod = a.m;
+    return genericMethod;
+  }(),
+  () {
+    final a = A<int>();
+    final Function(int, double) partialInstantiatedMethod = a.m;
+    return partialInstantiatedMethod;
+  }(),
+  () {
+    final a = Object();
+    dynamic inner() => a;
+    return inner;
+  }(),
+  () {
+    foo(var arg) {
+      return () => arg;
+    }
+
+    return foo(1);
+  }(),
+];
+
 class SendReceiveTest extends SendReceiveTestBase {
   Future runTests() async {
     await testSharable();
     await testSharable2();
+    await testCopyableClosures();
   }
 
   Future testSharable() async {
+    print('testSharable');
     final sharableObjectsCopy = await sendReceive([
       ...sharableObjects,
     ]);
@@ -57,6 +122,7 @@
   }
 
   Future testSharable2() async {
+    print('testSharable2');
     final sharableObjectsCopy = await sendReceive([
       notAllocatableInTLAB,
       ...sharableObjects,
@@ -68,6 +134,27 @@
       Expect.identical(sharableObjects[i], sharableObjectsCopy[i + 1]);
     }
   }
+
+  Future testCopyableClosures() async {
+    print('testCopyableClosures');
+    final copy = await sendReceive([
+      notAllocatableInTLAB,
+      ...copyableClosures,
+    ]);
+    for (int i = 0; i < copyableClosures.length; ++i) {
+      Expect.notIdentical(copyableClosures[i], copy[1 + i]);
+      Expect.equals(copyableClosures[i].runtimeType, copy[1 + i].runtimeType);
+    }
+
+    final copy2 = await sendReceive([
+      ...copyableClosures,
+      notAllocatableInTLAB,
+    ]);
+    for (int i = 0; i < copyableClosures.length; ++i) {
+      Expect.notIdentical(copyableClosures[i], copy2[i]);
+      Expect.equals(copyableClosures[i].runtimeType, copy2[i].runtimeType);
+    }
+  }
 }
 
 main() async {
diff --git a/runtime/tests/vm/dart/isolates/fast_object_copy_test.dart b/runtime/tests/vm/dart/isolates/fast_object_copy_test.dart
index 4f71fae..8509db3 100644
--- a/runtime/tests/vm/dart/isolates/fast_object_copy_test.dart
+++ b/runtime/tests/vm/dart/isolates/fast_object_copy_test.dart
@@ -24,7 +24,9 @@
 
 import 'package:expect/expect.dart';
 
-class ClassWithNativeFields extends NativeFieldWrapperClass1 {}
+class ClassWithNativeFields extends NativeFieldWrapperClass1 {
+  void m() {}
+}
 
 final Uint8List largeExternalTypedData =
     File(Platform.resolvedExecutable).readAsBytesSync()..[0] = 42;
@@ -221,6 +223,8 @@
     await testSlowOnly();
 
     await testWeakProperty();
+
+    await testForbiddenClosures();
   }
 
   Future testTransferrable() async {
@@ -644,6 +648,38 @@
       Expect.equals('bar', (expando4Copy[expando4Copy] as Map)['foo']);
     }
   }
+
+  Future testForbiddenClosures() async {
+    print('testForbiddenClosures');
+    final nonCopyableClosures = <dynamic>[
+      (() {
+        final a = ClassWithNativeFields();
+        return a.m;
+      })(),
+      (() {
+        final a = ClassWithNativeFields();
+        dynamic inner() => a;
+        return inner;
+      })(),
+      (() {
+        foo(var arg) {
+          return () => arg;
+        }
+
+        return foo(ClassWithNativeFields());
+      })(),
+    ];
+    for (final closure in nonCopyableClosures) {
+      Expect.throwsArgumentError(() => sendPort.send(closure));
+    }
+    for (final closure in nonCopyableClosures) {
+      Expect.throwsArgumentError(() => sendPort.send([closure]));
+    }
+    for (final closure in nonCopyableClosures) {
+      Expect.throwsArgumentError(
+          () => sendPort.send([notAllocatableInTLAB, closure]));
+    }
+  }
 }
 
 main() async {
diff --git a/runtime/tests/vm/dart/spawn_shutdown_test.dart b/runtime/tests/vm/dart/spawn_shutdown_test.dart
index 6e42f3e..d47db32 100644
--- a/runtime/tests/vm/dart/spawn_shutdown_test.dart
+++ b/runtime/tests/vm/dart/spawn_shutdown_test.dart
@@ -1,9 +1,10 @@
 // Copyright (c) 2015, 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.
-// VMOptions=--enable-asserts
 
-import 'dart:async';
+// VMOptions=--enable-asserts --enable-isolate-groups
+// VMOptions=--enable-asserts --no-enable-isolate-groups
+
 import 'dart:io';
 import 'dart:isolate';
 
diff --git a/runtime/tests/vm/dart/write_traces_to_invalid_file_test.dart b/runtime/tests/vm/dart/write_traces_to_invalid_file_test.dart
new file mode 100644
index 0000000..86df8d0
--- /dev/null
+++ b/runtime/tests/vm/dart/write_traces_to_invalid_file_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// VMOptions=--print_instructions_sizes-to=no/such/path
+// VMOptions=--timeline_dir=no/such/path
+// VMOptions=--trace_precompiler_to=no/such/path
+// VMOptions=--write_code_comments_as_synthetic_source_to=no/such/path
+// VMOptions=--write_retained_reasons_to=no/such/path
+// VMOptions=--write_v8_snapshot_profile-to=no/such/path
+
+main() {
+  print("Just checking we don't crash.");
+}
diff --git a/runtime/tests/vm/dart_2/isolates/fast_object_copy2_test.dart b/runtime/tests/vm/dart_2/isolates/fast_object_copy2_test.dart
index 8863949..a0aa022 100644
--- a/runtime/tests/vm/dart_2/isolates/fast_object_copy2_test.dart
+++ b/runtime/tests/vm/dart_2/isolates/fast_object_copy2_test.dart
@@ -21,6 +21,14 @@
 import 'fast_object_copy_test.dart'
     show UserObject, SendReceiveTestBase, notAllocatableInTLAB;
 
+topLevelClosure(a, b) {}
+topLevelClosureG<T>(T a, T b) {}
+Type getType<T>() => T;
+
+class A<T> {
+  dynamic m<H>(T a, H b) => this;
+}
+
 // When running with isolate groups enabled, we can share all of the following
 // objects.
 final sharableObjects = [
@@ -34,6 +42,35 @@
     rp.close();
     return sp;
   })(),
+  () {
+    innerClosure(a, b) {}
+    return innerClosure;
+  }(),
+  () {
+    innerClosureG<T>(T a, T b) {}
+    return innerClosureG;
+  }(),
+  () {
+    innerClosureG<T>() {
+      innerClosureG2<H>(T a, H b) {}
+      return innerClosureG2;
+    }
+
+    return innerClosureG<int>();
+  }(),
+  () {
+    innerClosureG<T>(T a, T b) {}
+    final Function(int, int) partialInstantiatedInnerClosure = innerClosureG;
+    return partialInstantiatedInnerClosure;
+  }(),
+  () {
+    return topLevelClosureG;
+  }(),
+  () {
+    final Function(int, int) partialInstantiatedInnerClosure = topLevelClosureG;
+    return partialInstantiatedInnerClosure;
+  }(),
+  getType<void Function(int, double, Object)>(),
   const [1, 2, 3],
   const {1: 1, 2: 2, 3: 2},
   const {1, 2, 3},
@@ -42,13 +79,40 @@
   Int32x4(1, 2, 3, 4),
 ];
 
+final copyableClosures = <dynamic>[
+  () {
+    final a = A<int>();
+    final Function<T>(int, T) genericMethod = a.m;
+    return genericMethod;
+  }(),
+  () {
+    final a = A<int>();
+    final Function(int, double) partialInstantiatedMethod = a.m;
+    return partialInstantiatedMethod;
+  }(),
+  () {
+    final a = Object();
+    dynamic inner() => a;
+    return inner;
+  }(),
+  () {
+    foo(var arg) {
+      return () => arg;
+    }
+
+    return foo(1);
+  }(),
+];
+
 class SendReceiveTest extends SendReceiveTestBase {
   Future runTests() async {
     await testSharable();
     await testSharable2();
+    await testCopyableClosures();
   }
 
   Future testSharable() async {
+    print('testSharable');
     final sharableObjectsCopy = await sendReceive([
       ...sharableObjects,
     ]);
@@ -59,6 +123,7 @@
   }
 
   Future testSharable2() async {
+    print('testSharable2');
     final sharableObjectsCopy = await sendReceive([
       notAllocatableInTLAB,
       ...sharableObjects,
@@ -70,6 +135,27 @@
       Expect.identical(sharableObjects[i], sharableObjectsCopy[i + 1]);
     }
   }
+
+  Future testCopyableClosures() async {
+    print('testCopyableClosures');
+    final copy = await sendReceive([
+      notAllocatableInTLAB,
+      ...copyableClosures,
+    ]);
+    for (int i = 0; i < copyableClosures.length; ++i) {
+      Expect.notIdentical(copyableClosures[i], copy[1 + i]);
+      Expect.equals(copyableClosures[i].runtimeType, copy[1 + i].runtimeType);
+    }
+
+    final copy2 = await sendReceive([
+      ...copyableClosures,
+      notAllocatableInTLAB,
+    ]);
+    for (int i = 0; i < copyableClosures.length; ++i) {
+      Expect.notIdentical(copyableClosures[i], copy2[i]);
+      Expect.equals(copyableClosures[i].runtimeType, copy2[i].runtimeType);
+    }
+  }
 }
 
 main() async {
diff --git a/runtime/tests/vm/dart_2/isolates/fast_object_copy_test.dart b/runtime/tests/vm/dart_2/isolates/fast_object_copy_test.dart
index 73b82f4..bad2e3a 100644
--- a/runtime/tests/vm/dart_2/isolates/fast_object_copy_test.dart
+++ b/runtime/tests/vm/dart_2/isolates/fast_object_copy_test.dart
@@ -26,7 +26,9 @@
 
 import 'package:expect/expect.dart';
 
-class ClassWithNativeFields extends NativeFieldWrapperClass1 {}
+class ClassWithNativeFields extends NativeFieldWrapperClass1 {
+  void m() {}
+}
 
 final Uint8List largeExternalTypedData =
     File(Platform.resolvedExecutable).readAsBytesSync()..[0] = 42;
@@ -223,6 +225,8 @@
     await testSlowOnly();
 
     await testWeakProperty();
+
+    await testForbiddenClosures();
   }
 
   Future testTransferrable() async {
@@ -646,6 +650,38 @@
       Expect.equals('bar', (expando4Copy[expando4Copy] as Map)['foo']);
     }
   }
+
+  Future testForbiddenClosures() async {
+    print('testForbiddenClosures');
+    final nonCopyableClosures = <dynamic>[
+      (() {
+        final a = ClassWithNativeFields();
+        return a.m;
+      })(),
+      (() {
+        final a = ClassWithNativeFields();
+        dynamic inner() => a;
+        return inner;
+      })(),
+      (() {
+        foo(var arg) {
+          return () => arg;
+        }
+
+        return foo(ClassWithNativeFields());
+      })(),
+    ];
+    for (final closure in nonCopyableClosures) {
+      Expect.throwsArgumentError(() => sendPort.send(closure));
+    }
+    for (final closure in nonCopyableClosures) {
+      Expect.throwsArgumentError(() => sendPort.send([closure]));
+    }
+    for (final closure in nonCopyableClosures) {
+      Expect.throwsArgumentError(
+          () => sendPort.send([notAllocatableInTLAB, closure]));
+    }
+  }
 }
 
 main() async {
diff --git a/runtime/tests/vm/dart_2/spawn_shutdown_test.dart b/runtime/tests/vm/dart_2/spawn_shutdown_test.dart
index 361d1fa..4c4eb86 100644
--- a/runtime/tests/vm/dart_2/spawn_shutdown_test.dart
+++ b/runtime/tests/vm/dart_2/spawn_shutdown_test.dart
@@ -1,11 +1,12 @@
 // Copyright (c) 2015, 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.
-// VMOptions=--enable-asserts
+
+// VMOptions=--enable-asserts --enable-isolate-groups
+// VMOptions=--enable-asserts --no-enable-isolate-groups
 
 // @dart = 2.9
 
-import 'dart:async';
 import 'dart:io';
 import 'dart:isolate';
 
diff --git a/runtime/tests/vm/dart_2/write_traces_to_invalid_file_test.dart b/runtime/tests/vm/dart_2/write_traces_to_invalid_file_test.dart
new file mode 100644
index 0000000..5d51641
--- /dev/null
+++ b/runtime/tests/vm/dart_2/write_traces_to_invalid_file_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+// VMOptions=--print_instructions_sizes-to=no/such/path
+// VMOptions=--timeline_dir=no/such/path
+// VMOptions=--trace_precompiler_to=no/such/path
+// VMOptions=--write_code_comments_as_synthetic_source_to=no/such/path
+// VMOptions=--write_retained_reasons_to=no/such/path
+// VMOptions=--write_v8_snapshot_profile-to=no/such/path
+
+// @dart = 2.9
+
+main() {
+  print("Just checking we don't crash.");
+}
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 5c02e8a..ec5c09d 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -174,15 +174,20 @@
   explicit RetainedReasonsWriter(Zone* zone)
       : zone_(zone), retained_reasons_map_(zone) {}
 
-  void Init(const char* filename) {
-    if (filename == nullptr) return;
-    const auto file_open = Dart::file_open_callback();
-    if (file_open == nullptr) return;
+  bool Init(const char* filename) {
+    if (filename == nullptr) return false;
 
-    const auto file = file_open(filename, /*write=*/true);
+    if ((Dart::file_write_callback() == nullptr) ||
+        (Dart::file_open_callback() == nullptr) ||
+        (Dart::file_close_callback() == nullptr)) {
+      OS::PrintErr("warning: Could not access file callbacks.");
+      return false;
+    }
+
+    void* file = Dart::file_open_callback()(filename, /*write=*/true);
     if (file == nullptr) {
-      OS::PrintErr("Failed to open file %s\n", filename);
-      return;
+      OS::PrintErr("warning: Failed to write retained reasons: %s\n", filename);
+      return false;
     }
 
     file_ = file;
@@ -191,6 +196,7 @@
     // and printed at one point. This avoids having to keep otherwise
     // unneeded information around.
     writer_.OpenArray();
+    return true;
   }
 
   void AddDropped(const Object& obj) {
@@ -446,8 +452,7 @@
     zone_ = stack_zone.GetZone();
     RetainedReasonsWriter reasons_writer(zone_);
 
-    if (FLAG_write_retained_reasons_to != nullptr) {
-      reasons_writer.Init(FLAG_write_retained_reasons_to);
+    if (reasons_writer.Init(FLAG_write_retained_reasons_to)) {
       retained_reasons_writer_ = &reasons_writer;
     }
 
@@ -652,7 +657,7 @@
       ProgramVisitor::Dedup(T);
     }
 
-    if (FLAG_write_retained_reasons_to != nullptr) {
+    if (retained_reasons_writer_ != nullptr) {
       reasons_writer.Write();
       retained_reasons_writer_ = nullptr;
     }
diff --git a/runtime/vm/compiler/aot/precompiler_tracer.cc b/runtime/vm/compiler/aot/precompiler_tracer.cc
index 40f6f58..72fcfdd 100644
--- a/runtime/vm/compiler/aot/precompiler_tracer.cc
+++ b/runtime/vm/compiler/aot/precompiler_tracer.cc
@@ -18,15 +18,22 @@
 
 PrecompilerTracer* PrecompilerTracer::StartTracingIfRequested(
     Precompiler* precompiler) {
-  if (FLAG_trace_precompiler_to != nullptr &&
-      Dart::file_write_callback() != nullptr &&
-      Dart::file_open_callback() != nullptr &&
-      Dart::file_close_callback() != nullptr) {
-    return new PrecompilerTracer(
-        precompiler, Dart::file_open_callback()(FLAG_trace_precompiler_to,
-                                                /*write=*/true));
+  const char* filename = FLAG_trace_precompiler_to;
+  if (filename == nullptr) {
+    return nullptr;
   }
-  return nullptr;
+  if ((Dart::file_write_callback() == nullptr) ||
+      (Dart::file_open_callback() == nullptr) ||
+      (Dart::file_close_callback() == nullptr)) {
+    OS::PrintErr("warning: Could not access file callbacks.");
+    return nullptr;
+  }
+  void* file = Dart::file_open_callback()(filename, /*write=*/true);
+  if (file == NULL) {
+    OS::PrintErr("warning: Failed to write precompiler trace: %s\n", filename);
+    return nullptr;
+  }
+  return new PrecompilerTracer(precompiler, file);
 }
 
 PrecompilerTracer::PrecompilerTracer(Precompiler* precompiler, void* stream)
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 704beaa..da9b346 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -4198,14 +4198,14 @@
   ASSERT(value == result);
   __ SmiUntag(value);
   __ j(NOT_CARRY, &done, compiler::Assembler::kNearJump);
-  __ movsxw(result, compiler::Address(value, TIMES_2, Mint::value_offset()));
+  __ movsxd(result, compiler::Address(value, TIMES_2, Mint::value_offset()));
 #else
   ASSERT(value != result);
   // Cannot speculatively untag with value == result because it erases the
   // upper bits needed to dereference when it is a Mint.
   __ SmiUntagAndSignExtend(result, value);
   __ j(NOT_CARRY, &done, compiler::Assembler::kNearJump);
-  __ movsxw(result, compiler::FieldAddress(value, Mint::value_offset()));
+  __ movsxd(result, compiler::FieldAddress(value, Mint::value_offset()));
 #endif
   __ Bind(&done);
 }
diff --git a/runtime/vm/dwarf.cc b/runtime/vm/dwarf.cc
index 000bab4c..4f98848 100644
--- a/runtime/vm/dwarf.cc
+++ b/runtime/vm/dwarf.cc
@@ -650,16 +650,17 @@
   auto file_close = Dart::file_close_callback();
   if ((file_open == nullptr) || (file_write == nullptr) ||
       (file_close == nullptr)) {
+    OS::PrintErr("warning: Could not access file callbacks.");
     return;
   }
 
   TextBuffer comments_buffer(128 * KB);
 
-  auto comments_file = file_open(
-      FLAG_write_code_comments_as_synthetic_source_to, /*write=*/true);
+  const char* filename = FLAG_write_code_comments_as_synthetic_source_to;
+  void* comments_file = file_open(filename, /*write=*/true);
   if (comments_file == nullptr) {
-    OS::PrintErr("Failed to open file %s\n",
-                 FLAG_write_code_comments_as_synthetic_source_to);
+    OS::PrintErr("warning: Failed to write code comments source: %s\n",
+                 filename);
     return;
   }
 
diff --git a/runtime/vm/hash_map.h b/runtime/vm/hash_map.h
index ec5ea08..7c0cb4b 100644
--- a/runtime/vm/hash_map.h
+++ b/runtime/vm/hash_map.h
@@ -15,7 +15,8 @@
 template <typename KeyValueTrait, typename B, typename Allocator = Zone>
 class BaseDirectChainedHashMap : public B {
  public:
-  explicit BaseDirectChainedHashMap(Allocator* allocator)
+  explicit BaseDirectChainedHashMap(Allocator* allocator,
+                                    intptr_t initial_size = kInitialSize)
       : array_size_(0),
         lists_size_(0),
         count_(0),
@@ -23,8 +24,9 @@
         lists_(NULL),
         free_list_head_(kNil),
         allocator_(allocator) {
-    ResizeLists(kInitialSize);
-    Resize(kInitialSize);
+    ASSERT(Utils::IsPowerOfTwo(initial_size));
+    ResizeLists(initial_size);
+    Resize(initial_size);
   }
 
   BaseDirectChainedHashMap(const BaseDirectChainedHashMap& other);
@@ -407,9 +409,12 @@
       : BaseDirectChainedHashMap<KeyValueTrait, ValueObject>(
             ASSERT_NOTNULL(ThreadState::Current()->zone())) {}
 
-  explicit DirectChainedHashMap(Zone* zone)
+  explicit DirectChainedHashMap(
+      Zone* zone,
+      intptr_t initial_size = DirectChainedHashMap::kInitialSize)
       : BaseDirectChainedHashMap<KeyValueTrait, ValueObject>(
-            ASSERT_NOTNULL(zone)) {}
+            ASSERT_NOTNULL(zone),
+            initial_size) {}
 
   // There is a current use of the copy constructor in CSEInstructionMap
   // (compiler/backend/redundancy_elimination.cc), so work is needed if we
@@ -425,9 +430,11 @@
 class MallocDirectChainedHashMap
     : public BaseDirectChainedHashMap<KeyValueTrait, MallocAllocated, Malloc> {
  public:
-  MallocDirectChainedHashMap()
-      : BaseDirectChainedHashMap<KeyValueTrait, MallocAllocated, Malloc>(NULL) {
-  }
+  MallocDirectChainedHashMap(
+      intptr_t initial_size = MallocDirectChainedHashMap::kInitialSize)
+      : BaseDirectChainedHashMap<KeyValueTrait, MallocAllocated, Malloc>(
+            NULL,
+            initial_size) {}
 
   // The only use of the copy constructor seems to be in hash_map_test.cc.
   // Not disallowing it for now just in case there are other users.
@@ -446,8 +453,12 @@
   ZoneDirectChainedHashMap()
       : BaseDirectChainedHashMap<KeyValueTrait, ZoneAllocated, Zone>(
             ThreadState::Current()->zone()) {}
-  explicit ZoneDirectChainedHashMap(Zone* zone)
-      : BaseDirectChainedHashMap<KeyValueTrait, ZoneAllocated, Zone>(zone) {}
+  explicit ZoneDirectChainedHashMap(
+      Zone* zone,
+      intptr_t initial_size = ZoneDirectChainedHashMap::kInitialSize)
+      : BaseDirectChainedHashMap<KeyValueTrait, ZoneAllocated, Zone>(
+            zone,
+            initial_size) {}
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ZoneDirectChainedHashMap);
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index 0f9bd6e..3d97c84 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -391,12 +391,14 @@
   auto file_close = Dart::file_close_callback();
   if ((file_open == nullptr) || (file_write == nullptr) ||
       (file_close == nullptr)) {
+    OS::PrintErr("warning: Could not access file callbacks.");
     return;
   }
 
-  auto file = file_open(FLAG_print_instructions_sizes_to, /*write=*/true);
+  const char* filename = FLAG_print_instructions_sizes_to;
+  void* file = file_open(filename, /*write=*/true);
   if (file == nullptr) {
-    OS::PrintErr("Failed to open file %s\n", FLAG_print_instructions_sizes_to);
+    OS::PrintErr("warning: Failed to write instruction sizes: %s\n", filename);
     return;
   }
 
diff --git a/runtime/vm/message_snapshot.cc b/runtime/vm/message_snapshot.cc
index 6c69e47..076f612 100644
--- a/runtime/vm/message_snapshot.cc
+++ b/runtime/vm/message_snapshot.cc
@@ -3066,22 +3066,20 @@
   }
 
     ILLEGAL(FunctionType)
-    ILLEGAL(DynamicLibrary)
     ILLEGAL(MirrorReference)
-    ILLEGAL(Pointer)
     ILLEGAL(ReceivePort)
     ILLEGAL(StackTrace)
     ILLEGAL(UserTag)
-#undef ILLEGAL
 
-    switch (cid) {
-#define ILLEGAL(type) case kFfi##type##Cid:
-      CLASS_LIST_FFI(ILLEGAL)
+    // From "dart:ffi" we handle only Pointer/DynamicLibrary specially, since
+    // those are the only non-abstract classes (so we avoid checking more cids
+    // here that cannot happen in reality)
+    ILLEGAL(DynamicLibrary)
+    ILLEGAL(Pointer)
+    ILLEGAL(FfiDynamicLibrary)
+    ILLEGAL(FfiPointer)
+
 #undef ILLEGAL
-      IllegalObject(*object,
-                    "Native objects (from dart:ffi) such as Pointers and "
-                    "Structs cannot be passed between isolates.");
-    }
 
     if (cid >= kNumPredefinedCids || cid == kInstanceCid ||
         cid == kByteBufferCid) {
diff --git a/runtime/vm/object_graph_copy.cc b/runtime/vm/object_graph_copy.cc
index 1a54883..c6e6c9d 100644
--- a/runtime/vm/object_graph_copy.cc
+++ b/runtime/vm/object_graph_copy.cc
@@ -29,7 +29,6 @@
   V(Code)                                                                      \
   V(CodeSourceMap)                                                             \
   V(CompressedStackMaps)                                                       \
-  V(Context)                                                                   \
   V(ContextScope)                                                              \
   V(DynamicLibrary)                                                            \
   V(Error)                                                                     \
@@ -138,7 +137,7 @@
 }
 
 DART_FORCE_INLINE
-static bool CanShareObject(uword tags) {
+static bool CanShareObject(ObjectPtr obj, uword tags) {
   if ((tags & UntaggedObject::CanonicalBit::mask_in_place()) != 0) {
     return true;
   }
@@ -164,6 +163,11 @@
   if (cid == kCapabilityCid) return true;
   if (cid == kRegExpCid) return true;
 
+  if (cid == kClosureCid) {
+    // We can share a closure iff it doesn't close over any state.
+    return Closure::RawCast(obj)->untag()->context() == Object::null();
+  }
+
   return false;
 }
 
@@ -259,6 +263,9 @@
   if (cid == kArrayCid) {
     static_cast<UntaggedArray*>(to.untag())->length_ =
         static_cast<UntaggedArray*>(from.untag())->length_;
+  } else if (cid == kContextCid) {
+    static_cast<UntaggedContext*>(to.untag())->num_variables_ =
+        static_cast<UntaggedContext*>(from.untag())->num_variables_;
   } else if (IsTypedDataClassId(cid)) {
     static_cast<UntaggedTypedDataBase*>(to.untag())->length_ =
         static_cast<UntaggedTypedDataBase*>(from.untag())->length_;
@@ -579,33 +586,18 @@
   }
 
     switch (cid) {
-      HANDLE_ILLEGAL_CASE(FunctionType)
+      // From "dart:ffi" we handle only Pointer/DynamicLibrary specially, since
+      // those are the only non-abstract classes (so we avoid checking more cids
+      // here that cannot happen in reality)
       HANDLE_ILLEGAL_CASE(DynamicLibrary)
-      HANDLE_ILLEGAL_CASE(MirrorReference)
       HANDLE_ILLEGAL_CASE(Pointer)
+      HANDLE_ILLEGAL_CASE(FfiDynamicLibrary)
+      HANDLE_ILLEGAL_CASE(FfiPointer)
+      HANDLE_ILLEGAL_CASE(FunctionType)
+      HANDLE_ILLEGAL_CASE(MirrorReference)
       HANDLE_ILLEGAL_CASE(ReceivePort)
       HANDLE_ILLEGAL_CASE(StackTrace)
       HANDLE_ILLEGAL_CASE(UserTag)
-#define CASE(type) case kFfi##type##Cid:
-      CLASS_LIST_FFI(CASE)
-#undef CASE
-      exception_msg_ =
-          "Native objects (from dart:ffi) such as Pointers and "
-          "Structs cannot be passed between isolates.";
-      return false;
-      case kClosureCid: {
-        if (!Function::IsImplicitStaticClosureFunction(
-                Closure::FunctionOf(Closure::RawCast(object)))) {
-          exception_msg_ = OS::SCreate(
-              zone_,
-              "Illegal argument in isolate message: (object is a closure - %s)",
-              Function::Handle(Closure::FunctionOf(Closure::RawCast(object)))
-                  .ToCString());
-          return false;
-        }
-        ASSERT(Closure::ContextOf(Closure::RawCast(object)) == Object::null());
-        return true;
-      }
       default:
         return true;
     }
@@ -672,6 +664,16 @@
     }
   }
 
+  void ForwardContextPointers(intptr_t context_length,
+                              ObjectPtr src,
+                              ObjectPtr dst,
+                              intptr_t offset,
+                              intptr_t end_offset) {
+    for (; offset < end_offset; offset += kWordSize) {
+      ForwardPointer(src, dst, offset);
+    }
+  }
+
   DART_FORCE_INLINE
   void ForwardCompressedPointer(ObjectPtr src, ObjectPtr dst, intptr_t offset) {
     auto value = LoadCompressedPointer(src, offset);
@@ -681,7 +683,7 @@
     }
     auto value_decompressed = value.Decompress(heap_base_);
     const uword tags = TagsFromUntaggedObject(value_decompressed.untag());
-    if (CanShareObject(tags)) {
+    if (CanShareObject(value_decompressed, tags)) {
       StoreCompressedPointerNoBarrier(dst, offset, value);
       return;
     }
@@ -703,6 +705,36 @@
     StoreCompressedPointerNoBarrier(dst, offset, to);
   }
 
+  // TODO(rmacnak): Can be removed if Contexts are compressed.
+  DART_FORCE_INLINE
+  void ForwardPointer(ObjectPtr src, ObjectPtr dst, intptr_t offset) {
+    auto value = LoadPointer(src, offset);
+    if (!value.IsHeapObject()) {
+      StorePointerNoBarrier(dst, offset, value);
+      return;
+    }
+    const uword tags = TagsFromUntaggedObject(value.untag());
+    if (CanShareObject(value, tags)) {
+      StorePointerNoBarrier(dst, offset, value);
+      return;
+    }
+
+    ObjectPtr existing_to = fast_forward_map_.ForwardedObject(value);
+    if (existing_to != Marker()) {
+      StorePointerNoBarrier(dst, offset, existing_to);
+      return;
+    }
+
+    if (UNLIKELY(!CanCopyObject(tags, value))) {
+      ASSERT(exception_msg_ != nullptr);
+      StorePointerNoBarrier(dst, offset, Object::null());
+      return;
+    }
+
+    auto to = Forward(tags, value);
+    StorePointerNoBarrier(dst, offset, to);
+  }
+
   ObjectPtr Forward(uword tags, ObjectPtr from) {
     const intptr_t header_size = UntaggedObject::SizeTag::decode(tags);
     const auto cid = UntaggedObject::ClassIdTag::decode(tags);
@@ -827,6 +859,16 @@
     }
   }
 
+  void ForwardContextPointers(intptr_t context_length,
+                              const Object& src,
+                              const Object& dst,
+                              intptr_t offset,
+                              intptr_t end_offset) {
+    for (; offset < end_offset; offset += kWordSize) {
+      ForwardPointer(src, dst, offset);
+    }
+  }
+
   DART_FORCE_INLINE
   void ForwardCompressedLargeArrayPointer(const Object& src,
                                           const Object& dst,
@@ -839,7 +881,7 @@
 
     auto value_decompressed = value.Decompress(heap_base_);
     const uword tags = TagsFromUntaggedObject(value_decompressed.untag());
-    if (CanShareObject(tags)) {
+    if (CanShareObject(value_decompressed, tags)) {
       StoreCompressedLargeArrayPointerBarrier(dst.ptr(), offset,
                                               value_decompressed);
       return;
@@ -874,7 +916,7 @@
     }
     auto value_decompressed = value.Decompress(heap_base_);
     const uword tags = TagsFromUntaggedObject(value_decompressed.untag());
-    if (CanShareObject(tags)) {
+    if (CanShareObject(value_decompressed, tags)) {
       StoreCompressedPointerBarrier(dst.ptr(), offset, value_decompressed);
       return;
     }
@@ -896,6 +938,37 @@
     tmp_ = Forward(tags, tmp_);  // Only this can cause allocation.
     StoreCompressedPointerBarrier(dst.ptr(), offset, tmp_.ptr());
   }
+
+  // TODO(rmacnak): Can be removed if Contexts are compressed.
+  DART_FORCE_INLINE
+  void ForwardPointer(const Object& src, const Object& dst, intptr_t offset) {
+    auto value = LoadPointer(src.ptr(), offset);
+    if (!value.IsHeapObject()) {
+      StorePointerNoBarrier(dst.ptr(), offset, value);
+      return;
+    }
+    const uword tags = TagsFromUntaggedObject(value.untag());
+    if (CanShareObject(value, tags)) {
+      StorePointerBarrier(dst.ptr(), offset, value);
+      return;
+    }
+
+    ObjectPtr existing_to = slow_forward_map_.ForwardedObject(value);
+    if (existing_to != Marker()) {
+      StorePointerBarrier(dst.ptr(), offset, existing_to);
+      return;
+    }
+
+    if (UNLIKELY(!CanCopyObject(tags, value))) {
+      ASSERT(exception_msg_ != nullptr);
+      StorePointerNoBarrier(dst.ptr(), offset, Object::null());
+      return;
+    }
+
+    tmp_ = value;
+    tmp_ = Forward(tags, tmp_);  // Only this can cause allocation.
+    StorePointerBarrier(dst.ptr(), offset, tmp_.ptr());
+  }
   ObjectPtr Forward(uword tags, const Object& from) {
     const intptr_t cid = UntaggedObject::ClassIdTag::decode(tags);
     intptr_t size = UntaggedObject::SizeTag::decode(tags);
@@ -1083,6 +1156,18 @@
                             UntagClosure(from)->entry_point_);
   }
 
+  void CopyContext(typename Types::Context from, typename Types::Context to) {
+    const intptr_t length = Context::NumVariables(Types::GetContextPtr(from));
+
+    UntagContext(to)->num_variables_ = UntagContext(from)->num_variables_;
+
+    Base::ForwardCompressedPointer(from, to,
+                                   OFFSET_OF(UntaggedContext, parent_));
+    Base::ForwardContextPointers(
+        length, from, to, Context::variable_offset(0),
+        Context::variable_offset(0) + kWordSize * length);
+  }
+
   void CopyArray(typename Types::Array from, typename Types::Array to) {
     const intptr_t length = Smi::Value(UntagArray(from)->length());
     Base::StoreCompressedArrayPointers(
@@ -1671,7 +1756,7 @@
       return result_array.ptr();
     }
     const uword tags = TagsFromUntaggedObject(root.ptr().untag());
-    if (CanShareObject(tags)) {
+    if (CanShareObject(root.ptr(), tags)) {
       result_array.SetAt(0, root);
       return result_array.ptr();
     }
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index f99afbe..5fd0641 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -2179,6 +2179,9 @@
   VARIABLE_POINTER_FIELDS(ObjectPtr, element, data)
 
   friend class Object;
+  friend void UpdateLengthField(intptr_t,
+                                ObjectPtr,
+                                ObjectPtr);  // num_variables_
 };
 
 class UntaggedContextScope : public UntaggedObject {
diff --git a/runtime/vm/regexp_assembler_bytecode.cc b/runtime/vm/regexp_assembler_bytecode.cc
index dbd71e2..dd8bd53 100644
--- a/runtime/vm/regexp_assembler_bytecode.cc
+++ b/runtime/vm/regexp_assembler_bytecode.cc
@@ -494,8 +494,7 @@
       TypedData::Handle(zone, regexp.bytecode(is_one_byte, sticky));
   ASSERT(!bytecode.IsNull());
   const Object& result = Object::Handle(
-      zone,
-      IrregexpInterpreter::Match(bytecode, subject, raw_output, index, zone));
+      zone, IrregexpInterpreter::Match(bytecode, subject, raw_output, index));
 
   if (result.ptr() == Bool::True().ptr()) {
     // Copy capture results to the start of the registers array.
@@ -503,11 +502,7 @@
   }
   if (result.ptr() == Object::null()) {
     // Exception during regexp processing
-    Thread* thread = Thread::Current();
-    auto isolate_group = thread->isolate_group();
-    const Instance& exception =
-        Instance::Handle(isolate_group->object_store()->stack_overflow());
-    Exceptions::Throw(thread, exception);
+    Exceptions::ThrowStackOverflow();
     UNREACHABLE();
   }
   return result.ptr();
diff --git a/runtime/vm/regexp_interpreter.cc b/runtime/vm/regexp_interpreter.cc
index d9248ac..610ac03 100644
--- a/runtime/vm/regexp_interpreter.cc
+++ b/runtime/vm/regexp_interpreter.cc
@@ -135,7 +135,7 @@
 // matching terminates.
 class BacktrackStack {
  public:
-  explicit BacktrackStack(Zone* zone) {
+  BacktrackStack() {
     memory_ = Isolate::Current()->TakeRegexpBacktrackStack();
     // Note: using malloc here has a potential of triggering jemalloc/tcmalloc
     // bugs which cause application to leak memory and eventually OOM.
@@ -147,15 +147,16 @@
           sizeof(intptr_t) * kBacktrackStackSize, /*is_executable=*/false,
           "regexp-backtrack-stack"));
     }
-    if (memory_ == nullptr) {
-      OUT_OF_MEMORY();
-    }
   }
 
   ~BacktrackStack() {
-    Isolate::Current()->CacheRegexpBacktrackStack(std::move(memory_));
+    if (memory_ != nullptr) {
+      Isolate::Current()->CacheRegexpBacktrackStack(std::move(memory_));
+    }
   }
 
+  bool out_of_memory() const { return memory_ == nullptr; }
+
   intptr_t* data() const {
     return reinterpret_cast<intptr_t*>(memory_->address());
   }
@@ -177,13 +178,15 @@
                           const String& subject,
                           int32_t* registers,
                           intptr_t current,
-                          uint32_t current_char,
-                          Zone* zone) {
-  const auto thread = Thread::Current();
+                          uint32_t current_char) {
   // BacktrackStack ensures that the memory allocated for the backtracking stack
   // is returned to the system or cached if there is no stack being cached at
   // the moment.
-  BacktrackStack backtrack_stack(zone);
+  BacktrackStack backtrack_stack;
+  if (backtrack_stack.out_of_memory()) {
+    Exceptions::ThrowOOM();
+    UNREACHABLE();
+  }
   intptr_t* backtrack_stack_base = backtrack_stack.data();
   intptr_t* backtrack_sp = backtrack_stack_base;
   intptr_t backtrack_stack_space = backtrack_stack.max_size();
@@ -199,6 +202,7 @@
     OS::PrintErr("Start irregexp bytecode interpreter\n");
   }
 #endif
+  const auto thread = Thread::Current();
   const uint8_t* code_base;
   const uint8_t* pc;
   {
@@ -683,8 +687,7 @@
 ObjectPtr IrregexpInterpreter::Match(const TypedData& bytecode,
                                      const String& subject,
                                      int32_t* registers,
-                                     intptr_t start_position,
-                                     Zone* zone) {
+                                     intptr_t start_position) {
   uint16_t previous_char = '\n';
   if (start_position != 0) {
     previous_char = subject.CharAt(start_position - 1);
@@ -692,10 +695,10 @@
 
   if (subject.IsOneByteString() || subject.IsExternalOneByteString()) {
     return RawMatch<uint8_t>(bytecode, subject, registers, start_position,
-                             previous_char, zone);
+                             previous_char);
   } else if (subject.IsTwoByteString() || subject.IsExternalTwoByteString()) {
     return RawMatch<uint16_t>(bytecode, subject, registers, start_position,
-                              previous_char, zone);
+                              previous_char);
   } else {
     UNREACHABLE();
     return Bool::False().ptr();
diff --git a/runtime/vm/regexp_interpreter.h b/runtime/vm/regexp_interpreter.h
index f451a40..a42bd95 100644
--- a/runtime/vm/regexp_interpreter.h
+++ b/runtime/vm/regexp_interpreter.h
@@ -21,8 +21,7 @@
   static ObjectPtr Match(const TypedData& bytecode,
                          const String& subject,
                          int32_t* captures,
-                         intptr_t start_position,
-                         Zone* zone);
+                         intptr_t start_position);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index de13805..9c14b8b 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -1052,6 +1052,7 @@
   Dart_FileWriteCallback file_write = Dart::file_write_callback();
   Dart_FileCloseCallback file_close = Dart::file_close_callback();
   if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) {
+    OS::PrintErr("warning: Could not access file callbacks.");
     return;
   }
 
@@ -1062,7 +1063,7 @@
       OS::SCreate(NULL, "%s/dart-timeline-%" Pd ".json", directory, pid);
   void* file = (*file_open)(filename, true);
   if (file == NULL) {
-    OS::PrintErr("Failed to write timeline file: %s\n", filename);
+    OS::PrintErr("warning: Failed to write timeline file: %s\n", filename);
     free(filename);
     return;
   }
diff --git a/runtime/vm/v8_snapshot_writer.cc b/runtime/vm/v8_snapshot_writer.cc
index c6e061a..d886122 100644
--- a/runtime/vm/v8_snapshot_writer.cc
+++ b/runtime/vm/v8_snapshot_writer.cc
@@ -16,6 +16,7 @@
 
 V8SnapshotProfileWriter::V8SnapshotProfileWriter(Zone* zone)
     : zone_(zone),
+      nodes_(zone_),
       node_types_(zone_),
       edge_types_(zone_),
       strings_(zone_),
@@ -41,7 +42,7 @@
   const intptr_t type_index = node_types_.Add(type);
   if (info->type != kInvalidString && info->type != type_index) {
     FATAL("Attempting to assign mismatching type %s to node %s", type,
-          info->ToCString(zone_));
+          info->ToCString(nullptr, zone_));
   }
   info->type = type_index;
   // Don't overwrite any existing name.
@@ -103,26 +104,30 @@
   return nodes_.Lookup(object_id);
 }
 
-const char* V8SnapshotProfileWriter::NodeInfo::ToCString(Zone* zone) const {
+const char* V8SnapshotProfileWriter::NodeInfo::ToCString(
+    V8SnapshotProfileWriter* profile_writer,
+    Zone* zone) const {
   JSONWriter writer;
-  WriteDebug(&writer);
+  WriteDebug(profile_writer, &writer);
   return OS::SCreate(zone, "%s", writer.buffer()->buffer());
 }
 
-void V8SnapshotProfileWriter::NodeInfo::Write(JSONWriter* writer) const {
+void V8SnapshotProfileWriter::NodeInfo::Write(
+    V8SnapshotProfileWriter* profile_writer,
+    JSONWriter* writer) const {
   ASSERT(id.space() != IdSpace::kInvalid);
   if (type == kInvalidString) {
-    FATAL("No type given for node %s", id.ToCString(profile_writer_->zone_));
+    FATAL("No type given for node %s", id.ToCString(profile_writer->zone_));
   }
   writer->PrintValue(type);
   if (name != kInvalidString) {
     writer->PrintValue(name);
   } else {
-    ASSERT(profile_writer_ != nullptr);
+    ASSERT(profile_writer != nullptr);
     // If we don't already have a name for the node, we lazily create a default
     // one. This is safe since the strings table is written out after the nodes.
-    const intptr_t name = profile_writer_->strings_.AddFormatted(
-        "Unnamed [%s] (nil)", profile_writer_->node_types_.At(type));
+    const intptr_t name = profile_writer->strings_.AddFormatted(
+        "Unnamed [%s] (nil)", profile_writer->node_types_.At(type));
     writer->PrintValue(name);
   }
   id.Write(writer);
@@ -130,17 +135,19 @@
   writer->PrintValue64(edges->Length());
 }
 
-void V8SnapshotProfileWriter::NodeInfo::WriteDebug(JSONWriter* writer) const {
+void V8SnapshotProfileWriter::NodeInfo::WriteDebug(
+    V8SnapshotProfileWriter* profile_writer,
+    JSONWriter* writer) const {
   writer->OpenObject();
   if (type != kInvalidString) {
-    writer->PrintProperty("type", profile_writer_->node_types_.At(type));
+    writer->PrintProperty("type", profile_writer->node_types_.At(type));
   }
   if (name != kInvalidString) {
-    writer->PrintProperty("name", profile_writer_->strings_.At(name));
+    writer->PrintProperty("name", profile_writer->strings_.At(name));
   }
   id.WriteDebug(writer, "id");
   writer->PrintProperty("self_size", self_size);
-  edges->WriteDebug(writer, "edges");
+  edges->WriteDebug(profile_writer, writer, "edges");
   writer->CloseObject();
 }
 
@@ -188,45 +195,52 @@
   }
 }
 
-const char* V8SnapshotProfileWriter::EdgeMap::ToCString(Zone* zone) const {
+const char* V8SnapshotProfileWriter::EdgeMap::ToCString(
+    V8SnapshotProfileWriter* profile_writer,
+    Zone* zone) const {
   JSONWriter writer;
-  WriteDebug(&writer);
+  WriteDebug(profile_writer, &writer);
   return OS::SCreate(zone, "%s", writer.buffer()->buffer());
 }
 
-void V8SnapshotProfileWriter::EdgeMap::WriteDebug(JSONWriter* writer,
-                                                  const char* property) const {
+void V8SnapshotProfileWriter::EdgeMap::WriteDebug(
+    V8SnapshotProfileWriter* profile_writer,
+    JSONWriter* writer,
+    const char* property) const {
   writer->OpenArray(property);
   auto edge_it = GetIterator();
   while (auto const pair = edge_it.Next()) {
-    pair->edge.WriteDebug(writer, pair->target);
+    pair->edge.WriteDebug(profile_writer, writer, pair->target);
   }
   writer->CloseArray();
 }
 
-void V8SnapshotProfileWriter::Edge::Write(JSONWriter* writer,
-                                          const ObjectId& target_id) const {
+void V8SnapshotProfileWriter::Edge::Write(
+    V8SnapshotProfileWriter* profile_writer,
+    JSONWriter* writer,
+    const ObjectId& target_id) const {
   ASSERT(type != Type::kInvalid);
   writer->PrintValue64(static_cast<intptr_t>(type));
   writer->PrintValue64(name_or_offset);
-  auto const target = profile_writer_->nodes_.LookupValue(target_id);
+  auto const target = profile_writer->nodes_.LookupValue(target_id);
   writer->PrintValue64(target.offset());
 }
 
 void V8SnapshotProfileWriter::Edge::WriteDebug(
+    V8SnapshotProfileWriter* profile_writer,
     JSONWriter* writer,
     const ObjectId& target_id) const {
   writer->OpenObject();
   if (type != Type::kInvalid) {
     writer->PrintProperty(
-        "type", profile_writer_->edge_types_.At(static_cast<intptr_t>(type)));
+        "type", profile_writer->edge_types_.At(static_cast<intptr_t>(type)));
   }
   if (type == Type::kProperty) {
-    writer->PrintProperty("name", profile_writer_->strings_.At(name_or_offset));
+    writer->PrintProperty("name", profile_writer->strings_.At(name_or_offset));
   } else {
     writer->PrintProperty64("offset", name_or_offset);
   }
-  auto const target = profile_writer_->nodes_.LookupValue(target_id);
+  auto const target = profile_writer->nodes_.LookupValue(target_id);
   target.id.WriteDebug(writer, "target");
   writer->CloseObject();
 }
@@ -349,14 +363,14 @@
     ASSERT(root != nullptr);
     intptr_t offset = 0;
     root->set_offset(offset);
-    root->Write(writer);
+    root->Write(this, writer);
     offset += kNumNodeFields;
     auto nodes_it = nodes_.GetIterator();
     for (auto entry = nodes_it.Next(); entry != nullptr;
          entry = nodes_it.Next()) {
       if (entry->id == kArtificialRootId) continue;
       entry->set_offset(offset);
-      entry->Write(writer);
+      entry->Write(this, writer);
       offset += kNumNodeFields;
     }
     writer->CloseArray();
@@ -366,7 +380,7 @@
     auto write_edges = [&](const NodeInfo& info) {
       auto edges_it = info.edges->GetIterator();
       while (auto const pair = edges_it.Next()) {
-        pair->edge.Write(writer, pair->target);
+        pair->edge.Write(this, writer, pair->target);
       }
     };
     writer->OpenArray("edges");
@@ -398,13 +412,13 @@
   auto file_close = Dart::file_close_callback();
   if ((file_open == nullptr) || (file_write == nullptr) ||
       (file_close == nullptr)) {
-    OS::PrintErr("Could not access file callbacks to write snapshot profile.");
+    OS::PrintErr("warning: Could not access file callbacks.");
     return;
   }
 
   auto file = file_open(filename, /*write=*/true);
   if (file == nullptr) {
-    OS::PrintErr("Failed to open file %s\n", filename);
+    OS::PrintErr("warning: Failed to write snapshot profile: %s\n", filename);
   } else {
     char* output = nullptr;
     intptr_t output_length = 0;
diff --git a/runtime/vm/v8_snapshot_writer.h b/runtime/vm/v8_snapshot_writer.h
index c69abdc..6cd20bc 100644
--- a/runtime/vm/v8_snapshot_writer.h
+++ b/runtime/vm/v8_snapshot_writer.h
@@ -154,7 +154,7 @@
   static constexpr intptr_t kNumEdgeFields = 3;
 
   struct Edge {
-    enum class Type : intptr_t {
+    enum class Type : int32_t {
       kInvalid = -1,
       kContext = 0,
       kElement = 1,
@@ -177,24 +177,22 @@
     Edge(V8SnapshotProfileWriter* profile_writer,
          Type type,
          intptr_t name_or_offset)
-        : type(type),
-          name_or_offset(name_or_offset),
-          profile_writer_(profile_writer) {}
+        : type(type), name_or_offset(name_or_offset) {}
 
     inline bool operator!=(const Edge& other) {
-      return profile_writer_ != other.profile_writer_ || type != other.type ||
-             name_or_offset != other.name_or_offset;
+      return type != other.type || name_or_offset != other.name_or_offset;
     }
     inline bool operator==(const Edge& other) { return !(*this != other); }
 
-    void Write(JSONWriter* writer, const ObjectId& target_id) const;
-    void WriteDebug(JSONWriter* writer, const ObjectId& target_id) const;
+    void Write(V8SnapshotProfileWriter* profile_writer,
+               JSONWriter* writer,
+               const ObjectId& target_id) const;
+    void WriteDebug(V8SnapshotProfileWriter* profile_writer,
+                    JSONWriter* writer,
+                    const ObjectId& target_id) const;
 
     Type type;
-    intptr_t name_or_offset;
-
-   private:
-    V8SnapshotProfileWriter* profile_writer_;
+    int32_t name_or_offset;
   };
 
   struct EdgeToObjectIdMapTrait {
@@ -219,10 +217,13 @@
 
   struct EdgeMap : public ZoneDirectChainedHashMap<EdgeToObjectIdMapTrait> {
     explicit EdgeMap(Zone* zone)
-        : ZoneDirectChainedHashMap<EdgeToObjectIdMapTrait>(zone) {}
+        : ZoneDirectChainedHashMap<EdgeToObjectIdMapTrait>(zone, 1) {}
 
-    const char* ToCString(Zone* zone) const;
-    void WriteDebug(JSONWriter* writer, const char* property = nullptr) const;
+    const char* ToCString(V8SnapshotProfileWriter* profile_writer,
+                          Zone* zone) const;
+    void WriteDebug(V8SnapshotProfileWriter* profile_writer,
+                    JSONWriter* writer,
+                    const char* property = nullptr) const;
   };
 
   struct NodeInfo {
@@ -232,16 +233,14 @@
              intptr_t type = kInvalidString,
              intptr_t name = kInvalidString)
         : id(id),
-          type(type),
-          name(name),
           edges(new (profile_writer->zone_) EdgeMap(profile_writer->zone_)),
-          profile_writer_(profile_writer) {}
+          type(type),
+          name(name) {}
 
     inline bool operator!=(const NodeInfo& other) {
       return id != other.id || type != other.type || name != other.name ||
              self_size != other.self_size || edges != other.edges ||
-             offset_ != other.offset_ ||
-             profile_writer_ != other.profile_writer_;
+             offset_ != other.offset_;
     }
     inline bool operator==(const NodeInfo& other) { return !(*this != other); }
 
@@ -250,9 +249,12 @@
     }
     bool HasEdge(const Edge& edge) { return edges->HasKey(edge); }
 
-    const char* ToCString(Zone* zone) const;
-    void Write(JSONWriter* writer) const;
-    void WriteDebug(JSONWriter* writer) const;
+    const char* ToCString(V8SnapshotProfileWriter* profile_writer,
+                          Zone* zone) const;
+    void Write(V8SnapshotProfileWriter* profile_writer,
+               JSONWriter* writer) const;
+    void WriteDebug(V8SnapshotProfileWriter* profile_writer,
+                    JSONWriter* writer) const;
 
     intptr_t offset() const { return offset_; }
     void set_offset(intptr_t offset) {
@@ -261,19 +263,16 @@
     }
 
     ObjectId id;
+    EdgeMap* edges = nullptr;
     intptr_t type = kInvalidString;
     intptr_t name = kInvalidString;
     intptr_t self_size = 0;
-    EdgeMap* edges = nullptr;
 
    private:
     // Populated during serialization.
     intptr_t offset_ = -1;
     // 'trace_node_id' isn't supported.
     // 'edge_count' is computed on-demand.
-
-    // Used for debugging prints and creating default names if none given.
-    V8SnapshotProfileWriter* profile_writer_ = nullptr;
   };
 
   NodeInfo* EnsureId(const ObjectId& object_id);
diff --git a/tests/lib/isolate/function_send_test.dart b/tests/lib/isolate/function_send_test.dart
index 82b6123..cd5ee40 100644
--- a/tests/lib/isolate/function_send_test.dart
+++ b/tests/lib/isolate/function_send_test.dart
@@ -7,10 +7,15 @@
 // VMOptions=--no-enable-isolate-groups
 
 import "dart:isolate";
+import "dart:io";
 import "dart:async";
+
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
 
+final bool isolateGroupsEnabled =
+    Platform.executableArguments.contains('--enable-isolate-groups');
+
 void toplevel(port, message) {
   port.send("toplevel:$message");
 }
@@ -175,6 +180,9 @@
 }
 
 void testUnsendable(name, func) {
+  // Isolate group support does allow sending closures.
+  if (isolateGroupsEnabled) return;
+
   asyncStart();
   Isolate.spawn(nop, func).then<void>((v) => throw "allowed spawn direct?",
       onError: (e, s) {
diff --git a/tests/lib/isolate/message3_test.dart b/tests/lib/isolate/message3_test.dart
index 37bf159..6809c95 100644
--- a/tests/lib/isolate/message3_test.dart
+++ b/tests/lib/isolate/message3_test.dart
@@ -7,17 +7,23 @@
 // VMOptions=--no-enable-isolate-groups
 
 // Dart test program for testing serialization of messages.
-// VMOptions=--enable_type_checks --enable_asserts
+// VMOptions=--enable_type_checks --enable_asserts --enable-isolate-groups
+// VMOptions=--enable_type_checks --enable_asserts --no-enable-isolate-groups
 
 library MessageTest;
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:io';
 import 'dart:isolate';
+
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
 import 'dart:typed_data';
 
+final bool isolateGroupsEnabled =
+    Platform.executableArguments.contains('--enable-isolate-groups');
+
 void echoMain(msg) {
   SendPort replyTo = msg[0];
   SendPort pong = msg[1];
@@ -408,7 +414,14 @@
     Expect.equals(42, x.fun()); //     //# fun: continued
   }); //                               //# fun: continued
 
-  Expect.throws(() => ping.send(new E(new E(E.fooFun).instanceFun)));
+  if (isolateGroupsEnabled) {
+    ping.send(new E(new E(E.fooFun).instanceFun));
+    checks.add((x) {
+      Expect.equals(1234, (x as E).fun());
+    });
+  } else {
+    Expect.throws(() => ping.send(new E(new E(E.fooFun).instanceFun)));
+  }
 
   F nonConstF = new F();
   ping.send(nonConstF);
diff --git a/tests/lib_2/isolate/function_send_test.dart b/tests/lib_2/isolate/function_send_test.dart
index e5e72cf..1f208e7 100644
--- a/tests/lib_2/isolate/function_send_test.dart
+++ b/tests/lib_2/isolate/function_send_test.dart
@@ -9,10 +9,15 @@
 // VMOptions=--no-enable-isolate-groups
 
 import "dart:isolate";
+import "dart:io";
 import "dart:async";
+
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
 
+final bool isolateGroupsEnabled =
+    Platform.executableArguments.contains('--enable-isolate-groups');
+
 void toplevel(port, message) {
   port.send("toplevel:$message");
 }
@@ -151,8 +156,8 @@
     completer.complete(p);
     initPort.close();
   });
-  return Isolate.spawn(_echo, [replyPort, initPort.sendPort]).then(
-      (isolate) => completer.future);
+  return Isolate.spawn(_echo, [replyPort, initPort.sendPort])
+      .then((isolate) => completer.future);
 }
 
 void _echo(msg) {
@@ -178,6 +183,9 @@
 }
 
 void testUnsendable(name, func) {
+  // Isolate group support does allow sending closures.
+  if (isolateGroupsEnabled) return;
+
   asyncStart();
   Isolate.spawn(nop, func).then((v) => throw "allowed spawn direct?",
       onError: (e, s) {
diff --git a/tests/lib_2/isolate/message3_test.dart b/tests/lib_2/isolate/message3_test.dart
index f5c436d..4eb2c6b 100644
--- a/tests/lib_2/isolate/message3_test.dart
+++ b/tests/lib_2/isolate/message3_test.dart
@@ -9,17 +9,23 @@
 // VMOptions=--no-enable-isolate-groups
 
 // Dart test program for testing serialization of messages.
-// VMOptions=--enable_type_checks --enable_asserts
+// VMOptions=--enable_type_checks --enable_asserts --enable-isolate-groups
+// VMOptions=--enable_type_checks --enable_asserts --no-enable-isolate-groups
 
 library MessageTest;
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:io';
 import 'dart:isolate';
+
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
 import 'dart:typed_data';
 
+final bool isolateGroupsEnabled =
+    Platform.executableArguments.contains('--enable-isolate-groups');
+
 void echoMain(msg) {
   SendPort replyTo = msg[0];
   SendPort pong = msg[1];
@@ -410,7 +416,14 @@
     Expect.equals(42, x.fun()); //     //# fun: continued
   }); //                               //# fun: continued
 
-  Expect.throws(() => ping.send(new E(new E(null).instanceFun)));
+  if (isolateGroupsEnabled) {
+    ping.send(new E(new E(null).instanceFun));
+    checks.add((x) {
+      Expect.equals(1234, (x as E).fun());
+    });
+  } else {
+    Expect.throws(() => ping.send(new E(new E(null).instanceFun)));
+  }
 
   F nonConstF = new F();
   ping.send(nonConstF);
diff --git a/tools/VERSION b/tools/VERSION
index 8b74792..db0425c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 74
+PRERELEASE 75
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 5d0abed..0759d39 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -4028,14 +4028,15 @@
     }
   ],
   "sanitizer_options": {
-    "ASAN_OPTIONS": "check_initialization_order=true:handle_segv=0:detect_leaks=1:detect_stack_use_after_return=0:disable_coredump=0:abort_on_error=1",
-    "LSAN_OPTIONS": "check_initialization_order=true:handle_segv=0:detect_leaks=1:detect_stack_use_after_return=0:disable_coredump=0:abort_on_error=1",
-    "MSAN_OPTIONS": "check_initialization_order=true:handle_segv=0:detect_leaks=1:detect_stack_use_after_return=0:disable_coredump=0:abort_on_error=1",
-    "TSAN_OPTIONS": "handle_segv=0:disable_coredump=0:abort_on_error=1:report_thread_leaks=0",
-    "UBSAN_OPTIONS": "handle_segv=0:disable_coredump=0:halt_on_error=1:print_stacktrace=1"
+    "ASAN_OPTIONS": "abort_on_error=1:symbolize=1:disable_coredump=0:handle_segv=0:check_initialization_order=true:detect_leaks=1:detect_stack_use_after_return=0",
+    "LSAN_OPTIONS": "abort_on_error=1:symbolize=1:disable_coredump=0:handle_segv=0:check_initialization_order=true:detect_leaks=1:detect_stack_use_after_return=0",
+    "MSAN_OPTIONS": "abort_on_error=1:symbolize=1:disable_coredump=0:handle_segv=0:check_initialization_order=true:detect_leaks=1:detect_stack_use_after_return=0",
+    "TSAN_OPTIONS": "abort_on_error=1:symbolize=1:disable_coredump=0:handle_segv=0:report_thread_leaks=0",
+    "UBSAN_OPTIONS": "halt_on_error=1:symbolize=1:disable_coredump=0:handle_segv=0:print_stacktrace=1"
   },
   "sanitizer_symbolizer": {
     "linux": "buildtools/linux-x64/clang/bin/llvm-symbolizer",
-    "macos": "buildtools/mac-x64/clang/bin/llvm-symbolizer"
+    "macos": "buildtools/mac-x64/clang/bin/llvm-symbolizer",
+    "windows": "buildtools/win-x64/clang/bin/llvm-symbolizer.exe"
   }
 }