Version 2.12.0-51.0.dev

Merge commit 'f0c9321b1430f3904097ee2a0c52b01d5e28944f' into 'dev'
diff --git a/DEPS b/DEPS
index 4dc0fef..5621e3d 100644
--- a/DEPS
+++ b/DEPS
@@ -146,7 +146,7 @@
   "source_maps-0.9.4_rev": "38524",
   "source_maps_rev": "53eb92ccfe6e64924054f83038a534b959b12b3e",
   "source_span_rev": "49ff31eabebed0da0ae6634124f8ba5c6fbf57f1",
-  "sse_tag": "814924bac4d3cd56f40d05b3427e69f3e966d139",
+  "sse_tag": "9a486d058a17e880afa9cc1c3c0dd8bad726bcbc",
   "stack_trace_tag": "6788afc61875079b71b3d1c3e65aeaa6a25cbc2f",
   "stagehand_tag": "v3.3.11",
   "stream_channel_tag": "d7251e61253ec389ee6e045ee1042311bced8f1d",
@@ -165,7 +165,7 @@
   "web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02",
   "web_socket_channel_rev": "490061ef0e22d3c8460ad2802f9948219365ad6b",
   "WebCore_rev": "fb11e887f77919450e497344da570d780e078bc8",
-  "yaml_rev": "925c406f8bdb06ce7935f0a7d03187b36c6b62d0",
+  "yaml_rev": "cca02c9e4f6826d62644901ed65c6d72b90a0713",
   "zlib_rev": "c44fb7248079cc3d5563b14b3f758aee60d6b415",
   "crashpad_rev": "bf327d8ceb6a669607b0dbab5a83a275d03f99ed",
   "minichromium_rev": "8d641e30a8b12088649606b912c2bc4947419ccc",
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index e739602..2e797f0 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -71,6 +71,7 @@
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/change_builder/conflicting_edit_exception.dart';
 
@@ -351,11 +352,13 @@
   /// diagnostics.
   ChangeBuilder builder;
 
+  /// A map associating libraries to fixes with change counts.
+  final ChangeMap changeMap = ChangeMap();
+
   /// Initialize a newly created processor to create fixes for diagnostics in
   /// libraries in the [workspace].
-  BulkFixProcessor(this.instrumentationService, this.workspace) {
-    builder = ChangeBuilder(workspace: workspace);
-  }
+  BulkFixProcessor(this.instrumentationService, this.workspace)
+      : builder = ChangeBuilder(workspace: workspace);
 
   /// Return a change builder that has been used to create fixes for the
   /// diagnostics in the libraries in the given [contexts].
@@ -431,19 +434,38 @@
       }
     }
 
+    int computeChangeHash() {
+      var hash = 0;
+      var edits = builder.sourceChange.edits;
+      for (var i = 0; i < edits.length; ++i) {
+        hash = JenkinsSmiHash.combine(hash, edits[i].hashCode);
+      }
+      return JenkinsSmiHash.finish(hash);
+    }
+
+    Future<void> generate(CorrectionProducer producer, String code) async {
+      var oldHash = computeChangeHash();
+      await compute(producer);
+      var newHash = computeChangeHash();
+      if (newHash != oldHash) {
+        changeMap.add(result.path, code);
+      }
+    }
+
     var errorCode = diagnostic.errorCode;
     try {
+      var codeName = errorCode.name;
       if (errorCode is LintCode) {
-        var generators = lintProducerMap[errorCode.name];
+        var generators = lintProducerMap[codeName];
         if (generators != null) {
           for (var generator in generators) {
-            await compute(generator());
+            await generate(generator(), codeName);
           }
         }
       } else {
         var generator = nonLintProducerMap[errorCode];
         if (generator != null) {
-          await compute(generator());
+          await generate(generator(), codeName);
         }
         var multiGenerators = nonLintMultiProducerMap[errorCode];
         if (multiGenerators != null) {
@@ -451,7 +473,7 @@
             var multiProducer = multiGenerator();
             multiProducer.configure(context);
             for (var producer in multiProducer.producers) {
-              await compute(producer);
+              await generate(producer, codeName);
             }
           }
         }
@@ -464,3 +486,15 @@
     }
   }
 }
