Version 2.13.0-59.0.dev

Merge commit '9d4ad8a14bb401dc1f22d730135a7c19b07c97f3' into 'dev'
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index e5f6988..57e7ef4 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html><html><head>
   <meta charset="UTF-8">
   <title>Analysis Server API Specification</title>
-<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro|Roboto:500,400italic,300,400" type="text/css"><style>body {
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@300;400;700&amp;family=Roboto:ital,wght@0,300;0,400;0,700;1,400&amp;display=swap" type="text/css"><style>body {
   font-family: 'Roboto', sans-serif;
   max-width: 800px;
   margin: 0 auto;
@@ -37,7 +37,7 @@
 
 pre {
   margin: 0;
-  font-family: 'Source Code Pro', monospace;
+  font-family: 'Roboto Mono', monospace;
   font-size: 15px;
 }
 
@@ -116,7 +116,7 @@
   analysis server. The API in this document is currently under
   development. Changes to the API will be accompanied by an update to the
   protocol version number according to the principles of semantic
-  versioning (<a href="http://semver.org/">semver.org</a>).
+  versioning (<a href="https://semver.org/">semver.org</a>).
 </p>
 <h2>Overview</h2>
 <p>
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 4430ee5..a404e8c 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -27,6 +27,7 @@
 import 'package:analyzer/src/manifest/manifest_validator.dart';
 import 'package:analyzer/src/pubspec/pubspec_validator.dart';
 import 'package:analyzer/src/task/options.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer/src/util/glob.dart';
 import 'package:analyzer/src/workspace/bazel.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
