Version 2.17.0-119.0.dev

Merge commit 'c4dc032f6cce966baa07cc44b10a6821c14c4622' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index b671ff4..a5e1bb0 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": "2022-02-16T14:11:48.394602",
+  "generated": "2022-02-17T08:48:00.006717",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
@@ -277,24 +277,12 @@
       "languageVersion": "2.15"
     },
     {
-      "name": "devtools_server",
-      "rootUri": "../third_party/devtools/devtools_server",
-      "packageUri": "lib/",
-      "languageVersion": "2.12"
-    },
-    {
       "name": "devtools_shared",
       "rootUri": "../third_party/devtools/devtools_shared",
       "packageUri": "lib/",
       "languageVersion": "2.12"
     },
     {
-      "name": "diagnostic",
-      "rootUri": "../pkg/diagnostic",
-      "packageUri": "lib/",
-      "languageVersion": "2.0"
-    },
-    {
       "name": "expect",
       "rootUri": "../pkg/expect",
       "packageUri": "lib/",
diff --git a/.packages b/.packages
index 38ab4a9..822b3c3 100644
--- a/.packages
+++ b/.packages
@@ -41,9 +41,7 @@
 dds:pkg/dds/lib
 dds_service_extensions:pkg/dds_service_extensions/lib
 dev_compiler:pkg/dev_compiler/lib
-devtools_server:third_party/devtools/devtools_server/lib
 devtools_shared:third_party/devtools/devtools_shared/lib
-diagnostic:pkg/diagnostic/lib
 expect:pkg/expect/lib
 ffi:third_party/pkg/ffi/lib
 fixnum:third_party/pkg/fixnum/lib
diff --git a/DEPS b/DEPS
index 1395058..3e26472 100644
--- a/DEPS
+++ b/DEPS
@@ -110,7 +110,7 @@
   "dart_style_rev": "6f894c0ca33686122be9085f06e5b9bf6ad55262",
 
   "dartdoc_rev" : "b3927dd89d6ff9c78dc88ab2901e63b6a3bf29b7",
-  "devtools_rev" : "3b054edf3a14a4a51bc8019f456efcf0073cd626",
+  "devtools_rev" : "2970d4eab8b8e023ac0779090ed17ae391418b9b",
   "ffi_rev": "4dd32429880a57b64edaf54c9d5af8a9fa9a4ffb",
   "fixnum_rev": "848341f061359ef7ddc0cad472c2ecbb036b28ac",
   "file_rev": "1ebc38852ffed24b564910317982298b56c2cedd",
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
index 79f8ef3..621744c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
@@ -541,16 +541,15 @@
     return false;
   }
 