+
+/// Maps changes to library paths.
+class ChangeMap {
+  /// Map of paths to maps of codes to counts.
+  final Map<String, Map<String, int>> libraryMap = {};
+
+  /// Add an entry for the given [code] in the given [libraryPath].
+  void add(String libraryPath, String code) {
+    var changes = libraryMap.putIfAbsent(libraryPath, () => {});
+    changes.update(code, (value) => value + 1, ifAbsent: () => 1);
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/bulk_fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/bulk_fix_processor.dart
index 3e9e14c..1f45cc4 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/bulk_fix_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/bulk_fix_processor.dart
@@ -36,7 +36,7 @@
   }
 
   Future<void> assertHasFix(String expected) async {
-    change = await _computeFixes();
+    change = await _computeSourceChange();
 
     // apply to "file"
     var fileEdits = change.edits;
@@ -48,11 +48,22 @@
   }
 
   Future<void> assertNoFix() async {
-    change = await _computeFixes();
+    change = await _computeSourceChange();
     var fileEdits = change.edits;
     expect(fileEdits, isEmpty);
   }
 
+  /// Computes fixes for the specified [testUnit].
+  Future<BulkFixProcessor> computeFixes() async {
+    var tracker = DeclarationsTracker(MemoryByteStore(), resourceProvider);
+    var analysisContext = contextFor(testFile);
+    tracker.addContext(analysisContext);
+    var processor =
+        BulkFixProcessor(InstrumentationService.NULL_SERVICE, workspace);
+    await processor.fixErrors([analysisContext]);
+    return processor;
+  }
+
   @override
   void setUp() {
     super.setUp();
@@ -60,15 +71,10 @@
     _createAnalysisOptionsFile();
   }
 
-  /// Computes fixes for the given [error] in [testUnit].
-  Future<SourceChange> _computeFixes() async {
-    var tracker = DeclarationsTracker(MemoryByteStore(), resourceProvider);
-    var analysisContext = contextFor(testFile);
-    tracker.addContext(analysisContext);
-    var changeBuilder =
-        await BulkFixProcessor(InstrumentationService.NULL_SERVICE, workspace)
-            .fixErrors([analysisContext]);
-    return changeBuilder.sourceChange;
+  /// Returns the source change for computed fixes in the specified [testUnit].
+  Future<SourceChange> _computeSourceChange() async {
+    var processor = await computeFixes();
+    return processor.builder.sourceChange;
   }
 
   /// Create the analysis options file needed in order to correctly analyze the
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/bulk_fix_processor_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/bulk_fix_processor_test.dart
new file mode 100644
index 0000000..8ac6ee0
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/bulk_fix_processor_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ChangeMapTest);
+  });
+}
+
+@reflectiveTest
+class ChangeMapTest extends BulkFixProcessorTest {
+  Future<void> test_changeMap() async {
+    createAnalysisOptionsFile(experiments: experiments, lints: [
+      LintNames.annotate_overrides,
+      LintNames.unnecessary_new,
+    ]);
+
+    await resolveTestCode('''
+class A { }
+
+var a = new A();
+var aa = new A();
+''');
+
+    var processor = await computeFixes();
+    var changeMap = processor.changeMap;
+    var errors = changeMap.libraryMap[testFile];
+    expect(errors, hasLength(1));
+    expect(errors[LintNames.unnecessary_new], 2);
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
index 3b98bfd..14012da 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
@@ -9,6 +9,7 @@
 import 'add_diagnostic_property_reference_test.dart'
     as add_diagnostic_property_reference;
 import 'add_override_test.dart' as add_override;
+import 'bulk_fix_processor_test.dart' as bulk_fix_processor;
 import 'convert_documentation_into_line_test.dart'
     as convert_documentation_into_line;
 import 'convert_map_from_iterable_to_for_literal_test.dart'
@@ -70,6 +71,7 @@
     add_const.main();
     add_diagnostic_property_reference.main();
     add_override.main();
+    bulk_fix_processor.main();
     convert_documentation_into_line.main();
     convert_map_from_iterable_to_for_literal.main();
     convert_to_contains.main();
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index c34d83f..d97ca2a 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -20,7 +20,7 @@
   pub_semver: ^1.4.2
   source_span: ^1.2.0
   watcher: ^0.9.6
-  yaml: ^2.1.2
+  yaml: ">=2.1.2 <4.0.0"
 dev_dependencies:
   analyzer_utilities:
     path: ../analyzer_utilities
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
index 4a8c027..a1980aa 100644
--- a/pkg/analyzer_cli/pubspec.yaml
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -17,7 +17,7 @@
   meta: any
   path: any
   pub_semver: ^1.4.2
-  yaml: ^2.1.2
+  yaml: any
 
 dev_dependencies:
   pedantic: ^1.9.0
diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md
index 32be6a6..54979eb3 100644
--- a/pkg/dds/CHANGELOG.md
+++ b/pkg/dds/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 1.5.1
+- Improve internal error handling for situations with less than graceful
+  shutdowns.
+
 # 1.5.0
 - Added event caching for `Stdout`, `Stderr`, and `Extension` streams. When a
 client subscribes to one of these streams, they will be sent up to 10,000
diff --git a/pkg/dds/lib/src/dds_impl.dart b/pkg/dds/lib/src/dds_impl.dart
index d2a6dcb..fbb6bba 100644
--- a/pkg/dds/lib/src/dds_impl.dart
+++ b/pkg/dds/lib/src/dds_impl.dart
@@ -4,6 +4,27 @@
 
 part of dds;
 
+@visibleForTesting
+typedef PeerBuilder = Future<json_rpc.Peer> Function(WebSocketChannel, dynamic);
+
+@visibleForTesting
+typedef WebSocketBuilder = WebSocketChannel Function(Uri);
+
+@visibleForTesting
+PeerBuilder peerBuilder = _defaultPeerBuilder;
+
+@visibleForTesting
+WebSocketBuilder webSocketBuilder = _defaultWebSocketBuilder;
+
+Future<json_rpc.Peer> _defaultPeerBuilder(
+    WebSocketChannel ws, dynamic streamManager) async {
+  return _BinaryCompatiblePeer(ws, streamManager);
+}
+
+WebSocketChannel _defaultWebSocketBuilder(Uri uri) {
+  return WebSocketChannel.connect(uri.replace(scheme: 'ws'));
+}
+
 class _DartDevelopmentService implements DartDevelopmentService {
   _DartDevelopmentService(
       this._remoteVmServiceUri, this._uri, this._authCodesEnabled, this._ipv6) {
@@ -19,8 +40,8 @@
     final completer = Completer<void>();
     // TODO(bkonyi): throw if we've already shutdown.
     // Establish the connection to the VM service.
-    _vmServiceSocket = WebSocketChannel.connect(remoteVmServiceWsUri);
-    _vmServiceClient = _BinaryCompatiblePeer(_vmServiceSocket, _streamManager);
+    _vmServiceSocket = webSocketBuilder(remoteVmServiceWsUri);
+    _vmServiceClient = await peerBuilder(_vmServiceSocket, _streamManager);
     // Setup the JSON RPC client with the VM service.
     unawaited(
       _vmServiceClient.listen().then(
@@ -37,11 +58,15 @@
         onError: (e, st) {
           shutdown();
           if (!completer.isCompleted) {
-            completer.completeError(e, st);
+            completer.completeError(
+              DartDevelopmentServiceException._(e.toString()),
+              st,
+            );
           }
         },
       ),
     );
+
     try {
       // Setup stream event handling.
       await streamManager.listen();
@@ -93,7 +118,9 @@
     } on json_rpc.RpcException catch (e) {
       await _server.close(force: true);
       // _yieldControlToDDS fails if DDS is not the only VM service client.
-      throw DartDevelopmentServiceException._(e.data['details']);
+      throw DartDevelopmentServiceException._(
+        e.data != null ? e.data['details'] : e.toString(),
+      );
     }
 
     _uri = tmpUri;
@@ -113,7 +140,7 @@
     await clientManager.shutdown();
 
     // Close connection to VM service.
-    await _vmServiceSocket.sink.close();
+    await _vmServiceSocket?.sink?.close();
 
     _done.complete();
   }
diff --git a/pkg/dds/lib/src/stream_manager.dart b/pkg/dds/lib/src/stream_manager.dart
index 542fe91..20be940 100644
--- a/pkg/dds/lib/src/stream_manager.dart
+++ b/pkg/dds/lib/src/stream_manager.dart
@@ -208,9 +208,7 @@
         (_) => null,
         // Ignore 'stream not subscribed' errors and StateErrors which arise
         // when DDS is shutting down.
-        test: (e) =>
-            (e is json_rpc.RpcException) ||
-            (dds._shuttingDown && e is StateError),
+        test: (e) => (e is json_rpc.RpcException) || (e is StateError),
       );
     }
     // Notify other service clients of service extensions that are being
diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml
index d2fdbdb..a04a63c 100644
--- a/pkg/dds/pubspec.yaml
+++ b/pkg/dds/pubspec.yaml
@@ -3,7 +3,7 @@
   A library used to spawn the Dart Developer Service, used to communicate with
   a Dart VM Service instance.
 
-version: 1.5.0
+version: 1.5.1
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/dds
 
@@ -25,5 +25,5 @@
 dev_dependencies:
   shelf_static: ^0.2.8
   test: ^1.0.0
-  vm_service: ^4.0.0
+  vm_service: ^5.0.0
   webdriver: ^2.1.2
diff --git a/pkg/dds/test/common/fakes.dart b/pkg/dds/test/common/fakes.dart
new file mode 100644
index 0000000..7e11f9d
--- /dev/null
+++ b/pkg/dds/test/common/fakes.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2020, 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:json_rpc_2/json_rpc_2.dart' as json_rpc;
+import 'package:test/fake.dart';
+import 'package:vm_service/vm_service.dart';
+
+/// [FakePeer] implements the bare minimum of the [Peer] interface needed for
+/// [DartDevelopmentService] to establish a connection with a VM service.
+///
+/// `sendRequest` can be overridden to provide custom handling for VM service
+/// RPCs and custom RPCs to control the state of the [FakePeer] instance from a
+/// VM service client request routed through a [DartDevelopmentService] instance.
+class FakePeer extends Fake implements json_rpc.Peer {
+  @override
+  Future<void> get done => doneCompleter.future;
+  final Completer<void> doneCompleter = Completer<void>();
+
+  bool get isClosed => doneCompleter.isCompleted;
+
+  @override
+  Future<void> listen() {
+    return done;
+  }
+
+  @override
+  void registerMethod(String name, Function callback) {}
+
+  @override
+  Future<dynamic> sendRequest(String method, [args]) async {
+    switch (method) {
+      case 'getVM':
+        return _buildResponse(VM(
+          name: 'Test',
+          architectureBits: 0,
+          hostCPU: '',
+          operatingSystem: '',
+          targetCPU: '',
+          version: '',
+          pid: 0,
+          startTime: 0,
+          isolates: [],
+          isolateGroups: [],
+          systemIsolateGroups: [],
+          systemIsolates: [],
+        ));
+      default:
+        return _buildResponse(Success());
+    }
+  }
+
+  Map<String, dynamic> _buildResponse(dynamic serviceObject) {
+    return {
+      'json_rpc': '2.0',
+      'id': _idCount++,
+      ...serviceObject.toJson(),
+    };
+  }
+
+  int _idCount = 0;
+}
diff --git a/pkg/dds/test/handles_client_disconnect_state_error_test.dart b/pkg/dds/test/handles_client_disconnect_state_error_test.dart
new file mode 100644
index 0000000..2bca092
--- /dev/null
+++ b/pkg/dds/test/handles_client_disconnect_state_error_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2020, 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:dds/dds.dart';
+import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
+import 'package:pedantic/pedantic.dart';
+import 'package:test/test.dart';
+import 'package:web_socket_channel/web_socket_channel.dart';
+
+import 'common/fakes.dart';
+
+class StreamCancelDisconnectPeer extends FakePeer {
+  @override
+  Future<dynamic> sendRequest(String method, [args]) async {
+    final completer = Completer<dynamic>();
+    switch (method) {
+      case 'streamCancel':
+        completer.completeError(
+          StateError('The client closed with pending request "streamCancel".'),
+        );
+        // Notify listeners that this client is closed.
+        doneCompleter.complete();
+        break;
+      default:
+        completer.complete(await super.sendRequest(method, args));
+    }
+    return completer.future;
+  }
+}
+
+void main() {
+  webSocketBuilder = (Uri _) => null;
+  peerBuilder =
+      (WebSocketChannel _, dynamic __) async => StreamCancelDisconnectPeer();
+
+  test('StateError handled by _StreamManager.clientDisconnect', () async {
+    final dds = await DartDevelopmentService.startDartDevelopmentService(
+        Uri(scheme: 'http'));
+    final ws = await WebSocketChannel.connect(dds.uri.replace(scheme: 'ws'));
+
+    // Create a VM service client that connects to DDS.
+    final client = json_rpc.Client(ws.cast<String>());
+    unawaited(client.listen());
+
+    // Listen to a non-core DDS stream so that DDS will cancel it once the
+    // client disconnects.
+    await client.sendRequest('streamListen', {
+      'streamId': 'Service',
+    });
+
+    // Closing the client should result in DDS cleaning up stream subscriptions
+    // with no more clients subscribed to them. This will result in
+    // streamCancel being invoked, which StreamCancelDisconnectPeer overrides
+    // to act as if the VM service has shutdown with the request in flight
+    // which would result in a StateError being thrown by sendRequest. This
+    // test ensures that this exception is handled and doesn't escape outside
+    // of DDS.
+    await client.close();
+    await dds.done;
+  });
+}
diff --git a/pkg/dds/test/handles_connection_closed_before_full_header.dart b/pkg/dds/test/handles_connection_closed_before_full_header.dart
new file mode 100644
index 0000000..65d6436
--- /dev/null
+++ b/pkg/dds/test/handles_connection_closed_before_full_header.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2020, 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 'dart:io';
+
+import 'package:dds/dds.dart';
+import 'package:test/test.dart';
+
+/// Simple socket server which immediately closes the first connection and
+/// shuts down. This causes the HTTP request to the server to fail with a
+/// WebSocketChannelException: connection closed before full header was
+/// received failure, which should be caught and surfaced in a
+/// [DartDevelopmentServiceException].
+Future<Uri> startTestServer() async {
+  final server = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0);
+  server.listen((Socket request) async {
+    await request.destroy();
+    await server.close();
+  });
+  return Uri(scheme: 'http', host: server.address.host, port: server.port);
+}
+
+/// Reproduction case for https://github.com/flutter/flutter/issues/69433
+void main() async {
+  test('Handle connection closed before full header received', () async {
+    final uri = await startTestServer();
+    try {
+      await DartDevelopmentService.startDartDevelopmentService(uri);
+      fail('Unexpected successful connection.');
+    } on DartDevelopmentServiceException catch (e) {
+      expect(e.toString().contains('WebSocketChannelException'), true);
+    }
+  });
+}
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 5d79c5f..db85b79 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -5486,8 +5486,29 @@
   @override
   js_ast.Expression visitAsExpression(AsExpression node) {
     var fromExpr = node.operand;
-    var to = node.type;
     var jsFrom = _visitExpression(fromExpr);
+
+    // The `_EventStreamSubscription.cancel()` method dart:html returns null in
+    // weak mode. This causes unwanted warnings/failures when you turn on the
+    // weak mode warnings/errors so we remove these specific runtime casts.
+    // TODO(44157) Remove this workaround once it returns a consistent type.
+    if (_isWebLibrary(currentLibraryUri) && node.parent is ReturnStatement) {
+      var parent = node.parent;
+      while (parent != null && parent is! FunctionNode) {
+        parent = parent?.parent;
+      }
+      parent = parent?.parent;
+      if (parent is Procedure) {
+        if (parent.enclosingClass != null &&
+            parent.enclosingClass.name == '_EventStreamSubscription' &&
+            parent.name.name == 'cancel') {
+          // Ignore these casts and just emit the expression.
+          return jsFrom;
+        }
+      }
+    }
+
+    var to = node.type;
     var from = fromExpr.getStaticType(_staticTypeContext);
 
     // If the check was put here by static analysis to ensure soundness, we
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index 65888a8..023d555 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -49,18 +49,18 @@
     ..addFlag('sound-null-safety',
         help: 'Compile for sound null safety at runtime. Passed through to the '
             'DDC binary. Defaults to false.',
-        defaultsTo: false,
-        negatable: true)
+        defaultsTo: false)
     ..addFlag('null-assertions',
         help: 'Run with assertions that values passed to non-nullable method '
             'parameters are not null.',
-        defaultsTo: false,
-        negatable: true)
+        defaultsTo: false)
     ..addFlag('native-null-assertions',
         help: 'Run with assertions on non-nullable values returned from native '
             'APIs.',
         defaultsTo: true,
         negatable: true)
