Version 2.17.0-29.0.dev

Merge commit '91154e78a32d506dd2989143840cc6785f4bc866' into 'dev'
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
index e8de391..3222ce8 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
@@ -628,7 +628,7 @@
     final kind = SymbolKind.fromJson(kindJson as int);
     final tagsJson = json['tags'];
     final tags = (tagsJson as List<Object?>?)
-        ?.map((item) => SymbolTag.fromJson(item as num))
+        ?.map((item) => SymbolTag.fromJson(item as int))
         .toList();
     final detailJson = json['detail'];
     final detail = detailJson as String?;
@@ -5528,7 +5528,7 @@
       Map<String, Object?> json) {
     final valueSetJson = json['valueSet'];
     final valueSet = (valueSetJson as List<Object?>)
-        .map((item) => InsertTextMode.fromJson(item as num))
+        .map((item) => InsertTextMode.fromJson(item as int))
         .toList();
     return CompletionClientCapabilitiesInsertTextModeSupport(
         valueSet: valueSet);
@@ -5743,7 +5743,7 @@
   CompletionContext({required this.triggerKind, this.triggerCharacter});
   static CompletionContext fromJson(Map<String, Object?> json) {
     final triggerKindJson = json['triggerKind'];
-    final triggerKind = CompletionTriggerKind.fromJson(triggerKindJson as num);
+    final triggerKind = CompletionTriggerKind.fromJson(triggerKindJson as int);
     final triggerCharacterJson = json['triggerCharacter'];
     final triggerCharacter = triggerCharacterJson as String?;
     return CompletionContext(
@@ -5879,7 +5879,7 @@
         : null;
     final insertTextModeJson = json['insertTextMode'];
     final insertTextMode = insertTextModeJson != null
-        ? InsertTextMode.fromJson(insertTextModeJson as num)
+        ? InsertTextMode.fromJson(insertTextModeJson as int)
         : null;
     final textEditJson = json['textEdit'];
     final textEdit = textEditJson == null
@@ -7041,7 +7041,7 @@
   const CompletionTriggerKind._(this._value);
   const CompletionTriggerKind.fromJson(this._value);
 
-  final num _value;
+  final int _value;
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
     switch (obj) {
@@ -8606,7 +8606,7 @@
     final range = Range.fromJson(rangeJson as Map<String, Object?>);
     final severityJson = json['severity'];
     final severity = severityJson != null
-        ? DiagnosticSeverity.fromJson(severityJson as num)
+        ? DiagnosticSeverity.fromJson(severityJson as int)
         : null;
     final codeJson = json['code'];
     final code = codeJson as String?;
@@ -8620,7 +8620,7 @@
     final message = messageJson as String;
     final tagsJson = json['tags'];
     final tags = (tagsJson as List<Object?>?)
-        ?.map((item) => DiagnosticTag.fromJson(item as num))
+        ?.map((item) => DiagnosticTag.fromJson(item as int))
         .toList();
     final relatedInformationJson = json['relatedInformation'];
     final relatedInformation = (relatedInformationJson as List<Object?>?)
@@ -8953,10 +8953,10 @@
   const DiagnosticSeverity(this._value);
   const DiagnosticSeverity.fromJson(this._value);
 
-  final num _value;
+  final int _value;
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
-    return obj is num;
+    return obj is int;
   }
 
   /// Reports an error.
@@ -8988,10 +8988,10 @@
   const DiagnosticTag(this._value);
   const DiagnosticTag.fromJson(this._value);
 
-  final num _value;
+  final int _value;
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
-    return obj is num;
+    return obj is int;
   }
 
   /// Unused or unnecessary code.
@@ -12384,7 +12384,7 @@
     final kind = SymbolKind.fromJson(kindJson as int);
     final tagsJson = json['tags'];
     final tags = (tagsJson as List<Object?>?)
-        ?.map((item) => SymbolTag.fromJson(item as num))
+        ?.map((item) => SymbolTag.fromJson(item as int))
         .toList();
     final deprecatedJson = json['deprecated'];
     final deprecated = deprecatedJson as bool?;
@@ -12864,7 +12864,7 @@
       Map<String, Object?> json) {
     final valueSetJson = json['valueSet'];
     final valueSet = (valueSetJson as List<Object?>)
-        .map((item) => SymbolTag.fromJson(item as num))
+        .map((item) => SymbolTag.fromJson(item as int))
         .toList();
     return DocumentSymbolClientCapabilitiesTagSupport(valueSet: valueSet);
   }
@@ -16348,7 +16348,8 @@
         final trace = obj['trace'];
         if (trace != null &&
             !((trace == 'off' || trace == 'message' || trace == 'verbose'))) {
-          reporter.reportError('must be of type String');
+          reporter.reportError(
+              'must be one of the literals \'off\', \'message\', \'verbose\'');
           return false;
         }
       } finally {
@@ -16870,10 +16871,10 @@
   const InsertTextMode(this._value);
   const InsertTextMode.fromJson(this._value);
 
-  final num _value;
+  final int _value;
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
-    return obj is num;
+    return obj is int;
   }
 
   /// The insertion or replace strings is taken as it is. If the value is multi
@@ -19567,10 +19568,10 @@
   const PrepareSupportDefaultBehavior(this._value);
   const PrepareSupportDefaultBehavior.fromJson(this._value);
 
-  final num _value;
+  final int _value;
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
-    return obj is num;
+    return obj is int;
   }
 
   /// The client's default behavior is to select the identifier according the to
@@ -19834,7 +19835,7 @@
       Map<String, Object?> json) {
     final valueSetJson = json['valueSet'];
     final valueSet = (valueSetJson as List<Object?>)
-        .map((item) => DiagnosticTag.fromJson(item as num))
+        .map((item) => DiagnosticTag.fromJson(item as int))
         .toList();
     return PublishDiagnosticsClientCapabilitiesTagSupport(valueSet: valueSet);
   }
@@ -20906,7 +20907,7 @@
     final prepareSupportDefaultBehavior =
         prepareSupportDefaultBehaviorJson != null
             ? PrepareSupportDefaultBehavior.fromJson(
-                prepareSupportDefaultBehaviorJson as num)
+                prepareSupportDefaultBehaviorJson as int)
             : null;
     final honorsChangeAnnotationsJson = json['honorsChangeAnnotations'];
     final honorsChangeAnnotations = honorsChangeAnnotationsJson as bool?;
@@ -26030,7 +26031,8 @@
           return false;
         }
         if (!((value == 'off' || value == 'message' || value == 'verbose'))) {
-          reporter.reportError('must be of type String');
+          reporter.reportError(
+              'must be one of the literals \'off\', \'message\', \'verbose\'');
           return false;
         }
       } finally {
@@ -27116,7 +27118,7 @@
   static SignatureHelpContext fromJson(Map<String, Object?> json) {
     final triggerKindJson = json['triggerKind'];
     final triggerKind =
-        SignatureHelpTriggerKind.fromJson(triggerKindJson as num);
+        SignatureHelpTriggerKind.fromJson(triggerKindJson as int);
     final triggerCharacterJson = json['triggerCharacter'];
     final triggerCharacter = triggerCharacterJson as String?;
     final isRetriggerJson = json['isRetrigger'];
@@ -27683,10 +27685,10 @@
   const SignatureHelpTriggerKind(this._value);
   const SignatureHelpTriggerKind.fromJson(this._value);
 
-  final num _value;
+  final int _value;
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
-    return obj is num;
+    return obj is int;
   }
 
   /// Signature help was invoked manually by the user or by a command.
@@ -27972,7 +27974,7 @@
     final kind = SymbolKind.fromJson(kindJson as int);
     final tagsJson = json['tags'];
     final tags = (tagsJson as List<Object?>?)
-        ?.map((item) => SymbolTag.fromJson(item as num))
+        ?.map((item) => SymbolTag.fromJson(item as int))
         .toList();
     final deprecatedJson = json['deprecated'];
     final deprecated = deprecatedJson as bool?;
@@ -28209,10 +28211,10 @@
   const SymbolTag(this._value);
   const SymbolTag.fromJson(this._value);
 
-  final num _value;
+  final int _value;
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
-    return obj is num;
+    return obj is int;
   }
 
   /// Render a symbol as obsolete, usually using a strike-out.