-  /// Return `true` if the [node] might be a type name.
-  bool mightBeTypeIdentifier(AstNode node) {
+  /// If the [node] might be a type name, return its name.
+  String? nameOfType(AstNode node) {
     if (node is SimpleIdentifier) {
-      var parent = node.parent;
-      if (parent is NamedType) {
-        return true;
+      var name = node.name;
+      if (node.parent is NamedType || _isNameOfType(name)) {
+        return name;
       }
-      return _isNameOfType(node.name);
     }
-    return false;
+    return null;
   }
 
   /// Replace all occurrences of the [oldIndent] with the [newIndent] within the
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart
index 2ec24e4..f474802 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart
@@ -74,9 +74,9 @@
       node = node.identifier;
     }
     // Process if looks like a type.
-    if (mightBeTypeIdentifier(node)) {
+    var name = nameOfType(node);
+    if (name != null) {
       // Prepare for selecting the closest element.
-      var name = (node as SimpleIdentifier).name;
       var finder = _ClosestElementFinder(
           name, (Element element) => element is ClassElement);
       // Check elements of this library.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_class.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_class.dart
index 9c01f35..9998f30 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_class.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_class.dart
@@ -48,10 +48,13 @@
     } else {
       return;
     }
-    if (!mightBeTypeIdentifier(nameNode)) {
+
+    final className = nameOfType(nameNode);
+    if (className == null) {
       return;
     }
-    className = nameNode.name;
+    this.className = className;
+
     // prepare environment
     Element targetUnit;
     var prefix = '';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_mixin.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_mixin.dart
index b9934c4..4769c4a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_mixin.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_mixin.dart
@@ -49,7 +49,7 @@
     } else {
       return;
     }
-    if (!mightBeTypeIdentifier(nameNode)) {
+    if (nameOfType(nameNode) == null) {
       return;
     }
     // prepare environment
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart b/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
index 98cc241..d39f695 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
@@ -104,10 +104,8 @@
           targetNode = name;
         }
       }
-      if (mightBeTypeIdentifier(targetNode)) {
-        var typeName = (targetNode is SimpleIdentifier)
-            ? targetNode.name
-            : (targetNode as PrefixedIdentifier).prefix.name;
+      var typeName = nameOfType(targetNode);
+      if (typeName != null) {
         yield* _importLibraryForElement(typeName, const [
           ElementKind.CLASS,
           ElementKind.ENUM,
@@ -124,17 +122,13 @@
   }
 
   @override
-  bool mightBeTypeIdentifier(AstNode node) {
-    if (super.mightBeTypeIdentifier(node)) {
-      return true;
-    }
+  String? nameOfType(AstNode node) {
     if (node is PrefixedIdentifier) {
-      var parent = node.parent;
-      if (parent is NamedType) {
-        return true;
+      if (node.parent is NamedType) {
+        return node.prefix.name;
       }
     }
-    return false;
+    return super.nameOfType(node);
   }
 
   Stream<CorrectionProducer> _importExtensionInLibrary(
diff --git a/pkg/analyzer/test/src/diagnostics/extraneous_modifier_test.dart b/pkg/analyzer/test/src/diagnostics/extraneous_modifier_test.dart
index 915db60..5687d0b 100644
--- a/pkg/analyzer/test/src/diagnostics/extraneous_modifier_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/extraneous_modifier_test.dart
@@ -3,11 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
-import 'package:analyzer_utilities/check/check.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../../util/ast_check.dart';
-import '../../util/token_check.dart';
 import 'parser_diagnostics.dart';
 
 main() {
@@ -27,10 +24,14 @@
     parseResult.assertErrors([
       error(ParserErrorCode.EXTRANEOUS_MODIFIER, 14, 5),
     ]);
-    check(parseResult.findNode.simpleFormalParameter('a);'))
-      ..keyword.isKeywordConst
-      ..type.isNull
-      ..identifier.isNotNull;
+
+    var node = parseResult.findNode.simpleFormalParameter('a);');
+    assertParsedNodeText(node, r'''
+SimpleFormalParameter
+  identifier: SimpleIdentifier
+    token: a
+  keyword: const
+''');
   }
 
   test_simpleFormalParameter_var() async {
@@ -40,10 +41,14 @@
 }
 ''');
     parseResult.assertNoErrors();
-    check(parseResult.findNode.simpleFormalParameter('a);'))
-      ..keyword.isKeywordVar
-      ..type.isNull
-      ..identifier.isNotNull;
+
+    var node = parseResult.findNode.simpleFormalParameter('a);');
+    assertParsedNodeText(node, r'''
+SimpleFormalParameter
+  identifier: SimpleIdentifier
+    token: a
+  keyword: var
+''');
   }
 
   test_superFormalParameter_var() async {
@@ -55,12 +60,15 @@
     parseResult.assertErrors([
       error(ParserErrorCode.EXTRANEOUS_MODIFIER, 14, 3),
     ]);
-    check(parseResult.findNode.superFormalParameter('super.a'))
-      ..keyword.isKeywordVar
-      ..superKeyword.isKeywordSuper
-      ..type.isNull
-      ..identifier.isNotNull
-      ..typeParameters.isNull
-      ..parameters.isNull;
+
+    var node = parseResult.findNode.superFormalParameter('super.a');
+    assertParsedNodeText(node, r'''
+SuperFormalParameter
+  identifier: SimpleIdentifier
+    token: a
+  keyword: var
+  period: .
+  superKeyword: super
+''');
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/function_typed_parameter_var_test.dart b/pkg/analyzer/test/src/diagnostics/function_typed_parameter_var_test.dart
index b9c031c..7dd9f51 100644
--- a/pkg/analyzer/test/src/diagnostics/function_typed_parameter_var_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/function_typed_parameter_var_test.dart
@@ -3,11 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
-import 'package:analyzer_utilities/check/check.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../../util/ast_check.dart';
-import '../../util/token_check.dart';
 import 'parser_diagnostics.dart';
 
 main() {
@@ -27,12 +24,24 @@
     parseResult.assertErrors([
       error(ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, 14, 3),
     ]);
-    check(parseResult.findNode.superFormalParameter('super.a'))
-      ..keyword.isNull
-      ..superKeyword.isKeywordSuper
-      ..type.isNull
-      ..identifier.isNotNull
-      ..typeParameters.isNotNull.typeParameters.hasLength(1)
-      ..parameters.isNotNull;
+
+    var node = parseResult.findNode.superFormalParameter('super.a');
+    assertParsedNodeText(node, r'''
+SuperFormalParameter
+  identifier: SimpleIdentifier
+    token: a
+  parameters: FormalParameterList
+    leftParenthesis: (
+    rightParenthesis: )
+  period: .
+  superKeyword: super
+  typeParameters: TypeParameterList
+    leftBracket: <
+    rightBracket: >
+    typeParameters
+      TypeParameter
+        name: SimpleIdentifier
+          token: T
+''');
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/parser_diagnostics.dart b/pkg/analyzer/test/src/diagnostics/parser_diagnostics.dart
index 975d781..fa161b9 100644
--- a/pkg/analyzer/test/src/diagnostics/parser_diagnostics.dart
+++ b/pkg/analyzer/test/src/diagnostics/parser_diagnostics.dart
@@ -5,13 +5,32 @@
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/utilities.dart';
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/test_utilities/find_node.dart';
+import 'package:test/test.dart';
 
 import '../../generated/test_support.dart';
+import '../summary/resolved_ast_printer.dart';
 
 class ParserDiagnosticsTest {
+  /// TODO(scheglov) Enable [withCheckingLinking] everywhere.
+  void assertParsedNodeText(
+    AstNode node,
+    String expected, {
+    bool withCheckingLinking = false,
+  }) {
+    var actual = _parsedNodeText(
+      node,
+      withCheckingLinking: withCheckingLinking,
+    );
+    if (actual != expected) {
+      print(actual);
+    }
+    expect(actual, expected);
+  }
+
   ExpectedError error(
     ErrorCode code,
     int offset,
@@ -45,6 +64,23 @@
       throwIfDiagnostics: false,
     );
   }
+
+  String _parsedNodeText(
+    AstNode node, {
+    required bool withCheckingLinking,
+  }) {
+    var buffer = StringBuffer();
+    node.accept(
+      ResolvedAstPrinter(
+        selfUriStr: null,
+        sink: buffer,
+        indent: '',
+        withCheckingLinking: withCheckingLinking,
+        withResolution: false,
+      ),
+    );
+    return buffer.toString();
+  }
 }
 
 extension ParseStringResultExtension on ParseStringResult {
diff --git a/pkg/analyzer/test/src/fasta/ast_builder_test.dart b/pkg/analyzer/test/src/fasta/ast_builder_test.dart
index 311e173..3498d93 100644
--- a/pkg/analyzer/test/src/fasta/ast_builder_test.dart
+++ b/pkg/analyzer/test/src/fasta/ast_builder_test.dart
@@ -2,14 +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:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
-import 'package:analyzer_utilities/check/check.dart';
-import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../../util/ast_check.dart';
-import '../../util/token_check.dart';
 import '../diagnostics/parser_diagnostics.dart';
 
 main() {
@@ -23,20 +18,26 @@
   void test_constructor_factory_misnamed() {
     var parseResult = parseStringWithErrors(r'''
 class A {
-  factory B() => throw 0;
+  factory B() => null;
 }
 ''');
     parseResult.assertNoErrors();
-    var unit = parseResult.unit;
-    expect(unit.declarations, hasLength(1));
-    var declaration = unit.declarations[0] as ClassDeclaration;
-    expect(declaration, isNotNull);
-    expect(declaration.members, hasLength(1));
-    var member = declaration.members[0] as ConstructorDeclaration;
-    expect(member, isNotNull);
-    expect(member.factoryKeyword, isNotNull);
-    expect(member.name, isNull);
-    expect(member.returnType.name, 'B');
+
+    var node = parseResult.findNode.constructor('B()');
+    assertParsedNodeText(node, r'''
+ConstructorDeclaration
+  body: ExpressionFunctionBody
+    expression: NullLiteral
+      literal: null
+    functionDefinition: =>
+    semicolon: ;
+  factoryKeyword: factory
+  parameters: FormalParameterList
+    leftParenthesis: (
+    rightParenthesis: )
+  returnType: SimpleIdentifier
+    token: B
+''');
   }
 
   void test_constructor_wrongName() {
@@ -48,14 +49,24 @@
     parseResult.assertErrors([
       error(ParserErrorCode.INVALID_CONSTRUCTOR_NAME, 12, 1),
     ]);
-    var unit = parseResult.unit;
-    expect(unit.declarations, hasLength(1));
-    var declaration = unit.declarations[0] as ClassDeclaration;
-    expect(declaration, isNotNull);
-    expect(declaration.members, hasLength(1));
-    var member = declaration.members[0] as ConstructorDeclaration;
-    expect(member, isNotNull);
-    expect(member.initializers, hasLength(1));
+
+    var node = parseResult.findNode.constructor('B()');
+    assertParsedNodeText(node, r'''
+ConstructorDeclaration
+  body: EmptyFunctionBody
+    semicolon: ;
+  initializers
+    SuperConstructorInvocation
+      argumentList: ArgumentList
+        leftParenthesis: (
+        rightParenthesis: )
+      superKeyword: super
+  parameters: FormalParameterList
+    leftParenthesis: (
+    rightParenthesis: )
+  returnType: SimpleIdentifier
+    token: B
+''');
   }
 
   void test_enum_constant_name_dot() {
@@ -68,12 +79,20 @@
       error(ParserErrorCode.MISSING_IDENTIFIER, 14, 1),
     ]);
 
-    var v = parseResult.findNode.enumConstantDeclaration('v.');
-    check(v).name.name.isEqualTo('v');
-    check(v).arguments.isNotNull
-      ..typeArguments.isNull
-      ..constructorSelector.isNotNull.name.isSynthetic
-      ..argumentList.isSynthetic;
+    var node = parseResult.findNode.enumConstantDeclaration('v.');
+    assertParsedNodeText(node, r'''
+EnumConstantDeclaration
+  arguments: EnumConstantArguments
+    argumentList: ArgumentList
+      leftParenthesis: ( <synthetic>
+      rightParenthesis: ) <synthetic>
+    constructorSelector: ConstructorSelector
+      name: SimpleIdentifier
+        token: <empty> <synthetic>
+      period: .
+  name: SimpleIdentifier
+    token: v
+''');
   }
 
   void test_enum_constant_name_dot_identifier_semicolon() {
@@ -84,12 +103,20 @@
 ''');
     parseResult.assertNoErrors();
 
-    var v = parseResult.findNode.enumConstantDeclaration('v.');
-    check(v).name.name.isEqualTo('v');
-    check(v).arguments.isNotNull
-      ..typeArguments.isNull
-      ..constructorSelector.isNotNull.name.name.isEqualTo('named')
-      ..argumentList.isSynthetic;
+    var node = parseResult.findNode.enumConstantDeclaration('v.');
+    assertParsedNodeText(node, r'''
+EnumConstantDeclaration
+  arguments: EnumConstantArguments
+    argumentList: ArgumentList
+      leftParenthesis: ( <synthetic>
+      rightParenthesis: ) <synthetic>
+    constructorSelector: ConstructorSelector
+      name: SimpleIdentifier
+        token: named
+      period: .
+  name: SimpleIdentifier
+    token: v
+''');
   }
 
   void test_enum_constant_name_dot_semicolon() {
@@ -102,12 +129,20 @@
       error(ParserErrorCode.MISSING_IDENTIFIER, 13, 1),
     ]);
 
-    var v = parseResult.findNode.enumConstantDeclaration('v.');
-    check(v).name.name.isEqualTo('v');
-    check(v).arguments.isNotNull
-      ..typeArguments.isNull
-      ..constructorSelector.isNotNull.name.isSynthetic
-      ..argumentList.isSynthetic;
+    var node = parseResult.findNode.enumConstantDeclaration('v.');
+    assertParsedNodeText(node, r'''
+EnumConstantDeclaration
+  arguments: EnumConstantArguments
+    argumentList: ArgumentList
+      leftParenthesis: ( <synthetic>
+      rightParenthesis: ) <synthetic>
+    constructorSelector: ConstructorSelector
+      name: SimpleIdentifier
+        token: <empty> <synthetic>
+      period: .
+  name: SimpleIdentifier
+    token: v
+''');
   }
 
   void test_enum_constant_name_typeArguments_dot() {
@@ -122,12 +157,27 @@
       error(ParserErrorCode.MISSING_IDENTIFIER, 19, 1),
     ]);
 
-    var v = parseResult.findNode.enumConstantDeclaration('v<int>.');
-    check(v).name.name.isEqualTo('v');
-    check(v).arguments.isNotNull
-      ..typeArguments.isNotNull
-      ..constructorSelector.isNotNull.name.isSynthetic
-      ..argumentList.isSynthetic;
+    var node = parseResult.findNode.enumConstantDeclaration('v<int>.');
+    assertParsedNodeText(node, r'''
+EnumConstantDeclaration
+  arguments: EnumConstantArguments
+    argumentList: ArgumentList
+      leftParenthesis: ( <synthetic>
+      rightParenthesis: ) <synthetic>
+    constructorSelector: ConstructorSelector
+      name: SimpleIdentifier
+        token: <empty> <synthetic>
+      period: .
+    typeArguments: TypeArgumentList
+      arguments
+        NamedType
+          name: SimpleIdentifier
+            token: int
+      leftBracket: <
+      rightBracket: >
+  name: SimpleIdentifier
+    token: v
+''');
   }
 
   @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/48380')
@@ -143,21 +193,30 @@
       error(ParserErrorCode.MISSING_IDENTIFIER, 18, 1),
     ]);
 