+    ..addFlag('weak-null-safety-errors',
+        help: 'Treat weak null safety warnings as errors.', defaultsTo: false)
     ..addFlag('observe',
         help:
             'Run the compiler in the Dart VM with --observe. Implies --debug.',
@@ -86,7 +86,6 @@
         abbr: 'v',
         help: 'Echos the commands, arguments, and environment this script is '
             'running.',
-        negatable: false,
         defaultsTo: false)
     ..addOption('vm-service-port',
         help: 'Specify the observatory port. Implied --observe.');
@@ -115,19 +114,10 @@
   var compile = mode == 'compile' || mode == 'all';
   var run = mode == 'run' || mode == 'all';
   var verbose = options['verbose'] as bool;
+  var soundNullSafety = options['sound-null-safety'] as bool;
   var nonNullAsserts = options['null-assertions'] as bool;
   var nativeNonNullAsserts = options['null-assertions'] as bool;
-
-  var soundNullSafety = options['sound-null-safety'] as bool;
-  // Enable null safety either by passing the `non-nullable` experiment flag or
-  // `sound-null-safety`.
-  var nnbd = experiments.contains('non-nullable') || soundNullSafety;
-
-  // Ensure non-nullable is passed as a flag.
-  if (soundNullSafety && !experiments.contains('non-nullable')) {
-    experiments.add('non-nullable');
-  }
-
+  var weakNullSafetyErrors = options['weak-null-safety-errors'] as bool;
   var entry = p.canonicalize(options.rest.first);
   var out = (options['out'] as String) ?? p.setExtension(entry, '.js');
   var libRoot = p.dirname(entry);