@@ -32991,7 +32993,7 @@
       Map<String, Object?> json) {
     final valueSetJson = json['valueSet'];
     final valueSet = (valueSetJson as List<Object?>)
-        .map((item) => SymbolTag.fromJson(item as num))
+        .map((item) => SymbolTag.fromJson(item as int))
         .toList();
     return WorkspaceSymbolClientCapabilitiesTagSupport(valueSet: valueSet);
   }
diff --git a/pkg/analysis_server/lib/src/lsp/constants.dart b/pkg/analysis_server/lib/src/lsp/constants.dart
index d8cc97f..a782782 100644
--- a/pkg/analysis_server/lib/src/lsp/constants.dart
+++ b/pkg/analysis_server/lib/src/lsp/constants.dart
@@ -134,6 +134,10 @@
   /// of the expression would show through the simple-colorings "string" colors.
   static const interpolation = SemanticTokenModifiers('interpolation');
 
+  /// A modifier applied to instance field/getter/setter/method references and
+  /// declarations to distinguish them from top-levels.
+  static const instance = SemanticTokenModifiers('instance');
+
   /// A modifier applied to the void keyword to allow users to color it
   /// differently (for example as a type).
   static const void_ = SemanticTokenModifiers('void');
@@ -147,6 +151,7 @@
     annotation,
     control,
     importPrefix,
+    instance,
     label,
     constructor,
     escape,
diff --git a/pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.dart b/pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.dart
index 18b0a43..7143991 100644
--- a/pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.dart
@@ -25,16 +25,35 @@
     CustomSemanticTokenModifiers.importPrefix,
   },
   HighlightRegionType.INSTANCE_FIELD_DECLARATION: {
-    SemanticTokenModifiers.declaration
+    SemanticTokenModifiers.declaration,
+    CustomSemanticTokenModifiers.instance
+  },
+  HighlightRegionType.INSTANCE_FIELD_REFERENCE: {
+    CustomSemanticTokenModifiers.instance
   },
   HighlightRegionType.INSTANCE_GETTER_DECLARATION: {
-    SemanticTokenModifiers.declaration
+    SemanticTokenModifiers.declaration,
+    CustomSemanticTokenModifiers.instance
+  },
+  HighlightRegionType.INSTANCE_GETTER_REFERENCE: {
+    CustomSemanticTokenModifiers.instance
   },
   HighlightRegionType.INSTANCE_METHOD_DECLARATION: {
-    SemanticTokenModifiers.declaration
+    SemanticTokenModifiers.declaration,
+    CustomSemanticTokenModifiers.instance
+  },
+  HighlightRegionType.INSTANCE_METHOD_REFERENCE: {
+    CustomSemanticTokenModifiers.instance
+  },
+  HighlightRegionType.INSTANCE_METHOD_TEAR_OFF: {
+    CustomSemanticTokenModifiers.instance
   },
   HighlightRegionType.INSTANCE_SETTER_DECLARATION: {
-    SemanticTokenModifiers.declaration
+    SemanticTokenModifiers.declaration,
+    CustomSemanticTokenModifiers.instance
+  },
+  HighlightRegionType.INSTANCE_SETTER_REFERENCE: {
+    CustomSemanticTokenModifiers.instance
   },
   HighlightRegionType.LOCAL_FUNCTION_DECLARATION: {
     SemanticTokenModifiers.declaration
diff --git a/pkg/analysis_server/test/analysis/notification_navigation_test.dart b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
index d01110b..3598517 100644
--- a/pkg/analysis_server/test/analysis/notification_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
@@ -1170,6 +1170,62 @@
     assertHasTarget('A {');
   }
 