-    var E = parseResult.findNode.enumDeclaration('enum E');
-    var v = parseResult.findNode.enumConstantDeclaration('v<int>');
-    check(v).name.name.isEqualTo('v');
-
-    var arguments = check(v).arguments.isNotNull;
-    arguments.typeArguments.isNotNull;
-
-    var constructorSelector = arguments.constructorSelector.isNotNull;
-    var syntheticName = constructorSelector.value.name;
-    constructorSelector.name.isSynthetic;
-
-    arguments.argumentList
-      ..isSynthetic
-      ..leftParenthesis.isLinkedToPrevious(syntheticName.token)
-      ..rightParenthesis.isLinkedToNext(E.semicolon!);
+    var node = parseResult.findNode.enumConstantDeclaration('v<int>');
+    assertParsedNodeText(
+        node,
+        r'''
+EnumConstantDeclaration
+  arguments: EnumConstantArguments
+    argumentList: ArgumentList
+      leftParenthesis: ( <synthetic>
+      rightParenthesis: ) <synthetic>
+    constructorSelector: ConstructorSelector
+      name: SimpleIdentifier
+        token: <empty> <synthetic>
+      period: .
+    typeArguments: TypeArgumentList
+      arguments
+        NamedType
+          name: SimpleIdentifier
+            token: int
+      leftBracket: <
+      rightBracket: >
+  name: SimpleIdentifier
+    token: v
+''',
+        withCheckingLinking: true);
   }
 
   void test_enum_constant_withTypeArgumentsWithoutArguments() {
@@ -171,11 +230,23 @@
           15, 5),
     ]);
 
-    var v = parseResult.findNode.enumConstantDeclaration('v<int>');
-    check(v).name.name.isEqualTo('v');
-    check(v).arguments.isNotNull
-      ..typeArguments.isNotNull
-      ..argumentList.isSynthetic;
+    var node = parseResult.findNode.enumConstantDeclaration('v<int>');
+    assertParsedNodeText(node, r'''
+EnumConstantDeclaration
+  arguments: EnumConstantArguments
+    argumentList: ArgumentList
+      leftParenthesis: ( <synthetic>
+      rightParenthesis: ) <synthetic>
+    typeArguments: TypeArgumentList
+      arguments
+        NamedType
+          name: SimpleIdentifier
+            token: int
+      leftBracket: <
+      rightBracket: >
+  name: SimpleIdentifier
+    token: v
+''');
   }
 
   void test_enum_semicolon_null() {
@@ -186,8 +257,16 @@
 ''');
     parseResult.assertNoErrors();
 
-    var v = parseResult.findNode.enumDeclaration('enum E');
-    check(v).semicolon.isNull;
+    var node = parseResult.findNode.enumDeclaration('enum E');
+    assertParsedNodeText(node, r'''
+EnumDeclaration
+  constants
+    EnumConstantDeclaration
+      name: SimpleIdentifier
+        token: v
+  name: SimpleIdentifier
+    token: E
+''');
   }
 
   void test_enum_semicolon_optional() {
@@ -198,8 +277,17 @@
 ''');
     parseResult.assertNoErrors();
 
