Version 2.14.0-377.7.beta

* Cherry-pick 7ad9feb2d6dd3814d0e2bf738c1403e123e00135 to beta
* Cherry-pick cfc3a654a5f2ac1df6a16ca74b83e5d59fb5e163 to beta
* Cherry-pick bebf9054214b97b59be80dda4635dd24dea03479 to beta
diff --git a/DEPS b/DEPS
index 613addf..6cd7c74 100644
--- a/DEPS
+++ b/DEPS
@@ -172,7 +172,7 @@
   "web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02",
   "web_socket_channel_rev": "6448ce532445a8a458fa191d9346df071ae0acad",
   "WebCore_rev": "fb11e887f77919450e497344da570d780e078bc8",
-  "webdev_rev": "b0aae7b6944d484722e6af164abedd864a2a0afa",
+  "webdev_rev": "50fe70a3137d9665fbe94cd34af5277b65d95079",
   "webkit_inspection_protocol_rev": "dd6fb5d8b536e19cedb384d0bbf1f5631923f1e8",
   "yaml_rev": "b4c4411631bda556ce9a45af1ab0eecaf9f3ac53",
   "zlib_rev": "bf44340d1b6be1af8950bbdf664fec0cf5a831cc",
diff --git a/pkg/analysis_server/test/services/search/hierarchy_test.dart b/pkg/analysis_server/test/services/search/hierarchy_test.dart
index 4af0fe9..9ac31f4 100644
--- a/pkg/analysis_server/test/services/search/hierarchy_test.dart
+++ b/pkg/analysis_server/test/services/search/hierarchy_test.dart
@@ -363,7 +363,10 @@
             'toString',
             'hashCode',
             'noSuchMethod',
-            'runtimeType'
+            'runtimeType',
+            'hash',
+            'hashAll',
+            'hashAllUnordered',
           ]));
     }
     {
@@ -380,7 +383,10 @@
             'toString',
             'hashCode',
             'noSuchMethod',
-            'runtimeType'
+            'runtimeType',
+            'hash',
+            'hashAll',
+            'hashAllUnordered',
           ]));
     }
   }
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 5c7a513..44388f6 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -422,7 +422,7 @@
     var target = objectElement.getMethod(nameNode.name);
 
     var hasMatchingObjectMethod = false;
