Version 2.17.0-84.0.dev

Merge commit '848e1063467f7d5c2520d6999f2d6d7a3b0aa1f0' into 'dev'
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index 1de1c68..ccea928 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -76,48 +76,6 @@
   }
 }
 
-abstract class Enqueuer {
-  /// If `true` the checking for unenqueued members is skipped. The current
-  /// implementation registers parameter usages as a side-effect so unit
-  /// testing of member usage we need to test both with and without the
-  /// enqueuer check.
-  // TODO(johnniwinther): [checkEnqueuerConsistency] should not have
-  // side-effects.
-  static bool skipEnqueuerCheckForTesting = false;
-
-  WorldBuilder get worldBuilder;
-
-  void open(ImpactStrategy impactStrategy, FunctionEntity mainMethod,
-      Iterable<Uri> libraries);
-  void close();
-
-  /// Returns [:true:] if this enqueuer is the resolution enqueuer.
-  bool get isResolutionQueue;
-
-  bool queueIsClosed;
-
-  bool get queueIsEmpty;
-
-  ImpactUseCase get impactUse;
-
-  void forEach(void f(WorkItem work));
-
-  /// Apply the [worldImpact] to this enqueuer. If the [impactSource] is
-  /// provided the impact strategy will remove it from the element impact cache,
-  /// if it is no longer needed.
-  void applyImpact(WorldImpact worldImpact, {var impactSource});
-  bool checkNoEnqueuedInvokedInstanceMethods(
-      ElementEnvironment elementEnvironment);
-
-  /// Check the enqueuer queue is empty or fail otherwise.
-  void checkQueueIsEmpty();
-  void logSummary(void log(String message));
-
-  Iterable<MemberEntity> get processedEntities;
-
-  Iterable<ClassEntity> get processedClasses;
-}
-
 abstract class EnqueuerListener {
   /// Called to instruct to the backend that [type] has been instantiated.
   void registerInstantiatedType(InterfaceType type,
@@ -176,7 +134,43 @@
   void logSummary(void log(String message));
 }
 
-abstract class EnqueuerImpl extends Enqueuer {
+abstract class Enqueuer {
+  /// If `true` the checking for unenqueued members is skipped. The current
+  /// implementation registers parameter usages as a side-effect so unit
+  /// testing of member usage we need to test both with and without the
+  /// enqueuer check.
+  // TODO(johnniwinther): [checkEnqueuerConsistency] should not have
+  // side-effects.
+  static bool skipEnqueuerCheckForTesting = false;
+
+  WorldBuilder get worldBuilder;
+
+  /// Returns [:true:] if this enqueuer is the resolution enqueuer.
+  bool get isResolutionQueue;
+
+  bool queueIsClosed;
+
+  bool get queueIsEmpty;
+
+  ImpactUseCase get impactUse;
+
+  void forEach(void f(WorkItem work));
+
+  /// Apply the [worldImpact] to this enqueuer. If the [impactSource] is
+  /// provided the impact strategy will remove it from the element impact cache,
+  /// if it is no longer needed.
+  void applyImpact(WorldImpact worldImpact, {var impactSource});
+  bool checkNoEnqueuedInvokedInstanceMethods(
+      ElementEnvironment elementEnvironment);
+
+  /// Check the enqueuer queue is empty or fail otherwise.
+  void checkQueueIsEmpty();
+  void logSummary(void log(String message));
+
+  Iterable<MemberEntity> get processedEntities;
+
+  Iterable<ClassEntity> get processedClasses;
+
   CompilerTask get task;
   void checkClass(ClassEntity cls);
   void processStaticUse(MemberEntity member, StaticUse staticUse);
@@ -190,14 +184,12 @@
 
   ImpactStrategy get impactStrategy => _impactStrategy;
 
-  @override
   void open(ImpactStrategy impactStrategy, FunctionEntity mainMethod,
       Iterable<Uri> libraries) {
     _impactStrategy = impactStrategy;
     listener.onQueueOpen(this, mainMethod, libraries);
   }
 
-  @override
   void close() {
     // TODO(johnniwinther): Set [_impactStrategy] to `null` and [queueIsClosed]
     // to `true` here.
@@ -223,7 +215,7 @@
 }
 
 /// [Enqueuer] which is specific to resolution.
-class ResolutionEnqueuer extends EnqueuerImpl {
+class ResolutionEnqueuer extends Enqueuer {
   static const ImpactUseCase IMPACT_USE = ImpactUseCase('ResolutionEnqueuer');
 
   @override
@@ -253,7 +245,7 @@
   ResolutionEnqueuer(this.task, this._reporter, this.listener,
       this._worldBuilder, this._workItemBuilder, this._annotationsData,
       [this.name = 'resolution enqueuer']) {
-    _impactVisitor = EnqueuerImplImpactVisitor(this);
+    _impactVisitor = EnqueuerImpactVisitor(this);
   }
 
   @override
@@ -531,10 +523,10 @@
   }
 }
 
-class EnqueuerImplImpactVisitor implements WorldImpactVisitor {
-  final EnqueuerImpl enqueuer;
+class EnqueuerImpactVisitor implements WorldImpactVisitor {
+  final Enqueuer enqueuer;
 
-  EnqueuerImplImpactVisitor(this.enqueuer);
+  EnqueuerImpactVisitor(this.enqueuer);
 
   @override
   void visitDynamicUse(MemberEntity member, DynamicUse dynamicUse) {
diff --git a/pkg/compiler/lib/src/js_backend/enqueuer.dart b/pkg/compiler/lib/src/js_backend/enqueuer.dart
index 4b011ff..73ba934 100644
--- a/pkg/compiler/lib/src/js_backend/enqueuer.dart
+++ b/pkg/compiler/lib/src/js_backend/enqueuer.dart
@@ -30,7 +30,7 @@
 import '../util/util.dart' show Setlet;
 
 /// [Enqueuer] which is specific to code generation.
-class CodegenEnqueuer extends EnqueuerImpl {
+class CodegenEnqueuer extends Enqueuer {
   final String name;
   final Set<ClassEntity> _recentClasses = Setlet();
   bool _recentConstants = false;
@@ -61,7 +61,7 @@
   CodegenEnqueuer(this.task, this._worldBuilder, this._workItemBuilder,
       this.listener, this._annotationsData)
       : this.name = 'codegen enqueuer' {
-    _impactVisitor = EnqueuerImplImpactVisitor(this);
+    _impactVisitor = EnqueuerImpactVisitor(this);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index b4a93af..7e4b112 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -56,7 +56,6 @@
 import 'kelements.dart';
 import 'kernel_impact.dart';
 
-part 'native_basic_data.dart';
 part 'no_such_method_resolver.dart';
 
 /// Implementation of [KernelToElementMap] that only supports world
diff --git a/pkg/compiler/lib/src/kernel/kernel_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
index 535a664..86fd3c3 100644
--- a/pkg/compiler/lib/src/kernel/kernel_strategy.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
@@ -47,6 +47,7 @@
 import 'element_map.dart';
 import 'element_map_impl.dart';
 import 'loader.dart';
+import 'native_basic_data.dart';
 
 /// Front end strategy that loads '.dill' files and builds a resolved element
 /// model from kernel IR nodes.
diff --git a/pkg/compiler/lib/src/kernel/native_basic_data.dart b/pkg/compiler/lib/src/kernel/native_basic_data.dart
index fc85b5e..014ceff 100644
--- a/pkg/compiler/lib/src/kernel/native_basic_data.dart
+++ b/pkg/compiler/lib/src/kernel/native_basic_data.dart
@@ -2,8 +2,18 @@
 // 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.
 
-// TODO(johnniwinther): Make this a separate library.
-part of dart2js.kernel.element_map;
+import 'package:kernel/ast.dart' as ir;
+
+import '../common.dart';
+import '../common_elements.dart';
+import '../constants/values.dart';
+import '../elements/entities.dart';
+import '../frontend_strategy.dart';
+import '../ir/annotations.dart';
+import '../js_backend/native_data.dart';
+import '../native/resolver.dart';
+
+import 'element_map_impl.dart';
 
 class KernelAnnotationProcessor implements AnnotationProcessor {
   final KernelToElementMapImpl elementMap;
diff --git a/pkg/dds/lib/src/dap/isolate_manager.dart b/pkg/dds/lib/src/dap/isolate_manager.dart
index ee48794..d13e8fa 100644
--- a/pkg/dds/lib/src/dap/isolate_manager.dart
+++ b/pkg/dds/lib/src/dap/isolate_manager.dart
@@ -445,11 +445,11 @@
     } else if (eventKind == vm.EventKind.kPauseStart) {
       // Don't resume from a PauseStart if this has already happened (see
       // comments on [thread.hasBeenStarted]).
-      if (!thread.hasBeenStarted) {
+      if (!thread.startupHandled) {
+        thread.startupHandled = true;
         // If requested, automatically resume. Otherwise send a Stopped event to
         // inform the client UI the thread is paused.
         if (resumeIfStarting) {
-          thread.hasBeenStarted = true;
           await resumeThread(thread.threadId);
         } else {
           sendStoppedOnEntryEvent(thread.threadId);
@@ -730,7 +730,11 @@
   int? exceptionReference;
   var paused = false;
 
-  /// Tracks whether an isolate has been started from its PauseStart state.
+  /// Tracks whether an isolates startup routine has been handled.
+  ///
+  /// The startup routine will either automatically resume the isolate or send
+  /// a stopped-on-entry event, depending on whether we're launching or
+  /// attaching.
   ///
   /// This is used to prevent trying to resume a thread twice if a PauseStart
   /// event arrives around the same time that are our initialization code (which
@@ -739,7 +743,12 @@
   ///
   /// If we send a duplicate resume, it could trigger an unwanted resume for a
   /// breakpoint or exception that occur early on.
-  bool hasBeenStarted = false;
+  ///
+  /// In the case of attach, a similar race exists.. The initialization may
+  /// choose not to resume the isolate (so we can attach to a VM with paused
+  /// isolates) but then a PauseStart event that arrived during initialization
+  /// could trigger a resume that we don't want.
+  bool startupHandled = false;
 
   /// The most recent pauseEvent for this isolate.
   vm.Event? pauseEvent;
diff --git a/pkg/dds/test/dap/integration/test_support.dart b/pkg/dds/test/dap/integration/test_support.dart
index 5e4c792..7a55bb2 100644
--- a/pkg/dds/test/dap/integration/test_support.dart
+++ b/pkg/dds/test/dap/integration/test_support.dart
@@ -241,7 +241,30 @@
     await server.stop();
 
     // Clean up any temp folders created during the test runs.
-    testDir.deleteSync(recursive: true);
+    await tryDelete(testDir);
+  }
+
+  /// Tries to delete [dir] multiple times before printing a warning and giving up.
+  ///
+  /// This avoids "The process cannot access the file because it is being
+  /// used by another process" errors on Windows trying to delete folders that
+  /// have only very recently been unlocked.
+  Future<void> tryDelete(Directory dir) async {
+    const maxAttempts = 10;
+    const delay = Duration(milliseconds: 100);
+    var attempt = 0;
+    while (++attempt <= maxAttempts) {
+      try {
+        testDir.deleteSync(recursive: true);
+        break;
+      } catch (e) {
+        if (attempt == maxAttempts) {
+          print('Failed to delete $testDir after $maxAttempts attempts.\n$e');
+          break;
+        }
+        await Future.delayed(delay);
+      }
+    }
   }
 
   static Future<DapTestSession> setUp({List<String>? additionalArgs}) async {
diff --git a/pkg/dds/tool/devtools_server/serve_local.dart b/pkg/dds/tool/devtools_server/serve_local.dart
new file mode 100644
index 0000000..db893fe
--- /dev/null
+++ b/pkg/dds/tool/devtools_server/serve_local.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:args/args.dart';
+import 'package:dds/devtools_server.dart';
+
+const argDevToolsBuild = 'devtools-build';
+
+void main(List<String> args) {
+  final argParser = ArgParser()
+    ..addOption(
+      argDevToolsBuild,
+      help: 'The location of the DevTools build to serve from DevTools server '
+          '(e.g. --devtools-build=absolute/path/to/devtools/build).',
+      mandatory: true,
+    );
+
+  try {
+    final ArgResults argResults = argParser.parse(args);
+    unawaited(
+      DevToolsServer().serveDevTools(
+        customDevToolsPath: argResults[argDevToolsBuild],
+      ),
+    );
+  } on FormatException catch (e) {
+    print(e.message);
+    print('');
+    print(argParser.usage);
+  }
+}
diff --git a/runtime/lib/errors.cc b/runtime/lib/errors.cc
index 7a3415a..3ef3079 100644
--- a/runtime/lib/errors.cc
+++ b/runtime/lib/errors.cc
@@ -168,57 +168,6 @@
   return Object::null();
 }
 
-// Allocate and throw a new FallThroughError.
-// Arg0: index of the case clause token into which we fall through.
-// Return value: none, throws an exception.
-DEFINE_NATIVE_ENTRY(FallThroughError_throwNew, 0, 1) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Smi, smi_pos, arguments->NativeArgAt(0));
-  TokenPosition fallthrough_pos = TokenPosition::Deserialize(smi_pos.Value());
-
-  const Array& args = Array::Handle(Array::New(2));
-
-  // Initialize 'url' and 'line' arguments.
-  DartFrameIterator iterator(thread,
-                             StackFrameIterator::kNoCrossThreadIteration);
-  iterator.NextFrame();  // Skip native call.
-  const Script& script = Script::Handle(Exceptions::GetCallerScript(&iterator));
-  args.SetAt(0, String::Handle(script.url()));
-  intptr_t line = -1;
-  script.GetTokenLocation(fallthrough_pos, &line);
-  args.SetAt(1, Smi::Handle(Smi::New(line)));
-
-  Exceptions::ThrowByType(Exceptions::kFallThrough, args);
-  UNREACHABLE();
-  return Object::null();
-}
-
-// Allocate and throw a new AbstractClassInstantiationError.
-// Arg0: Token position of allocation statement.
-// Arg1: class name of the abstract class that cannot be instantiated.
-// Return value: none, throws an exception.
-DEFINE_NATIVE_ENTRY(AbstractClassInstantiationError_throwNew, 0, 2) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Smi, smi_pos, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(String, class_name, arguments->NativeArgAt(1));
-  TokenPosition error_pos = TokenPosition::Deserialize(smi_pos.Value());
-
-  const Array& args = Array::Handle(Array::New(3));
-
-  // Initialize 'className', 'url' and 'line' arguments.
-  DartFrameIterator iterator(thread,
-                             StackFrameIterator::kNoCrossThreadIteration);
-  iterator.NextFrame();  // Skip native call.
-  const Script& script = Script::Handle(Exceptions::GetCallerScript(&iterator));
-  args.SetAt(0, class_name);
-  args.SetAt(1, String::Handle(script.url()));
-  intptr_t line = -1;
-  script.GetTokenLocation(error_pos, &line);
-  args.SetAt(2, Smi::Handle(Smi::New(line)));
-
-  Exceptions::ThrowByType(Exceptions::kAbstractClassInstantiation, args);
-  UNREACHABLE();
-  return Object::null();
-}
-
 // Rethrow an error with a stacktrace.
 DEFINE_NATIVE_ENTRY(Error_throwWithStackTrace, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, error, arguments->NativeArgAt(0));
diff --git a/runtime/tests/vm/dart/finalizer/weak_reference_run_gc_test.dart b/runtime/tests/vm/dart/finalizer/weak_reference_run_gc_test.dart
index 74e128e..5679b3c 100644
--- a/runtime/tests/vm/dart/finalizer/weak_reference_run_gc_test.dart
+++ b/runtime/tests/vm/dart/finalizer/weak_reference_run_gc_test.dart
@@ -11,6 +11,7 @@
 import 'package:expect/expect.dart';
 
 void main() {
+  testWeakReferenceNonExpandoKey();
   testWeakReference();
 }
 
@@ -22,6 +23,12 @@
   String toString() => 'Nonce($value)';
 }
 
+void testWeakReferenceNonExpandoKey() {
+  Expect.throwsArgumentError(() {
+    WeakReference<String>("Hello world!");
+  });
+}
+
 void testWeakReference() async {
   final weakRef = () {
     final object = Nonce(23);
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 20a2d74e..271ff4c 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -152,8 +152,6 @@
   V(Error_throwWithStackTrace, 2)                                              \
   V(StackTrace_current, 0)                                                     \
   V(TypeError_throwNew, 4)                                                     \
-  V(FallThroughError_throwNew, 1)                                              \
-  V(AbstractClassInstantiationError_throwNew, 2)                               \
   V(Stopwatch_now, 0)                                                          \
   V(Stopwatch_frequency, 0)                                                    \
   V(Timeline_getNextAsyncId, 0)                                                \
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart
index cf1bdbd..761bf6e 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart
@@ -15,7 +15,7 @@
 var _issuedRegisterExtensionWarning = false;
 final _developerSupportWarning = 'from dart:developer is only supported in '
     'build/run/test environments where the developer event method hooks have '
-    'been set.';
+    'been set by package:dwds v11.1.0 or higher.';
 
 /// Returns `true` if the debugger service has been attached to the app.
 // TODO(46377) Update this check when we have a documented API for DDC apps.
@@ -85,8 +85,7 @@
     JS('', r'#.$emitRegisterEvent(#)', dart.global_, method);
     return;
   }
-  // TODO(nshahan) Remove use of debug log after package:dwds removes support.
-  // https://github.com/dart-lang/webdev/issues/1342
+  // TODO(48103) Remove use of debug log in Dart 3.0.0.
   JS('', 'console.debug("dart.developer.registerExtension", #)', method);
 }
 
@@ -134,8 +133,7 @@
     JS('', r'#.$emitDebugEvent(#, #)', dart.global_, eventKind, eventData);
     return;
   }
-  // TODO(nshahan) Remove use of debug log after package:dwds removes support.
-  // https://github.com/dart-lang/webdev/issues/1342
+  // TODO(48103) Remove use of debug log in Dart 3.0.0.
   JS('', 'console.debug("dart.developer.postEvent", #, #)', eventKind,
       eventData);
 }
diff --git a/sdk/lib/_internal/vm/lib/errors_patch.dart b/sdk/lib/_internal/vm/lib/errors_patch.dart
index aaaf11f..05b0afa 100644
--- a/sdk/lib/_internal/vm/lib/errors_patch.dart
+++ b/sdk/lib/_internal/vm/lib/errors_patch.dart
@@ -134,9 +134,6 @@
   @pragma("vm:entry-point")
   FallThroughError._create(this._url, this._line);
 
-  @pragma("vm:external-name", "FallThroughError_throwNew")
-  external static _throwNew(int caseClausePos);
-
   @patch
   String toString() {
     return "'$_url': Switch case fall-through at line $_line.";
@@ -176,9 +173,6 @@
   AbstractClassInstantiationError._create(
       this._className, this._url, this._line);
 
-  @pragma("vm:external-name", "AbstractClassInstantiationError_throwNew")
-  external static _throwNew(int caseClausePos, String className);
-
   @patch
   String toString() {
     return "Cannot instantiate abstract class $_className: "
diff --git a/sdk/lib/_internal/vm/lib/expando_patch.dart b/sdk/lib/_internal/vm/lib/expando_patch.dart
index 882231f..c217336 100644
--- a/sdk/lib/_internal/vm/lib/expando_patch.dart
+++ b/sdk/lib/_internal/vm/lib/expando_patch.dart
@@ -178,7 +178,9 @@
   // instead of reusing WeakProperty.
   final _WeakProperty _weakProperty;
 
-  _WeakReferenceImpl(T object) : _weakProperty = _WeakProperty()..key = object;
+  _WeakReferenceImpl(T object) : _weakProperty = _WeakProperty()..key = object {
+    Expando._checkType(object);
+  }
 
   T? get target => unsafeCast<T?>(_weakProperty.key);
 }
diff --git a/tools/VERSION b/tools/VERSION
index f4a203c..e692984 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 83
+PRERELEASE 84
 PRERELEASE_PATCH 0
\ No newline at end of file