-    var v = parseResult.findNode.enumDeclaration('enum E');
-    check(v).semicolon.isNotNull.isSemicolon;
+    var node = parseResult.findNode.enumDeclaration('enum E');
+    assertParsedNodeText(node, r'''
+EnumDeclaration
+  constants
+    EnumConstantDeclaration
+      name: SimpleIdentifier
+        token: v
+  name: SimpleIdentifier
+    token: E
+  semicolon: ;
+''');
   }
 
   void test_getter_sameNameAsClass() {
@@ -211,15 +299,19 @@
     parseResult.assertErrors([
       error(ParserErrorCode.MEMBER_WITH_CLASS_NAME, 16, 1),
     ]);
-    var unit = parseResult.unit;
-    expect(unit.declarations, hasLength(1));
-    var declaration = unit.declarations[0] as ClassDeclaration;
-    expect(declaration, isNotNull);
-    expect(declaration.members, hasLength(1));
-    var member = declaration.members[0] as MethodDeclaration;
-    expect(member, isNotNull);
-    expect(member.isGetter, isTrue);
-    expect(member.name.name, 'A');
+
+    var node = parseResult.findNode.methodDeclaration('get A');
+    assertParsedNodeText(node, r'''
+MethodDeclaration
+  body: ExpressionFunctionBody
+    expression: IntegerLiteral
+      literal: 0
+    functionDefinition: =>
+    semicolon: ;
+  name: SimpleIdentifier
+    token: A
+  propertyKeyword: get
+''');
   }
 
   void test_superFormalParameter() {
@@ -229,13 +321,14 @@
 }
 ''');
     parseResult.assertNoErrors();
-    check(parseResult.findNode.superFormalParameter('super.a'))
-      ..type.isNull
-      ..superKeyword.isKeywordSuper
-      ..identifier.which((it) => it
-        ..name.isEqualTo('a')
-        ..inDeclarationContext.isTrue)
-      ..typeParameters.isNull
-      ..parameters.isNull;
+
+    var node = parseResult.findNode.superFormalParameter('super.a');
+    assertParsedNodeText(node, r'''
+SuperFormalParameter
+  identifier: SimpleIdentifier
+    token: a
+  period: .
+  superKeyword: super
+''');
   }
 }
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index dfdbf61..d2903bd 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/syntactic_entity.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -12,6 +13,7 @@
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary2/reference.dart';
+import 'package:test/test.dart';
 
 /// Used in [ResolvedAstPrinter] to print lines of code that corresponding
 /// to a subtree of AST. This help to make the bulky presentation of AST a
@@ -33,9 +35,16 @@
   /// The optional provider for code lines, might be `null`.
   final CodeLinesProvider? _codeLinesProvider;
 
+  /// If `true`, linking of [EnumConstantDeclaration] will be checked
+  /// TODO(scheglov) Remove after https://github.com/dart-lang/sdk/issues/48380
+  final bool withCheckingLinking;
+
   /// If `true`, selected tokens and nodes should be printed with offsets.
   final bool _withOffsets;
 
+  /// If `true`, resolution should be printed.
+  final bool _withResolution;
+
   String _indent = '';
 
   ResolvedAstPrinter({
@@ -43,11 +52,14 @@
     required StringSink sink,
     required String indent,
     CodeLinesProvider? codeLinesProvider,
+    this.withCheckingLinking = false,
     bool withOffsets = false,
+    bool withResolution = true,
   })  : _selfUriStr = selfUriStr,
         _sink = sink,
         _codeLinesProvider = codeLinesProvider,
         _withOffsets = withOffsets,
+        _withResolution = withResolution,
         _indent = indent;
 
   @override
@@ -373,6 +385,18 @@
   }
 
   @override
+  void visitConstructorSelector(ConstructorSelector node) {
+    _checkChildrenEntitiesLinking(node);
+    _writeln('ConstructorSelector');
+    _withIndent(() {
+      var properties = _Properties();
+      properties.addNode('name', node.name);
+      properties.addToken('period', node.period);
+      _writeProperties(properties);
+    });
+  }
+
+  @override
   void visitContinueStatement(ContinueStatement node) {
     _writeNextCodeLine(node);
     _writeln('ContinueStatement');
@@ -450,11 +474,28 @@
   }
 
   @override
+  void visitEnumConstantArguments(EnumConstantArguments node) {
+    if (withCheckingLinking) {
+      _checkChildrenEntitiesLinking(node);
+    }
+    _writeln('EnumConstantArguments');
+    _withIndent(() {
+      var properties = _Properties();
+      properties.addNode('argumentList', node.argumentList);
+      properties.addNode('constructorSelector', node.constructorSelector);
+      properties.addNode('typeArguments', node.typeArguments);
+      _writeProperties(properties);
+    });
+  }
+
+  @override
   void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+    _checkChildrenEntitiesLinking(node);
     _writeNextCodeLine(node);
     _writeln('EnumConstantDeclaration');
     _withIndent(() {
       var properties = _Properties();
+      properties.addNode('arguments', node.arguments);
       properties.addNode('name', node.name);
       _addDeclaration(properties, node);
       _writeProperties(properties);
@@ -468,6 +509,7 @@
     _withIndent(() {
       var properties = _Properties();
       properties.addNodeList('constants', node.constants);
+      properties.addToken('semicolon', node.semicolon);
       _addNamedCompilationUnitMember(properties, node);
       _writeProperties(properties);
     });
@@ -548,6 +590,7 @@
       var properties = _Properties();
       properties.addToken('keyword', node.keyword);
       properties.addNode('parameters', node.parameters);
+      properties.addToken('period', node.period);
       properties.addToken('thisKeyword', node.thisKeyword);
       properties.addNode('type', node.type);
       properties.addNode('typeParameters', node.typeParameters);
@@ -990,7 +1033,9 @@
     _withIndent(() {
       var properties = _Properties();
       properties.addNode('body', node.body);
-      properties.addType('declaredElementType', node.declaredElement!.type);
+      if (_withResolution) {
+        properties.addType('declaredElementType', node.declaredElement!.type);
+      }
       properties.addToken('externalKeyword', node.externalKeyword);
       properties.addToken('modifierKeyword', node.modifierKeyword);
       properties.addNode('name', node.name);
@@ -1328,6 +1373,26 @@
   }
 
   @override
+  void visitSuperFormalParameter(SuperFormalParameter node) {
+    if (withCheckingLinking) {
+      _checkChildrenEntitiesLinking(node);
+    }
+    _writeNextCodeLine(node);
+    _writeln('SuperFormalParameter');
+    _withIndent(() {
+      var properties = _Properties();
+      properties.addToken('keyword', node.keyword);
+      properties.addNode('parameters', node.parameters);
+      properties.addToken('period', node.period);
+      properties.addToken('superKeyword', node.superKeyword);
+      properties.addNode('type', node.type);
+      properties.addNode('typeParameters', node.typeParameters);
+      _addNormalFormalParameter(properties, node);
+      _writeProperties(properties);
+    });
+  }
+
+  @override
   void visitSwitchCase(SwitchCase node) {
     _writeNextCodeLine(node);
     _writeln('SwitchCase');
@@ -1624,7 +1689,9 @@
   }
 
   void _addDeclaration(_Properties properties, Declaration node) {
-    properties.addElement('declaredElement', node.declaredElement);
+    if (_withResolution) {
+      properties.addElement('declaredElement', node.declaredElement);
+    }
     _addAnnotatedNode(properties, node);
   }
 
@@ -1653,8 +1720,10 @@
 
   void _addFormalParameter(_Properties properties, FormalParameter node) {
     properties.addToken('covariantKeyword', node.covariantKeyword);
-    properties.addElement('declaredElement', node.declaredElement);
-    properties.addType('declaredElementType', node.declaredElement!.type);
+    if (_withResolution) {
+      properties.addElement('declaredElement', node.declaredElement);
+      properties.addType('declaredElementType', node.declaredElement!.type);
+    }
     properties.addNode('identifier', node.identifier);
     properties.addNodeList('metadata', node.metadata);
     properties.addToken('requiredKeyword', node.requiredKeyword);
@@ -1788,6 +1857,19 @@
     _addDirective(properties, node);
   }
 
+  /// Check that children entities of the [node] link to each other.
+  void _checkChildrenEntitiesLinking(AstNode node) {
+    Token? lastEnd;
+    for (var entity in node.childEntities) {
+      if (lastEnd != null) {
+        var begin = _entityBeginToken(entity);
+        expect(lastEnd.next, begin);
+        expect(begin.previous, lastEnd);
+      }
+      lastEnd = _entityEndToken(entity);
+    }
+  }
+
   String _referenceToString(Reference reference) {
     var parent = reference.parent!;
     if (parent.parent == null) {
@@ -1836,9 +1918,11 @@
   }
 
   void _writeElement(String name, Element? element) {
-    _sink.write(_indent);
-    _sink.write('$name: ');
-    _writeElement0(element);
+    if (_withResolution) {
+      _sink.write(_indent);
+      _sink.write('$name: ');
+      _writeElement0(element);
+    }
   }
 
   void _writeElement0(Element? element) {
@@ -1971,11 +2055,16 @@
 
   void _writeToken(String name, Token? token) {
     if (token != null) {
+      _sink.write(_indent);
+      _sink.write('$name: ');
+      _sink.write(token.lexeme.isNotEmpty ? token : '<empty>');
       if (_withOffsets) {
-        _writelnWithIndent('$name: $token @${token.offset}');
-      } else {
-        _writelnWithIndent('$name: $token');
+        _sink.write(' @${token.offset}');
       }
+      if (token.isSynthetic) {
+        _sink.write(' <synthetic>');
+      }
+      _sink.writeln();
     }
   }
 
@@ -1995,8 +2084,10 @@
   }
 
   void _writeType(String name, DartType? type) {
-    var typeStr = _typeStr(type);
-    _writelnWithIndent('$name: $typeStr');
+    if (_withResolution) {
+      var typeStr = _typeStr(type);
+      _writelnWithIndent('$name: $typeStr');
+    }
   }
 
   void _writeTypeList(String name, List<DartType>? types) {
@@ -2011,6 +2102,26 @@
     }
   }
 
+  static Token _entityBeginToken(SyntacticEntity entity) {
+    if (entity is Token) {
+      return entity;
+    } else if (entity is AstNode) {
+      return entity.beginToken;
+    } else {
+      throw UnimplementedError('(${entity.runtimeType}) $entity');
+    }
+  }
+
+  static Token _entityEndToken(SyntacticEntity entity) {
+    if (entity is Token) {
+      return entity;
+    } else if (entity is AstNode) {
+      return entity.endToken;
+    } else {
+      throw UnimplementedError('(${entity.runtimeType}) $entity');
+    }
+  }
+
   static String _nameOfMemberClass(Member member) {
     return '${member.runtimeType}';
   }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 085c1c1..111f776 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -8314,7 +8314,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -8337,7 +8337,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -8360,7 +8360,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -13557,7 +13557,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -13578,7 +13578,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -13599,7 +13599,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -15845,7 +15845,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -15866,7 +15866,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -15887,7 +15887,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -15968,7 +15968,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -16962,7 +16962,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -16983,7 +16983,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -17032,7 +17032,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -17053,7 +17053,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -17074,7 +17074,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -17367,7 +17367,7 @@
                       base: self::@enum::E::@constructor::•
                       substitution: {T: int}
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: ConstructorMember
                     base: self::@enum::E::@constructor::•
@@ -17395,7 +17395,7 @@
                       base: self::@enum::E::@constructor::•
                       substitution: {T: String}
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: ConstructorMember
                     base: self::@enum::E::@constructor::•
@@ -17463,7 +17463,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -17529,7 +17529,7 @@
                       base: self::@enum::E::@constructor::•
                       substitution: {T: double}
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: ConstructorMember
                     base: self::@enum::E::@constructor::•
@@ -17600,7 +17600,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -17657,7 +17657,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -17717,7 +17717,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -17775,7 +17775,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -17845,7 +17845,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -17914,7 +17914,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -17976,7 +17976,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -18042,7 +18042,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -18108,7 +18108,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -18243,7 +18243,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -18304,7 +18304,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -18361,7 +18361,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -18426,7 +18426,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -18493,7 +18493,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -18564,7 +18564,7 @@
                       base: self::@enum::E::@constructor::•
                       substitution: {U: dynamic}
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: ConstructorMember
                     base: self::@enum::E::@constructor::•
@@ -18634,7 +18634,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -18696,7 +18696,7 @@
                       base: self::@enum::E::@constructor::•
                       substitution: {T: dynamic}
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: ConstructorMember
                     base: self::@enum::E::@constructor::•
@@ -18765,7 +18765,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -18827,7 +18827,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -18894,7 +18894,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -18968,7 +18968,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -19036,7 +19036,7 @@
                       base: self::@enum::E::@constructor::•
                       substitution: {T: dynamic}
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: ConstructorMember
                     base: self::@enum::E::@constructor::•
@@ -19103,7 +19103,7 @@
                       base: self::@enum::E::@constructor::•
                       substitution: {T: num, U: num}
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: ConstructorMember
                     base: self::@enum::E::@constructor::•
@@ -19382,7 +19382,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -19404,7 +19404,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -19484,7 +19484,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -19514,7 +19514,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -19582,7 +19582,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -19603,7 +19603,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -19661,7 +19661,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E1::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E1::@constructor::•
                   type: NamedType
@@ -19704,7 +19704,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E2::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E2::@constructor::•
                   type: NamedType
@@ -19814,7 +19814,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -19835,7 +19835,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -19856,7 +19856,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -26751,7 +26751,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -26853,7 +26853,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -26874,7 +26874,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -26910,7 +26910,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -26982,7 +26982,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -28513,7 +28513,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -28534,7 +28534,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -28563,7 +28563,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -29655,7 +29655,7 @@
                       base: self::@enum::E::@constructor::•
                       substitution: {T: dynamic}
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: ConstructorMember
                     base: self::@enum::E::@constructor::•
@@ -29901,7 +29901,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -29922,7 +29922,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -29943,7 +29943,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -31282,7 +31282,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -31304,7 +31304,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -33328,7 +33328,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -33459,7 +33459,7 @@
                     name: SimpleIdentifier
                       staticElement: self::@enum::E::@constructor::•
                       staticType: null
-                      token:  @-1
+                      token: <empty> @-1 <synthetic>
                     period: . @0
                     staticElement: self::@enum::E::@constructor::•
                     type: NamedType
@@ -33524,7 +33524,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
@@ -33626,7 +33626,7 @@
                     name: SimpleIdentifier
                       staticElement: self::@enum::E::@constructor::•
                       staticType: null
-                      token:  @-1
+                      token: <empty> @-1 <synthetic>
                     period: . @0
                     staticElement: self::@enum::E::@constructor::•
                     type: NamedType
@@ -33726,7 +33726,7 @@
                     name: SimpleIdentifier
                       staticElement: self::@enum::E::@constructor::•
                       staticType: null
-                      token:  @-1
+                      token: <empty> @-1 <synthetic>
                     period: . @0
                     staticElement: self::@enum::E::@constructor::•
                     type: NamedType
@@ -33894,7 +33894,7 @@
                   name: SimpleIdentifier
                     staticElement: self::@enum::E::@constructor::•
                     staticType: null
-                    token:  @-1
+                    token: <empty> @-1 <synthetic>
                   period: . @0
                   staticElement: self::@enum::E::@constructor::•
                   type: NamedType
diff --git a/pkg/diagnostic/CHANGELOG.md b/pkg/diagnostic/CHANGELOG.md
deleted file mode 100644
index cb12c59..0000000
--- a/pkg/diagnostic/CHANGELOG.md
+++ /dev/null
@@ -1,3 +0,0 @@
-## 0.1.0
-
-* Initial version
diff --git a/pkg/diagnostic/LICENSE b/pkg/diagnostic/LICENSE
deleted file mode 100644
index 4d1ad40..0000000
--- a/pkg/diagnostic/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright 2018, the Dart project authors.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google LLC nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkg/diagnostic/OWNERS b/pkg/diagnostic/OWNERS
deleted file mode 100644
index 2b67506..0000000
--- a/pkg/diagnostic/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-file:/tools/OWNERS_ENG
diff --git a/pkg/diagnostic/README.md b/pkg/diagnostic/README.md
deleted file mode 100644
index 4c5ddfa..0000000
--- a/pkg/diagnostic/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# Diagnostics for Dart
-
-This package defines the support used by Dart tools to represent diagnostics, and the diagnostic codes that are shared
-by those tools.
-
-## Support
-
-Post issues and feature requests at https://github.com/dart-lang/sdk/issues
-
-## License
-
-See the [LICENSE] file.
-
-[LICENSE]: https://github.com/dart-lang/sdk/blob/main/pkg/diagnostic/LICENSE
diff --git a/pkg/diagnostic/doc/diagnostics.md b/pkg/diagnostic/doc/diagnostics.md
deleted file mode 100644
index b0261a5..0000000
--- a/pkg/diagnostic/doc/diagnostics.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Diagnostics Design
-
-This document discusses the principles used to design the diagnostics used by
-Dart tooling.
diff --git a/pkg/diagnostic/lib/diagnostic.dart b/pkg/diagnostic/lib/diagnostic.dart
deleted file mode 100644
index babf863..0000000
--- a/pkg/diagnostic/lib/diagnostic.dart
+++ /dev/null
@@ -1,3 +0,0 @@
-// Copyright (c) 2018, 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.
diff --git a/pkg/diagnostic/pubspec.yaml b/pkg/diagnostic/pubspec.yaml
deleted file mode 100644
index b42e69b..0000000
--- a/pkg/diagnostic/pubspec.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-name: diagnostic
-# This package is not intended for consumption on pub.dev. DO NOT publish.
-publish_to: none
-author: Dart Team <misc@dartlang.org>
-description: Diagnostics for Dart
-homepage: https://github.com/dart-lang/sdk/tree/master/pkg/diagnostic
-environment:
-  sdk: '>=2.0.0-dev.48.0 <3.0.0'
diff --git a/runtime/vm/field_table.cc b/runtime/vm/field_table.cc
index 7e147c5..935b157 100644
--- a/runtime/vm/field_table.cc
+++ b/runtime/vm/field_table.cc
@@ -117,8 +117,7 @@
   old_tables_->Add(old_table);
   // Ensure that new_table_ is populated before it is published
   // via store to table_.
-  std::atomic_thread_fence(std::memory_order_release);
-  table_ = new_table;
+  reinterpret_cast<AcqRelAtomic<ObjectPtr*>*>(&table_)->store(new_table);
   if (isolate_ != nullptr) {
     isolate_->mutator_thread()->field_table_values_ = table_;
   }
diff --git a/runtime/vm/field_table.h b/runtime/vm/field_table.h
index 71c01ef..cd25aa9 100644
--- a/runtime/vm/field_table.h
+++ b/runtime/vm/field_table.h
@@ -60,14 +60,15 @@
 
   ObjectPtr At(intptr_t index, bool concurrent_use = false) const {
     ASSERT(IsValidIndex(index));
-    ObjectPtr* slot = &table_[index];
     if (concurrent_use) {
-      return reinterpret_cast<AcqRelAtomic<ObjectPtr>*>(slot)->load();
+      ObjectPtr* table =
+          reinterpret_cast<const AcqRelAtomic<ObjectPtr*>*>(&table_)->load();
+      return reinterpret_cast<AcqRelAtomic<ObjectPtr>*>(&table[index])->load();
     } else {
       // There is no concurrent access expected for this field, so we avoid
       // using atomics. This will allow us to detect via TSAN if there are
       // racy uses.
-      return *slot;
+      return table_[index];
     }
   }
 
diff --git a/third_party/devtools/update.sh b/third_party/devtools/update.sh
index 92d6f2d..6723520 100755
--- a/third_party/devtools/update.sh
+++ b/third_party/devtools/update.sh
@@ -30,9 +30,8 @@
 # Copy the build output as well as the devtools packages needed
 # to serve from DDS.
 mkdir cipd_package
-cp -R packages/devtools/build/ cipd_package/web
+cp -R packages/devtools_app/build/web cipd_package/web
 cp -r packages/devtools_shared cipd_package
-cp -r packages/devtools_server cipd_package
 
 cipd create \
   -name dart/third_party/flutter/devtools \
diff --git a/tools/VERSION b/tools/VERSION
index 5f763ec..b6083b2 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 118
+PRERELEASE 119
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/addlatexhash.dart b/tools/addlatexhash.dart
index a3b2230..d1cc30f 100755
--- a/tools/addlatexhash.dart
+++ b/tools/addlatexhash.dart
@@ -22,6 +22,10 @@
 // NB: This utility assumes UN*X style line endings, \n, in the LaTeX
 // source file received as input; it will not work with other styles.
 
+// @dart = 2.9
+
+// ignore_for_file: constant_identifier_names
+
 import 'dart:convert';
 import 'dart:io';
 
@@ -32,15 +36,15 @@
 // Normalization of the text: removal or normalization of parts that
 // do not affect the output from latex, such as white space.
 
-final commentRE = new RegExp(r"[^\\]%.*"); // NB: . does not match \n.
-final whitespaceAllRE = new RegExp(r"^\s+$");
-final whitespaceRE = new RegExp(r"(?:(?=\s).){2,}"); // \s except end-of-line
+final commentRE = RegExp(r"[^\\]%.*"); // NB: . does not match \n.
+final whitespaceAllRE = RegExp(r"^\s+$");
+final whitespaceRE = RegExp(r"(?:(?=\s).){2,}"); // \s except end-of-line
 
 /// Removes [match]ing part of [line], adjusting that part with the
 /// given [startOffset] and [endOffset], bounded to be valid indices
 /// into the string if needed, then inserts [glue] where text was
 /// removed.  If there is no match then [line] is returned.
-cutMatch(line, match, {startOffset: 0, endOffset: 0, glue: ""}) {
+cutMatch(line, match, {startOffset = 0, endOffset = 0, glue = ""}) {
   if (match == null) return line;
   var start = match.start + startOffset;
   var end = match.end + endOffset;
@@ -50,7 +54,7 @@
   return line.substring(0, start) + glue + line.substring(end);
 }
 
-cutRegexp(line, re, {startOffset: 0, endOffset: 0, glue: ""}) {
+cutRegexp(line, re, {startOffset = 0, endOffset = 0, glue = ""}) {
   return cutMatch(line, re.firstMatch(line),
       startOffset: startOffset, endOffset: endOffset, glue: glue);
 }
@@ -58,12 +62,12 @@
 /// Removes the rest of [line] starting from the beginning of the
 /// given [match], and adjusting with the given [offset].  If there
 /// is no match then [line] is returned.
-cutFromMatch(line, match, {offset: 0, glue: ""}) {
+cutFromMatch(line, match, {offset = 0, glue = ""}) {
   if (match == null) return line;
   return line.substring(0, match.start + offset) + glue;
 }
 
-cutFromRegexp(line, re, {offset: 0, glue: ""}) {
+cutFromRegexp(line, re, {offset = 0, glue = ""}) {
   return cutFromMatch(line, re.firstMatch(line), offset: offset, glue: glue);
 }
 
@@ -175,8 +179,8 @@
 
 // Managing fragments with significant spacing.
 
-final dartCodeBeginRE = new RegExp(r"^\s*\\begin\s*\{dartCode\}");
-final dartCodeEndRE = new RegExp(r"^\s*\\end\s*\{dartCode\}");
+final dartCodeBeginRE = RegExp(r"^\s*\\begin\s*\{dartCode\}");
+final dartCodeEndRE = RegExp(r"^\s*\\end\s*\{dartCode\}");
 
 /// Recognizes beginning of dartCode block.
 sispIsDartBegin(line) => line.contains(dartCodeBeginRE);
@@ -204,11 +208,10 @@
 /// Returns RegExp text for recognizing a command occupying a line
 /// of its own, given the part of the RegExp that recognizes the
 /// command name, [cmdNameRE]
-lineCommandRE(cmdNameRE) =>
-    new RegExp(r"^\s*\\" + cmdNameRE + r"\s*\{.*\}%?\s*$");
+lineCommandRE(cmdNameRE) => RegExp(r"^\s*\\" + cmdNameRE + r"\s*\{.*\}%?\s*$");
 
-final hashLabelStartRE = new RegExp(r"^\s*\\LMLabel\s*\{");
-final hashLabelEndRE = new RegExp(r"\}\s*$");
+final hashLabelStartRE = RegExp(r"^\s*\\LMLabel\s*\{");
+final hashLabelEndRE = RegExp(r"\}\s*$");
 
 final hashMarkRE = lineCommandRE("LMHash");
 final hashLabelRE = lineCommandRE("LMLabel");
@@ -259,19 +262,19 @@
   /// The endLineNumber specifies the end of the block of lines
   /// associated with a given event, for event types concerned with
   /// blocks of lines rather than single lines.
-  setEndLineNumber(n) {}
+  setEndLineNumber(int n) {}
 
   /// Returns null except for \LMHash{} events, where it returns
   /// the startLineNumber.  This serves to specify a boundary because
   /// the preceding \LMHash{} block should stop before the line of
   /// this \LMHash{} command.  Note that hash blocks may stop earlier,
   /// because they cannot contain sectioning commands.
-  getStartLineNumber() => null;
+  int getStartLineNumber() => null;
 }
 
 class HashMarkerEvent extends HashEvent {
   // Line number of first line in block that gets hashed.
-  var startLineNumber;
+  int startLineNumber;
 
   // Highest possible number of first line after block that gets
   // hashed (where the next \LMHash{} occurs).  Note that this value
@@ -279,19 +282,21 @@
   // reached), so [endLineNumber] will be initialized in a separate
   // scan.  Also note that the block may end earlier, because a block
   // ends if it would otherwise include a sectioning command.
-  var endLineNumber;
+  int endLineNumber;
 
   HashMarkerEvent(this.startLineNumber);
 
-  setEndLineNumber(n) {
+  @override
+  setEndLineNumber(int n) {
     endLineNumber = n;
   }
 
-  getStartLineNumber() => startLineNumber;
+  @override
+  int getStartLineNumber() => startLineNumber;
 }
 
 class HashLabelEvent extends HashEvent {
-  var labelText;
+  String labelText;
   HashLabelEvent(this.labelText);
 }
 
@@ -337,10 +342,8 @@
         return "subsec:";
       case PENDING_IS_SUBSUBSECTION:
         return "subsubsec:";
-      case PENDING_IS_PARAGRAPH:
-        return "par:";
       case PENDING_IS_NONE:
-        throw "\\LMHash{..} should only be used after a sectioning command " +
+        throw "\\LMHash{..} should only be used after a sectioning command "
             "(\\section, \\subsection, \\subsubsection, \\paragraph)";
       default:
         // set of PENDING_IS_.. was extended, but updates here omitted
@@ -351,10 +354,10 @@
   analyze(line) {
     var currentLineNumber = lineNumber++;
     if (isHashMarker(line)) {
-      return new HashMarkerEvent(currentLineNumber);
+      return HashMarkerEvent(currentLineNumber);
     } else if (isHashLabel(line)) {
       var labelText = sectioningPrefix() + extractHashLabel(line);
-      return new HashLabelEvent(labelText);
+      return HashLabelEvent(labelText);
     } else {
       // No events to emit, but we may need to note state changes
       if (isSectionCommand(line)) {
@@ -375,7 +378,7 @@
 
 findHashEvents(lines) {
   // Create the list of events, omitting endLineNumbers.
-  var events = findEvents(lines, new HashAnalyzer());
+  var events = findEvents(lines, HashAnalyzer());
   // Set the endLineNumbers.
   var currentEndLineNumber = lines.length;
   for (var event in events.reversed) {
@@ -444,8 +447,8 @@
   throw "Unmatched braces";
 }
 
-final commentaryRE = new RegExp(r"\\commentary\s*\{");
-final rationaleRE = new RegExp(r"\\rationale\s*\{");
+final commentaryRE = RegExp(r"\\commentary\s*\{");
+final rationaleRE = RegExp(r"\\rationale\s*\{");
 
 /// Removes {}-balanced '\commentary{..}' commands from [line].
 removeCommentary(line) {
@@ -473,7 +476,7 @@
 // ----------------------------------------------------------------------
 // Recognition of line blocks, insertion of block hash into \LMHash{}.
 
-final latexArgumentRE = new RegExp(r"\{.*\}");
+final latexArgumentRE = RegExp(r"\{.*\}");
 
 cleanupLine(line) => cutRegexp(line, commentRE, startOffset: 1).trimRight();
 
@@ -530,15 +533,15 @@
   }
 
   // Get LaTeX source.
-  var inputFile = new File(args[0]);
+  var inputFile = File(args[0]);
   assert(inputFile.existsSync());
   var lines = inputFile.readAsLinesSync();
 
   // Will hold LaTeX source with normalized spacing etc., plus hash values.
-  var outputFile = new File(args[1]);
+  var outputFile = File(args[1]);
 
   // Will hold hierarchical list of hash values.
-  var listFile = new File(args[2]);
+  var listFile = File(args[2]);
   var listSink = listFile.openWrite();
 
   // Perform single-line normalization.
diff --git a/tools/analysis_options.yaml b/tools/analysis_options.yaml
new file mode 100644
index 0000000..204e7c6
--- /dev/null
+++ b/tools/analysis_options.yaml
@@ -0,0 +1,17 @@
+include: package:lints/recommended.yaml
+
+analyzer:
+  exclude:
+    # This directory isn't intended to be analyzed.
+    - sdks/**
+    # There are a fair number of issues in here.
+    - dart2js/**
+    - dom/**
+    - test_generators/**
+
+linter:
+  rules:
+    # TODO: Enable this once other issues are addressed.
+    # - avoid_dynamic_calls
+    - depend_on_referenced_packages
+    - directives_ordering
diff --git a/tools/bots/compare_results.dart b/tools/bots/compare_results.dart
index bcf9abe52..1e2bad3 100755
--- a/tools/bots/compare_results.dart
+++ b/tools/bots/compare_results.dart
@@ -9,8 +9,8 @@
 
 // @dart = 2.9
 
-import '../../pkg/test_runner/bin/compare_results.dart' as compareResults;
+import '../../pkg/test_runner/bin/compare_results.dart' as compare_results;
 
 main(List<String> args) {
-  compareResults.main(args);
+  compare_results.main(args);
 }
diff --git a/tools/bots/extend_results.dart b/tools/bots/extend_results.dart
index 4ab1d2c..6b03623 100644
--- a/tools/bots/extend_results.dart
+++ b/tools/bots/extend_results.dart
@@ -63,7 +63,7 @@
       result['changed'] = true;
     }
   }
-  final sink = new File(newResultsPath).openWrite();
+  final sink = File(newResultsPath).openWrite();
   final sorted = results.keys.toList()..sort();
   for (final key in sorted) {
     sink.writeln(jsonEncode(results[key]));
diff --git a/tools/bots/find_base_commit.dart b/tools/bots/find_base_commit.dart
index 4a68e261..595871d 100755
--- a/tools/bots/find_base_commit.dart
+++ b/tools/bots/find_base_commit.dart
@@ -14,7 +14,7 @@
 import 'package:glob/glob.dart';
 
 void main(List<String> args) async {
-  final parser = new ArgParser();
+  final parser = ArgParser();
   parser.addMultiOption("builder",
       abbr: "b",
       help: "Select the builders matching the glob [option is repeatable]",
@@ -40,15 +40,15 @@
   }
 
   int count = int.parse(options["count"]);
-  final globs = new List<Glob>.from(
-      options["builder"].map((String pattern) => new Glob(pattern)));
+  final globs = List<Glob>.from(
+      options["builder"].map((String pattern) => Glob(pattern)));
 
   // Download the most recent builds from buildbucket.
   const maxBuilds = 1000;
   final url = Uri.parse("https://cr-buildbucket.appspot.com"
       "/prpc/buildbucket.v2.Builds/SearchBuilds");
   const maxRetries = 3;
-  const timeout = const Duration(seconds: 30);
+  const timeout = Duration(seconds: 30);
   final query = jsonEncode({
     "predicate": {
       "builder": {"project": "dart", "bucket": "ci.sandbox"},
@@ -60,7 +60,7 @@
   late Map<String, dynamic> searchResult;
   for (int i = 1; i <= maxRetries; i++) {
     try {
-      final client = new HttpClient();
+      final client = HttpClient();
       final request = await client.postUrl(url).timeout(timeout)
         ..headers.contentType = ContentType.json
         ..headers.add(HttpHeaders.acceptHeader, ContentType.json)
@@ -74,10 +74,10 @@
       const prefix = ")]}'";
       searchResult = await (response
           .cast<List<int>>()
-          .transform(new Utf8Decoder())
+          .transform(Utf8Decoder())
           .map((event) =>
               event.startsWith(prefix) ? event.substring(prefix.length) : event)
-          .transform(new JsonDecoder())
+          .transform(JsonDecoder())
           .cast<Map<String, dynamic>>()
           .first
           .timeout(timeout));
@@ -132,7 +132,7 @@
     }
     final commit = input["id"] as String;
     final buildersForCommit =
-        buildersForCommits.putIfAbsent(commit, () => new Set<String>());
+        buildersForCommits.putIfAbsent(commit, () => <String>{});
     buildersForCommit.add(builder);
   }
 
diff --git a/tools/bots/lib/src/firestore.dart b/tools/bots/lib/src/firestore.dart
index c1d602a..aed2175 100644
--- a/tools/bots/lib/src/firestore.dart
+++ b/tools/bots/lib/src/firestore.dart
@@ -74,7 +74,7 @@
         path: '$collectionName/$documentName',
         query: _currentTransaction == null
             ? null
-            : 'transaction=${_escapedCurrentTransaction}'));
+            : 'transaction=$_escapedCurrentTransaction'));
     var response = await _client.get(url, headers: _headers);
     if (response.statusCode == HttpStatus.ok) {
       var document = jsonDecode(response.body);
@@ -123,7 +123,7 @@
     }
     var body = jsonEncode({
       "writes": writes.map((write) => write.data).toList(),
-      "transaction": "$_currentTransaction"
+      "transaction": _currentTransaction
     });
     var response =
         await _client.post(_commitUrl, headers: _headers, body: body);
@@ -140,7 +140,7 @@
     return true;
   }
 
-  Exception _error(http.Response response, {String message: 'Error'}) {
+  Exception _error(http.Response response, {String message = 'Error'}) {
     throw Exception('$message: ${response.statusCode}: '
         '${response.reasonPhrase}:\n${response.body}');
   }
@@ -154,6 +154,7 @@
 }
 
 class Update implements Write {
+  @override
   final Map data;
   Update(List<String> updateMask, Map document, {String updateTime})
       : data = {
@@ -188,7 +189,7 @@
           'fieldFilter': {
             'field': {'fieldPath': field},
             'op': op,
-            'value': {'$type': value},
+            'value': {type: value},
           }
         });
 }
diff --git a/tools/bots/update_blamelists.dart b/tools/bots/update_blamelists.dart
index af8d525..5488856 100644
--- a/tools/bots/update_blamelists.dart
+++ b/tools/bots/update_blamelists.dart
@@ -11,9 +11,9 @@
 import 'dart:io';
 
 import 'package:args/args.dart';
+import 'package:test_runner/bot_results.dart';
 
 import 'lib/src/firestore.dart';
-import 'package:test_runner/bot_results.dart';
 
 const newTest = 'new test';
 const skippedTest = 'skipped';
@@ -23,7 +23,7 @@
 FirestoreDatabase database;
 
 class ResultRecord {
-  final data;
+  final Map data;
 
   ResultRecord(this.data);
 
@@ -33,7 +33,7 @@
     return int.parse(field('blamelist_start_index')['integerValue']);
   }
 
-  void set blamelistStartIndex(int index) {
+  set blamelistStartIndex(int index) {
     field('blamelist_start_index')['integerValue'] = '$index';
   }
 
@@ -109,7 +109,7 @@
         .where((result) => result['document'] != null)
         .map((result) => result['document']['name']);
     for (var documentPath in documents) {
-      await database.beginTransaction();
+      database.beginTransaction();
       var documentName = documentPath.split('/').last;
       var result =
           ResultRecord(await database.getDocument('results', documentName));
@@ -181,6 +181,6 @@
   var project = options['staging'] ? 'dart-ci-staging' : 'dart-ci';
   database = FirestoreDatabase(
       project, await readGcloudAuthToken(options['auth-token']));
-  await updateBlameLists(configuration, commit, results);
+  updateBlameLists(configuration, commit, results);
   database.closeClient();
 }
diff --git a/tools/diff_results.dart b/tools/diff_results.dart
index 427534f..e00f65b 100644
--- a/tools/diff_results.dart
+++ b/tools/diff_results.dart
@@ -6,8 +6,8 @@
 // @dart = 2.9
 
 import 'dart:async';
-import 'dart:io';
 import 'dart:convert';
+import 'dart:io';
 
 import 'package:args/args.dart';
 import 'package:glob/glob.dart';
@@ -213,7 +213,7 @@
   int h = 0;
   while (h < diffs.length) {
     final d = diffs[h++];
-    final builders = Set<String>()..add(d.builder);
+    final builders = <String>{}..add(d.builder);
     final gropupDiffs = <Diff>[d];
 
     while (h < diffs.length) {
@@ -294,6 +294,7 @@
   Result(this.commit, this.builderName, this.buildNumber, this.name,
       this.expected, this.result);
 
+  @override
   String toString() => '(expected: $expected, actual: $result)';
 
   bool sameResult(Result other) {
@@ -310,7 +311,14 @@
     return false;
   }
 
+  @override
   int get hashCode => name.hashCode ^ builderName.hashCode;
+
+  @override
+  bool operator ==(Object other) {
+    // TODO: implement ==
+    return super == other;
+  }
 }
 
 String currentDate() {
@@ -322,7 +330,7 @@
   final contents = File('tools/bots/test_matrix.json').readAsStringSync();
   final testMatrix = json.decode(contents);
 
-  final vmBuilders = Set<String>();
+  final vmBuilders = <String>{};
   for (final config in testMatrix['builder_configurations']) {
     for (final builder in config['builders']) {
       if (builder.startsWith('vm-') || builder.startsWith('app-')) {
@@ -334,7 +342,7 @@
   // This one is in the test_matrix.json but we don't run it on CI.
   vmBuilders.remove('vm-kernel-asan-linux-release-ia32');
 
-  if (!globs.isEmpty) {
+  if (globs.isNotEmpty) {
     vmBuilders.removeWhere((String builder) {
       return !globs.any((Glob glob) => glob.matches(builder));
     });
diff --git a/tools/generate_experimental_flags.dart b/tools/generate_experimental_flags.dart
index bdb089e..3ae2858 100644
--- a/tools/generate_experimental_flags.dart
+++ b/tools/generate_experimental_flags.dart
@@ -8,12 +8,11 @@
 import 'package:yaml/yaml.dart' show YamlMap, loadYaml;
 
 void main() {
-  YamlMap yaml =
-      loadYaml(new File.fromUri(computeYamlFile()).readAsStringSync());
+  YamlMap yaml = loadYaml(File.fromUri(computeYamlFile()).readAsStringSync());
   final currentVersion = getAsVersionNumber(yaml['current-version']);
-  final enumNames = new StringBuffer();
-  final featureValues = new StringBuffer();
-  final featureNames = new StringBuffer();
+  final enumNames = StringBuffer();
+  final featureValues = StringBuffer();
+  final featureNames = StringBuffer();
 
   YamlMap features = yaml['features'];
   for (var entry in features.entries) {
@@ -112,7 +111,9 @@
 List<num> getAsVersionNumber(dynamic value) {
   if (value == null) return null;
   final version = List.of("$value".split(".").map(int.parse));
-  while (version.length < 3) version.add(0);
+  while (version.length < 3) {
+    version.add(0);
+  }
   return version;
 }
 
diff --git a/tools/generate_package_config.dart b/tools/generate_package_config.dart
index d6c7b56..4d8b3ce 100644
--- a/tools/generate_package_config.dart
+++ b/tools/generate_package_config.dart
@@ -58,7 +58,6 @@
         'runtime/observatory_2/tests/service_2/observatory_test_package_2'),
     packageDirectory('pkg/vm_service/test/test_package'),
     packageDirectory('sdk/lib/_internal/sdk_library_metadata'),
-    packageDirectory('third_party/devtools/devtools_server'),
     packageDirectory('third_party/devtools/devtools_shared'),
     packageDirectory('third_party/pkg/protobuf/protobuf'),
     packageDirectory('third_party/pkg/webdev/frontend_server_client'),
diff --git a/tools/line_doc_comments.dart b/tools/line_doc_comments.dart
index cedd1b8..e31109d 100755
--- a/tools/line_doc_comments.dart
+++ b/tools/line_doc_comments.dart
@@ -9,10 +9,10 @@
 
 import 'package:path/path.dart' as path;
 
-final oneLineBlock = new RegExp(r'^(\s*)/\*\*\s?(.*)\*/\s*$');
-final startBlock = new RegExp(r'^(\s*)/\*\*(.*)$');
-final blockLine = new RegExp(r'^\s*\*\s?(.*)$');
-final endBlock = new RegExp(r'^\s*\*/\s*$');
+final oneLineBlock = RegExp(r'^(\s*)/\*\*\s?(.*)\*/\s*$');
+final startBlock = RegExp(r'^(\s*)/\*\*(.*)$');
+final blockLine = RegExp(r'^\s*\*\s?(.*)$');
+final endBlock = RegExp(r'^\s*\*/\s*$');
 
 main(List<String> args) {
   if (args.length != 1) {
@@ -23,7 +23,7 @@
     return;
   }
 
-  var dir = new Directory(args[0]);
+  var dir = Directory(args[0]);
   dir.list(recursive: true, followLinks: false).listen((entity) {
     if (entity is File) {
       var file = entity.path;
@@ -34,19 +34,19 @@
 }
 
 void fixFile(String path) {
-  var file = new File(path);
+  var file = File(path);
   file.readAsLines().then((lines) => fixContents(lines, path)).then((fixed) {
-    return new File(path).writeAsString(fixed);
+    return File(path).writeAsString(fixed);
   }).then((file) {
     print(file.path);
   });
 }
 
 String fixContents(List<String> lines, String path) {
-  var buffer = new StringBuffer();
+  var buffer = StringBuffer();
   var linesOut = 0;
   var inBlock = false;
-  var indent;
+  String indent;
 
   for (var line in lines) {
     var oldLine = line;
@@ -104,11 +104,11 @@
 
       // Warn about lines that crossed 80 columns as a result of the change.
       if (line.length > 80 && oldLine.length <= 80) {
-        const _PURPLE = '\u001b[35m';
-        const _RED = '\u001b[31m';
-        const _NO_COLOR = '\u001b[0m';
+        const purple = '\u001b[35m';
+        const red = '\u001b[31m';
+        const reset = '\u001b[0m';
 
-        print('$_PURPLE$path$_NO_COLOR:$_RED$linesOut$_NO_COLOR: '
+        print('$purple$path$reset:$red$linesOut$reset: '
             'line exceeds 80 cols:\n    $line');
       }
 
diff --git a/tools/manage_deps.dart b/tools/manage_deps.dart
index 9c8e1c6..f954327 100755
--- a/tools/manage_deps.dart
+++ b/tools/manage_deps.dart
@@ -19,8 +19,8 @@
 library bump;
 
 import 'dart:io';
-import 'package:args/command_runner.dart';
 
+import 'package:args/command_runner.dart';
 import 'package:path/path.dart' as p;
 
 class BumpCommand extends Command<int> {
@@ -36,6 +36,7 @@
 4. Prompt to create a CL
 ''';
 