@@ -147,21 +148,6 @@
 /// Class that maintains a mapping from included/excluded paths to a set of
 /// folders that should correspond to analysis contexts.
 class ContextManagerImpl implements ContextManager {
-  /// The name of the data file used to specify data-driven fixes.
-  static const String dataFileName = 'fix_data.yaml';
-
-  /// The name of the `doc` directory.
-  static const String DOC_DIR_NAME = 'doc';
-
-  /// File name of Android manifest files.
-  static const String MANIFEST_NAME = 'AndroidManifest.xml';
-
-  /// File name of pubspec files.
-  static const String PUBSPEC_NAME = 'pubspec.yaml';
-
-  /// File name of package spec files.
-  static const String PACKAGE_SPEC_NAME = '.packages';
-
   /// The [ResourceProvider] using which paths are converted into [Resource]s.
   final ResourceProvider resourceProvider;
 
@@ -409,7 +395,7 @@
   }
 
   void _checkForDataFileUpdate(String path) {
-    if (_isDataFile(path)) {
+    if (file_paths.isFixDataYaml(pathContext, path)) {
       var context = getContextFor(path);
       var driver = context.driver;
       _analyzeDataFile(driver, path);
@@ -417,7 +403,7 @@
   }
 
   void _checkForManifestUpdate(String path) {
-    if (_isManifest(path)) {
+    if (file_paths.isAndroidManifestXml(pathContext, path)) {
       var context = getContextFor(path);
       var driver = context.driver;
       _analyzeManifestFile(driver, path);
@@ -478,12 +464,12 @@
 
       var dataFile = rootFolder
           .getChildAssumingFolder('lib')
-          .getChildAssumingFile(dataFileName);
+          .getChildAssumingFile(file_paths.fixDataYaml);
       if (dataFile.exists) {
         _analyzeDataFile(driver, dataFile.path);
       }
 
-      var pubspecFile = rootFolder.getChildAssumingFile(PUBSPEC_NAME);
+      var pubspecFile = rootFolder.getChildAssumingFile(file_paths.pubspecYaml);
       if (pubspecFile.exists) {
         _analyzePubspecFile(driver, pubspecFile.path);
       }
@@ -496,7 +482,7 @@
 
         for (var child in folder.getChildren()) {
           if (child is File) {
-            if (child.shortName == MANIFEST_NAME &&
+            if (file_paths.isAndroidManifestXml(pathContext, child.path) &&
                 !excludedPaths.contains(child.path)) {
               _analyzeManifestFile(driver, child.path);
             }
@@ -582,15 +568,16 @@
 
     _instrumentationService.logWatchEvent('<unknown>', path, type.toString());
 
-    if (_isPackageConfigJsonFilePath(path) ||
-        _isDotPackagesFilePath(path) ||
-        _isPubspec(path) ||
-        AnalysisEngine.isAnalysisOptionsFileName(path, pathContext)) {
+    if (file_paths.isAnalysisOptionsYaml(pathContext, path) ||
+        file_paths.isDotPackages(pathContext, path) ||
+        file_paths.isPackageConfigJson(pathContext, path) ||
+        file_paths.isPubspecYaml(pathContext, path) ||
+        false) {
       _createAnalysisContexts();
       return;
     }
 
-    if (path.endsWith('.dart')) {
+    if (file_paths.isDart(pathContext, path)) {
       for (var analysisContext_ in _collection.contexts) {
         var analysisContext = analysisContext_ as DriverBasedAnalysisContext;
         switch (type) {
@@ -651,25 +638,6 @@
     return false;
   }
 
-  /// Return `true` if the [path] appears to be the name of the data file used
-  /// to specify data-driven fixes.
-  bool _isDataFile(String path) => pathContext.basename(path) == dataFileName;
-
-  bool _isDotPackagesFilePath(String path) {
-    return pathContext.basename(path) == PACKAGE_SPEC_NAME;
-  }
-
-  bool _isManifest(String path) => pathContext.basename(path) == MANIFEST_NAME;
-
-  bool _isPackageConfigJsonFilePath(String path) {
-    var components = pathContext.split(path);
-    return components.length > 2 &&
-        components[components.length - 1] == 'package_config.json' &&
-        components[components.length - 2] == '.dart_tool';
-  }
-
-  bool _isPubspec(String path) => pathContext.basename(path) == PUBSPEC_NAME;
-
   /// Read the contents of the file at the given [path], or throw an exception
   /// if the contents cannot be read.
   String _readFile(String path) {
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index d649879..6c26a54 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -24,6 +24,7 @@
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer/src/util/performance/operation_performance.dart';
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -152,7 +153,7 @@
   /// given [offset].
   YamlCompletionResults computeYamlSuggestions(String file, int offset) {
     var provider = server.resourceProvider;
-    if (AnalysisEngine.isAnalysisOptionsFileName(file)) {
+    if (file_paths.isAnalysisOptionsYaml(provider.pathContext, file)) {
       var generator = AnalysisOptionsGenerator(provider);
       return generator.getSuggestions(file, offset);
     }
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 6cbe8fa..dc88ddf 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -54,6 +54,7 @@
 import 'package:analyzer/src/manifest/manifest_values.dart';
 import 'package:analyzer/src/pubspec/pubspec_validator.dart';
 import 'package:analyzer/src/task/options.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:dart_style/dart_style.dart';
@@ -780,14 +781,14 @@
   /// Compute and return the fixes associated with server-generated errors.
   Future<List<AnalysisErrorFixes>> _computeServerErrorFixes(
       Request request, String file, int offset) async {
-    var context = server.resourceProvider.pathContext;
+    var pathContext = server.resourceProvider.pathContext;
     if (AnalysisEngine.isDartFileName(file)) {
       return _computeDartFixes(request, file, offset);
-    } else if (AnalysisEngine.isAnalysisOptionsFileName(file, context)) {
+    } else if (file_paths.isAnalysisOptionsYaml(pathContext, file)) {
       return _computeAnalysisOptionsFixes(file, offset);
-    } else if (context.basename(file) == 'pubspec.yaml') {
+    } else if (file_paths.isPubspecYaml(pathContext, file)) {
       return _computePubspecFixes(file, offset);
-    } else if (context.basename(file) == 'manifest.xml') {
+    } else if (pathContext.basename(file) == 'manifest.xml') {
       // TODO(brianwilkerson) Do we need to check more than the file name?
       return _computeManifestFixes(file, offset);
     }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
index fccc0eb..1aac9f8 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
@@ -4,14 +4,13 @@
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
-import 'package:analysis_server/src/context_manager.dart'
-    show ContextManagerImpl;
 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/lsp/source_edits.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:path/path.dart' show dirname, join;
 
 /// Finds the nearest ancestor to [filePath] that contains a pubspec/.packages/build file.
@@ -20,9 +19,9 @@
   var folder = dirname(filePath);
   while (folder != dirname(folder)) {
     final pubspec =
-        resourceProvider.getFile(join(folder, ContextManagerImpl.PUBSPEC_NAME));
-    final packages = resourceProvider
-        .getFile(join(folder, ContextManagerImpl.PACKAGE_SPEC_NAME));
+        resourceProvider.getFile(join(folder, file_paths.pubspecYaml));
+    final packages =
+        resourceProvider.getFile(join(folder, file_paths.dotPackages));
     final build = resourceProvider.getFile(join(folder, 'BUILD'));
 
     if (pubspec.exists || packages.exists || build.exists) {
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 94445ff..dfa44a4 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -1310,7 +1310,7 @@
 
   void _assertFlushedResults(List<String> paths) {
     var convertedPaths = paths.map(convertPath).toList();
-    expect(flushResults, convertedPaths);
+    expect(flushResults, unorderedEquals(convertedPaths));
     flushResults.clear();
   }
 
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index a2c3b0a..5a582d5 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -14,7 +14,7 @@
   analysis server. The API in this document is currently under
   development. Changes to the API will be accompanied by an update to the
   protocol version number according to the principles of semantic
-  versioning (<a href="http://semver.org/">semver.org</a>).
+  versioning (<a href="https://semver.org/">semver.org</a>).
 </p>
 <h2>Overview</h2>
 <p>
diff --git a/pkg/analysis_server/tool/spec/to_html.dart b/pkg/analysis_server/tool/spec/to_html.dart
index 7246acd..35768e6 100644
--- a/pkg/analysis_server/tool/spec/to_html.dart
+++ b/pkg/analysis_server/tool/spec/to_html.dart
@@ -52,7 +52,7 @@
 
 pre {
   margin: 0;
-  font-family: 'Source Code Pro', monospace;
+  font-family: 'Roboto Mono', monospace;
   font-size: 15px;
 }
 
@@ -441,7 +441,7 @@
               element('link', {
                 'rel': 'stylesheet',
                 'href':
-                    'https://fonts.googleapis.com/css?family=Source+Code+Pro|Roboto:500,400italic,300,400',
+                    'https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@300;400;700&family=Roboto:ital,wght@0,300;0,400;0,700;1,400&display=swap',
                 'type': 'text/css'
               });
               element('style', {}, () {
diff --git a/pkg/analyzer/lib/src/error/imports_verifier.dart b/pkg/analyzer/lib/src/error/imports_verifier.dart
index caeba58..c421a30 100644
--- a/pkg/analyzer/lib/src/error/imports_verifier.dart
+++ b/pkg/analyzer/lib/src/error/imports_verifier.dart
@@ -414,15 +414,18 @@
         _unusedImports.isEmpty && _unusedShownNamesMap.isEmpty;
 
     // Process import prefixes.
-    usedElements.prefixMap
-        .forEach((PrefixElement prefix, List<Element> elements) {
+    for (var entry in usedElements.prefixMap.entries) {
       if (everythingIsKnownToBeUsed()) {
         return;
       }
+      var prefix = entry.key;
+      var importDirectives = _prefixElementMap[prefix];
+      if (importDirectives == null) {
+        continue;
+      }
+      var elements = entry.value;
       // Find import directives using namespaces.
-      for (var importDirective
-          in _prefixElementMap[prefix] ?? <ImportDirective>[]) {
-        var namespace = _computeNamespace(importDirective);
+      for (var importDirective in importDirectives) {
         if (elements.isEmpty) {
           // [prefix] and [elements] were added to [usedElements.prefixMap] but
           // [elements] is empty, so the prefix was referenced incorrectly.
@@ -430,14 +433,19 @@
           // shouldn't confuse by also reporting an unused prefix.
           _unusedImports.remove(importDirective);
         }
+        var namespace = _computeNamespace(importDirective);
+        if (namespace == null) {
+          continue;
+        }
         for (var element in elements) {
-          if (namespace?.getPrefixed(prefix.name, element.name!) != null) {
+          if (namespace.getPrefixed(prefix.name, element.name!) != null) {
             _unusedImports.remove(importDirective);
             _removeFromUnusedShownNamesMap(element, importDirective);
           }
         }
       }
-    });
+    }
+
     // Process top-level elements.
     for (Element element in usedElements.elements) {
       if (everythingIsKnownToBeUsed()) {
@@ -460,10 +468,13 @@
       // Find import directives using namespaces.
       for (ImportDirective importDirective in _allImports) {
         var namespace = _computeNamespace(importDirective);
+        if (namespace == null) {
+          continue;
+        }
         var prefix = importDirective.prefix?.name;
         var elementName = extensionElement.name!;
         if (prefix == null) {
-          if (namespace?.get(elementName) == extensionElement) {
+          if (namespace.get(elementName) == extensionElement) {
             _unusedImports.remove(importDirective);
             _removeFromUnusedShownNamesMap(extensionElement, importDirective);
           }
@@ -471,7 +482,7 @@
           // An extension might be used solely because one or more instance
           // members are referenced, which does not require explicit use of the
           // prefix. We still indicate that the import directive is used.
-          if (namespace?.getPrefixed(prefix, elementName) == extensionElement) {
+          if (namespace.getPrefixed(prefix, elementName) == extensionElement) {
             _unusedImports.remove(importDirective);
             _removeFromUnusedShownNamesMap(extensionElement, importDirective);
           }
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index f82bc93..12491b5 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -15,7 +15,6 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/summary/api_signature.dart';
-import 'package:path/path.dart' as pathos;
 import 'package:pub_semver/pub_semver.dart';
 
 export 'package:analyzer/error/listener.dart' show RecordingErrorListener;
@@ -141,16 +140,6 @@
   @deprecated
   void processRequiredPlugins() {}
 
-  /// Return `true` if the given [fileName] is an analysis options file.
-  static bool isAnalysisOptionsFileName(String? fileName,
-      [pathos.Context? context]) {
-    if (fileName == null) {
-      return false;
-    }
-    String basename = (context ?? pathos.posix).basename(fileName);
-    return basename == ANALYSIS_OPTIONS_YAML_FILE;
-  }
-
   /// Return `true` if the given [fileName] is assumed to contain Dart source
   /// code.
   static bool isDartFileName(String? fileName) {
@@ -160,14 +149,6 @@
     String extension = FileNameUtilities.getExtension(fileName).toLowerCase();
     return extension == SUFFIX_DART;
   }
-
-  /// Return `true` if the given [fileName] is AndroidManifest.xml.
-  static bool isManifestFileName(String? fileName) {
-    if (fileName == null) {
-      return false;
-    }
-    return fileName.endsWith(AnalysisEngine.ANDROID_MANIFEST_FILE);
-  }
 }
 
 /// The analysis errors and line information for the errors.
diff --git a/pkg/analyzer/lib/src/util/file_paths.dart b/pkg/analyzer/lib/src/util/file_paths.dart
new file mode 100644
index 0000000..46e450f
--- /dev/null
+++ b/pkg/analyzer/lib/src/util/file_paths.dart
@@ -0,0 +1,62 @@
+// 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.
+
+/// The set of constants and utilities to check file paths.
+///
+/// The recommended import prefix in `file_paths`.
+import 'package:path/path.dart' as p;
+
+/// The file name used for analysis options files.
+const String analysisOptionsYaml = 'analysis_options.yaml';
+
+/// File name of Android manifest files.
+const String androidManifestXml = 'AndroidManifest.xml';
+
+/// File name of package spec files.
+const String dotPackages = '.packages';
+
+/// The name of the data file used to specify data-driven fixes.
+const String fixDataYaml = 'fix_data.yaml';
+
+/// File name of pubspec files.
+const String pubspecYaml = 'pubspec.yaml';
+
+/// Return `true` if [path] is an analysis options file.
+bool isAnalysisOptionsYaml(p.Context pathContext, String path) {
+  return pathContext.basename(path) == analysisOptionsYaml;
+}
+
+/// Return `true` if [path] is a `AndroidManifest.xml` file.
+bool isAndroidManifestXml(p.Context pathContext, String path) {
+  return pathContext.basename(path) == androidManifestXml;
+}
+
+/// Return `true` if [path] is a Dart file.
+bool isDart(p.Context pathContext, String path) {
+  return pathContext.extension(path) == '.dart';
+}
+
+/// Return `true` if [path] is a `.packages` file.
+bool isDotPackages(p.Context pathContext, String path) {
+  return pathContext.basename(path) == dotPackages;
+}
+
+/// Return `true` if the [path] is a `fix_data.yaml` file.
+/// Such files specify data-driven fixes.
+bool isFixDataYaml(p.Context pathContext, String path) {
+  return pathContext.basename(path) == fixDataYaml;
+}
+
+/// Return `true` if [path] is a `.dart_tool/package_config.json` file.
+bool isPackageConfigJson(p.Context pathContext, String path) {
+  var components = pathContext.split(path);
+  return components.length > 2 &&
+      components[components.length - 1] == 'package_config.json' &&
+      components[components.length - 2] == '.dart_tool';
+}
+
+/// Return `true` if [path] is a `pubspec.yaml` file.
+bool isPubspecYaml(p.Context pathContext, String path) {
+  return pathContext.basename(path) == pubspecYaml;
+}
diff --git a/pkg/analyzer/test/src/diagnostics/null_aware_in_condition_test.dart b/pkg/analyzer/test/src/diagnostics/null_aware_in_condition_test.dart
index 4c3a84ba..ec3781d 100644
--- a/pkg/analyzer/test/src/diagnostics/null_aware_in_condition_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/null_aware_in_condition_test.dart
@@ -16,8 +16,6 @@
 @reflectiveTest
 class NullAwareInConditionTest extends PubPackageResolutionTest
     with WithoutNullSafetyMixin {
-  // TODO(https://github.com/dart-lang/sdk/issues/44666): Use null safety in
-  //  test cases.
   test_assert() async {
     await assertErrorsInCode(r'''
 m(x) {
diff --git a/pkg/analyzer/test/src/diagnostics/null_aware_in_logical_operator_test.dart b/pkg/analyzer/test/src/diagnostics/null_aware_in_logical_operator_test.dart
index 384de5c..6ce804b 100644
--- a/pkg/analyzer/test/src/diagnostics/null_aware_in_logical_operator_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/null_aware_in_logical_operator_test.dart
@@ -16,8 +16,6 @@
 @reflectiveTest
 class NullAwareInLogicalOperatorTest extends PubPackageResolutionTest
     with WithoutNullSafetyMixin {
-  // TODO(https://github.com/dart-lang/sdk/issues/44666): Use null safety in
-  //  test cases.
   test_conditionalAnd_first() async {
     await assertErrorsInCode(r'''
 m(x) {
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index cd9a1cc..7452a90 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -36,6 +36,7 @@
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/summary/summary_sdk.dart' show SummaryBasedDartSdk;
 import 'package:analyzer/src/task/options.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer/src/util/yaml.dart';
 import 'package:analyzer_cli/src/analyzer_impl.dart';
 import 'package:analyzer_cli/src/batch_mode.dart';
@@ -495,11 +496,12 @@
     } else {
       var directory = io.Directory(filePath);
       if (directory.existsSync()) {
+        var pathContext = resourceProvider.pathContext;
         for (var entry
             in directory.listSync(recursive: true, followLinks: false)) {
           var relative = path.relative(entry.path, from: directory.path);
-          if ((AnalysisEngine.isDartFileName(entry.path) ||
-                  AnalysisEngine.isManifestFileName(entry.path)) &&
+          if ((file_paths.isDart(pathContext, entry.path) ||
+                  file_paths.isAndroidManifestXml(pathContext, entry.path)) &&
               entry is io.File &&
               !pathFilter.ignored(entry.path) &&
               !_isInHiddenDir(relative)) {
diff --git a/pkg/dev_compiler/lib/src/compiler/js_names.dart b/pkg/dev_compiler/lib/src/compiler/js_names.dart
index 7d3ff1e..81e3899 100644
--- a/pkg/dev_compiler/lib/src/compiler/js_names.dart
+++ b/pkg/dev_compiler/lib/src/compiler/js_names.dart
@@ -399,6 +399,7 @@
   '&': 'bitAnd',
   '<<': 'leftShift',
   '>>': 'rightShift',
+  '>>>': 'tripleShift',
   '~': 'bitNot',
   // These ones are always renamed, hence the choice of `_` to avoid conflict
   // with Dart names. See _emitMemberName.
diff --git a/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt b/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
index 960c5e4..98ddc8c 100644
--- a/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
+++ b/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
@@ -1,6 +1,7 @@
 ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|Superinterfaces don't have a valid override for '&': JSNumber.& (num Function(num)), int.& (int Function(int)).
 ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|Superinterfaces don't have a valid override for '<<': JSNumber.<< (num Function(num)), int.<< (int Function(int)).
 ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|Superinterfaces don't have a valid override for '>>': JSNumber.>> (num Function(num)), int.>> (int Function(int)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|Superinterfaces don't have a valid override for '>>>': JSNumber.>>> (num Function(num)), int.>>> (int Function(int)).
 ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|Superinterfaces don't have a valid override for '\|': JSNumber.\| (num Function(num)), int.\| (int Function(int)).
 ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|Superinterfaces don't have a valid override for '^': JSNumber.^ (num Function(num)), int.^ (int Function(int)).
 ERROR|COMPILE_TIME_ERROR|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|The operator '&' isn't defined for the type 'JSInt'.
diff --git a/pkg/dev_compiler/tool/patch_sdk.dart b/pkg/dev_compiler/tool/patch_sdk.dart
index dd83595..f1cd943 100755
--- a/pkg/dev_compiler/tool/patch_sdk.dart
+++ b/pkg/dev_compiler/tool/patch_sdk.dart
@@ -478,7 +478,7 @@
 ParseStringResult _parseString(String source, {bool useNnbd}) {
   var features = FeatureSet.fromEnableFlags2(
     sdkLanguageVersion: Version.parse('2.10.0'),
-    flags: [if (useNnbd) 'non-nullable'],
+    flags: [if (useNnbd) 'non-nullable', 'triple-shift'],
   );
   return parseString(content: source, featureSet: features);
 }
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
index 2c56811..e08bdf9 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
@@ -141,6 +141,7 @@
 const AllowedExperimentalFlags defaultAllowedExperimentalFlags =
     const AllowedExperimentalFlags(sdkDefaultExperiments: {
   ExperimentalFlag.nonNullable,
+  ExperimentalFlag.tripleShift,
 }, sdkLibraryExperiments: {}, packageExperiments: {
   "async": {
     ExperimentalFlag.nonNullable,
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.expect b/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.expect
index a425f18..bb1a380 100644
--- a/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.expect
+++ b/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.expect
@@ -7,25 +7,10 @@
 // const int unaryPlus = +2;
 //                       ^
 //
-// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:6:30: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int shiftNegative2 = 2 >>> -1;
-//                              ^^^
-//
 // pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
 // const int divZero = 2 / 0;
 //                       ^
 //
-// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:27:29: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int binaryShift2 = 84 >>> 1;
-//                             ^^^
-//
-// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:28:29: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int binaryShift3 = 21 >>> 64;
-//                             ^^^
-//
 // pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:5:30: Error: Constant evaluation error:
 // const int shiftNegative1 = 2 << -1;
 //                              ^
@@ -36,6 +21,16 @@
 // const int shiftNegative1 = 2 << -1;
 //           ^
 //
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:6:30: Error: Constant evaluation error:
+// const int shiftNegative2 = 2 >>> -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:6:30: Context: Binary operator '>>>' on '2.0' requires non-negative operand, but was '-1.0'.
+// const int shiftNegative2 = 2 >>> -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:6:11: Context: While analyzing:
+// const int shiftNegative2 = 2 >>> -1;
+//           ^
+//
 // pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:7:30: Error: Constant evaluation error:
 // const int shiftNegative3 = 2 >> -1;
 //                              ^
@@ -100,10 +95,7 @@
 import "dart:core" as core;
 
 static const field core::int* shiftNegative1 = invalid-expression "Binary operator '<<' on '2.0' requires non-negative operand, but was '-1.0'.";
-static const field core::int* shiftNegative2 = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:6:30: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int shiftNegative2 = 2 >>> -1;
-                             ^^^";
+static const field core::int* shiftNegative2 = invalid-expression "Binary operator '>>>' on '2.0' requires non-negative operand, but was '-1.0'.";
 static const field core::int* shiftNegative3 = invalid-expression "Binary operator '>>' on '2.0' requires non-negative operand, but was '-1.0'.";
 static const field core::int* modZero = invalid-expression "Binary operator '%' on '2.0' requires non-zero divisor, but divisor was '0'.";
 static const field core::int* divZero = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
@@ -125,35 +117,30 @@
 static const field core::int* binaryAnd = #C3;
 static const field core::int* binaryXor = #C3;
 static const field core::int* binaryShift1 = #C3;
-static const field core::int* binaryShift2 = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:27:29: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int binaryShift2 = 84 >>> 1;
-                            ^^^";
-static const field core::int* binaryShift3 = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:28:29: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int binaryShift3 = 21 >>> 64;
-                            ^^^";
+static const field core::int* binaryShift2 = #C3;
+static const field core::int* binaryShift3 = #C4;
 static const field core::int* binaryShift4 = #C3;
-static const field core::int* binaryShift5 = #C4;
-static const field core::bool* binaryLess = #C5;
-static const field core::bool* binaryLessEqual = #C6;
-static const field core::bool* binaryGreaterEqual = #C6;
-static const field core::bool* binaryGreater = #C5;
+static const field core::int* binaryShift5 = #C5;
+static const field core::bool* binaryLess = #C6;
+static const field core::bool* binaryLessEqual = #C7;
+static const field core::bool* binaryGreaterEqual = #C7;
+static const field core::bool* binaryGreater = #C6;
 static const field core::int* doubleTruncateDiv = #C3;
 static const field core::int* doubleTruncateDivZero = invalid-expression "Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.";
 static const field core::int* doubleTruncateDivNull = invalid-expression "Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.";
-static const field core::double* doubleNan = #C7;
+static const field core::double* doubleNan = #C8;
 static const field core::int* doubleTruncateDivNaN = invalid-expression "Binary operator '84.2 ~/ NaN' results is Infinity or NaN.";
-static const field core::int* bigNumber = #C8;
+static const field core::int* bigNumber = #C9;
 static method main() → dynamic {}
 
 constants  {
   #C1 = -2.0
   #C2 = 4294967293.0
   #C3 = 42.0
-  #C4 = 4294967295.0
-  #C5 = false
-  #C6 = true
-  #C7 = NaN
-  #C8 = 9223372036854776000.0
+  #C4 = 0.0
+  #C5 = 4294967295.0
+  #C6 = false
+  #C7 = true
+  #C8 = NaN
+  #C9 = 9223372036854776000.0
 }
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.outline.expect b/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.outline.expect
index 870f990..ce47e53 100644
--- a/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.outline.expect
@@ -7,33 +7,15 @@
 // const int unaryPlus = +2;
 //                       ^
 //
-// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:6:30: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int shiftNegative2 = 2 >>> -1;
-//                              ^^^
-//
 // pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
 // const int divZero = 2 / 0;
 //                       ^
 //
-// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:27:29: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int binaryShift2 = 84 >>> 1;
-//                             ^^^
-//
-// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:28:29: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int binaryShift3 = 21 >>> 64;
-//                             ^^^
-//
 import self as self;
 import "dart:core" as core;
 
 static const field core::int* shiftNegative1 = 2.{core::int::<<}(1.{core::int::unary-}(){() →* core::int*}){(core::int*) →* core::int*};
-static const field core::int* shiftNegative2 = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:6:30: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int shiftNegative2 = 2 >>> -1;
-                             ^^^" as{TypeError,ForDynamic} core::int*;
+static const field core::int* shiftNegative2 = 2.{core::int::>>>}(1.{core::int::unary-}(){() →* core::int*}){(core::int*) →* core::int*};
 static const field core::int* shiftNegative3 = 2.{core::int::>>}(1.{core::int::unary-}(){() →* core::int*}){(core::int*) →* core::int*};
 static const field core::int* modZero = 2.{core::num::%}(0){(core::num*) →* core::int*};
 static const field core::int* divZero = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
@@ -55,14 +37,8 @@
 static const field core::int* binaryAnd = 63.{core::int::&}(106){(core::int*) →* core::int*};
 static const field core::int* binaryXor = 63.{core::int::^}(21){(core::int*) →* core::int*};
 static const field core::int* binaryShift1 = 21.{core::int::<<}(1){(core::int*) →* core::int*};
-static const field core::int* binaryShift2 = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:27:29: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int binaryShift2 = 84 >>> 1;
-                            ^^^" as{TypeError,ForDynamic} core::int*;
-static const field core::int* binaryShift3 = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:28:29: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int binaryShift3 = 21 >>> 64;
-                            ^^^" as{TypeError,ForDynamic} core::int*;
+static const field core::int* binaryShift2 = 84.{core::int::>>>}(1){(core::int*) →* core::int*};
+static const field core::int* binaryShift3 = 21.{core::int::>>>}(64){(core::int*) →* core::int*};
 static const field core::int* binaryShift4 = 84.{core::int::>>}(1){(core::int*) →* core::int*};
 static const field core::int* binaryShift5 = 1.{core::int::unary-}(){() →* core::int*}.{core::int::>>}(1){(core::int*) →* core::int*};
 static const field core::bool* binaryLess = 42.{core::num::<}(42){(core::num*) →* core::bool*};
@@ -81,6 +57,7 @@
 
 Extra constant evaluation status:
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:5:33 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:6:34 -> DoubleConstant(-1.0)
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:7:33 -> DoubleConstant(-1.0)
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:9:23 -> DoubleConstant(Infinity)
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:11:24 -> DoubleConstant(-2.0)
@@ -95,6 +72,8 @@
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:22:26 -> DoubleConstant(42.0)
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:23:26 -> DoubleConstant(42.0)
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:24:29 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:27:29 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:28:29 -> DoubleConstant(0.0)
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:30:29 -> DoubleConstant(42.0)
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:31:29 -> DoubleConstant(4294967295.0)
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:32:28 -> BoolConstant(false)
@@ -104,4 +83,4 @@
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:37:36 -> DoubleConstant(42.0)
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:40:27 -> DoubleConstant(NaN)
 Evaluated: StaticGet @ org-dartlang-testcase:///number_folds.dart:41:42 -> DoubleConstant(NaN)
-Extra constant evaluation: evaluated: 38, effectively constant: 24
+Extra constant evaluation: evaluated: 39, effectively constant: 27
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.transformed.expect
index a425f18..bb1a380 100644
--- a/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.transformed.expect
@@ -7,25 +7,10 @@
 // const int unaryPlus = +2;
 //                       ^
 //
-// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:6:30: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int shiftNegative2 = 2 >>> -1;
-//                              ^^^
-//
 // pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
 // const int divZero = 2 / 0;
 //                       ^
 //
-// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:27:29: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int binaryShift2 = 84 >>> 1;
-//                             ^^^
-//
-// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:28:29: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int binaryShift3 = 21 >>> 64;
-//                             ^^^
-//
 // pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:5:30: Error: Constant evaluation error:
 // const int shiftNegative1 = 2 << -1;
 //                              ^
@@ -36,6 +21,16 @@
 // const int shiftNegative1 = 2 << -1;
 //           ^
 //
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:6:30: Error: Constant evaluation error:
+// const int shiftNegative2 = 2 >>> -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:6:30: Context: Binary operator '>>>' on '2.0' requires non-negative operand, but was '-1.0'.
+// const int shiftNegative2 = 2 >>> -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:6:11: Context: While analyzing:
+// const int shiftNegative2 = 2 >>> -1;
+//           ^
+//
 // pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:7:30: Error: Constant evaluation error:
 // const int shiftNegative3 = 2 >> -1;
 //                              ^
@@ -100,10 +95,7 @@
 import "dart:core" as core;
 
 static const field core::int* shiftNegative1 = invalid-expression "Binary operator '<<' on '2.0' requires non-negative operand, but was '-1.0'.";
-static const field core::int* shiftNegative2 = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:6:30: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int shiftNegative2 = 2 >>> -1;
-                             ^^^";
+static const field core::int* shiftNegative2 = invalid-expression "Binary operator '>>>' on '2.0' requires non-negative operand, but was '-1.0'.";
 static const field core::int* shiftNegative3 = invalid-expression "Binary operator '>>' on '2.0' requires non-negative operand, but was '-1.0'.";
 static const field core::int* modZero = invalid-expression "Binary operator '%' on '2.0' requires non-zero divisor, but divisor was '0'.";
 static const field core::int* divZero = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
@@ -125,35 +117,30 @@
 static const field core::int* binaryAnd = #C3;
 static const field core::int* binaryXor = #C3;
 static const field core::int* binaryShift1 = #C3;
-static const field core::int* binaryShift2 = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:27:29: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int binaryShift2 = 84 >>> 1;
-                            ^^^";
-static const field core::int* binaryShift3 = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:28:29: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int binaryShift3 = 21 >>> 64;
-                            ^^^";
+static const field core::int* binaryShift2 = #C3;
+static const field core::int* binaryShift3 = #C4;
 static const field core::int* binaryShift4 = #C3;
-static const field core::int* binaryShift5 = #C4;
-static const field core::bool* binaryLess = #C5;
-static const field core::bool* binaryLessEqual = #C6;
-static const field core::bool* binaryGreaterEqual = #C6;
-static const field core::bool* binaryGreater = #C5;
+static const field core::int* binaryShift5 = #C5;
+static const field core::bool* binaryLess = #C6;
+static const field core::bool* binaryLessEqual = #C7;
+static const field core::bool* binaryGreaterEqual = #C7;
+static const field core::bool* binaryGreater = #C6;
 static const field core::int* doubleTruncateDiv = #C3;
 static const field core::int* doubleTruncateDivZero = invalid-expression "Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.";
 static const field core::int* doubleTruncateDivNull = invalid-expression "Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.";
-static const field core::double* doubleNan = #C7;
+static const field core::double* doubleNan = #C8;
 static const field core::int* doubleTruncateDivNaN = invalid-expression "Binary operator '84.2 ~/ NaN' results is Infinity or NaN.";
-static const field core::int* bigNumber = #C8;
+static const field core::int* bigNumber = #C9;
 static method main() → dynamic {}
 
 constants  {
   #C1 = -2.0
   #C2 = 4294967293.0
   #C3 = 42.0
-  #C4 = 4294967295.0
-  #C5 = false
-  #C6 = true
-  #C7 = NaN
-  #C8 = 9223372036854776000.0
+  #C4 = 0.0
+  #C5 = 4294967295.0
+  #C6 = false
+  #C7 = true
+  #C8 = NaN
+  #C9 = 9223372036854776000.0
 }
diff --git a/pkg/front_end/testcases/general/constants/number_folds.dart.weak.expect b/pkg/front_end/testcases/general/constants/number_folds.dart.weak.expect
index f20a0df..dc5a80f 100644
--- a/pkg/front_end/testcases/general/constants/number_folds.dart.weak.expect
+++ b/pkg/front_end/testcases/general/constants/number_folds.dart.weak.expect
@@ -7,25 +7,10 @@
 // const int unaryPlus = +2;
 //                       ^
 //
-// pkg/front_end/testcases/general/constants/number_folds.dart:6:30: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int shiftNegative2 = 2 >>> -1;
-//                              ^^^
-//
 // pkg/front_end/testcases/general/constants/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
 // const int divZero = 2 / 0;
 //                       ^
 //
-// pkg/front_end/testcases/general/constants/number_folds.dart:27:29: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int binaryShift2 = 84 >>> 1;
-//                             ^^^
-//
-// pkg/front_end/testcases/general/constants/number_folds.dart:28:29: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int binaryShift3 = 21 >>> 64;
-//                             ^^^
-//
 // pkg/front_end/testcases/general/constants/number_folds.dart:5:30: Error: Constant evaluation error:
 // const int shiftNegative1 = 2 << -1;
 //                              ^
@@ -36,6 +21,16 @@
 // const int shiftNegative1 = 2 << -1;
 //           ^
 //
+// pkg/front_end/testcases/general/constants/number_folds.dart:6:30: Error: Constant evaluation error:
+// const int shiftNegative2 = 2 >>> -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/number_folds.dart:6:30: Context: Binary operator '>>>' on '2' requires non-negative operand, but was '-1'.
+// const int shiftNegative2 = 2 >>> -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/number_folds.dart:6:11: Context: While analyzing:
+// const int shiftNegative2 = 2 >>> -1;
+//           ^
+//
 // pkg/front_end/testcases/general/constants/number_folds.dart:7:30: Error: Constant evaluation error:
 // const int shiftNegative3 = 2 >> -1;
 //                              ^
@@ -100,10 +95,7 @@
 import "dart:core" as core;
 
 static const field core::int* shiftNegative1 = invalid-expression "Binary operator '<<' on '2' requires non-negative operand, but was '-1'.";
-static const field core::int* shiftNegative2 = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:6:30: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int shiftNegative2 = 2 >>> -1;
-                             ^^^";
+static const field core::int* shiftNegative2 = invalid-expression "Binary operator '>>>' on '2' requires non-negative operand, but was '-1'.";
 static const field core::int* shiftNegative3 = invalid-expression "Binary operator '>>' on '2' requires non-negative operand, but was '-1'.";
 static const field core::int* modZero = invalid-expression "Binary operator '%' on '2' requires non-zero divisor, but divisor was '0'.";
 static const field core::int* divZero = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
@@ -125,23 +117,17 @@
 static const field core::int* binaryAnd = #C3;
 static const field core::int* binaryXor = #C3;
 static const field core::int* binaryShift1 = #C3;
-static const field core::int* binaryShift2 = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:27:29: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int binaryShift2 = 84 >>> 1;
-                            ^^^";
-static const field core::int* binaryShift3 = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:28:29: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int binaryShift3 = 21 >>> 64;
-                            ^^^";
+static const field core::int* binaryShift2 = #C3;
+static const field core::int* binaryShift3 = #C5;
 static const field core::int* binaryShift4 = #C3;
-static const field core::bool* binaryLess = #C5;
-static const field core::bool* binaryLessEqual = #C6;
-static const field core::bool* binaryGreaterEqual = #C6;
-static const field core::bool* binaryGreater = #C5;
+static const field core::bool* binaryLess = #C6;
+static const field core::bool* binaryLessEqual = #C7;
+static const field core::bool* binaryGreaterEqual = #C7;
+static const field core::bool* binaryGreater = #C6;
 static const field core::int* doubleTruncateDiv = #C3;
 static const field core::int* doubleTruncateDivZero = invalid-expression "Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.";
 static const field core::int* doubleTruncateDivNull = invalid-expression "Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.";
-static const field core::double* doubleNan = #C7;
+static const field core::double* doubleNan = #C8;
 static const field core::int* doubleTruncateDivNaN = invalid-expression "Binary operator '84.2 ~/ NaN' results is Infinity or NaN.";
 static method main() → dynamic {}
 
@@ -150,7 +136,8 @@
   #C2 = -3
   #C3 = 42
   #C4 = 42.0
-  #C5 = false
-  #C6 = true
-  #C7 = NaN
+  #C5 = 0
+  #C6 = false
+  #C7 = true
+  #C8 = NaN
 }
diff --git a/pkg/front_end/testcases/general/constants/number_folds.dart.weak.outline.expect b/pkg/front_end/testcases/general/constants/number_folds.dart.weak.outline.expect
index 0c36235..f1e66af 100644
--- a/pkg/front_end/testcases/general/constants/number_folds.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/constants/number_folds.dart.weak.outline.expect
@@ -7,33 +7,15 @@
 // const int unaryPlus = +2;
 //                       ^
 //
-// pkg/front_end/testcases/general/constants/number_folds.dart:6:30: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int shiftNegative2 = 2 >>> -1;
-//                              ^^^
-//
 // pkg/front_end/testcases/general/constants/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
 // const int divZero = 2 / 0;
 //                       ^
 //
-// pkg/front_end/testcases/general/constants/number_folds.dart:27:29: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int binaryShift2 = 84 >>> 1;
-//                             ^^^
-//
-// pkg/front_end/testcases/general/constants/number_folds.dart:28:29: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int binaryShift3 = 21 >>> 64;
-//                             ^^^
-//
 import self as self;
 import "dart:core" as core;
 
 static const field core::int* shiftNegative1 = 2.{core::int::<<}(1.{core::int::unary-}());
-static const field core::int* shiftNegative2 = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:6:30: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int shiftNegative2 = 2 >>> -1;
-                             ^^^" as{TypeError,ForDynamic} core::int*;
+static const field core::int* shiftNegative2 = 2.{core::int::>>>}(1.{core::int::unary-}());
 static const field core::int* shiftNegative3 = 2.{core::int::>>}(1.{core::int::unary-}());
 static const field core::int* modZero = 2.{core::num::%}(0);
 static const field core::int* divZero = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
@@ -55,14 +37,8 @@
 static const field core::int* binaryAnd = 63.{core::int::&}(106);
 static const field core::int* binaryXor = 63.{core::int::^}(21);
 static const field core::int* binaryShift1 = 21.{core::int::<<}(1);
-static const field core::int* binaryShift2 = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:27:29: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int binaryShift2 = 84 >>> 1;
-                            ^^^" as{TypeError,ForDynamic} core::int*;
-static const field core::int* binaryShift3 = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:28:29: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int binaryShift3 = 21 >>> 64;
-                            ^^^" as{TypeError,ForDynamic} core::int*;
+static const field core::int* binaryShift2 = 84.{core::int::>>>}(1);
+static const field core::int* binaryShift3 = 21.{core::int::>>>}(64);
 static const field core::int* binaryShift4 = 84.{core::int::>>}(1);
 static const field core::bool* binaryLess = 42.{core::num::<}(42);
 static const field core::bool* binaryLessEqual = 42.{core::num::<=}(42);
@@ -79,6 +55,7 @@
 
 Extra constant evaluation status:
 Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:5:33 -> IntConstant(-1)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:6:34 -> IntConstant(-1)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:7:33 -> IntConstant(-1)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:9:23 -> DoubleConstant(Infinity)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:11:24 -> IntConstant(-2)
@@ -93,6 +70,8 @@
 Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:22:26 -> IntConstant(42)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:23:26 -> IntConstant(42)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:24:29 -> IntConstant(42)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:27:29 -> IntConstant(42)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:28:29 -> IntConstant(0)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:30:29 -> IntConstant(42)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:31:28 -> BoolConstant(false)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:32:33 -> BoolConstant(true)
@@ -101,4 +80,4 @@
 Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:36:36 -> IntConstant(42)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:39:27 -> DoubleConstant(NaN)
 Evaluated: StaticGet @ org-dartlang-testcase:///number_folds.dart:40:42 -> DoubleConstant(NaN)
-Extra constant evaluation: evaluated: 37, effectively constant: 23
+Extra constant evaluation: evaluated: 38, effectively constant: 26
diff --git a/pkg/front_end/testcases/general/constants/number_folds.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/number_folds.dart.weak.transformed.expect
index f20a0df..dc5a80f 100644
--- a/pkg/front_end/testcases/general/constants/number_folds.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/constants/number_folds.dart.weak.transformed.expect
@@ -7,25 +7,10 @@
 // const int unaryPlus = +2;
 //                       ^
 //
-// pkg/front_end/testcases/general/constants/number_folds.dart:6:30: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int shiftNegative2 = 2 >>> -1;
-//                              ^^^
-//
 // pkg/front_end/testcases/general/constants/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
 // const int divZero = 2 / 0;
 //                       ^
 //
-// pkg/front_end/testcases/general/constants/number_folds.dart:27:29: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int binaryShift2 = 84 >>> 1;
-//                             ^^^
-//
-// pkg/front_end/testcases/general/constants/number_folds.dart:28:29: Error: The operator '>>>' isn't defined for the class 'int'.
-// Try correcting the operator to an existing operator, or defining a '>>>' operator.
-// const int binaryShift3 = 21 >>> 64;
-//                             ^^^
-//
 // pkg/front_end/testcases/general/constants/number_folds.dart:5:30: Error: Constant evaluation error:
 // const int shiftNegative1 = 2 << -1;
 //                              ^
@@ -36,6 +21,16 @@
 // const int shiftNegative1 = 2 << -1;
 //           ^
 //
+// pkg/front_end/testcases/general/constants/number_folds.dart:6:30: Error: Constant evaluation error:
+// const int shiftNegative2 = 2 >>> -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/number_folds.dart:6:30: Context: Binary operator '>>>' on '2' requires non-negative operand, but was '-1'.
+// const int shiftNegative2 = 2 >>> -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/number_folds.dart:6:11: Context: While analyzing:
+// const int shiftNegative2 = 2 >>> -1;
+//           ^
+//
 // pkg/front_end/testcases/general/constants/number_folds.dart:7:30: Error: Constant evaluation error:
 // const int shiftNegative3 = 2 >> -1;
 //                              ^
@@ -100,10 +95,7 @@
 import "dart:core" as core;
 
 static const field core::int* shiftNegative1 = invalid-expression "Binary operator '<<' on '2' requires non-negative operand, but was '-1'.";
-static const field core::int* shiftNegative2 = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:6:30: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int shiftNegative2 = 2 >>> -1;
-                             ^^^";
+static const field core::int* shiftNegative2 = invalid-expression "Binary operator '>>>' on '2' requires non-negative operand, but was '-1'.";
 static const field core::int* shiftNegative3 = invalid-expression "Binary operator '>>' on '2' requires non-negative operand, but was '-1'.";
 static const field core::int* modZero = invalid-expression "Binary operator '%' on '2' requires non-zero divisor, but divisor was '0'.";
 static const field core::int* divZero = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
@@ -125,23 +117,17 @@
 static const field core::int* binaryAnd = #C3;
 static const field core::int* binaryXor = #C3;
 static const field core::int* binaryShift1 = #C3;
-static const field core::int* binaryShift2 = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:27:29: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int binaryShift2 = 84 >>> 1;
-                            ^^^";
-static const field core::int* binaryShift3 = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:28:29: Error: The operator '>>>' isn't defined for the class 'int'.
-Try correcting the operator to an existing operator, or defining a '>>>' operator.
-const int binaryShift3 = 21 >>> 64;
-                            ^^^";
+static const field core::int* binaryShift2 = #C3;
+static const field core::int* binaryShift3 = #C5;
 static const field core::int* binaryShift4 = #C3;
-static const field core::bool* binaryLess = #C5;
-static const field core::bool* binaryLessEqual = #C6;
-static const field core::bool* binaryGreaterEqual = #C6;
-static const field core::bool* binaryGreater = #C5;
+static const field core::bool* binaryLess = #C6;
+static const field core::bool* binaryLessEqual = #C7;
+static const field core::bool* binaryGreaterEqual = #C7;
+static const field core::bool* binaryGreater = #C6;
 static const field core::int* doubleTruncateDiv = #C3;
 static const field core::int* doubleTruncateDivZero = invalid-expression "Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.";
 static const field core::int* doubleTruncateDivNull = invalid-expression "Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.";
-static const field core::double* doubleNan = #C7;
+static const field core::double* doubleNan = #C8;
 static const field core::int* doubleTruncateDivNaN = invalid-expression "Binary operator '84.2 ~/ NaN' results is Infinity or NaN.";
 static method main() → dynamic {}
 
@@ -150,7 +136,8 @@
   #C2 = -3
   #C3 = 42
   #C4 = 42.0
-  #C5 = false
-  #C6 = true
-  #C7 = NaN
+  #C5 = 0
+  #C6 = false
+  #C7 = true
+  #C8 = NaN
 }
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index eaaaf4b..857a8cf 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -10652,7 +10652,7 @@
 }
 
 class InterfaceType extends DartType {
-  Reference className;
+  final Reference className;
 
   @override
   final Nullability declaredNullability;
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index 0a5ad7f..1ca7114 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -841,19 +841,21 @@
           " ${node.classNode.typeParameters.length} parameters.");
     }
     if (node.classNode.isAnonymousMixin) {
+      bool isOk = false;
       if (currentParent is FunctionNode) {
         TreeNode? functionNodeParent = currentParent!.parent;
-        if (functionNodeParent is Constructor ||
-            functionNodeParent is Procedure &&
-                functionNodeParent.kind == ProcedureKind.Factory) {
-          if (functionNodeParent!.parent == node.classNode) {
+        if (functionNodeParent is Constructor) {
+          if (functionNodeParent.parent == node.classNode) {
             // We only allow references to anonymous mixins in types as the
             // return type of its own constructor.
-            return;
+            isOk = true;
           }
         }
       }
-      problem(currentParent, "Type $node references an anonymous mixin class.");
+      if (!isOk) {
+        problem(
+            currentParent, "Type $node references an anonymous mixin class.");
+      }
     }
     defaultDartType(node);
   }
diff --git a/pkg/vm/lib/transformations/mixin_deduplication.dart b/pkg/vm/lib/transformations/mixin_deduplication.dart
index dce3d1b..a328961 100644
--- a/pkg/vm/lib/transformations/mixin_deduplication.dart
+++ b/pkg/vm/lib/transformations/mixin_deduplication.dart
@@ -35,10 +35,6 @@
   // TODO(dartbug.com/39375): Remove this extra O(N) pass over the AST if the
   // CFE decides to consistently let the interface target point to the mixin
   // class (instead of mixin application).
-  //
-  // Types could also contain references to removed mixin applications due to
-  // LUB algorithm in CFE (calculating static type of a conditional expression)
-  // and type inference which can spread types and produce derived types.
   component.libraries.forEach(referenceUpdater.visitLibrary);
 }
 
@@ -160,18 +156,10 @@
 /// classes. Updates interface targets and types.
 class ReferenceUpdater extends RecursiveVisitor {
   final DeduplicateMixinsTransformer transformer;
-  final _visitedConstants = new Set<Constant>.identity();
 
   ReferenceUpdater(this.transformer);
 
   @override
-  visitLibrary(Library node) {
-    super.visitLibrary(node);
-    // Avoid accumulating too many constants in case of huge programs.
-    _visitedConstants.clear();
-  }
-
-  @override
   void visitProcedure(Procedure node) {
     super.visitProcedure(node);
     node.stubTarget = _resolveNewInterfaceTarget(node.stubTarget);
@@ -239,35 +227,6 @@
   }
 
   @override
-  visitInterfaceType(InterfaceType node) {
-    node.className = _updateClassReference(node.className);
-    super.visitInterfaceType(node);
-  }
-
-  Reference _updateClassReference(Reference classRef) {
-    final Class c = classRef.asClass;
-    if (c.isAnonymousMixin) {
-      final Class? replacement = transformer._duplicatedMixins[c];
-      if (replacement != null) {
-        return replacement.reference;
-      }
-    }
-    return classRef;
-  }
-
-  @override
-  defaultConstantReference(Constant node) {
-    // By default, RecursiveVisitor stops at constants. We need to go deeper
-    // into constants in order to update types which are only referenced from
-    // constants. However, constants are DAGs and not trees, so visiting
-    // the same constant multiple times should be avoided to prevent
-    // exponential running time.
-    if (_visitedConstants.add(node)) {
-      node.accept(this);
-    }
-  }
-
-  @override
   visitClassReference(Class node) {
     // Safeguard against any possible leaked uses of anonymous mixin
     // applications which are not updated.
diff --git a/pkg/vm/test/modular_kernel_plus_aot_test.dart b/pkg/vm/test/modular_kernel_plus_aot_test.dart
index 8b950bd..8d9419d 100644
--- a/pkg/vm/test/modular_kernel_plus_aot_test.dart
+++ b/pkg/vm/test/modular_kernel_plus_aot_test.dart
@@ -148,6 +148,15 @@
   a2.mixinProperty.foo();
   a2.mixinMethod('').foo();
   R().bar();
+  B1();
+  B1.named();
+  B2();
+  final b2 = B2.named();
+  // The mixin deduplication will remove the anonymous mixin application class
+  // from `B2 & Mixin` and instead use the one from `B1 & Mixin`.
+  b2.mixinProperty= '';
+  b2.mixinProperty.foo();
+  b2.mixinMethod('').foo();
 }
 ''';
 
@@ -162,4 +171,16 @@
 }
 class A1 extends Object with Mixin { }
 class A2 extends Object with Mixin { }
+class B {
+   B();
+   B.named();
+}
+class B1 extends B with Mixin {
+  B1() : super();
+  B1.named() : super.named();
+}
+class B2 extends B with Mixin {
+  B2() : super();
+  B2.named() : super.named();
+}
 ''';
diff --git a/pkg/vm_snapshot_analysis/lib/v8_profile.dart b/pkg/vm_snapshot_analysis/lib/v8_profile.dart
index 0c824f2..404fe66 100644
--- a/pkg/vm_snapshot_analysis/lib/v8_profile.dart
+++ b/pkg/vm_snapshot_analysis/lib/v8_profile.dart
@@ -398,11 +398,8 @@
   ProgramInfoNode createInfoNodeFor(Node node) {
     switch (node.type) {
       case 'Code':
-        var owner = node['owner_'];
+        var owner = node[':owner_'] ?? node['owner_'];
         if (owner.type != 'Type') {
-          if (owner.type == 'WeakSerializationReference') {
-            owner = node[':owner_'];
-          }
           final ownerNode =
               owner.type == 'Null' ? program.stubs : getInfoNodeFor(owner);
           if (owner.type == 'Function') {
@@ -437,13 +434,15 @@
         return getInfoNodeFor(node['patched_class_']);
 
       case 'Class':
+        // Default to root node. Some builtin classes (void, dynamic) don't have
+        // any information about their library written out.
+        var ownerNode = program.root;
         if (node['library_'] != null) {
-          return makeInfoNode(node.index,
-              name: node.name,
-              parent: getInfoNodeFor(node['library_']) ?? program.root,
-              type: NodeType.classNode);
+          ownerNode = getInfoNodeFor(node['library_']) ?? ownerNode;
         }
-        break;
+
+        return makeInfoNode(node.index,
+            name: node.name, parent: ownerNode, type: NodeType.classNode);
 
       case 'Library':
         // Create fake owner node for the package which contains this library.
diff --git a/pkg/vm_snapshot_analysis/test/instruction_sizes_test.dart b/pkg/vm_snapshot_analysis/test/instruction_sizes_test.dart
index fd4cdd8..ddb2ac4 100644
--- a/pkg/vm_snapshot_analysis/test/instruction_sizes_test.dart
+++ b/pkg/vm_snapshot_analysis/test/instruction_sizes_test.dart
@@ -24,9 +24,9 @@
 @pragma('vm:never-inline')
 dynamic makeSomeClosures() {
   return [
-    () => const K(0),
-    () => const K(1),
-    () => 11,
+    () => [const K(0)],
+    () => [const K(1)],
+    () => [11],
   ];
 }
 
@@ -77,10 +77,10 @@
 @pragma('vm:never-inline')
 dynamic makeSomeClosures() {
   return [
-    () => const K(0),
-    () => const K(1),
-    () => 11,
-    () => {},  // modified
+    () => [const K(0)],
+    () => [const K(1)],
+    () => [11],
+    () => [const K(2)],  // modified
   ];
 }
 
@@ -130,7 +130,7 @@
 @pragma('vm:never-inline')
 dynamic makeSomeClosures() {
   return [
-    () => const K(0),
+    () => [const K(0)],
   ];
 }
 
@@ -202,10 +202,24 @@
     // If we are not running from the prebuilt SDK then this test does nothing.
     return;
   }
+  group('no-size-impact', () {
+    for (var flag in [printInstructionSizesFlag, writeV8ProfileFlag]) {
+      test(flag, () async {
+        await withFlagImpl(testSource, null, (baseline) async {
+          await withFlagImpl(testSource, flag, (snapshotWithFlag) async {
+            final sizeBaseline = File(baseline.outputBinary).statSync().size;
+            final sizeWithFlag =
+                File(snapshotWithFlag.outputBinary).statSync().size;
+            expect(sizeWithFlag - sizeBaseline, equals(0));
+          });
+        });
+      });
+    }
+  });
 
   group('instruction-sizes', () {
     test('basic-parsing', () async {
-      await withSymbolSizes('basic-parsing', testSource, (sizesJson) async {
+      await withSymbolSizes(testSource, (sizesJson) async {
         final json = await loadJson(File(sizesJson));
         final symbols = instruction_sizes.fromJson(json);
         expect(symbols, isNotNull,
@@ -278,8 +292,7 @@
     });
 
     test('program-info-from-sizes', () async {
-      await withSymbolSizes('program-info-from-sizes', testSource,
-          (sizesJson) async {
+      await withSymbolSizes(testSource, (sizesJson) async {
         final json = await loadJson(File(sizesJson));
         final info = loadProgramInfoFromJson(json);
         expect(info.root.children, contains('dart:core'));
@@ -327,7 +340,7 @@
     });
 
     test('histograms', () async {
-      await withSymbolSizes('histograms', testSource, (sizesJson) async {
+      await withSymbolSizes(testSource, (sizesJson) async {
         final json = await loadJson(File(sizesJson));
         final info = loadProgramInfoFromJson(json);
         final bySymbol = computeHistogram(info, HistogramType.bySymbol);
@@ -379,9 +392,8 @@
     });
 
     test('diff', () async {
-      await withSymbolSizes('diff-1', testSource, (sizesJson) async {
-        await withSymbolSizes('diff-2', testSourceModified,
-            (modifiedSizesJson) async {
+      await withSymbolSizes(testSource, (sizesJson) async {
+        await withSymbolSizes(testSourceModified, (modifiedSizesJson) async {
           final infoJson = await loadJson(File(sizesJson));
           final info = loadProgramInfoFromJson(infoJson);
           final modifiedJson = await loadJson(File(modifiedSizesJson));
@@ -401,7 +413,7 @@
                       'makeSomeClosures': {
                         '#type': 'function',
                         '#size': greaterThan(0), // We added code here.
-                        '<anonymous closure @180>': {
+                        '<anonymous closure @186>': {
                           '#type': 'function',
                           '#size': greaterThan(0),
                         },
@@ -426,9 +438,8 @@
     });
 
     test('diff-collapsed', () async {
-      await withSymbolSizes('diff-collapsed-1', testSource, (sizesJson) async {
-        await withSymbolSizes('diff-collapsed-2', testSourceModified2,
-            (modifiedSizesJson) async {
+      await withSymbolSizes(testSource, (sizesJson) async {
+        await withSymbolSizes(testSourceModified2, (modifiedSizesJson) async {
           final json = await loadJson(File(sizesJson));
           final info =
               loadProgramInfoFromJson(json, collapseAnonymousClosures: true);
@@ -436,11 +447,17 @@
           final modifiedInfo = loadProgramInfoFromJson(modifiedJson,
               collapseAnonymousClosures: true);
           final diff = computeDiff(info, modifiedInfo);
-
           expect(
               diffToJson(diff),
               equals({
                 '#type': 'library',
+                '@stubs': {
+                  '#type': 'library',
+                  'Type Test Type: int*': {
+                    '#type': 'function',
+                    '#size': lessThan(0),
+                  },
+                },
                 'package:input': {
                   '#type': 'package',
                   'package:input/input.dart': {
@@ -466,8 +483,7 @@
 
   group('v8-profile', () {
     test('program-info-from-profile', () async {
-      await withV8Profile('program-info-from-profile', testSource,
-          (profileJson) async {
+      await withV8Profile(testSource, (profileJson) async {
         final infoJson = await loadJson(File(profileJson));
         final info = loadProgramInfoFromJson(infoJson);
         expect(info.root.children, contains('dart:core'));
@@ -525,8 +541,42 @@
       });
     });
 
+    // This test verifies that we are able to attribute instructions to the
+    // function they originated from.
+    test('instruction ownership is preserved', () async {
+      await withV8Profile(testSource, (profileJson) async {
+        await withSymbolSizes(testSource, (sizesJson) async {
+          final fromProfile =
+              loadProgramInfoFromJson(await loadJson(File(profileJson)));
+          final fromSymbolSizes = loadProgramInfoFromJson(
+              await loadJson(File(sizesJson)),
+              collapseAnonymousClosures: true);
+          final functionNode = fromProfile.lookup([
+            'package:input',
+            'package:input/input.dart',
+            '::',
+            'makeSomeClosures'
+          ]);
+          final codeNode = fromProfile.snapshotInfo.snapshot.nodes.firstWhere(
+              (n) =>
+                  n.type == 'Code' &&
+                  fromProfile.snapshotInfo.ownerOf(n) == functionNode &&
+                  n.name.contains('makeSomeClosures'));
+          expect(codeNode['<instructions>'], isNotNull);
+          final instructionsSize = codeNode['<instructions>'].selfSize;
+          final symbolSize = fromSymbolSizes.lookup([
+            'package:input',
+            'package:input/input.dart',
+            '',
+            'makeSomeClosures'
+          ]).size;
+          expect(instructionsSize - symbolSize, equals(0));
+        });
+      });
+    });
+
     test('histograms', () async {
-      await withV8Profile('histograms', testSource, (sizesJson) async {
+      await withV8Profile(testSource, (sizesJson) async {
         final infoJson = await loadJson(File(sizesJson));
         final info = loadProgramInfoFromJson(infoJson);
         final bySymbol = computeHistogram(info, HistogramType.bySymbol);
@@ -578,9 +628,8 @@
     });
 
     test('diff', () async {
-      await withV8Profile('diff-1', testSource, (profileJson) async {
-        await withV8Profile('diff-2', testSourceModified,
-            (modifiedProfileJson) async {
+      await withV8Profile(testSource, (profileJson) async {
+        await withV8Profile(testSourceModified, (modifiedProfileJson) async {
           final infoJson = await loadJson(File(profileJson));
           final info = loadProgramInfoFromJson(infoJson);
           final modifiedJson = await loadJson(File(modifiedProfileJson));
@@ -599,7 +648,7 @@
                       'makeSomeClosures': {
                         '#type': 'function',
                         '#size': greaterThan(0),
-                        '<anonymous closure @180>': {
+                        '<anonymous closure @186>': {
                           '#type': 'function',
                           '#size': greaterThan(0),
                         },
@@ -624,9 +673,8 @@
     });
 
     test('diff-collapsed', () async {
-      await withV8Profile('diff-collapsed-1', testSource, (profileJson) async {
-        await withV8Profile('diff-collapsed-2', testSourceModified2,
-            (modifiedProfileJson) async {
+      await withV8Profile(testSource, (profileJson) async {
+        await withV8Profile(testSourceModified2, (modifiedProfileJson) async {
           final infoJson = await loadJson(File(profileJson));
           final info = loadProgramInfoFromJson(infoJson,
               collapseAnonymousClosures: true);
@@ -646,7 +694,6 @@
                       '#type': 'class',
                       'makeSomeClosures': {
                         '#type': 'function',
-                        '#size': lessThan(0),
                         '<anonymous closure>': {
                           '#type': 'function',
                           '#size': lessThan(0),
@@ -661,7 +708,7 @@
     });
 
     test('treemap', () async {
-      await withV8Profile('treemap', testSource, (profileJson) async {
+      await withV8Profile(testSource, (profileJson) async {
         final infoJson = await loadJson(File(profileJson));
         final info = await loadProgramInfoFromJson(infoJson,
             collapseAnonymousClosures: true);
@@ -695,8 +742,7 @@
     });
 
     test('dominators', () async {
-      await withV8Profile('dominators', chainOfStaticCalls,
-          (profileJson) async {
+      await withV8Profile(chainOfStaticCalls, (profileJson) async {
         // Note: computing dominators also verifies that we don't have
         // unreachable nodes in the snapshot.
         final infoJson = await loadJson(File(profileJson));
@@ -709,13 +755,17 @@
   });
 }
 
-Future withSymbolSizes(String prefix, Map<String, String> source,
-        Future Function(String sizesJson) f) =>
-    withFlag(prefix, source, '--print_instructions_sizes_to', f);
+final printInstructionSizesFlag = '--print_instructions_sizes_to';
 
-Future withV8Profile(String prefix, Map<String, String> source,
-        Future Function(String sizesJson) f) =>
-    withFlag(prefix, source, '--write_v8_snapshot_profile_to', f);
+Future withSymbolSizes(
+        Map<String, String> source, Future Function(String sizesJson) f) =>
+    withFlag(source, printInstructionSizesFlag, f);
+
+final writeV8ProfileFlag = '--write_v8_snapshot_profile_to';
+
+Future withV8Profile(
+        Map<String, String> source, Future Function(String sizesJson) f) =>
+    withFlag(source, writeV8ProfileFlag, f);
 
 // On Windows there is some issue with interpreting entry point URI as a package URI
 // it instead gets interpreted as a file URI - which breaks comparison. So we
diff --git a/pkg/vm_snapshot_analysis/test/precompiler_trace_test.dart b/pkg/vm_snapshot_analysis/test/precompiler_trace_test.dart
index c4ad546..2392171 100644
--- a/pkg/vm_snapshot_analysis/test/precompiler_trace_test.dart
+++ b/pkg/vm_snapshot_analysis/test/precompiler_trace_test.dart
@@ -69,8 +69,7 @@
 
   group('precompiler-trace', () {
     test('basic-parsing', () async {
-      await withFlag('basic-parsing', testSource, '--trace_precompiler_to',
-          (json) async {
+      await withFlag(testSource, '--trace_precompiler_to', (json) async {
         final jsonRaw = await loadJson(File(json));
         final callGraph = loadTrace(jsonRaw);
         callGraph.computeDominators();
@@ -102,9 +101,7 @@
     });
 
     test('collapse-by-package', () async {
-      await withFlag(
-          'collapse-by-package', testSource, '--trace_precompiler_to',
-          (json) async {
+      await withFlag(testSource, '--trace_precompiler_to', (json) async {
         final jsonRaw = await loadJson(File(json));
         final callGraph = loadTrace(jsonRaw).collapse(NodeType.packageNode);
 
diff --git a/pkg/vm_snapshot_analysis/test/utils.dart b/pkg/vm_snapshot_analysis/test/utils.dart
index acdf42f..bdc14e7 100644
--- a/pkg/vm_snapshot_analysis/test/utils.dart
+++ b/pkg/vm_snapshot_analysis/test/utils.dart
@@ -20,11 +20,25 @@
   return path.canonicalize(dart2native);
 }();
 
-Future withFlag(String prefix, Map<String, String> source, String flag,
-    Future Function(String sizesJson) f) {
-  return withTempDir(prefix, (dir) async {
-    final outputBinary = path.join(dir, 'output.exe');
-    final sizesJson = path.join(dir, 'sizes.json');
+class AotSnapshot {
+  final String outputBinary;
+  final String sizesJson;
+
+  AotSnapshot({this.outputBinary, this.sizesJson});
+}
+
+Future withFlag(
+    Map<String, String> source, String flag, Future Function(String) f) {
+  return withFlagImpl(source, flag, (info) => f(info.sizesJson));
+}
+
+Future withFlagImpl(
+    Map<String, String> source, String flag, Future Function(AotSnapshot) f) {
+  return withTempDir((dir) async {
+    final snapshot = AotSnapshot(
+      outputBinary: path.join(dir, 'output.exe'),
+      sizesJson: path.join(dir, 'sizes.json'),
+    );
     final packages = path.join(dir, '.packages');
     final mainDart = path.join(dir, 'main.dart');
 
@@ -41,12 +55,17 @@
 void main(List<String> args) => input.main(args);
 ''');
 
+    final extraGenSnapshotOptions = [
+      '--dwarf-stack-traces',
+      if (flag != null) '$flag=${snapshot.sizesJson}',
+    ];
+
     // Compile input.dart to native and output instruction sizes.
     final result = await Process.run(dart2native, [
       '-o',
-      outputBinary,
+      snapshot.outputBinary,
       '--packages=$packages',
-      '--extra-gen-snapshot-options=--dwarf-stack-traces,$flag=$sizesJson',
+      '--extra-gen-snapshot-options=${extraGenSnapshotOptions.join(',')}',
       mainDart,
     ]);
 
@@ -56,18 +75,20 @@
 stdout: ${result.stdout}
 stderr: ${result.stderr}
 ''');
-    expect(File(outputBinary).existsSync(), isTrue,
+    expect(File(snapshot.outputBinary).existsSync(), isTrue,
         reason: 'Output binary exists');
-    expect(File(sizesJson).existsSync(), isTrue,
-        reason: 'Instruction sizes output exists');
+    if (flag != null) {
+      expect(File(snapshot.sizesJson).existsSync(), isTrue,
+          reason: 'Instruction sizes output exists');
+    }
 
-    await f(sizesJson);
+    await f(snapshot);
   });
 }
 
-Future withTempDir(String prefix, Future Function(String dir) f) async {
+Future withTempDir(Future Function(String dir) f) async {
   final tempDir =
-      Directory.systemTemp.createTempSync('instruction-sizes-test-${prefix}');
+      Directory.systemTemp.createTempSync('instruction-sizes-test-');
   try {
     await f(tempDir.path);
   } finally {
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 1849a38..1661602 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -1499,18 +1499,28 @@
   struct CodeOrderInfo {
     CodePtr code;
     intptr_t order;
+    intptr_t original_index;
   };
 
+  // We sort code objects in such a way that code objects with the same
+  // instructions are grouped together. To make sorting more stable between
+  // similar programs we also sort them further by their original indices -
+  // this helps to stabilize output of --print-instructions-sizes-to which uses
+  // the name of the first code object (among those pointing to the same
+  // instruction objects).
   static int CompareCodeOrderInfo(CodeOrderInfo const* a,
                                   CodeOrderInfo const* b) {
     if (a->order < b->order) return -1;
     if (a->order > b->order) return 1;
+    if (a->original_index < b->original_index) return -1;
+    if (a->original_index > b->original_index) return 1;
     return 0;
   }
 
   static void Insert(GrowableArray<CodeOrderInfo>* order_list,
                      IntMap<intptr_t>* order_map,
-                     CodePtr code) {
+                     CodePtr code,
+                     intptr_t original_index) {
     InstructionsPtr instr = code->untag()->instructions_;
     intptr_t key = static_cast<intptr_t>(instr);
     intptr_t order;
@@ -1523,6 +1533,7 @@
     CodeOrderInfo info;
     info.code = code;
     info.order = order;
+    info.original_index = original_index;
     order_list->Add(info);
   }
 
@@ -1530,7 +1541,7 @@
     GrowableArray<CodeOrderInfo> order_list;
     IntMap<intptr_t> order_map;
     for (intptr_t i = 0; i < codes->length(); i++) {
-      Insert(&order_list, &order_map, (*codes)[i]);
+      Insert(&order_list, &order_map, (*codes)[i], i);
     }
     order_list.Sort(CompareCodeOrderInfo);
     ASSERT(order_list.length() == codes->length());
@@ -1543,7 +1554,7 @@
     GrowableArray<CodeOrderInfo> order_list;
     IntMap<intptr_t> order_map;
     for (intptr_t i = 0; i < codes->length(); i++) {
-      Insert(&order_list, &order_map, (*codes)[i]->ptr());
+      Insert(&order_list, &order_map, (*codes)[i]->ptr(), i);
     }
     order_list.Sort(CompareCodeOrderInfo);
     ASSERT(order_list.length() == codes->length());
@@ -5030,11 +5041,14 @@
       // Error, CallSiteData has no class object.
       if (cid != kErrorCid && cid != kCallSiteDataCid) {
         ASSERT(table->HasValidClassAt(cid));
-        s->AddBaseObject(table->At(cid), "Class");
+        s->AddBaseObject(
+            table->At(cid), "Class",
+            Class::Handle(table->At(cid))
+                .NameCString(Object::NameVisibility::kInternalName));
       }
     }
-    s->AddBaseObject(table->At(kDynamicCid), "Class");
-    s->AddBaseObject(table->At(kVoidCid), "Class");
+    s->AddBaseObject(table->At(kDynamicCid), "Class", "dynamic");
+    s->AddBaseObject(table->At(kVoidCid), "Class", "void");
 
     if (!Snapshot::IncludesCode(s->kind())) {
       for (intptr_t i = 0; i < StubCode::NumEntries(); i++) {
diff --git a/sdk/lib/_internal/allowed_experiments.json b/sdk/lib/_internal/allowed_experiments.json
index 4644443..66da861 100644
--- a/sdk/lib/_internal/allowed_experiments.json
+++ b/sdk/lib/_internal/allowed_experiments.json
@@ -1,13 +1,17 @@
 {
   "version": 1,
   "experimentSets": {
+    "sdkExperiments": [
+      "non-nullable",
+      "triple-shift"
+    ],
     "nullSafety": [
       "non-nullable"
     ]
   },
   "sdk": {
     "default": {
-      "experimentSet": "nullSafety"
+      "experimentSet": "sdkExperiments"
     },
     "_example_libraries": {
       "ui": {
diff --git a/sdk/lib/_internal/js_dev_runtime/private/js_number.dart b/sdk/lib/_internal/js_dev_runtime/private/js_number.dart
index 60b9246..c70de91 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/js_number.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/js_number.dart
@@ -335,6 +335,9 @@
     return _shrOtherPositive(other);
   }
 
+  int operator >>>(@nullCheck num other) =>
+    throw UnimplementedError('int.>>> is not implemented yet');
+
   @notNull
   int _shrOtherPositive(@notNull num other) {
     return JS<num>('!', '#', this) > 0
diff --git a/sdk/lib/_internal/js_runtime/lib/js_number.dart b/sdk/lib/_internal/js_runtime/lib/js_number.dart
index eac0bc3..1d3ad24 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_number.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_number.dart
@@ -404,6 +404,9 @@
     return _shrOtherPositive(other);
   }
 
+  num operator >>>(num other) =>
+    throw UnimplementedError('int.>>> is not implemented yet');
+
   num _shrOtherPositive(num other) {
     return JS('num', '#', this) > 0
         ? _shrBothPositive(other)
diff --git a/sdk/lib/_internal/vm/lib/integers.dart b/sdk/lib/_internal/vm/lib/integers.dart
index 3ce3af5..f53e439 100644
--- a/sdk/lib/_internal/vm/lib/integers.dart
+++ b/sdk/lib/_internal/vm/lib/integers.dart
@@ -105,6 +105,9 @@
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
   int operator >>(int other) => other._shrFromInteger(this);
+  @pragma("vm:never-inline")
+  int operator >>>(int other) =>
+    throw UnimplementedError('int.>>> is not implemented yet');
   @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index 1578770..dd35a3f 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -105,6 +105,17 @@
   /// It is an error if [shiftAmount] is negative.
   int operator >>(int shiftAmount);
 
+  /// Bitwise unsigned right shift by [shiftAmount] bits.
+  ///
+  /// NOT IMPLEMENTED YET.
+  ///
+  /// The least significant [shiftAmount] bits are dropped,
+  /// the remaining bits (if any) are shifted down,
+  /// and zero-bits are shifted in as the new most signficant bits.
+  ///
+  /// The [shiftAmount] must be non-negative.
+  int operator >>>(int shiftAmount);
+
   /// Returns this integer to the power of [exponent] modulo [modulus].
   ///
   /// The [exponent] must be non-negative and [modulus] must be
diff --git a/tools/VERSION b/tools/VERSION
index 440dbfb..598505e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 58
+PRERELEASE 59
 PRERELEASE_PATCH 0
\ No newline at end of file