Version 2.15.0-52.0.dev

Merge commit '3aab52f4980cb96b936f29615789c7139d755679' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index b347d13..81fe255 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
     "constraint, update this by running tools/generate_package_config.dart."
   ],
   "configVersion": 2,
-  "generated": "2021-08-12T14:38:50.585343",
+  "generated": "2021-08-23T16:52:51.727804",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
@@ -372,12 +372,6 @@
       "languageVersion": "2.12"
     },
     {
-      "name": "http_throttle",
-      "rootUri": "../third_party/pkg/http_throttle",
-      "packageUri": "lib/",
-      "languageVersion": "2.0"
-    },
-    {
       "name": "intl",
       "rootUri": "../third_party/pkg/intl",
       "packageUri": "lib/",
diff --git a/DEPS b/DEPS
index ed209a5..8315824 100644
--- a/DEPS
+++ b/DEPS
@@ -117,7 +117,6 @@
   "http_multi_server_rev": "de1b312164c24a1690b46c6e97bd47eff40c4649",
   "http_parser_rev": "202391286ddc13c4c3c284ac5b511f04697250ed",
   "http_rev": "778174bca2c13becd88ef3353309190b1e8b9479",
-  "http_throttle_tag" : "1.0.2",
   "icu_rev" : "81d656878ec611cb0b42d52c82e9dae93920d9ba",
   "idl_parser_rev": "5fb1ebf49d235b5a70c9f49047e83b0654031eb7",
   "intl_tag": "0.17.0-nullsafety",
@@ -159,8 +158,8 @@
   "stream_channel_rev": "d7251e61253ec389ee6e045ee1042311bced8f1d",
   "string_scanner_rev": "1b63e6e5db5933d7be0a45da6e1129fe00262734",
   "sync_http_rev": "b59c134f2e34d12acac110d4f17f83e5a7db4330",
-  "test_descriptor_tag": "2.0.0",
-  "test_process_tag": "2.0.0",
+  "test_descriptor_rev": "ead23c1e7df079ac0f6457a35f7a71432892e527",
+  "test_process_rev": "7c73ec8a8a6e0e63d0ec27d70c21ca4323fb5e8f",
   "term_glyph_rev": "6a0f9b6fb645ba75e7a00a4e20072678327a0347",
   "test_reflective_loader_rev": "54e930a11c372683792e22bddad79197728c91ce",
   "test_rev": "099dcc4d052a30c6921489cfbefa1c8531d12975",
@@ -369,9 +368,6 @@
       "@" + Var("http_multi_server_rev"),
   Var("dart_root") + "/third_party/pkg/http_parser":
       Var("dart_git") + "http_parser.git" + "@" + Var("http_parser_rev"),
-  Var("dart_root") + "/third_party/pkg/http_throttle":
-      Var("dart_git") + "http_throttle.git" +
-      "@" + Var("http_throttle_tag"),
   Var("dart_root") + "/third_party/pkg/intl":
       Var("dart_git") + "intl.git" + "@" + Var("intl_tag"),
   Var("dart_root") + "/third_party/pkg/json_rpc_2":
@@ -449,9 +445,9 @@
   Var("dart_root") + "/third_party/pkg/test":
       Var("dart_git") + "test.git" + "@" + Var("test_rev"),
   Var("dart_root") + "/third_party/pkg/test_descriptor":
-      Var("dart_git") + "test_descriptor.git" + "@" + Var("test_descriptor_tag"),
+      Var("dart_git") + "test_descriptor.git" + "@" + Var("test_descriptor_rev"),
   Var("dart_root") + "/third_party/pkg/test_process":
-      Var("dart_git") + "test_process.git" + "@" + Var("test_process_tag"),
+      Var("dart_git") + "test_process.git" + "@" + Var("test_process_rev"),
   Var("dart_root") + "/third_party/pkg/test_reflective_loader":
       Var("dart_git") + "test_reflective_loader.git" +
       "@" + Var("test_reflective_loader_rev"),
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/null_aware_call.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/null_aware_call.dart
new file mode 100644
index 0000000..0f37b5e
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/null_aware_call.dart
@@ -0,0 +1,47 @@
+// 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.
+
+class C {
+  C method(dynamic value) => this;
+  C Function(dynamic) get functionGetter => (_) => this;
+}
+
+void methodCall(C? c) {
+  c?.method(/*nonNullable*/ c);
+}
+
+void functionGetterCall(C? c) {
+  c?.functionGetter(/*nonNullable*/ c);
+}
+
+void methodCall_nullShorting(C? c) {
+  c?.method(/*nonNullable*/ c).method(/*nonNullable*/ c);
+}
+
+void functionGetterCall_nullShorting(C? c) {
+  c?.functionGetter(/*nonNullable*/ c).functionGetter(/*nonNullable*/ c);
+}
+
+void null_aware_cascades_promote_target(C? c) {
+  c?..method(/*nonNullable*/ c);
+  c?..functionGetter(/*nonNullable*/ c);
+}
+
+void null_aware_cascades_do_not_promote_others(C? c, int? i) {
+  // Promotions that happen inside null-aware cascade sections
+  // disappear after the cascade section, because they are not
+  // guaranteed to execute.
+  c?..method(i!);
+  c?..functionGetter(i!);
+  i;
+}
+
+void normal_cascades_do_promote_others(C c, int? i, int? j) {
+  // Promotions that happen inside non-null-aware cascade sections
+  // don't disappear after the cascade section.
+  c..method(i!);
+  c..functionGetter(j!);
+  /*nonNullable*/ i;
+  /*nonNullable*/ j;
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_missing_overrides.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_missing_overrides.dart
index e6e0c70..5d642cb 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_missing_overrides.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_missing_overrides.dart
@@ -16,7 +16,7 @@
   int _numElements = 0;
 
   @override
-  List<Object> get fixArguments => [_numElements];
+  List<Object> get fixArguments => [_numElements, _numElements == 1 ? '' : 's'];
 
   @override
   FixKind get fixKind => DartFixKind.CREATE_MISSING_OVERRIDES;
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 83b6c8b..fb59750 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -366,7 +366,7 @@
   static const CREATE_MISSING_OVERRIDES = FixKind(
       'dart.fix.create.missingOverrides',
       DartFixKindPriority.DEFAULT + 1,
-      'Create {0} missing override(s)');
+      'Create {0} missing override{1}');
   static const CREATE_MIXIN = FixKind('dart.fix.create.mixin',
       DartFixKindPriority.DEFAULT, "Create mixin '{0}'");
   static const CREATE_NO_SUCH_METHOD = FixKind(
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index cf52ef4..616c214 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -288,11 +288,12 @@
   void UpdateStoreBuffer(ObjectPtr obj) {
     ASSERT(obj->IsHeapObject());
     // If the newly written object is not a new object, drop it immediately.
-    if (!obj->IsNewObject() || visiting_old_object_->untag()->IsRemembered()) {
+    if (!obj->IsNewObject()) {
       return;
     }
-    visiting_old_object_->untag()->SetRememberedBit();
-    thread_->StoreBufferAddObjectGC(visiting_old_object_);
+    if (visiting_old_object_->untag()->TryAcquireRememberedBit()) {
+      thread_->StoreBufferAddObjectGC(visiting_old_object_);
+    }
   }
 
   DART_FORCE_INLINE
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index f99afbe..c27f8e8 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -317,10 +317,9 @@
     ASSERT(IsOldObject());
     return !tags_.Read<OldAndNotRememberedBit>();
   }
-  void SetRememberedBit() {
-    ASSERT(!IsRemembered());
+  bool TryAcquireRememberedBit() {
     ASSERT(!IsCardRemembered());
-    tags_.UpdateBool<OldAndNotRememberedBit>(false);
+    return tags_.TryClear<OldAndNotRememberedBit>();
   }
   void ClearRememberedBit() {
     ASSERT(IsOldObject());
@@ -328,10 +327,10 @@
   }
 
   DART_FORCE_INLINE
-  void AddToRememberedSet(Thread* thread) {
-    ASSERT(!this->IsRemembered());
-    this->SetRememberedBit();
-    thread->StoreBufferAddObject(ObjectPtr(this));
+  void EnsureInRememberedSet(Thread* thread) {
+    if (TryAcquireRememberedBit()) {
+      thread->StoreBufferAddObject(ObjectPtr(this));
+    }
   }
 
   bool IsCardRemembered() const { return tags_.Read<CardRememberedBit>(); }
@@ -665,7 +664,7 @@
       if (value->IsNewObject()) {
         // Generational barrier: record when a store creates an
         // old-and-not-remembered -> new reference.
-        AddToRememberedSet(thread);
+        EnsureInRememberedSet(thread);
       } else {
         // Incremental barrier: record when a store creates an
         // old -> old-and-not-marked reference.
@@ -695,11 +694,9 @@
       if (value->IsNewObject()) {
         // Generational barrier: record when a store creates an
         // old-and-not-remembered -> new reference.
-        ASSERT(!this->IsRemembered());
         if (this->IsCardRemembered()) {
           RememberCard(addr);
-        } else {
-          this->SetRememberedBit();
+        } else if (this->TryAcquireRememberedBit()) {
           thread->StoreBufferAddObject(static_cast<ObjectPtr>(this));
         }
       } else {
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index a545c0e..d6c3ad6 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -483,7 +483,7 @@
   }
 
   if (add_to_remembered_set) {
-    object->untag()->AddToRememberedSet(thread);
+    object->untag()->EnsureInRememberedSet(thread);
   }
 
   // For incremental write barrier elimination, we need to ensure that the
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 09a3b25..a9e319e 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -688,9 +688,7 @@
 
       switch (op_) {
         case Thread::RestoreWriteBarrierInvariantOp::kAddToRememberedSet:
-          if (!obj->untag()->IsRemembered()) {
-            obj->untag()->AddToRememberedSet(current_);
-          }
+          obj->untag()->EnsureInRememberedSet(current_);
           if (current_->is_marking()) {
             current_->DeferredMarkingStackAddObject(obj);
           }
diff --git a/tools/VERSION b/tools/VERSION
index ac3e141..e582617 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 51
+PRERELEASE 52
 PRERELEASE_PATCH 0
\ No newline at end of file