+  @override
   String get invocation =>
       './tools/manage_deps.dart bump <path/to/dependency> <options>';
 
diff --git a/tools/opt_out_files.dart b/tools/opt_out_files.dart
index 6932604..10ec4dd 100644
--- a/tools/opt_out_files.dart
+++ b/tools/opt_out_files.dart
@@ -10,7 +10,7 @@
 final languageMarker = RegExp(r"^\s*//\s*@dart\s*=");
 
 void main(List<String> args) {
-  if (args.length < 1) {
+  if (args.isEmpty) {
     print('Mark files passed on the command line or under a directory');
     print(' passed on the command line as opted out of null safety.  Does');
     print(' not mark files under directories containing a pubspec.yaml file');
diff --git a/tools/package_deps/bin/package_deps.dart b/tools/package_deps/bin/package_deps.dart
index 1bf3598..5fee3c1 100644
--- a/tools/package_deps/bin/package_deps.dart
+++ b/tools/package_deps/bin/package_deps.dart
@@ -101,6 +101,7 @@
   late final String _packageName;
   late final Set<String> _declaredDependencies;
   late final Set<String> _declaredDevDependencies;
+  // ignore: unused_field
   late final Set<String> _declaredOverrideDependencies;
   late final bool _publishToNone;
 
@@ -208,9 +209,9 @@
     //   print('  dev deps: ${devdeps}');
     // }
 
-    var out = (String message) {
+    void out(String message) {
       logger.stdout(logger.ansi.emphasized(message));
-    };
+    }
 
     var undeclaredRegularUses = Set<String>.from(deps)
       ..removeAll(_declaredDependencies);
@@ -439,6 +440,7 @@
 
   PubDep(this.name);
 
+  @override
   String toString() => name;
 
   static PubDep parse(String name, Object dep) {
@@ -461,6 +463,7 @@
 
   SemverPubDep(String name, this.value) : super(name);
 
+  @override
   String toString() => '$name: $value';
 }
 
@@ -469,6 +472,7 @@
 
   PathPubDep(String name, this.path) : super(name);
 
+  @override
   String toString() => '$name: $path';
 }
 
diff --git a/tools/spec_parser/spec_parse.dart b/tools/spec_parser/spec_parse.dart
index d94ce95..d680f6d 100755
--- a/tools/spec_parser/spec_parse.dart
+++ b/tools/spec_parser/spec_parse.dart
@@ -5,9 +5,9 @@
 
 import 'dart:io';
 
-const String ClassPath = '.:/usr/share/java/antlr3-runtime.jar';
-const String MainClass = 'SpecParser';
-const String JavaExecutable = 'java';
+const String classPath = '.:/usr/share/java/antlr3-runtime.jar';
+const String mainClass = 'SpecParser';
+const String javaExecutable = 'java';
 
 main([arguments]) {
   for (String arg in arguments) {
@@ -18,7 +18,7 @@
       print(result.stdout);
     }
 
-    List<String> javaArguments = <String>['-cp', ClassPath, MainClass, arg];
-    Process.run(JavaExecutable, javaArguments).then(handleResult);
+    List<String> javaArguments = <String>['-cp', classPath, mainClass, arg];
+    Process.run(javaExecutable, javaArguments).then(handleResult);
   }
 }
diff --git a/tools/validate_test_matrix.dart b/tools/validate_test_matrix.dart
index 9006b54..ce4e1f1 100644
--- a/tools/validate_test_matrix.dart
+++ b/tools/validate_test_matrix.dart
@@ -8,11 +8,12 @@
 
 import 'dart:convert' show jsonDecode;
 import 'dart:io' show File, Platform;
+
 import 'package:smith/smith.dart' show TestMatrix;
 
 main() {
   var path = Platform.script.resolve("bots/test_matrix.json").toFilePath();
-  var json;
+  Map<String, dynamic> json;
   try {
     json = jsonDecode(File(path).readAsStringSync());
   } catch (e) {
diff --git a/tools/verify_docs/bin/verify_docs.dart b/tools/verify_docs/bin/verify_docs.dart
index ebe1ce7..85bcdf7 100755
--- a/tools/verify_docs/bin/verify_docs.dart
+++ b/tools/verify_docs/bin/verify_docs.dart
@@ -297,7 +297,7 @@
         ..writeAllLines(lines)
         ..writeln('}');
     } else if (template == 'expression') {
-      assert(lines.length >= 1);
+      assert(lines.isNotEmpty);
       buffer
         ..writeln('void main() async =>')
         ..writeAllLines(lines.take(lines.length - 1))
@@ -375,7 +375,7 @@
         print('');
       }
     } else {
-      throw 'unexpected result type: ${result}';
+      throw 'unexpected result type: $result';
     }
 
     return;
@@ -520,7 +520,7 @@
   /// Write every line, right-trimmed, of [lines] with a newline after.
   void writeAllLines(Iterable<String> lines) {
     for (var line in lines) {
-      this.writeln(line.trimRight());
+      writeln(line.trimRight());
     }
   }
 }
