Version 2.16.0-3.0.dev

Merge commit 'b34f39985971d099994e93012cb3b2319712e6b6' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 9b9add9..4a949fb 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -2033,6 +2033,10 @@
 
 /// A base class for concrete implementations of an [Element].
 abstract class ElementImpl implements Element {
+  static const _metadataFlag_isReady = 1 << 0;
+  static const _metadataFlag_hasDeprecated = 1 << 1;
+  static const _metadataFlag_hasOverride = 1 << 2;
+
   /// An Unicode right arrow.
   @deprecated
   static final String RIGHT_ARROW = " \u2192 ";
@@ -2061,6 +2065,9 @@
   /// A list containing all of the metadata associated with this element.
   List<ElementAnnotation> _metadata = const [];
 
+  /// Cached flags denoting presence of specific annotations in [_metadata].
+  int _metadataFlags = 0;
+
   /// A cached copy of the calculated hashCode for this element.
   int? _cachedHashCode;
 
@@ -2138,14 +2145,7 @@
 
   @override
   bool get hasDeprecated {
-    final metadata = this.metadata;
-    for (var i = 0; i < metadata.length; i++) {
-      var annotation = metadata[i];
-      if (annotation.isDeprecated) {
-        return true;
-      }
-    }
-    return false;
+    return (_getMetadataFlags() & _metadataFlag_hasDeprecated) != 0;
   }
 
   @override
@@ -2277,14 +2277,7 @@
 
   @override
   bool get hasOverride {
-    final metadata = this.metadata;
-    for (var i = 0; i < metadata.length; i++) {
-      var annotation = metadata[i];
-      if (annotation.isOverride) {
-        return true;
-      }
-    }
-    return false;
+    return (_getMetadataFlags() & _metadataFlag_hasOverride) != 0;
   }
 
   /// Return `true` if this element has an annotation of the form
@@ -2587,6 +2580,29 @@
   void visitChildren(ElementVisitor visitor) {
     // There are no children to visit
   }
+
+  /// Return flags that denote presence of a few specific annotations.
+  int _getMetadataFlags() {
+    var result = _metadataFlags;
+
+    // Has at least `_metadataFlag_isReady`.
+    if (result != 0) {
+      return result;
+    }
+
+    final metadata = this.metadata;
+    for (var i = 0; i < metadata.length; i++) {
+      var annotation = metadata[i];
+      if (annotation.isDeprecated) {
+        result |= _metadataFlag_hasDeprecated;
+      } else if (annotation.isOverride) {
+        result |= _metadataFlag_hasOverride;
+      }
+    }
+
+    result |= _metadataFlag_isReady;
+    return _metadataFlags = result;
+  }
 }
 
 /// Abstract base class for elements whose type is guaranteed to be a function
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index ff38ff8..a7f3ca8 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -262,15 +262,35 @@
 }
 
 class Primitives {
+  static Object? _identityHashCodeProperty;
+
   static int objectHashCode(object) {
-    int? hash = JS('int|Null', r'#.$identityHash', object);
+    Object property =
+        _identityHashCodeProperty ??= _computeIdentityHashCodeProperty();
+    int? hash = JS('int|Null', r'#[#]', object, property);
     if (hash == null) {
       hash = JS('int', '(Math.random() * 0x3fffffff) | 0');
-      JS('void', r'#.$identityHash = #', object, hash);
+      JS('void', r'#[#] = #', object, property, hash);
     }
     return JS('int', '#', hash);
   }
 
+  static Object _computeIdentityHashCodeProperty() =>
+      JS_GET_FLAG('LEGACY_JAVASCRIPT')
+          ? _computeIdentityHashCodePropertyLegacy()
+          : _computeIdentityHashCodePropertyModern();
+
+  static Object _computeIdentityHashCodePropertyLegacy() {
+    if (JS<bool>('bool', 'typeof Symbol == "function"') ||
+        JS<bool>('bool', 'typeof Symbol() == "symbol"')) {
+      return _computeIdentityHashCodePropertyModern();
+    }
+    return r'$identityHashCode';
+  }
+
+  static Object _computeIdentityHashCodePropertyModern() =>
+      JS('', 'Symbol("identityHashCode")');
+
   static int? parseInt(String source, int? radix) {
     checkString(source);
     var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i');
diff --git a/tools/VERSION b/tools/VERSION
index b0b82aa..83662b0 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 16
 PATCH 0
-PRERELEASE 2
+PRERELEASE 3
 PRERELEASE_PATCH 0
\ No newline at end of file