-    if (target is MethodElement) {
+    if (target is MethodElement && !target.isStatic) {
       var arguments = node.argumentList.arguments;
       hasMatchingObjectMethod = arguments.length == target.parameters.length &&
           !arguments.any((e) => e is NamedExpression);
diff --git a/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
index 4ffbaaa..6183525 100644
--- a/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
@@ -73,7 +73,10 @@
     receiverType = _resolveTypeParameter(receiverType, ifLegacy: true);
 
     if (_typeSystem.isDynamicBounded(receiverType)) {
-      _lookupInterfaceType(_typeProvider.objectType);
+      _lookupInterfaceType(
+        _typeProvider.objectType,
+        recoverWithStatic: false,
+      );
       _needsGetterError = false;
       _needsSetterError = false;
       return _toResult();
@@ -207,7 +210,10 @@
     }
   }
 
-  void _lookupInterfaceType(InterfaceType type) {
+  void _lookupInterfaceType(
+    InterfaceType type, {
+    bool recoverWithStatic = true,
+  }) {
     var isSuper = _receiver is SuperExpression;
 
     var getterName = Name(_definingLibrary.source.uri, _name);
@@ -215,7 +221,7 @@
         _resolver.inheritance.getMember(type, getterName, forSuper: isSuper);
     _needsGetterError = _getterRequested == null;
 
-    if (_getterRequested == null) {
+    if (_getterRequested == null && recoverWithStatic) {
       var classElement = type.element as AbstractClassElementImpl;
       _getterRecovery ??=
           classElement.lookupStaticGetter(_name, _definingLibrary) ??
@@ -228,7 +234,7 @@
         _resolver.inheritance.getMember(type, setterName, forSuper: isSuper);
     _needsSetterError = _setterRequested == null;
 
-    if (_setterRequested == null) {
+    if (_setterRequested == null && recoverWithStatic) {
       var classElement = type.element as AbstractClassElementImpl;
       _setterRecovery ??=
           classElement.lookupStaticSetter(_name, _definingLibrary);
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index b20ece0..47cc45d0 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -521,6 +521,10 @@
 
   external String toString();
   external dynamic noSuchMethod(Invocation invocation);
+
+  static int hash(Object? object1, Object? object2) => 0;
+  static int hashAll(Iterable<Object?> objects) => 0;
+  static int hashAllUnordered(Iterable<Object?> objects) => 0;
 }
 
 abstract class Enum {
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index a76e41a..f094945 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -1410,6 +1410,21 @@
     assertType(findNode.binary('1 + 2'), 'int');
   }
 
+  test_hasReceiver_dynamic_hash() async {
+    await assertNoErrorsInCode(r'''
+void f(dynamic a) {
+  a.hash(0, 1);
+}
+''');
+    assertMethodInvocation2(
+      findNode.methodInvocation('hash('),
+      element: null,
+      typeArgumentTypes: [],
+      invokeType: 'dynamic',
+      type: 'dynamic',
+    );
+  }
+
   test_hasReceiver_functionTyped() async {
     await assertNoErrorsInCode(r'''
 void foo(int _) {}
diff --git a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
index e3ef89b..d209f0c 100644
--- a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
@@ -422,6 +422,105 @@
     );
   }
 
+  test_ofDynamic_read_hash() async {
+    await assertNoErrorsInCode('''
+void f(dynamic a) {
+  (a).hash;
+}
+''');
+
+    var propertyAccess = findNode.propertyAccess('hash;');
+    assertPropertyAccess2(
+      propertyAccess,
+      element: null,
+      type: 'dynamic',
+    );
+
+    assertSimpleIdentifier(
+      propertyAccess.propertyName,
+      element: null,
+      type: 'dynamic',
+    );
+  }
+
+  test_ofDynamic_read_hashCode() async {
+    await assertNoErrorsInCode('''
+void f(dynamic a) {
+  (a).hashCode;
+}
+''');
+
+    var hashCodeElement = elementMatcher(
+      objectElement.getGetter('hashCode'),
+      isLegacy: isLegacyLibrary,
+    );
+
+    var propertyAccess = findNode.propertyAccess('hashCode;');
+    assertPropertyAccess2(
+      propertyAccess,
+      element: hashCodeElement,
+      type: 'int',
+    );
+
+    assertSimpleIdentifier(
+      propertyAccess.propertyName,
+      element: hashCodeElement,
+      type: 'int',
+    );
+  }
+
+  test_ofDynamic_read_runtimeType() async {
+    await assertNoErrorsInCode('''
+void f(dynamic a) {
+  (a).runtimeType;
+}
+''');
+
+    var runtimeTypeElement = elementMatcher(
+      objectElement.getGetter('runtimeType'),
+      isLegacy: isLegacyLibrary,
+    );
+
+    var propertyAccess = findNode.propertyAccess('runtimeType;');
+    assertPropertyAccess2(
+      propertyAccess,
+      element: runtimeTypeElement,
+      type: 'Type',
+    );
+
+    assertSimpleIdentifier(
+      propertyAccess.propertyName,
+      element: runtimeTypeElement,
+      type: 'Type',
+    );
+  }
+
+  test_ofDynamic_read_toString() async {
+    await assertNoErrorsInCode('''
+void f(dynamic a) {
+  (a).toString;
+}
+''');
+
+    var toStringElement = elementMatcher(
+      objectElement.getMethod('toString'),
+      isLegacy: isLegacyLibrary,
+    );
+
+    var propertyAccess = findNode.propertyAccess('toString;');
+    assertPropertyAccess2(
+      propertyAccess,
+      element: toStringElement,
+      type: 'String Function()',
+    );
+
+    assertSimpleIdentifier(
+      propertyAccess.propertyName,
+      element: toStringElement,
+      type: 'String Function()',
+    );
+  }
+
   test_ofExtension_read() async {
     await assertNoErrorsInCode('''
 class A {}
diff --git a/pkg/dartdev/lib/src/sdk.dart b/pkg/dartdev/lib/src/sdk.dart
index 426f810..833df09 100644
--- a/pkg/dartdev/lib/src/sdk.dart
+++ b/pkg/dartdev/lib/src/sdk.dart
@@ -39,8 +39,11 @@
 /// A utility class for finding and referencing paths within the Dart SDK.
 class Sdk {
   final String sdkPath;
+  final String version;
 
-  Sdk() : sdkPath = _computeSdkPath;
+  Sdk()
+      : sdkPath = _computeSdkPath,
+        version = Runtime.runtime.version;
 
   // Assume that we want to use the same Dart executable that we used to spawn
   // DartDev. We should be able to run programs with out/ReleaseX64/dart even
@@ -97,25 +100,20 @@
   static Runtime runtime = Runtime._();
 
   // Match "2.10.0-edge.0b2da6e7 (be) ...".
-  static RegExp channelRegex = RegExp(r'.* \(([\d\w]+)\) .*');
+  static final RegExp _channelRegex = RegExp(r'.* \(([\d\w]+)\) .*');
 
-  String _channel;
-
-  Runtime._() {
-    _parseVersion();
-  }
+  /// The SDK's version number (x.y.z-a.b.channel).
+  final String version;
 
   /// The SDK's release channel (`be`, `dev`, `beta`, `stable`).
-  String get channel => _channel;
+  final String channel;
 
-  /// Return whether the SDK is from the stable release channel.
-  bool get stableChannel => channel == 'stable';
+  Runtime._()
+      : version = _computeVersion(Platform.version),
+        channel = _computeChannel(Platform.version);
 
-  void _parseVersion() {
-    final version = Platform.version;
-    final match = channelRegex.firstMatch(version);
-    if (match != null) {
-      _channel = match.group(1);
-    }
-  }
+  static String _computeVersion(String version) =>
+      version.substring(0, version.indexOf(' '));
+  static String _computeChannel(String version) =>
+      _channelRegex.firstMatch(version)?.group(1);
 }
diff --git a/pkg/dartdev/lib/src/templates/common.dart b/pkg/dartdev/lib/src/templates/common.dart
index 2aac572..ac53756 100644
--- a/pkg/dartdev/lib/src/templates/common.dart
+++ b/pkg/dartdev/lib/src/templates/common.dart
@@ -2,7 +2,13 @@
 // 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.
 
-final String gitignore = '''
+import '../sdk.dart';
+
+String get sdkConstraint => '''
+  sdk: '>=${sdk.version} <3.0.0'
+''';
+
+const String gitignore = '''
 # Files and directories created by pub.
 .dart_tool/
 .packages
@@ -11,7 +17,7 @@
 build/
 ''';
 
-final String analysisOptions = '''
+const String analysisOptions = '''
 # This file configures the static analysis results for your project (errors,
 # warnings, and lints).
 #
@@ -44,7 +50,7 @@
 # https://dart.dev/guides/language/analysis-options
 ''';
 
-final String changelog = '''
+const String changelog = '''
 ## 1.0.0
 
 - Initial version.
diff --git a/pkg/dartdev/lib/src/templates/console_full.dart b/pkg/dartdev/lib/src/templates/console_full.dart
index 5797c9a..553ceeb 100644
--- a/pkg/dartdev/lib/src/templates/console_full.dart
+++ b/pkg/dartdev/lib/src/templates/console_full.dart
@@ -38,7 +38,7 @@
 # homepage: https://www.example.com
 
 environment:
-  sdk: '>=2.12.0 <3.0.0'
+${common.sdkConstraint}
 
 # dependencies:
 #   path: ^1.8.0
diff --git a/pkg/dartdev/lib/src/templates/console_simple.dart b/pkg/dartdev/lib/src/templates/console_simple.dart
index 376249b..5c6d381 100644
--- a/pkg/dartdev/lib/src/templates/console_simple.dart
+++ b/pkg/dartdev/lib/src/templates/console_simple.dart
@@ -36,7 +36,7 @@
 # homepage: https://www.example.com
 
 environment:
-  sdk: '>=2.12.0 <3.0.0'
+${common.sdkConstraint}
 
 # dependencies:
 #   path: ^1.8.0
diff --git a/pkg/dartdev/lib/src/templates/package_simple.dart b/pkg/dartdev/lib/src/templates/package_simple.dart
index efe98f9..591f110 100644
--- a/pkg/dartdev/lib/src/templates/package_simple.dart
+++ b/pkg/dartdev/lib/src/templates/package_simple.dart
@@ -55,7 +55,7 @@
 # homepage: https://www.example.com
 
 environment:
-  sdk: '>=2.12.0 <3.0.0'
+${common.sdkConstraint}
 
 # dependencies:
 #   path: ^1.8.0
diff --git a/pkg/dartdev/lib/src/templates/server_shelf.dart b/pkg/dartdev/lib/src/templates/server_shelf.dart
index 45873bc..ed6b730 100644
--- a/pkg/dartdev/lib/src/templates/server_shelf.dart
+++ b/pkg/dartdev/lib/src/templates/server_shelf.dart
@@ -42,7 +42,7 @@
 # homepage: https://www.example.com
 
 environment:
-  sdk: '>=2.12.0 <3.0.0'
+${common.sdkConstraint}
 
 dependencies:
   args: ^2.0.0
diff --git a/pkg/dartdev/lib/src/templates/web_simple.dart b/pkg/dartdev/lib/src/templates/web_simple.dart
index 4bceae1..2dde7de 100644
--- a/pkg/dartdev/lib/src/templates/web_simple.dart
+++ b/pkg/dartdev/lib/src/templates/web_simple.dart
@@ -42,7 +42,7 @@
 # homepage: https://www.example.com
 
 environment:
-  sdk: '>=2.12.0 <3.0.0'
+${common.sdkConstraint}
 
 # dependencies:
 #   path: ^1.7.0
diff --git a/tools/VERSION b/tools/VERSION
index 8741365..afb109a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
 MINOR 14
 PATCH 0
 PRERELEASE 377
-PRERELEASE_PATCH 4
\ No newline at end of file
+PRERELEASE_PATCH 7
\ No newline at end of file