diff --git a/tools/yaml2json.dart b/tools/yaml2json.dart
index ef9fcdd..b8936fe 100644
--- a/tools/yaml2json.dart
+++ b/tools/yaml2json.dart
@@ -2,16 +2,14 @@
 // 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:io' show File, exit, stderr;
-
-import 'dart:isolate' show RawReceivePort;
-
 import 'dart:convert' show JsonEncoder;
+import 'dart:io' show File, exit, stderr;
+import 'dart:isolate' show RawReceivePort;
 
 import 'package:yaml/yaml.dart' show loadYaml;
 
 main(List<String> rawArguments) {
-  var port = new RawReceivePort();
+  var port = RawReceivePort();
   bool check = false;
   String? relative;
   List<String> arguments = [];
@@ -28,12 +26,12 @@
     stderr.writeln("Usage: yaml2json.dart input.yaml output.json [--check]");
     exit(1);
   }
-  Uri input = new File(arguments[0]).absolute.uri;
-  Uri output = new File(arguments[1]).absolute.uri;
+  Uri input = File(arguments[0]).absolute.uri;
+  Uri output = File(arguments[1]).absolute.uri;
   String inputString = arguments[0];
   String outputString = arguments[1];
   if (relative != null) {
-    String relativeTo = new File(relative).absolute.uri.toString();
+    String relativeTo = File(relative).absolute.uri.toString();
     if (input.toString().startsWith(relativeTo)) {
       inputString = input.toString().substring(relativeTo.length);
     }
@@ -41,15 +39,15 @@
       outputString = output.toString().substring(relativeTo.length);
     }
   }
-  Map yaml = loadYaml(new File.fromUri(input).readAsStringSync());
-  Map<String, dynamic> result = new Map<String, dynamic>();
+  Map yaml = loadYaml(File.fromUri(input).readAsStringSync());
+  Map<String, dynamic> result = <String, dynamic>{};
   result["comment:0"] = "NOTE: THIS FILE IS GENERATED. DO NOT EDIT.";
   result["comment:1"] =
       "Instead modify '$inputString' and follow the instructions therein.";
   for (String key in yaml.keys) {
     result[key] = yaml[key];
   }
-  File file = new File.fromUri(output);
+  File file = File.fromUri(output);
   String text = const JsonEncoder.withIndent("  ").convert(result);
   if (check) {
     bool needsUpdate = true;