+  Future<void> test_superFormalParameter_requiredNamed() async {
+    addTestFile('''
+class A {
+  A({required int a}); // 0
+}
+class B extends A {
+  B({required super.a}); // 1
+}
+''');
+    await prepareNavigation();
+    assertHasRegionTarget('a}); // 1', 'a}); // 0');
+  }
+
+  Future<void> test_superFormalParameter_requiredPositional() async {
+    addTestFile('''
+class A {
+  A(int a); // 0
+}
+class B extends A {
+  B(super.a); // 1
+}
+''');
+    await prepareNavigation();
+    assertHasRegionTarget('super.a', 'a); // 0');
+    assertHasRegionTarget('a); // 1', 'a); // 0');
+  }
+
+  Future<void>
+      test_superFormalParameter_requiredPositional_functionTyped() async {
+    addTestFile('''
+class A {
+  A(Object a); // 0
+}
+class B extends A {
+  B(int super.a<T>(T b)); // 1
+}
+''');
+    await prepareNavigation();
+    assertHasRegionTarget('a<T>', 'a); // 0');
+    assertHasRegion('int ');
+    assertHasRegionTarget('T>', 'T>');
+    assertHasRegionTarget('T b', 'T>');
+    assertHasRegionTarget('b))', 'b))');
+  }
+
+  Future<void> test_superFormalParameter_requiredPositional_unresolved() async {
+    addTestFile('''
+class A {}
+class B extends A {
+  B(super.a); // 1
+}
+''');
+    await prepareNavigation();
+    assertNoRegionAt('a); // 1');
+  }
+
   Future<void> test_targetElement() async {
     addTestFile('''
 class AAA {}
diff --git a/pkg/analysis_server/test/lsp/semantic_tokens_test.dart b/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
index 907b8fa..3b99787 100644
--- a/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
+++ b/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
@@ -273,8 +273,10 @@
       _Token('/// field docs', SemanticTokenTypes.comment,
           [SemanticTokenModifiers.documentation]),
       _Token('String', SemanticTokenTypes.class_),
-      _Token('myField', SemanticTokenTypes.property,
-          [SemanticTokenModifiers.declaration]),
+      _Token('myField', SemanticTokenTypes.property, [
+        SemanticTokenModifiers.declaration,
+        CustomSemanticTokenModifiers.instance
+      ]),
       _Token("'FieldVal'", SemanticTokenTypes.string),
       _Token('/// static field docs', SemanticTokenTypes.comment,
           [SemanticTokenModifiers.documentation]),
@@ -292,7 +294,8 @@
           [CustomSemanticTokenModifiers.constructor]),
       _Token('print', SemanticTokenTypes.function),
       _Token('a', SemanticTokenTypes.variable),
-      _Token('myField', SemanticTokenTypes.property),
+      _Token('myField', SemanticTokenTypes.property,
+          [CustomSemanticTokenModifiers.instance]),
       _Token('MyClass', SemanticTokenTypes.class_),
       _Token('myStaticField', SemanticTokenTypes.property,
           [SemanticTokenModifiers.static]),
@@ -334,14 +337,18 @@
           [SemanticTokenModifiers.documentation]),
       _Token('String', SemanticTokenTypes.class_),
       _Token('get', SemanticTokenTypes.keyword),
-      _Token('myGetter', SemanticTokenTypes.property,
-          [SemanticTokenModifiers.declaration]),
+      _Token('myGetter', SemanticTokenTypes.property, [
+        SemanticTokenModifiers.declaration,
+        CustomSemanticTokenModifiers.instance
+      ]),
       _Token("'GetterVal'", SemanticTokenTypes.string),
       _Token('/// setter docs', SemanticTokenTypes.comment,
           [SemanticTokenModifiers.documentation]),
       _Token('set', SemanticTokenTypes.keyword),
-      _Token('mySetter', SemanticTokenTypes.property,
-          [SemanticTokenModifiers.declaration]),
+      _Token('mySetter', SemanticTokenTypes.property, [
+        SemanticTokenModifiers.declaration,
+        CustomSemanticTokenModifiers.instance
+      ]),
       _Token('String', SemanticTokenTypes.class_),
       _Token('v', SemanticTokenTypes.parameter,
           [SemanticTokenModifiers.declaration]),
@@ -371,9 +378,11 @@
           [CustomSemanticTokenModifiers.constructor]),
       _Token('print', SemanticTokenTypes.function),
       _Token('a', SemanticTokenTypes.variable),
-      _Token('myGetter', SemanticTokenTypes.property),
+      _Token('myGetter', SemanticTokenTypes.property,
+          [CustomSemanticTokenModifiers.instance]),
       _Token('a', SemanticTokenTypes.variable),
-      _Token('mySetter', SemanticTokenTypes.property),
+      _Token('mySetter', SemanticTokenTypes.property,
+          [CustomSemanticTokenModifiers.instance]),
       _Token("'a'", SemanticTokenTypes.string),
     ];
 
@@ -416,8 +425,10 @@
           [CustomSemanticTokenModifiers.annotation]),
       _Token('void', SemanticTokenTypes.keyword,
           [CustomSemanticTokenModifiers.void_]),
-      _Token('myMethod', SemanticTokenTypes.method,
-          [SemanticTokenModifiers.declaration]),
+      _Token('myMethod', SemanticTokenTypes.method, [
+        SemanticTokenModifiers.declaration,
+        CustomSemanticTokenModifiers.instance
+      ]),
       _Token('/// static method docs', SemanticTokenTypes.comment,
           [SemanticTokenModifiers.documentation]),
       _Token('static', SemanticTokenTypes.keyword),
@@ -434,7 +445,8 @@
       _Token('MyClass', SemanticTokenTypes.class_,
           [CustomSemanticTokenModifiers.constructor]),
       _Token('a', SemanticTokenTypes.variable),
-      _Token('myMethod', SemanticTokenTypes.method),
+      _Token('myMethod', SemanticTokenTypes.method,
+          [CustomSemanticTokenModifiers.instance]),
       _Token('MyClass', SemanticTokenTypes.class_),
       _Token('myStaticMethod', SemanticTokenTypes.method,
           [SemanticTokenModifiers.static]),
@@ -442,7 +454,8 @@
       _Token('b', SemanticTokenTypes.variable,
           [SemanticTokenModifiers.declaration]),
       _Token('a', SemanticTokenTypes.variable),
-      _Token('myMethod', SemanticTokenTypes.method),
+      _Token('myMethod', SemanticTokenTypes.method,
+          [CustomSemanticTokenModifiers.instance]),
       _Token('final', SemanticTokenTypes.keyword),
       _Token('c', SemanticTokenTypes.variable,
           [SemanticTokenModifiers.declaration]),
@@ -473,14 +486,17 @@
     final expected = [
       _Token('/// before [', SemanticTokenTypes.comment,
           [SemanticTokenModifiers.documentation]),
-      _Token('aaa', SemanticTokenTypes.property),
+      _Token('aaa', SemanticTokenTypes.property,
+          [CustomSemanticTokenModifiers.instance]),
       _Token('] after', SemanticTokenTypes.comment,
           [SemanticTokenModifiers.documentation]),
       _Token('class', SemanticTokenTypes.keyword),
       _Token('MyClass', SemanticTokenTypes.class_),
       _Token('String', SemanticTokenTypes.class_),
-      _Token('aaa', SemanticTokenTypes.property,
-          [SemanticTokenModifiers.declaration]),
+      _Token('aaa', SemanticTokenTypes.property, [
+        SemanticTokenModifiers.declaration,
+        CustomSemanticTokenModifiers.instance
+      ]),
       _Token('/// before [', SemanticTokenTypes.comment,
           [SemanticTokenModifiers.documentation]),
       _Token('bbb', SemanticTokenTypes.parameter),
@@ -813,8 +829,10 @@
         _Token('/// test', SemanticTokenTypes.comment,
             [SemanticTokenModifiers.documentation]),
         _Token('bool', SemanticTokenTypes.class_),
-        _Token('test$i', SemanticTokenTypes.property,
-            [SemanticTokenModifiers.declaration]),
+        _Token('test$i', SemanticTokenTypes.property, [
+          SemanticTokenModifiers.declaration,
+          CustomSemanticTokenModifiers.instance
+        ]),
         _Token('false', CustomSemanticTokenTypes.boolean),
       ],
     ];
diff --git a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
index 5383d50..ba060b9 100644
--- a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
+++ b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
@@ -131,6 +131,8 @@
 }
 
 String _getTypeCheckFailureMessage(TypeBase type) {
+  type = resolveTypeAlias(type);
+
   if (type is LiteralType) {
     return 'must be the literal ${type.literal}';
   } else if (type is LiteralUnionType) {
diff --git a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart b/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
index 28bf1c5..d897d0b 100644
--- a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
+++ b/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
@@ -42,7 +42,8 @@
   return parser.parse();
 }
 
-TypeBase typeOfLiteral(TokenType tokenType) {
+TypeBase typeOfLiteral(Token token) {
+  final tokenType = token.type;
   final typeName = tokenType == TokenType.STRING
       ? 'string'
       : tokenType == TokenType.NUMBER
@@ -178,7 +179,7 @@
 }
 
 class LiteralType extends TypeBase {
-  final Type type;
+  final TypeBase type;
   final String literal;
 
   LiteralType(this.type, this.literal);
@@ -278,7 +279,7 @@
     final value = _match([TokenType.EQUAL]) ? _advance() : null;
 
     if (type == null && value != null) {
-      type = typeOfLiteral(value.type);
+      type = typeOfLiteral(value);
     }
 
     _consume(TokenType.SEMI_COLON, 'Expected ;');
@@ -339,7 +340,7 @@
     final value = _match([TokenType.EQUAL]) ? _advance() : null;
 
     if (type == null && value != null) {
-      type = typeOfLiteral(value.type);
+      type = typeOfLiteral(value);
     }
     return Const(leadingComment, name, type!, value!);
   }
@@ -601,17 +602,13 @@
         // Some types are in (parens), so we just parse the contents as a nested type.
         type = _type(containerName, fieldName);
         _consume(TokenType.RIGHT_PAREN, 'Expected )');
-      } else if (_check(TokenType.STRING)) {
+      } else if (_check(TokenType.STRING) || _check(TokenType.NUMBER)) {
         final token = _advance();
-        // In TS and the spec, literal strings can be types:
+        // In TS and the spec, literal values can be types:
         // export const PlainText: 'plaintext' = 'plaintext';
         // trace?: 'off' | 'messages' | 'verbose';
-        type = LiteralType(Type.identifier('string'), token.lexeme);
-      } else if (_check(TokenType.NUMBER)) {
-        final token = _advance();
-        // In TS and the spec, literal numbers can be types:
         // export const Invoked: 1 = 1;
-        type = LiteralType(Type.identifier('number'), token.lexeme);
+        type = LiteralType(typeOfLiteral(token), token.lexeme);
       } else if (_match([TokenType.LEFT_BRACKET])) {
         // Tuples will just be converted to List/Array.
         final tupleElementTypes = <TypeBase>[];
diff --git a/pkg/analyzer/README.md b/pkg/analyzer/README.md
index d35c78b..6f5102e 100644
--- a/pkg/analyzer/README.md
+++ b/pkg/analyzer/README.md
@@ -3,7 +3,7 @@
 This package provides a library that performs static analysis
 of Dart code. It is useful for tool integration and embedding.
 
-End-users should use the [dartanalyzer][] command-line tool
+End-users should use the [dart analyze][] command-line tool
 to analyze their Dart code.
 
 Integrators that want to add Dart support to their editor
@@ -14,7 +14,7 @@
 
 ## Configuring the analyzer
 
-Both `dartanalyzer` and Dart Analysis Server can be configured with an
+Both `dart analyze` and Dart Analysis Server can be configured with an
 `analysis_options.yaml` file (using an `.analysis_options` file is deprecated).
 This YAML file can control which files and paths are analyzed,
 which lints are applied, and more.
@@ -24,7 +24,7 @@
 
 The analysis options file should live at the root of your project (for example,
 next to your `pubspec.yaml`). Different embedders of analyzer, such as
-`dartanalyzer` or Dart Analysis Server, may choose to find the file in various
+`dart analyze` or Dart Analysis Server, may choose to find the file in various
 different ways. Consult their documentation to learn more.
 
 Here is an example file that instructs the analyzer to ignore two files:
@@ -71,7 +71,7 @@
 Many tools embed this library, such as:
 
 * [dart format] - a formatter for Dart code
-* [dartdoc] - a documentation generator for Dart code
+* [dart doc] - a documentation generator for Dart code
 * [Dart Analysis Server][analysis_sever] - a stateful server that supports IDEs and editors
 
 ## Support
@@ -97,12 +97,12 @@
 See the [LICENSE] file.
 
 [serverapi]: https://htmlpreview.github.io/?https://github.com/dart-lang/sdk/blob/main/pkg/analysis_server/doc/api.html
-[dartanalyzer]: https://github.com/dart-lang/sdk/tree/main/pkg/analyzer_cli#dartanalyzer
+[dart analyze]: https://dart.dev/tools/dart-analyze
 [list]: https://groups.google.com/a/dartlang.org/forum/#!forum/analyzer-discuss
 [lintrules]: https://dart-lang.github.io/linter/lints/
 [glob]: https://pub.dev/packages/glob
 [LICENSE]: https://github.com/dart-lang/sdk/blob/main/pkg/analyzer/LICENSE
 [dart format]: https://github.com/dart-lang/dart_style
-[dartdoc]: https://github.com/dart-lang/dartdoc
+[dart doc]: https://github.com/dart-lang/dartdoc
 [analysis_sever]: https://github.com/dart-lang/sdk/tree/main/pkg/analysis_server
 [custom_analysis]: https://dart.dev/guides/language/analysis-options
diff --git a/pkg/analyzer/lib/file_system/file_system.dart b/pkg/analyzer/lib/file_system/file_system.dart
index d3b6913..96f5b84 100644
--- a/pkg/analyzer/lib/file_system/file_system.dart
+++ b/pkg/analyzer/lib/file_system/file_system.dart
@@ -15,8 +15,8 @@
   /// Watch for changes to this file.
   ///
   /// File watchers are initialized asynchronously so modifications made for a
-  /// short period after calling this getter may be lost. Use [watch()] to
-  /// obtain the stream in a [Future] that completes once initialization is
+  /// short period after calling this getter may be lost. Use [watch()] and
+  /// await the `ready` [Future] that completes once initialization is
   /// complete.
   @Deprecated('Use watch() instead')
   Stream<WatchEvent> get changes;
@@ -53,8 +53,10 @@
   /// an exception is thrown.
   File renameSync(String newPath);
 
-  /// Watch for changes to the files inside this folder (and in any nested
-  /// folders, including folders reachable via links).
+  /// Watch for changes to this file.
+  ///
+  /// Watchers are initialized asynchronously. Until [ResourceWatcher.ready]
+  /// completes, events are not guaranteed.
   @override
   ResourceWatcher watch();
 
@@ -87,9 +89,9 @@
   /// Watch for changes to the files inside this folder (and in any nested
   /// folders, including folders reachable via links).
   ///
-  /// File watchers are initialized asynchronously so modifications made for a
-  /// short period after calling this getter may be lost. Use [watch()] to
-  /// obtain the stream in a [Future] that completes once initialization is
+  /// Folder watchers are initialized asynchronously so modifications made for a
+  /// short period after calling this getter may be lost. Use [watch()] and
+  /// await the `ready` [Future] that completes once initialization is
   /// complete.
   @Deprecated('Use watch() instead')
   Stream<WatchEvent> get changes;
@@ -140,6 +142,9 @@
 
   /// Watch for changes to the files inside this folder (and in any nested
   /// folders, including folders reachable via links).
+  ///
+  /// Watchers are initialized asynchronously. Until [ResourceWatcher.ready]
+  /// completes, events are not guaranteed.
   @override
   ResourceWatcher watch();
 }
diff --git a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
index 5ad2871..537f6c2 100644
--- a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
@@ -482,6 +482,20 @@
   }
 
   @override
+  void visitSuperFormalParameter(SuperFormalParameter node) {
+    var element = node.declaredElement;
+    if (element is SuperFormalParameterElementImpl) {
+      var superParameter = element.superConstructorParameter;
+      computer._addRegionForToken(node.superKeyword, superParameter);
+      computer._addRegionForNode(node.identifier, superParameter);
+    }
+
+    node.type?.accept(this);
+    node.typeParameters?.accept(this);
+    node.parameters?.accept(this);
+  }
+
+  @override
   void visitVariableDeclarationList(VariableDeclarationList node) {
     /// Return the element for the type inferred for each of the variables in
     /// the given list of [variables], or `null` if not all variable have the
diff --git a/pkg/dds/analysis_options.yaml b/pkg/dds/analysis_options.yaml
index 1f83658..6b1919a 100644
--- a/pkg/dds/analysis_options.yaml
+++ b/pkg/dds/analysis_options.yaml
@@ -5,3 +5,4 @@
     - depend_on_referenced_packages
     - directives_ordering
     - prefer_generic_function_type_aliases
+    - prefer_relative_imports
diff --git a/pkg/dds/lib/src/cpu_samples_manager.dart b/pkg/dds/lib/src/cpu_samples_manager.dart
index 14b5c22..aafb15d 100644
--- a/pkg/dds/lib/src/cpu_samples_manager.dart
+++ b/pkg/dds/lib/src/cpu_samples_manager.dart
@@ -2,9 +2,9 @@
 // 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 'package:dds/src/common/ring_buffer.dart';
 import 'package:vm_service/vm_service.dart';
 
+import 'common/ring_buffer.dart';
 import 'dds_impl.dart';
 
 /// Manages CPU sample caches for an individual [Isolate].
diff --git a/pkg/dds/lib/src/dap/adapters/dart.dart b/pkg/dds/lib/src/dap/adapters/dart.dart
index 5e1cda7..83c9d9d 100644
--- a/pkg/dds/lib/src/dap/adapters/dart.dart
+++ b/pkg/dds/lib/src/dap/adapters/dart.dart
@@ -21,6 +21,7 @@
 import '../protocol_converter.dart';
 import '../protocol_generated.dart';
 import '../protocol_stream.dart';
+import '../utils.dart';
 
 /// The mime type to send with source responses to the client.
 ///
@@ -382,6 +383,20 @@
   /// VM Service disconnects.
   bool isTerminating = false;
 
+  /// Whether isolates that pause in the PauseExit state should be automatically
+  /// resumed after any in-process log events have completed.
+  ///
+  /// Normally this will be true, but it may be set to false if the user
+  /// also manually passes pause-isolates-on-exit.
+  bool resumeIsolatesAfterPauseExit = true;
+
+  /// A [Future] that completes when the last queued OutputEvent has been sent.
+  ///
+  /// Calls to [SendOutput] will reserve their place in this queue and
+  /// subsequent calls will chain their own sends onto this (and replace it) to
+  /// preserve order.
+  Future? _lastOutputEvent;
+
   /// Removes any breakpoints or pause behaviour and resumes any paused
   /// isolates.
   ///
@@ -903,7 +918,11 @@
   }
 
   /// Sends a [TerminatedEvent] if one has not already been sent.
-  void handleSessionTerminate([String exitSuffix = '']) {
+  ///
+  /// Waits for any in-progress output events to complete first.
+  void handleSessionTerminate([String exitSuffix = '']) async {
+    await _waitForPendingOutputEvents();
+
     if (_hasSentTerminatedEvent) {
       return;
     }
@@ -911,8 +930,9 @@
     isTerminating = true;
     _hasSentTerminatedEvent = true;
     // Always add a leading newline since the last written text might not have
-    // had one.
-    sendOutput('console', '\nExited$exitSuffix.');
+    // had one. Send directly via sendEvent and not sendOutput to ensure no
+    // async since we're about to terminate.
+    sendEvent(OutputEventBody(output: '\nExited$exitSuffix.'));
     sendEvent(TerminatedEventBody());
   }
 
@@ -1100,9 +1120,32 @@
   }
 
   /// Sends an OutputEvent (without a newline, since calls to this method
-  /// may be used by buffered data).
-  void sendOutput(String category, String message) {
-    sendEvent(OutputEventBody(category: category, output: message));
+  /// may be using buffered data that is not split cleanly on newlines).
+  ///
+  /// If [category] is `stderr`, will also look for stack traces and extract
+  /// file/line information to add to the metadata of the event.
+  ///
+  /// To ensure output is sent to the client in the correct order even if
+  /// processing stack frames requires async calls, this function will insert
+  /// output events into a queue and only send them when previous calls have
+  /// been completed.
+  void sendOutput(String category, String message) async {
+    // Reserve our place in the queue be inserting a future that we can complete
+    // after we have sent the output event.
+    final completer = Completer<void>();
+    final _previousEvent = _lastOutputEvent ?? Future.value();
+    _lastOutputEvent = completer.future;
+
+    try {
+      final outputEvents = await _buildOutputEvents(category, message);
+
+      // Chain our sends onto the end of the previous one, and complete our Future
+      // once done so that the next one can go.
+      await _previousEvent;
+      outputEvents.forEach(sendEvent);
+    } finally {
+      completer.complete();
+    }
   }
 
   /// Sends an OutputEvent for [message], prefixed with [prefix] and with [message]
@@ -1577,6 +1620,108 @@
     return uri.replace(path: newPath);
   }
 
+  /// Creates one or more OutputEvents for the provided [message].
+  ///
+  /// Messages that contain stack traces may be split up into seperate events
+  /// for each frame to allow location metadata to be attached.
+  Future<List<OutputEventBody>> _buildOutputEvents(
+    String category,
+    String message,
+  ) async {
+    try {
+      if (category == 'stderr') {
+        return await _buildStdErrOutputEvents(message);
+      } else {
+        return [OutputEventBody(category: category, output: message)];
+      }
+    } catch (e, s) {
+      // Since callers of [sendOutput] may not await it, don't allow unhandled
+      // errors (for example if the VM Service quits while we were trying to
+      // map URIs), just log and return the event without metadata.
+      logger?.call('Failed to build OutputEvent: $e, $s');
+      return [OutputEventBody(category: category, output: message)];
+    }
+  }
+
+  /// Builds OutputEvents for stderr.
+  ///
+  /// If a stack trace can be parsed from [message], file/line information will
+  /// be included in the metadata of the event.
+  Future<List<OutputEventBody>> _buildStdErrOutputEvents(String message) async {
+    final events = <OutputEventBody>[];
+
+    // Extract all the URIs so we can send a batch request for resolving them.
+    final lines = message.split('\n');
+    final frames = lines.map(parseStackFrame).toList();
+    final uris = frames.whereNotNull().map((f) => f.uri).toList();
+
+    // We need an Isolate to resolve package URIs. Since we don't know what
+    // isolate printed an error to stderr, we just have to use the first one and
+    // hope the packages are available. If one is not available (which should
+    // never be the case), we will just skip resolution.
+    final thread = _isolateManager.threads.firstOrNull;
+
+    // Send a batch request. This will cache the results so we can easily use
+    // them in the loop below by calling the method again.
+    if (uris.isNotEmpty) {
+      try {
+        await thread?.resolveUrisToPathsBatch(uris);
+      } catch (e, s) {
+        // Ignore errors that may occur if the VM is shutting down before we got
+        // this request out. In most cases we will have pre-cached the results
+        // when the libraries were loaded (in order to check if they're user code)
+        // so it's likely this won't cause any issues (dart:isolate-patch is an
+        // exception seen that appears in the stack traces but was not previously
+        // seen/cached).
+        logger?.call('Failed to resolve URIs: $e\n$s');
+      }
+    }
+
+    // Convert any URIs to paths.
+    final paths = await Future.wait(frames.map((frame) async {
+      final uri = frame?.uri;
+      if (uri == null) return null;
+      if (uri.isScheme('file')) return uri.toFilePath();
+      if (isResolvableUri(uri)) {
+        try {
+          return await thread?.resolveUriToPath(uri);
+        } catch (e, s) {
+          // Swallow errors for the same reason noted above.
+          logger?.call('Failed to resolve URIs: $e\n$s');
+        }
+      }
+      return null;
+    }));
+
+    for (var i = 0; i < lines.length; i++) {
+      final line = lines[i];
+      final frame = frames[i];
+      final uri = frame?.uri;
+      final path = paths[i];
+      // For the name, we usually use the package URI, but if we only ended up
+      // with a file URI, try to make it relative to cwd so it's not so long.
+      final name = uri != null && path != null
+          ? (uri.isScheme('file')
+              ? _converter.convertToRelativePath(path)
+              : uri.toString())
+          : null;
+      // Because we split on newlines, all items exept the last one need to
+      // have their trailing newlines added back.
+      final output = i == lines.length - 1 ? line : '$line\n';
+      events.add(
+        OutputEventBody(
+          category: 'stderr',
+          output: output,
+          source: path != null ? Source(name: name, path: path) : null,
+          line: frame?.line,
+          column: frame?.column,
+        ),
+      );
+    }
+
+    return events;
+  }
+
   /// Handles evaluation of an expression that is (or begins with)
   /// `threadExceptionExpression` which corresponds to the exception at the top
   /// of [thread].
@@ -1618,6 +1763,18 @@
     await debuggerInitialized;
 
     await _isolateManager.handleEvent(event);
+
+    final eventKind = event.kind;
+    final isolate = event.isolate;
+    // We pause isolates on exit to allow requests for resolving URIs in
+    // stderr call stacks, so when we see an isolate pause, wait for any
+    // pending logs and then resume it (so it exits).
+    if (resumeIsolatesAfterPauseExit &&
+        eventKind == vm.EventKind.kPauseExit &&
+        isolate != null) {
+      await _waitForPendingOutputEvents();
+      await _isolateManager.resumeIsolate(isolate);
+    }
   }
 
   @protected
@@ -1857,6 +2014,20 @@
     return (data) => _withErrorHandling(() => handler(data));
   }
 
+  /// Waits for any pending async output events that might be in progress.
+  ///
+  /// If another output event is queued while waiting, the new event will be
+  /// waited for, until there are no more.
+  Future<void> _waitForPendingOutputEvents() async {
+    // Keep awaiting it as long as it's changing to allow for other
+    // events being queued up while it runs.
+    var lastEvent = _lastOutputEvent;
+    do {
+      lastEvent = _lastOutputEvent;
+      await lastEvent;
+    } while (lastEvent != _lastOutputEvent);
+  }
+
   /// Calls a function with an error handler that handles errors that occur when
   /// the VM Service/DDS shuts down.
   ///
diff --git a/pkg/dds/lib/src/dap/adapters/dart_cli_adapter.dart b/pkg/dds/lib/src/dap/adapters/dart_cli_adapter.dart
index 928f94a..06def69 100644
--- a/pkg/dds/lib/src/dap/adapters/dart_cli_adapter.dart
+++ b/pkg/dds/lib/src/dap/adapters/dart_cli_adapter.dart
@@ -73,6 +73,14 @@
     terminatePids(ProcessSignal.sigkill);
   }
 
+  /// Checks whether [flag] is in [args], allowing for both underscore and
+  /// dash format.
+  bool _containsVmFlag(List<String> args, String flag) {
+    final flagUnderscores = flag.replaceAll('-', '_');
+    final flagDashes = flag.replaceAll('_', '-');
+    return args.contains(flagUnderscores) || args.contains(flagDashes);
+  }
+
   /// Called by [launchRequest] to request that we actually start the app to be
   /// run/debugged.
   ///
@@ -103,6 +111,17 @@
       ],
     ];
 
+    final toolArgs = args.toolArgs ?? [];
+    if (debug) {
+      // If the user has explicitly set pause-isolates-on-exit we need to
+      // not add it ourselves, and disable auto-resuming.
+      if (_containsVmFlag(toolArgs, '--pause_isolates_on_exit')) {
+        resumeIsolatesAfterPauseExit = false;
+      } else {
+        vmArgs.add('--pause_isolates_on_exit');
+      }
+    }
+
     // Handle customTool and deletion of any arguments for it.
     final executable = args.customTool ?? Platform.resolvedExecutable;
     final removeArgs = args.customToolReplacesArgs;
@@ -112,7 +131,7 @@
 
     final processArgs = [
       ...vmArgs,
-      ...?args.toolArgs,
+      ...toolArgs,
       args.program,
       ...?args.args,
     ];
diff --git a/pkg/dds/lib/src/dap/isolate_manager.dart b/pkg/dds/lib/src/dap/isolate_manager.dart
index b3fac35..ee48794 100644
--- a/pkg/dds/lib/src/dap/isolate_manager.dart
+++ b/pkg/dds/lib/src/dap/isolate_manager.dart
@@ -13,6 +13,7 @@
 import 'adapters/dart.dart';
 import 'exceptions.dart';
 import 'protocol_generated.dart';
+import 'utils.dart';
 
 /// Manages state of Isolates (called Threads by the DAP protocol).
 ///
@@ -215,8 +216,7 @@
     ));
   }
 
-  Future<void> resumeIsolate(vm.IsolateRef isolateRef,
-      [String? resumeType]) async {
+  Future<void> resumeIsolate(vm.IsolateRef isolateRef) async {
     final isolateId = isolateRef.id!;
 
     final thread = _threadsByIsolateId[isolateId];
@@ -823,7 +823,7 @@
   Future<List<String?>> resolveUrisToPathsBatch(List<Uri> uris) async {
     // First find the set of URIs we don't already have results for.
     final requiredUris = uris
-        .where((uri) => !uri.isScheme('file'))
+        .where(isResolvableUri)
         .where((uri) => !_resolvedPaths.containsKey(uri.toString()))
         .toSet() // Take only distinct values.
         .toList();
@@ -837,17 +837,24 @@
       completers.forEach(
         (uri, completer) => _resolvedPaths[uri] = completer.future,
       );
-      final results =
-          await _manager._lookupResolvedPackageUris(isolate, requiredUris);
-      if (results == null) {
-        // If no result, all of the results are null.
-        completers.forEach((uri, completer) => completer.complete(null));
-      } else {
-        // Otherwise, complete each one by index with the corresponding value.
-        results.map(_convertUriToFilePath).forEachIndexed((i, result) {
-          final uri = requiredUris[i].toString();
-          completers[uri]!.complete(result);
-        });
+      try {
+        final results =
+            await _manager._lookupResolvedPackageUris(isolate, requiredUris);
+        if (results == null) {
+          // If no result, all of the results are null.
+          completers.forEach((uri, completer) => completer.complete(null));
+        } else {
+          // Otherwise, complete each one by index with the corresponding value.
+          results.map(_convertUriToFilePath).forEachIndexed((i, result) {
+            final uri = requiredUris[i].toString();
+            completers[uri]!.complete(result);
+          });
+        }
+      } catch (e) {
+        // We can't leave dangling completers here because others may already
+        // be waiting on them, so propogate the error to them.
+        completers.forEach((uri, completer) => completer.completeError(e));
+        rethrow;
       }
     }
 
diff --git a/pkg/dds/lib/src/dap/utils.dart b/pkg/dds/lib/src/dap/utils.dart
new file mode 100644
index 0000000..fa47866
--- /dev/null
+++ b/pkg/dds/lib/src/dap/utils.dart
@@ -0,0 +1,42 @@
+// 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 'package:stack_trace/stack_trace.dart' as stack;
+
+/// Returns whether this URI has a scheme that can be resolved to a file path
+/// via the VM Service.
+bool isResolvableUri(Uri uri) {
+  return !uri.isScheme('file') &&
+      // Parsed stack frames may have URIs with no scheme and the text
+      // "unparsed" if they looked like stack frames but had no file
+      // information.
+      !uri.isScheme('');
+}
+
+/// Attempts to parse a line as a stack frame in order to read path/line/col
+/// information.
+///
+/// It should not be assumed that if a [stack.Frame] is returned that the input
+/// was necessarily a stack frame or that calling `toString` will return the
+/// original input text.
+stack.Frame? parseStackFrame(String line) {
+  /// Helper to try parsing a frame with [parser], returning `null` if it
+  /// fails to parse.
+  stack.Frame? tryParseFrame(stack.Frame Function(String) parser) {
+    final frame = parser(line);
+    return frame is stack.UnparsedFrame ? null : frame;
+  }
+
+  // Try different formats of stack frames.
+  // pkg:stack_trace does not have a generic Frame.parse() and Trace.parse()
+  // doesn't work well when the content includes non-stack-frame lines
+  // (https://github.com/dart-lang/stack_trace/issues/115).
+  return tryParseFrame((line) => stack.Frame.parseVM(line)) ??
+      // TODO(dantup): Tidy up when constructor tear-offs are available.
+      tryParseFrame((line) => stack.Frame.parseV8(line)) ??
+      tryParseFrame((line) => stack.Frame.parseSafari(line)) ??
+      tryParseFrame((line) => stack.Frame.parseFirefox(line)) ??
+      tryParseFrame((line) => stack.Frame.parseIE(line)) ??
+      tryParseFrame((line) => stack.Frame.parseFriendly(line));
+}
diff --git a/pkg/dds/lib/src/devtools/devtools_handler.dart b/pkg/dds/lib/src/devtools/devtools_handler.dart
index 3b55bfb..ad7067d 100644
--- a/pkg/dds/lib/src/devtools/devtools_handler.dart
+++ b/pkg/dds/lib/src/devtools/devtools_handler.dart
@@ -4,12 +4,12 @@
 
 import 'dart:async';
 
-import 'package:dds/src/constants.dart';
 import 'package:devtools_shared/devtools_server.dart';
 import 'package:shelf/shelf.dart';
 import 'package:shelf_static/shelf_static.dart';
 import 'package:sse/server/sse_handler.dart';
 
+import '../constants.dart';
 import '../dds_impl.dart';
 import 'devtools_client.dart';
 
diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml
index 92adad1..51e3d8d 100644
--- a/pkg/dds/pubspec.yaml
+++ b/pkg/dds/pubspec.yaml
@@ -23,6 +23,7 @@
   shelf_proxy: ^1.0.0
   shelf_static: ^1.0.0
   shelf_web_socket: ^1.0.0
+  stack_trace: ^1.10.0
   sse: ^4.0.0
   stream_channel: ^2.0.0
   vm_service: ^8.1.0
diff --git a/pkg/dds/test/dap/integration/debug_exceptions_test.dart b/pkg/dds/test/dap/integration/debug_exceptions_test.dart
index 752ce5f..157f136 100644
--- a/pkg/dds/test/dap/integration/debug_exceptions_test.dart
+++ b/pkg/dds/test/dap/integration/debug_exceptions_test.dart
@@ -70,6 +70,25 @@
         exceptionPauseMode: 'All',
       );
     });
+
+    test('parses line/column information from stack traces', () async {
+      final client = dap.client;
+      final testFile = dap.createTestFile(simpleThrowingProgram);
+      final exceptionLine = lineWith(testFile, 'throw');
+      final outputEvents = await client.collectOutput(file: testFile);
+
+      // Find the output event for the top of the printed stack trace.
+      // It should look something like:
+      // #0      main (file:///var/folders/[...]/app3JZLvu/test_file.dart:2:5)
+      final mainStackFrameEvent = outputEvents
+          .firstWhere((event) => event.output.startsWith('#0      main'));
+
+      // Expect that there is metadata attached that matches the file/location we
+      // expect.
+      expect(mainStackFrameEvent.source?.path, testFile.path);
+      expect(mainStackFrameEvent.line, exceptionLine);
+      expect(mainStackFrameEvent.column, 5);
+    });
     // These tests can be slow due to starting up the external server process.
   }, timeout: Timeout.none);
 }
diff --git a/pkg/dds/test/dap/integration/debug_test.dart b/pkg/dds/test/dap/integration/debug_test.dart
index 6655b58..974692f 100644
--- a/pkg/dds/test/dap/integration/debug_test.dart
+++ b/pkg/dds/test/dap/integration/debug_test.dart
@@ -94,6 +94,76 @@
       expect(proc!.exitCode, completes);
     });
 
+    test('does not resume isolates if user passes --pause-isolates-on-exit',
+        () async {
+      // Internally we always pass --pause-isolates-on-exit and resume the
+      // isolates after waiting for any output events to complete (in case they
+      // need to resolve URIs that involve API calls on an Isolate).
+      //
+      // However if a user passes this flag explicitly, we should not
+      // auto-resume because they might be trying to debug something.
+      final testFile = dap.createTestFile(simpleArgPrintingProgram);
+
+      // Run the script, expecting a Stopped event.
+      final stop = dap.client.expectStop('pause');
+      await Future.wait([
+        stop,
+        dap.client.initialize(),
+        dap.client
+            .launch(testFile.path, toolArgs: ["--pause-isolates-on-exit"]),
+      ], eagerError: true);
+
+      // Resume and expect termination.
+      await await Future.wait([
+        dap.client.event('terminated'),
+        dap.client.continue_((await stop).threadId!),
+      ], eagerError: true);
+    });
+
+    test('sends output events in the correct order', () async {
+      // Output events that have their URIs mapped will be processed slowly due
+      // the async requests for resolving the package URI. This should not cause
+      // them to appear out-of-order with other lines that do not require this
+      // work.
+      //
+      // Use a sample program that prints output to stderr that includes:
+      // - non stack frame lines
+      // - stack frames with file:// URIs
+      // - stack frames with package URIs (that need asynchronously resolving)
+      final fileUri = Uri.file(dap.createTestFile('').path);
+      final packageUri = await dap.createFooPackage();
+      final testFile =
+          dap.createTestFile(stderrPrintingProgram(fileUri, packageUri));
+
+      var outputEvents = await dap.client.collectOutput(
+        launch: () => dap.client.launch(testFile.path),
+      );
+      outputEvents = outputEvents.where((e) => e.category == 'stderr').toList();
+
+      // Verify the order of the stderr output events.
+      final output = outputEvents
+          .map((e) => '${e.output.trim()}')
+          .where((output) => output.isNotEmpty)
+          .join('\n');
+      expectLines(output, [
+        'Start',
+        '#0      main ($fileUri:1:2)',
+        '#1      main2 ($packageUri:1:2)',
+        'End',
+      ]);
+
+      // As a sanity check, verify we did actually do the async path mapping and
+      // got both frames with paths in our test folder.
+      final stackFramesWithPaths = outputEvents.where((e) =>
+          e.source?.path != null &&
+          path.isWithin(dap.testDir.path, e.source!.path!));
+      expect(
+        stackFramesWithPaths,
+        hasLength(2),
+        reason: 'Expected two frames within path ${dap.testDir.path}',
+      );
+    });
+
     test('provides a list of threads', () async {
       final client = dap.client;
       final testFile = dap.createTestFile(simpleBreakpointProgram);
diff --git a/pkg/dds/test/dap/integration/test_client.dart b/pkg/dds/test/dap/integration/test_client.dart
index ec3c7c0..8ce631d 100644
--- a/pkg/dds/test/dap/integration/test_client.dart
+++ b/pkg/dds/test/dap/integration/test_client.dart
@@ -224,6 +224,7 @@
   Future<Response> launch(
     String program, {
     List<String>? args,
+    List<String>? toolArgs,
     String? cwd,
     bool? noDebug,
     List<String>? additionalProjectPaths,
@@ -240,6 +241,7 @@
         program: program,
         cwd: cwd,
         args: args,
+        toolArgs: toolArgs,
         additionalProjectPaths: additionalProjectPaths,
         console: console,
         debugSdkLibraries: debugSdkLibraries,
diff --git a/pkg/dds/test/dap/integration/test_scripts.dart b/pkg/dds/test/dap/integration/test_scripts.dart
index 429018b..84eea06 100644
--- a/pkg/dds/test/dap/integration/test_scripts.dart
+++ b/pkg/dds/test/dap/integration/test_scripts.dart
@@ -55,6 +55,24 @@
   }
 ''';
 
+/// A simple Dart script that prints to stderr without throwing/terminating.
+///
+/// The output will contain stack traces include both the supplied file and
+/// package URIs.
+String stderrPrintingProgram(Uri fileUri, Uri packageUri) {
+  return '''
+  import 'dart:io';
+  import '$packageUri';
+
+  void main(List<String> args) async {
+    stderr.writeln('Start');
+    stderr.writeln('#0      main ($fileUri:1:2)');
+    stderr.writeln('#1      main2 ($packageUri:1:2)');
+    stderr.write('End');
+  }
+''';
+}
+
 /// Returns a simple Dart script that prints the provided string repeatedly.
 String stringPrintingProgram(String text) {
   // jsonEncode the string to get it into a quoted/escaped form that can be
diff --git a/pkg/dds/test/dap/integration/test_support.dart b/pkg/dds/test/dap/integration/test_support.dart
index d4c2a8b..ebabce8 100644
--- a/pkg/dds/test/dap/integration/test_support.dart
+++ b/pkg/dds/test/dap/integration/test_support.dart
@@ -133,15 +133,15 @@
 class DapTestSession {
   DapTestServer server;
   DapTestClient client;
-  final Directory _testDir =
+  final Directory testDir =
       Directory.systemTemp.createTempSync('dart-sdk-dap-test');
   late final Directory testAppDir;
   late final Directory testPackagesDir;
 
   DapTestSession._(this.server, this.client) {
-    testAppDir = _testDir.createTempSync('app');
+    testAppDir = testDir.createTempSync('app');
     createPubspec(testAppDir, 'my_test_project');
-    testPackagesDir = _testDir.createTempSync('packages');
+    testPackagesDir = testDir.createTempSync('packages');
   }
 
   /// Adds package with [name] (optionally at [packageFolderUri]) to the
@@ -236,7 +236,7 @@
     await server.stop();
 
     // Clean up any temp folders created during the test runs.
-    _testDir.deleteSync(recursive: true);
+    testDir.deleteSync(recursive: true);
   }
 
   static Future<DapTestSession> setUp({List<String>? additionalArgs}) async {
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index 8cf19ba..6185d8f 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -1086,13 +1086,7 @@
   String computeCompilerPath() {
     var prefix = 'sdk/bin';
     if (_isHostChecked) {
-      if (_useSdk) {
-        throw "--host-checked and --use-sdk cannot be used together";
-      }
-      // The script dartanalyzer_developer is not included in the
-      // shipped SDK, that is the script is not installed in
-      // "$buildDir/dart-sdk/bin/"
-      return '$prefix/dartanalyzer_developer$shellScriptExtension';
+      throw "--host-checked cannot be used for dartanalyzer";
     }
     if (_useSdk) {
       prefix = '${_configuration.buildDirectory}/dart-sdk/bin';
diff --git a/runtime/lib/core_sources.gni b/runtime/lib/core_sources.gni
index 7e18428..c5b40f1 100644
--- a/runtime/lib/core_sources.gni
+++ b/runtime/lib/core_sources.gni
@@ -22,5 +22,4 @@
   "stopwatch.cc",
   "string.cc",
   "uri.cc",
-  "weak_property.cc",
 ]
diff --git a/runtime/lib/weak_property.cc b/runtime/lib/weak_property.cc
deleted file mode 100644
index 16eb41c..0000000
--- a/runtime/lib/weak_property.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012, 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.
-
-#include "vm/bootstrap_natives.h"
-
-#include "vm/exceptions.h"
-#include "vm/native_entry.h"
-#include "vm/object.h"
-
-namespace dart {
-
-DEFINE_NATIVE_ENTRY(WeakProperty_getKey, 0, 1) {
-  GET_NON_NULL_NATIVE_ARGUMENT(WeakProperty, weak_property,
-                               arguments->NativeArgAt(0));
-  return weak_property.key();
-}
-
-DEFINE_NATIVE_ENTRY(WeakProperty_setKey, 0, 2) {
-  GET_NON_NULL_NATIVE_ARGUMENT(WeakProperty, weak_property,
-                               arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, key, arguments->NativeArgAt(1));
-  weak_property.set_key(key);
-  return Object::null();
-}
-
-DEFINE_NATIVE_ENTRY(WeakProperty_getValue, 0, 1) {
-  GET_NON_NULL_NATIVE_ARGUMENT(WeakProperty, weak_property,
-                               arguments->NativeArgAt(0));
-  return weak_property.value();
-}
-
-DEFINE_NATIVE_ENTRY(WeakProperty_setValue, 0, 2) {
-  GET_NON_NULL_NATIVE_ARGUMENT(WeakProperty, weak_property,
-                               arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(1));
-  weak_property.set_value(value);
-  return Object::null();
-}
-
-}  // namespace dart
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index a0e0c19..bf6ce73 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -182,7 +182,7 @@
     if (!testeeControlsServer) {
       fullArgs.add('--enable-vm-service:$port');
     }
-    if (serviceResponseSizesDir != null) {
+    if (serviceResponseSizesDir.isNotEmpty) {
       // Dump service response size details to a CSV. This feature is not used
       // on the build bots and the generated output will persist after the test
       // has completed.
diff --git a/runtime/observatory_2/tests/service_2/test_helper.dart b/runtime/observatory_2/tests/service_2/test_helper.dart
index 6c782b8..b2667bf 100644
--- a/runtime/observatory_2/tests/service_2/test_helper.dart
+++ b/runtime/observatory_2/tests/service_2/test_helper.dart
@@ -182,7 +182,7 @@
     if (!testeeControlsServer) {
       fullArgs.add('--enable-vm-service:$port');
     }
-    if (serviceResponseSizesDir != null) {
+    if (serviceResponseSizesDir.isNotEmpty) {
       // Dump service response size details to a CSV. This feature is not used
       // on the build bots and the generated output will persist after the test
       // has completed.
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 69ed79e..4c86f33 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -345,10 +345,6 @@
   V(Internal_deoptimizeFunctionsOnStack, 0)                                    \
   V(InvocationMirror_unpackTypeArguments, 2)                                   \
   V(NoSuchMethodError_existingMethodSignature, 3)                              \
-  V(WeakProperty_getKey, 1)                                                    \
-  V(WeakProperty_setKey, 2)                                                    \
-  V(WeakProperty_getValue, 1)                                                  \
-  V(WeakProperty_setValue, 2)                                                  \
   V(Uri_isWindowsPlatform, 0)                                                  \
   V(UserTag_new, 2)                                                            \
   V(UserTag_label, 1)                                                          \
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index 20c4ba0..d2824a2 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -1643,16 +1643,10 @@
     Value* left = op->left()->CopyWithType();
     Value* right = op->right()->CopyWithType();
     intptr_t deopt_id = op->DeoptimizationTarget();
-    if (def->IsBinaryInt64Op()) {
-      return new (Z) BinaryUint32OpInstr(op_kind, left, right, deopt_id);
-    } else if (def->IsShiftInt64Op()) {
-      return new (Z) ShiftUint32OpInstr(op_kind, left, right, deopt_id);
-    } else if (def->IsSpeculativeShiftInt64Op()) {
-      return new (Z)
-          SpeculativeShiftUint32OpInstr(op_kind, left, right, deopt_id);
-    } else {
-      UNREACHABLE();
-    }
+    return BinaryIntegerOpInstr::Make(
+        kUnboxedUint32, op_kind, left, right, deopt_id,
+        def->IsSpeculativeShiftInt64Op() ? Instruction::kGuardInputs
+                                         : Instruction::kNotSpeculative);
   } else if (def->IsBoxInt64()) {
     Value* value = def->AsBoxInt64()->value()->CopyWithType();
     return new (Z) BoxUint32Instr(value);
diff --git a/runtime/vm/compiler/backend/range_analysis_test.cc b/runtime/vm/compiler/backend/range_analysis_test.cc
index 2d42347..ce2d3d5 100644
--- a/runtime/vm/compiler/backend/range_analysis_test.cc
+++ b/runtime/vm/compiler/backend/range_analysis_test.cc
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/compiler/backend/range_analysis.h"
+#include "vm/compiler/backend/il_test_helper.h"
 #include "vm/unit_test.h"
 
 namespace dart {
@@ -640,4 +641,53 @@
           .IsMaximumOrAbove(size));
 }
 
+#if defined(DART_PRECOMPILER) && defined(TARGET_ARCH_IS_64_BIT)
+
+// Regression test for https://github.com/dart-lang/sdk/issues/48153.
+ISOLATE_UNIT_TEST_CASE(RangeAnalysis_ShiftUint32Op) {
+  const char* kScript = R"(
+    @pragma('vm:never-inline')
+    int foo(int hash) {
+      return 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
+    }
+    void main() {
+      foo(42);
+    }
+  )";
+
+  const auto& root_library = Library::Handle(LoadTestScript(kScript));
+
+  Invoke(root_library, "main");
+
+  const auto& function = Function::Handle(GetFunction(root_library, "foo"));
+  TestPipeline pipeline(function, CompilerPass::kAOT);
+  FlowGraph* flow_graph = pipeline.RunPasses({});
+
+  auto entry = flow_graph->graph_entry()->normal_entry();
+  EXPECT(entry != nullptr);
+  ILMatcher cursor(flow_graph, entry, /*trace=*/true,
+                   ParallelMovesHandling::kSkip);
+
+  ShiftUint32OpInstr* shift = nullptr;
+
+  RELEASE_ASSERT(cursor.TryMatch({
+      kMoveGlob,
+      kMatchAndMoveBinaryUint32Op,
+      kMoveGlob,
+      {kMatchAndMoveShiftUint32Op, &shift},
+      kMoveGlob,
+      kMatchAndMoveBinaryUint32Op,
+      kMoveGlob,
+      kMatchAndMoveBinaryUint32Op,
+      kMoveGlob,
+      kMatchReturn,
+  }));
+
+  EXPECT(shift->shift_range() != nullptr);
+  EXPECT(shift->shift_range()->min().ConstantValue() == 10);
+  EXPECT(shift->shift_range()->max().ConstantValue() == 10);
+}
+
+#endif  // defined(DART_PRECOMPILER) && defined(TARGET_ARCH_IS_64_BIT)
+
 }  // namespace dart
diff --git a/sdk/bin/dartanalyzer_developer b/sdk/bin/dartanalyzer_developer
deleted file mode 100755
index 373dc67..0000000
--- a/sdk/bin/dartanalyzer_developer
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env bash
-# Copyright (c) 2014, 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.
-
-. ${BASH_SOURCE%_developer}
diff --git a/sdk/bin/dartanalyzer_developer.bat b/sdk/bin/dartanalyzer_developer.bat
deleted file mode 100644
index b560fe8..0000000
--- a/sdk/bin/dartanalyzer_developer.bat
+++ /dev/null
@@ -1,10 +0,0 @@
-@echo off
-REM Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-REM for details. All rights reserved. Use of this source code is governed by a
-REM BSD-style license that can be found in the LICENSE file.
-
-setlocal
-set DARTANALYZER_DEVELOPER_MODE=1
-call "%~dp0dartanalyzer.bat" %*
-endlocal
-exit /b %errorlevel%
diff --git a/tests/language/enum/enhanced_enums_basic_test.dart b/tests/language/enum/enhanced_enums_basic_test.dart
index ee3a0e0..655a1f0 100644
--- a/tests/language/enum/enhanced_enums_basic_test.dart
+++ b/tests/language/enum/enhanced_enums_basic_test.dart
@@ -269,7 +269,7 @@
 
 extension EnumAllExtension on EnumAll {
   String get notExtension => Expect.fail("Unreachable");
-  String get extension => "extension":
+  String get extension => "extension";
 }
 
 typedef TypeDefAll = EnumAll<num, num>;
diff --git a/tools/VERSION b/tools/VERSION
index b7b6318..bb3a9c1 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 28
+PRERELEASE 29
 PRERELEASE_PATCH 0
\ No newline at end of file