@@ -275,11 +265,12 @@
   require(['dart_sdk', '$basename'],
         function(sdk, app) {
     'use strict';
-    if ($nnbd) {
-      sdk.dart.weakNullSafetyWarnings(!$soundNullSafety);
-      sdk.dart.nonNullAsserts($nonNullAsserts);
-      sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
-    }
+
+    sdk.dart.weakNullSafetyWarnings(
+        !($weakNullSafetyErrors || $soundNullSafety));
+    sdk.dart.weakNullSafetyErrors($weakNullSafetyErrors);
+    sdk.dart.nonNullAsserts($nonNullAsserts);
+    sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
     sdk._debugger.registerDevtoolsFormatter();
     app.$libname.main([]);
   });
@@ -311,11 +302,11 @@
 sdk.dart.global.self = sdk.dart.global;
 let main = require(\"./$basename\").$libname.main;
 try {
-  if ($nnbd) {
-    sdk.dart.weakNullSafetyWarnings(!$soundNullSafety);
-    sdk.dart.nonNullAsserts($nonNullAsserts);
-    sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
-  }
+  sdk.dart.weakNullSafetyWarnings(
+      !($weakNullSafetyErrors || $soundNullSafety));
+  sdk.dart.weakNullSafetyErrors($weakNullSafetyErrors);
+  sdk.dart.nonNullAsserts($nonNullAsserts);
+  sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
   sdk._isolate_helper.startRootIsolate(main, []);
 } catch(e) {
   if (!source_maps) {
@@ -346,14 +337,14 @@
 load("$sdkJsPath/dart_sdk.js");
 load("$out");
 
-let dart_sdk = dart_library.import('dart_sdk');
+let sdk = dart_library.import('dart_sdk');
 // Create a self reference for JS interop tests that set fields on self.
-dart_sdk.dart.global.self = dart_sdk.dart.global;
-if ($nnbd) {
-  dart_sdk.dart.weakNullSafetyWarnings(!$soundNullSafety);
-  dart_sdk.dart.nonNullAsserts($nonNullAsserts);
-  dart_sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
-}
+sdk.dart.global.self = sdk.dart.global;
+sdk.dart.weakNullSafetyWarnings(
+    !($weakNullSafetyErrors || $soundNullSafety));
+sdk.dart.weakNullSafetyErrors($weakNullSafetyErrors);
+sdk.dart.nonNullAsserts($nonNullAsserts);
+sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
 dart_library.start('$basename', '$libname');
 ''';
       var d8File = p.setExtension(out, '.d8.js');
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index e34f9f2..77ae47b 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -38,7 +38,7 @@
   vm_service:
     path: ../vm_service
   web_socket_channel: ^1.0.4
-  yaml: '^2.1.12'
+  yaml: any
 
 dependency_overrides:
   _fe_analyzer_shared:
diff --git a/pkg/modular_test/pubspec.yaml b/pkg/modular_test/pubspec.yaml
index 19e04da..68974ee 100644
--- a/pkg/modular_test/pubspec.yaml
+++ b/pkg/modular_test/pubspec.yaml
@@ -10,8 +10,8 @@
 
 dependencies:
   args: any
-  package_config: ^1.0.5
-  yaml: ^2.1.15
+  package_config: any
+  yaml: any
 
 dev_dependencies:
   async_helper:
diff --git a/pkg/nnbd_migration/pubspec.yaml b/pkg/nnbd_migration/pubspec.yaml
index 7917b78..ed3de13 100644
--- a/pkg/nnbd_migration/pubspec.yaml
+++ b/pkg/nnbd_migration/pubspec.yaml
@@ -18,7 +18,7 @@
   path: ^1.6.2
   pub_semver: ^1.4.2
   source_span: ^1.4.1
-  yaml: ^2.1.15
+  yaml: any
 
 dev_dependencies:
   analyzer_utilities:
diff --git a/pkg/test_runner/lib/src/browser.dart b/pkg/test_runner/lib/src/browser.dart
index 521e3c9..6625a5a 100644
--- a/pkg/test_runner/lib/src/browser.dart
+++ b/pkg/test_runner/lib/src/browser.dart
@@ -147,9 +147,16 @@
 /// [testJSDir] is the relative path to the build directory where the
 /// dartdevc-generated JS file is stored. [nonNullAsserts] enables non-null
 /// assertions for non-nullable method parameters when running with weak null
-/// safety.
-String dartdevcHtml(String testName, String testNameAlias, String testJSDir,
-    Compiler compiler, NnbdMode mode, bool nonNullAsserts) {
+/// safety. [weakNullSafetyErrors] enables null safety type violations to throw
+/// when running in weak mode.
+String dartdevcHtml(
+    String testName,
+    String testNameAlias,
+    String testJSDir,
+    Compiler compiler,
+    NnbdMode mode,
+    bool nonNullAsserts,
+    bool weakNullSafetyErrors) {
   var testId = pathToJSIdentifier(testName);
   var testIdAlias = pathToJSIdentifier(testNameAlias);
   var isNnbd = mode != NnbdMode.legacy;
@@ -233,7 +240,8 @@
   };
 
   if ($isNnbd) {
-    sdk.dart.weakNullSafetyWarnings(!$isNnbdStrong);
+    sdk.dart.weakNullSafetyWarnings(!($weakNullSafetyErrors || $isNnbdStrong));
+    sdk.dart.weakNullSafetyErrors($weakNullSafetyErrors);
     sdk.dart.nonNullAsserts($nonNullAsserts);
   }
 
diff --git a/pkg/test_runner/lib/src/test_suite.dart b/pkg/test_runner/lib/src/test_suite.dart
index 53af2c7..91e0731 100644
--- a/pkg/test_runner/lib/src/test_suite.dart
+++ b/pkg/test_runner/lib/src/test_suite.dart
@@ -925,8 +925,16 @@
             Path(compilationTempDir).relativeTo(Repository.dir).toString();
         var nullAssertions =
             testFile.sharedOptions.contains('--null-assertions');
-        content = dartdevcHtml(nameNoExt, nameFromModuleRootNoExt, jsDir,
-            configuration.compiler, configuration.nnbdMode, nullAssertions);
+        var weakNullSafetyErrors =
+            testFile.ddcOptions.contains('--weak-null-safety-errors');
+        content = dartdevcHtml(
+            nameNoExt,
+            nameFromModuleRootNoExt,
+            jsDir,
+            configuration.compiler,
+            configuration.nnbdMode,
+            nullAssertions,
+            weakNullSafetyErrors);
       }
     }
 
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index 8118b63..269a793 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -3694,7 +3694,7 @@
                                                    alloc_object->cls()));
     }
   }
-  if (auto create_array = alloc->AsCreateArray()) {
+  if (alloc->IsCreateArray()) {
     AddSlot(slots,
             Slot::GetTypeArgumentsSlotFor(
                 flow_graph_->thread(),
diff --git a/runtime/vm/elf.cc b/runtime/vm/elf.cc
index 138d02e..b6abf76 100644
--- a/runtime/vm/elf.cc
+++ b/runtime/vm/elf.cc
@@ -1141,8 +1141,8 @@
                                     intptr_t offset2) {
     auto const address1 = RelocatedAddress(symbol1, offset1);
     auto const address2 = RelocatedAddress(symbol2, offset2);
+    RELEASE_ASSERT(address1 >= address2);
     auto const delta = address1 - address2;
-    RELEASE_ASSERT(delta >= 0);
     uleb128(delta);
   }
   void InitializeAbstractOrigins(intptr_t size) {
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index 197e24f..8188276 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -1208,7 +1208,7 @@
   ASSERT(compiler::target::kBitsPerWord == kBitsPerWord ||
          Utils::IsAbsoluteUint(compiler::target::kBitsPerWord, value));
   // Padding is helpful for comparing the .S with --disassemble.
-  assembly_stream_->Printf("%s 0x%0.*" Px "\n", kWordDirective,
+  assembly_stream_->Printf("%s 0x%.*" Px "\n", kWordDirective,
                            2 * compiler::target::kWordSize, value);
   return compiler::target::kWordSize;
 }
@@ -1365,7 +1365,7 @@
   if (end != end_of_words) {
     assembly_stream_->WriteString(kSizeDirectives[kInt8SizeLog2]);
     for (auto cursor = end_of_words; cursor < end; cursor++) {
-      assembly_stream_->Printf("%s 0x%0.2x", cursor != end_of_words ? "," : "",
+      assembly_stream_->Printf("%s 0x%.2x", cursor != end_of_words ? "," : "",
                                *cursor);
     }
     assembly_stream_->WriteString("\n");
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index aeacffe..3f24672 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -14518,7 +14518,7 @@
     if (!first_entry) {
       buffer->AddString(separator);
     }
-    buffer->Printf("0x%0.8" Px32 ": ", it.pc_offset());
+    buffer->Printf("0x%.8" Px32 ": ", it.pc_offset());
     for (intptr_t i = 0, n = it.Length(); i < n; i++) {
       buffer->AddString(it.IsObject(i) ? "1" : "0");
     }
@@ -24322,7 +24322,7 @@
       const intptr_t length = isolate_instructions_image.build_id_length();
       buffer.Printf("build_id: '");
       for (intptr_t i = 0; i < length; i++) {
-        buffer.Printf("%02.2x", build_id[i]);
+        buffer.Printf("%2.2x", build_id[i]);
       }
       buffer.Printf("'\n");
     }
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 91a2ddc..0c40cad 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1833,8 +1833,8 @@
   class KindBits : public BitField<int32_t, int8_t, kKindPos, kKindSize> {};
 
   struct VarInfo {
-    int32_t index_kind;  // Bitfield for slot index on stack or in context,
-                         // and Entry kind of type VarInfoKind.
+    int32_t index_kind = 0;  // Bitfield for slot index on stack or in context,
+                             // and Entry kind of type VarInfoKind.
     TokenPosition declaration_pos;  // Token position of declaration.
     TokenPosition begin_pos;        // Token position of scope start.
     TokenPosition end_pos;          // Token position of scope end.
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index bac9226..f0fa4f0 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -12,27 +12,50 @@
 @notNull
 external bool compileTimeFlag(String flag);
 
-_throwNullSafetyWarningError() => throw UnsupportedError(
-    'Null safety errors cannot be shown as warnings when running with sound '
-    'null safety.');
+_throwInvalidFlagError(String message) =>
+    throw UnsupportedError('Invalid flag combination.\n$message');
 
 @notNull
 bool _weakNullSafetyWarnings = false;
 
-/// Sets the runtime mode to show warnings when running with weak null safety.
+/// Sets the runtime mode to show warnings when types violate sound null safety.
 ///
-/// These are warnings for issues that will become errors when sound null safety
-/// is enabled. Showing warnings while running with sound null safety is not
-/// supported (they will be errors).
+/// This option is not compatible with weak null safety errors or sound null
+/// safety (the warnings will be errors).
 void weakNullSafetyWarnings(bool showWarnings) {
   if (showWarnings && compileTimeFlag('soundNullSafety')) {
-    _throwNullSafetyWarningError();
+    _throwInvalidFlagError(
+        'Null safety violations cannot be shown as warnings when running with '
+        'sound null safety.');
   }
 
   _weakNullSafetyWarnings = showWarnings;
 }
 
 @notNull
+bool _weakNullSafetyErrors = false;
+
+/// Sets the runtime mode to throw errors when types violate sound null safety.
+///
+/// This option is not compatible with weak null safety warnings (the warnings
+/// are now errors) or sound null safety (the errors are already errors).
+void weakNullSafetyErrors(bool showErrors) {
+  if (showErrors && compileTimeFlag('soundNullSafety')) {
+    _throwInvalidFlagError(
+        'Null safety violations are already thrown as errors when running with '
+        'sound null safety.');
+  }
+
+  if (showErrors && _weakNullSafetyWarnings) {
+    _throwInvalidFlagError(
+        'Null safety violations can be shown as warnings or thrown as errors, '
+        'not both.');
+  }
+
+  _weakNullSafetyErrors = showErrors;
+}
+
+@notNull
 bool _nonNullAsserts = false;
 
 /// Sets the runtime mode to insert non-null assertions on non-nullable method
@@ -250,10 +273,12 @@
   JS('void', 'console.warn(#)', arg);
 }
 
-void _nullWarn(arg) {
+void _nullWarn(message) {
   if (_weakNullSafetyWarnings) {
-    _warn('$arg\n'
+    _warn('$message\n'
         'This will become a failure when runtime null safety is enabled.');
+  } else if (_weakNullSafetyErrors) {
+    throw TypeErrorImpl(message);
   }
 }
 
diff --git a/sdk/lib/_internal/sdk_library_metadata/pubspec.yaml b/sdk/lib/_internal/sdk_library_metadata/pubspec.yaml
index 79b69ee..7f66713 100644
--- a/sdk/lib/_internal/sdk_library_metadata/pubspec.yaml
+++ b/sdk/lib/_internal/sdk_library_metadata/pubspec.yaml
@@ -2,3 +2,5 @@
 # make it easer to depend on libraries.dart from sdk packages like dart2js.
 name: sdk_library_metadata
 publish_to: none
+environment:
+  sdk: '>=2.11.0 <3.0.0'
diff --git a/tests/dartdevc/weak_null_safety_errors_test.dart b/tests/dartdevc/weak_null_safety_errors_test.dart
new file mode 100644
index 0000000..b6663e9
--- /dev/null
+++ b/tests/dartdevc/weak_null_safety_errors_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, 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.
+
+// Requirements=nnbd-weak
+
+// dartdevcOptions=--weak-null-safety-errors
+
+import 'package:expect/expect.dart';
+
+void main() {
+  Expect.throwsTypeError(() => null as int);
+  dynamic dynamicNull = null;
+  Expect.throwsTypeError(() => fn(dynamicNull));
+}
+
+void fn(StringBuffer arg) {}
diff --git a/tests/standalone/standalone_kernel.status b/tests/standalone/standalone_kernel.status
index 63813b2..47d354b 100644
--- a/tests/standalone/standalone_kernel.status
+++ b/tests/standalone/standalone_kernel.status
@@ -109,3 +109,6 @@
 
 [ $builder_tag == crossword || $compiler != dartk && $compiler != dartkp || $compiler == dartkp && $system == windows ]
 entrypoints_verification_test: SkipByDesign # Requires VM to run. Cannot run in precompiled Windows because the DLL is linked against dart.exe instead of dart_precompiled_runtime.exe. Cannot run in cross-word environment as native extension is not built.
+
+[ $compiler != dartk || $runtime != vm ]
+check_for_aot_snapshot_jit_test: SkipByDesign # Test relies on paths, requires JIT test environment.
diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status
index 52e78e2..5a07018 100644
--- a/tests/standalone_2/standalone_2_kernel.status
+++ b/tests/standalone_2/standalone_2_kernel.status
@@ -110,3 +110,6 @@
 
 [ $builder_tag == crossword || $compiler != dartk && $compiler != dartkp || $compiler == dartkp && $system == windows ]
 entrypoints_verification_test: SkipByDesign # Requires VM to run. Cannot run in precompiled Windows because the DLL is linked against dart.exe instead of dart_precompiled_runtime.exe. Cannot run in cross-word environment as native extension is not built.
+
+[ $compiler != dartk || $runtime != vm ]
+check_for_aot_snapshot_jit_test: SkipByDesign # Test relies on paths, requires JIT test environment.
diff --git a/tools/VERSION b/tools/VERSION
index 6296136..ccc77af 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 50
+PRERELEASE 51
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/generate_package_config.dart b/tools/generate_package_config.dart
index 24c69c2..9369cce 100644
--- a/tools/generate_package_config.dart
+++ b/tools/generate_package_config.dart
@@ -98,8 +98,7 @@
           .toUri(p.relative(packageDir, from: p.dirname(configFilePath)))
           .toString(),
       if (hasLibDirectory) 'packageUri': 'lib/',
-      if (version != null)
-        'languageVersion': '${version.major}.${version.minor}'
+      'languageVersion': '${version.major}.${version.minor}'
     };
   }
 }
@@ -153,18 +152,29 @@
 /// Returns `null` if there is no pubspec or no SDK constraint.
 Version pubspecLanguageVersion(String packageDir) {
   var pubspecFile = File(p.join(packageDir, 'pubspec.yaml'));
+  var relative = p.relative(packageDir, from: repoRoot);
 
-  if (!pubspecFile.existsSync()) return null;
+  if (!pubspecFile.existsSync()) {
+    print("Error: Missing pubspec for $relative.");
+    exit(1);
+  }
 
   var pubspec =
       loadYaml(pubspecFile.readAsStringSync()) as Map<dynamic, dynamic>;
-  if (!pubspec.containsKey('environment')) return null;
+  if (!pubspec.containsKey('environment')) {
+    print("Error: Pubspec for $relative has no SDK constraint.");
+    exit(1);
+  }
 
   var environment = pubspec['environment'] as Map<dynamic, dynamic>;
-  if (!environment.containsKey('sdk')) return null;
+  if (!environment.containsKey('sdk')) {
+    print("Error: Pubspec for $relative has no SDK constraint.");
+    exit(1);
+  }
 
   var sdkConstraint = VersionConstraint.parse(environment['sdk'] as String);
   if (sdkConstraint is VersionRange) return sdkConstraint.min;
 
-  return null;
+  print("Error: SDK constraint $relative is not a version range.");
+  exit(1);
 }