Version 2.14.0-217.0.dev

Merge commit 'dc116a332eefc1305684a3cc4eae88881d43646c' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4722f5c..9d9e862 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -89,32 +89,38 @@
 
 #### Linter
 
-Updated the Linter to `1.5.0`, which includes:
+Updated the Linter to `1.6.1`, which includes changes that
 
-- (internal) migrated to `SecurityLintCode` instead of deprecated
+- relax `non_constant_identifier_names` to allow for a trailing
+  underscore.
+- fix false negative in `prefer_final_parameters` where first parameter
+  is final.
+- improve `directives_ordering` sorting of directives with dot paths and 
+  dot-separated package names.
+- (internal) migrate to `SecurityLintCode` instead of deprecated
   `SecurityLintCodeWithUniqueName`.
-- (internal) fixed `avoid_types_as_parameter_names` to skip field formal
+- (internal) fix `avoid_types_as_parameter_names` to skip field formal
   parameters.
-- fixed false positives in `prefer_interpolation_to_compose_strings` where
+- fix false positives in `prefer_interpolation_to_compose_strings` where
   the left operand is not a String.
-- fixed false positives in `only_throw_errors` for misidentified type
+- fix false positives in `only_throw_errors` for misidentified type
   variables.
-- new lint: `depend_on_referenced_packages`.
+- add new lint: `depend_on_referenced_packages`.
 - update `avoid_returning_null_for_future` to skip checks for null-safe
   libraries.
-- new lint: `use_test_throws_matchers`.
-- relaxed `sort_child_properties_last` to accept closures after child.
-- performance improvements for `prefer_contains` and `prefer_is_empty`.
-- new lint: `noop_primitive_operations`.
-- marked `avoid_web_libraries_in_flutter` as stable.
-- new lint: `prefer_final_parameters`.
-- updated `prefer_initializing_formals` to allow assignments where identifier
+- add new lint: `use_test_throws_matchers`.
+- relax `sort_child_properties_last` to accept closures after child.
+- improve performance for `prefer_contains` and `prefer_is_empty`.
+- add new lint: `noop_primitive_operations`.
+- mark `avoid_web_libraries_in_flutter` as stable.
+- add new lint: `prefer_final_parameters`.
+- update `prefer_initializing_formals` to allow assignments where identifier
   names don't match.
-- `directives_ordering` now checks ordering of `package:` imports in code
+- update `directives_ordering` to checks ordering of `package:` imports in code
   outside pub packages.
-- simple reachability analysis added to `use_build_context_synchronously` to
+- add simple reachability analysis to `use_build_context_synchronously` to
   short-circuit await-discovery in terminating blocks.
-- `use_build_context_synchronously` updated to recognize nullable types when
+- update `use_build_context_synchronously` to recognize nullable types when
   accessed from legacy libraries.
 
 #### Pub
diff --git a/DEPS b/DEPS
index f63c925..8a1a74c 100644
--- a/DEPS
+++ b/DEPS
@@ -125,7 +125,7 @@
   "intl_tag": "0.17.0-nullsafety",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_rev": "7e00f893440a72de0637970325e4ea44bd1e8c8e",
-  "linter_tag": "1.5.0",
+  "linter_tag": "1.6.1",
   "lints_tag": "f9670df2a66e0ec12eb51554e70c1cbf56c8f5d0",
   "logging_rev": "e2f633b543ef89c54688554b15ca3d7e425b86a2",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 047e8b1..721f37c 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -175,6 +175,10 @@
   final Map<Folder, AnalysisDriver> driverMap =
       HashMap<Folder, AnalysisDriver>();
 
+  /// The timer that is started after creating analysis contexts, to check
+  /// for in-between changes to configuration files.
+  Timer? _collectionConsistencyCheckTimer;
+
   /// Stream subscription we are using to watch each analysis root directory for
   /// changes.
   final Map<Folder, StreamSubscription<WatchEvent>> changeSubscriptions =
@@ -461,6 +465,7 @@
     }
 
     callbacks.afterContextsCreated();
+    _scheduleCollectionConsistencyCheck(collection);
   }
 
   /// Clean up and destroy the context associated with the given folder.
@@ -482,6 +487,7 @@
   void _destroyAnalysisContexts() {
     var collection = _collection;
     if (collection != null) {
+      _collectionConsistencyCheckTimer?.cancel();
       for (var analysisContext in collection.contexts) {
         _destroyAnalysisContext(analysisContext);
       }
@@ -632,6 +638,28 @@
         existingExcludedSet.containsAll(excludedPaths);
   }
 
+  /// We create analysis contexts, and then start watching the file system
+  /// for modifications to Dart files, and to configuration files, e.g.
+  /// `pubspec.yaml` file Pub workspaces.
+  ///
+  /// So, it is possible that one of these files will be changed between the
+  /// moment when we read it, and the moment when we started watching for
+  /// changes. Using `package:watcher` before creating analysis contexts
+  /// was still not reliable enough.
+  ///
+  /// To work around this we check after a short timeout, and hope that
+  /// any subsequent changes will be noticed by `package:watcher`.
+  void _scheduleCollectionConsistencyCheck(
+    AnalysisContextCollectionImpl collection,
+  ) {
+    _collectionConsistencyCheckTimer = Timer(Duration(seconds: 1), () {
+      _collectionConsistencyCheckTimer = null;
+      if (!collection.areWorkspacesConsistent) {
+        _createAnalysisContexts();
+      }
+    });
+  }
+
   /// Starts watching for the `bazel-bin` and `blaze-bin` symlinks.
   ///
   /// This is important since these symlinks might not be present when the
diff --git a/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart b/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
index 2335ded..103c1a6 100644
--- a/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
@@ -79,6 +79,20 @@
     }
   }
 
+  /// Return `true` if the read state of configuration files is consistent
+  /// with their current state on the file system. We use this as a work
+  /// around an issue with watching for file system changes.
+  bool get areWorkspacesConsistent {
+    for (var analysisContext in contexts) {
+      var contextRoot = analysisContext.contextRoot;
+      var workspace = contextRoot.workspace;
+      if (!workspace.isConsistentWithFileSystem) {
+        return false;
+      }
+    }
+    return true;
+  }
+
   @override
   DriverBasedAnalysisContext contextFor(String path) {
     _throwIfNotAbsoluteNormalizedPath(path);
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index c01791f..d9d2a5c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -82,7 +82,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 156;
+  static const int DATA_VERSION = 157;
 
   /// The number of exception contexts allowed to write. Once this field is
   /// zero, we stop writing any new exception contexts in this process.
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 9b4fa31..098b70f 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -173,10 +173,9 @@
     }
   }
 
-  IntegerLiteral _createIntegerLiteral(int value) {
-    // TODO(scheglov) Write token?
+  IntegerLiteral _createIntegerLiteral(String lexeme, int value) {
     var node = astFactory.integerLiteral(
-      TokenFactory.tokenFromTypeAndString(TokenType.INT, '$value'),
+      TokenFactory.tokenFromTypeAndString(TokenType.INT, lexeme),
       value,
     );
     _readExpressionResolution(node);
@@ -203,7 +202,9 @@
 
   AdjacentStrings _readAdjacentStrings() {
     var components = _readNodeList<StringLiteral>();
-    return astFactory.adjacentStrings(components);
+    var node = astFactory.adjacentStrings(components);
+    _readExpressionResolution(node);
+    return node;
   }
 
   Annotation _readAnnotation() {
@@ -698,13 +699,15 @@
   }
 
   IntegerLiteral _readIntegerLiteralNegative() {
+    var lexeme = _readStringReference();
     var value = (_readUInt32() << 32) | _readUInt32();
-    return _createIntegerLiteral(-value);
+    return _createIntegerLiteral(lexeme, -value);
   }
 
   IntegerLiteral _readIntegerLiteralNegative1() {
+    var lexeme = _readStringReference();
     var value = _readByte();
-    return _createIntegerLiteral(-value);
+    return _createIntegerLiteral(lexeme, -value);
   }
 
   IntegerLiteral _readIntegerLiteralNull() {
@@ -718,13 +721,15 @@
   }
 
   IntegerLiteral _readIntegerLiteralPositive() {
+    var lexeme = _readStringReference();
     var value = (_readUInt32() << 32) | _readUInt32();
-    return _createIntegerLiteral(value);
+    return _createIntegerLiteral(lexeme, value);
   }
 
   IntegerLiteral _readIntegerLiteralPositive1() {
+    var lexeme = _readStringReference();
     var value = _readByte();
-    return _createIntegerLiteral(value);
+    return _createIntegerLiteral(lexeme, value);
   }
 
   InterpolationExpression _readInterpolationExpression() {
@@ -1053,10 +1058,12 @@
     var lexeme = _readStringReference();
     var value = _readStringReference();
 
-    return astFactory.simpleStringLiteral(
+    var node = astFactory.simpleStringLiteral(
       TokenFactory.tokenFromString(lexeme),
       value,
     );
+    _readExpressionResolution(node);
+    return node;
   }
 
   SpreadElement _readSpreadElement() {
@@ -1072,7 +1079,9 @@
 
   StringInterpolation _readStringInterpolation() {
     var elements = _readNodeList<InterpolationElement>();
-    return astFactory.stringInterpolation(elements);
+    var node = astFactory.stringInterpolation(elements);
+    _readExpressionResolution(node);
+    return node;
   }
 
   String _readStringReference() {
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 7e73650..45e78a4 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -29,6 +29,7 @@
   void visitAdjacentStrings(AdjacentStrings node) {
     _writeByte(Tag.AdjacentStrings);
     _writeNodeList(node.strings);
+    _storeExpression(node);
   }
 
   @override
@@ -397,11 +398,13 @@
               ? Tag.IntegerLiteralPositive1
               : Tag.IntegerLiteralNegative1,
         );
+        _writeStringReference(node.literal.lexeme);
         _writeByte(value);
       } else {
         _writeByte(
           isPositive ? Tag.IntegerLiteralPositive : Tag.IntegerLiteralNegative,
         );
+        _writeStringReference(node.literal.lexeme);
         _writeUInt32(value >> 32);
         _writeUInt32(value & 0xFFFFFFFF);
       }
@@ -634,6 +637,7 @@
     _writeByte(Tag.SimpleStringLiteral);
     _writeStringReference(node.literal.lexeme);
     _writeStringReference(node.value);
+    _storeExpression(node);
   }
 
   @override
@@ -652,6 +656,7 @@
   void visitStringInterpolation(StringInterpolation node) {
     _writeByte(Tag.StringInterpolation);
     _writeNodeList(node.elements);
+    _storeExpression(node);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/summary2/detach_nodes.dart b/pkg/analyzer/lib/src/summary2/detach_nodes.dart
index b4c5697..3f93f01 100644
--- a/pkg/analyzer/lib/src/summary2/detach_nodes.dart
+++ b/pkg/analyzer/lib/src/summary2/detach_nodes.dart
@@ -56,6 +56,7 @@
       element.typeInference = null;
     }
     _detachConstVariable(element);
+    super.visitPropertyInducingElement(element);
   }
 
   void _detachConstVariable(Element element) {
diff --git a/pkg/analyzer/lib/src/summary2/informative_data.dart b/pkg/analyzer/lib/src/summary2/informative_data.dart
index 62d03b7..9b1bcc9 100644
--- a/pkg/analyzer/lib/src/summary2/informative_data.dart
+++ b/pkg/analyzer/lib/src/summary2/informative_data.dart
@@ -1967,6 +1967,12 @@
   }
 
   @override
+  void visitSymbolLiteral(SymbolLiteral node) {
+    _tokenOrNull(node.poundSign);
+    node.components.forEach(_tokenOrNull);
+  }
+
+  @override
   void visitThisExpression(ThisExpression node) {
     _tokenOrNull(node.thisKeyword);
   }
diff --git a/pkg/analyzer/lib/src/workspace/package_build.dart b/pkg/analyzer/lib/src/workspace/package_build.dart
index 5d2ee1e..7e0c179 100644
--- a/pkg/analyzer/lib/src/workspace/package_build.dart
+++ b/pkg/analyzer/lib/src/workspace/package_build.dart
@@ -145,6 +145,9 @@
   /// package:build does it.
   static const String _pubspecName = 'pubspec.yaml';
 
+  /// The associated pubspec file.
+  final File _pubspecFile;
+
   /// The content of the `pubspec.yaml` file.
   /// We read it once, so that all usages return consistent results.
   final String? _pubspecContent;
@@ -185,11 +188,17 @@
     this.generatedRootPath,
     this.generatedThisPath,
     File pubspecFile,
-  ) : _pubspecContent = _fileContentOrNull(pubspecFile) {
+  )   : _pubspecFile = pubspecFile,
+        _pubspecContent = _fileContentOrNull(pubspecFile) {
     _theOnlyPackage = PackageBuildWorkspacePackage(root, this);
   }
 
   @override
+  bool get isConsistentWithFileSystem {
+    return _fileContentOrNull(_pubspecFile) == _pubspecContent;
+  }
+
+  @override
   UriResolver get packageUriResolver => PackageBuildPackageUriResolver(
       this, PackageMapUriResolver(provider, packageMap));
 
diff --git a/pkg/analyzer/lib/src/workspace/pub.dart b/pkg/analyzer/lib/src/workspace/pub.dart
index ef69e23..e5059d7 100644
--- a/pkg/analyzer/lib/src/workspace/pub.dart
+++ b/pkg/analyzer/lib/src/workspace/pub.dart
@@ -21,6 +21,9 @@
   /// Each Pub workspace is itself one package.
   late final PubWorkspacePackage _theOnlyPackage;
 
+  /// The associated pubspec file.
+  final File _pubspecFile;
+
   /// The content of the `pubspec.yaml` file.
   /// We read it once, so that all usages return consistent results.
   final String? _pubspecContent;
@@ -30,11 +33,17 @@
     Map<String, List<Folder>> packageMap,
     String root,
     File pubspecFile,
-  )   : _pubspecContent = _fileContentOrNull(pubspecFile),
+  )   : _pubspecFile = pubspecFile,
+        _pubspecContent = _fileContentOrNull(pubspecFile),
         super(provider, packageMap, root) {
     _theOnlyPackage = PubWorkspacePackage(root, this);
   }
 
+  @override
+  bool get isConsistentWithFileSystem {
+    return _fileContentOrNull(_pubspecFile) == _pubspecContent;
+  }
+
   @internal
   @override
   void contributeToResolutionSalt(ApiSignature buffer) {
diff --git a/pkg/analyzer/lib/src/workspace/workspace.dart b/pkg/analyzer/lib/src/workspace/workspace.dart
index c4cb125..34ab9c1 100644
--- a/pkg/analyzer/lib/src/workspace/workspace.dart
+++ b/pkg/analyzer/lib/src/workspace/workspace.dart
@@ -17,6 +17,11 @@
   /// Return true iff this [Workspace] is a [BazelWorkspace].
   bool get isBazel => false;
 
+  /// Return `true` if the read state of configuration files is consistent
+  /// with their current state on the file system.
+  @internal
+  bool get isConsistentWithFileSystem => true;
+
   /// The [UriResolver] that can resolve `package` URIs.
   UriResolver get packageUriResolver;
 
diff --git a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
index 730e36a..40f03e0 100644
--- a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
@@ -116,7 +116,7 @@
         staticType: A
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 80
+  atSign: @
   element: self::@class::A::@constructor::•
   name: SimpleIdentifier
     staticElement: self::@class::A
@@ -404,7 +404,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 53
+  atSign: @
   element: self::@class::A::@constructor::named
   name: PrefixedIdentifier
     identifier: SimpleIdentifier
@@ -443,7 +443,7 @@
     var annotation = findNode.annotation('@A');
     _assertResolvedNodeText(annotation, r'''
 Annotation
-  atSign.offset: 42
+  atSign: @
   element: self::@class::A::@getter::foo
   name: PrefixedIdentifier
     identifier: SimpleIdentifier
@@ -484,7 +484,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 48
+  atSign: @
   element: self::@class::A::@constructor::•
   name: SimpleIdentifier
     staticElement: self::@class::A
@@ -523,7 +523,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 54
+  atSign: @
   element: ConstructorMember
     base: self::@class::A::@constructor::named
     substitution: {T: int}
@@ -576,7 +576,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 49
+  atSign: @
   element: ConstructorMember
     base: self::@class::A::@constructor::•
     substitution: {T: int}
@@ -608,7 +608,7 @@
 
     _assertResolvedNodeText(findNode.annotation('@A'), r'''
 Annotation
-  atSign.offset: 31
+  atSign: @
   element: self::@class::A::@getter::foo
   name: PrefixedIdentifier
     identifier: SimpleIdentifier
@@ -646,7 +646,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 56
+  atSign: @
   element: ConstructorMember
     base: self::@class::A::@constructor::named
     substitution: {T: dynamic}
@@ -686,7 +686,7 @@
     var annotation = findNode.annotation('@A');
     _assertResolvedNodeText(annotation, r'''
 Annotation
-  atSign.offset: 38
+  atSign: @
   element: self::@class::A::@getter::foo
   name: PrefixedIdentifier
     identifier: SimpleIdentifier
@@ -727,7 +727,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 54
+  atSign: @
   constructorName: SimpleIdentifier
     staticElement: ConstructorMember
       base: self::@class::A::@constructor::named
@@ -784,7 +784,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 49
+  atSign: @
   element: ConstructorMember
     base: self::@class::A::@constructor::•
     substitution: {T: int}
@@ -836,7 +836,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 48
+  atSign: @
   element: ConstructorMember
     base: self::@class::A::@constructor::•
     substitution: {T: dynamic}
@@ -881,7 +881,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 88
+  atSign: @
   element: ConstructorMember
     base: self::@class::B::@constructor::•
     substitution: {T: int}
@@ -922,7 +922,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 88
+  atSign: @
   element: ConstructorMember
     base: self::@class::B::@constructor::•
     substitution: {T: int}
@@ -1055,7 +1055,7 @@
     var annotation = findNode.annotation('@prefix.B');
     _assertResolvedNodeText(annotation, r'''
 Annotation
-  atSign.offset: 28
+  atSign: @
   constructorName: SimpleIdentifier
     staticElement: package:test/a.dart::@class::A::@getter::foo
     staticType: null
@@ -1105,7 +1105,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 28
+  atSign: @
   constructorName: SimpleIdentifier
     staticElement: ConstructorMember
       base: package:test/a.dart::@class::A::@constructor::named
@@ -1166,7 +1166,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 28
+  atSign: @
   element: ConstructorMember
     base: package:test/a.dart::@class::A::@constructor::•
     substitution: {T: int}
@@ -1221,7 +1221,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 28
+  atSign: @
   constructorName: SimpleIdentifier
     staticElement: ConstructorMember
       base: package:test/a.dart::@class::A::@constructor::named
@@ -1292,7 +1292,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 28
+  atSign: @
   element: ConstructorMember
     base: package:test/a.dart::@class::A::@constructor::•
     substitution: {T: int}
@@ -1346,7 +1346,7 @@
     var annotation = findNode.annotation('@B');
     _assertResolvedNodeText(annotation, r'''
 Annotation
-  atSign.offset: 58
+  atSign: @
   element: self::@class::A::@getter::foo
   name: PrefixedIdentifier
     identifier: SimpleIdentifier
@@ -1393,7 +1393,7 @@
         staticType: double
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 108
+  atSign: @
   constructorName: SimpleIdentifier
     staticElement: ConstructorMember
       base: self::@class::A::@constructor::named
@@ -1464,7 +1464,7 @@
         staticType: double
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 102
+  atSign: @
   element: ConstructorMember
     base: self::@class::A::@constructor::•
     substitution: {T: int, U: double}
@@ -1525,7 +1525,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 76
+  atSign: @
   element: ConstructorMember
     base: self::@class::A::@constructor::named
     substitution: {T: int}
@@ -1581,7 +1581,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 70
+  atSign: @
   element: ConstructorMember
     base: self::@class::A::@constructor::•
     substitution: {T: int}
@@ -1625,7 +1625,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 76
+  atSign: @
   constructorName: SimpleIdentifier
     staticElement: ConstructorMember
       base: self::@class::A::@constructor::named
@@ -1685,7 +1685,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 70
+  atSign: @
   element: ConstructorMember
     base: self::@class::A::@constructor::•
     substitution: {T: int}
@@ -1739,7 +1739,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 75
+  atSign: @
   element: ConstructorMember
     base: self::@class::A::@constructor::named
     substitution: {T: int}
@@ -1795,7 +1795,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 69
+  atSign: @
   element: ConstructorMember
     base: self::@class::A::@constructor::•
     substitution: {T: int}
@@ -1839,7 +1839,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 69
+  atSign: @
   element: self::@class::A::@constructor::named
   name: PrefixedIdentifier
     identifier: SimpleIdentifier
@@ -1888,7 +1888,7 @@
         staticType: int
     leftParenthesis: (
     rightParenthesis: )
-  atSign.offset: 63
+  atSign: @
   element: self::@class::A::@constructor::•
   name: SimpleIdentifier
     staticElement: self::@typeAlias::B
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index ea5951a..b9c4e07 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -73,7 +73,7 @@
     _writeln('Annotation');
     _withIndent(() {
       _writeNode('arguments', node.arguments);
-      _writeOffset('atSign.offset', node.atSign.offset);
+      _writeToken('atSign', node.atSign);
       _writeNode('constructorName', node.constructorName);
       _writeElement('element', node.element);
       _writeNode('name', node.name);
@@ -1925,6 +1925,7 @@
     }
   }
 
+  /// TODO(scheglov) maybe inline?
   void _writeTokenList(String name, List<Token> tokens) {
     if (tokens.isNotEmpty) {
       _writelnWithIndent(name);
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 3ea7149..0cf4788 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -1735,7 +1735,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @39
               rightParenthesis: ) @40
-            atSign.offset: 28
+            atSign: @ @28
             element: self::@class::Annotation::@constructor::•
             name: SimpleIdentifier
               staticElement: self::@class::Annotation
@@ -1750,7 +1750,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @108
               rightParenthesis: ) @109
-            atSign.offset: 91
+            atSign: @ @91
             element: self::@class::Annotation::@constructor::named
             name: PrefixedIdentifier
               identifier: SimpleIdentifier
@@ -1773,7 +1773,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @148
               rightParenthesis: ) @149
-            atSign.offset: 137
+            atSign: @ @137
             element: self::@class::Annotation::@constructor::•
             name: SimpleIdentifier
               staticElement: self::@class::Annotation
@@ -1788,7 +1788,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @224
               rightParenthesis: ) @225
-            atSign.offset: 213
+            atSign: @ @213
             element: self::@class::Annotation::@constructor::•
             name: SimpleIdentifier
               staticElement: self::@class::Annotation
@@ -1803,7 +1803,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @290
               rightParenthesis: ) @291
-            atSign.offset: 279
+            atSign: @ @279
             element: self::@class::Annotation::@constructor::•
             name: SimpleIdentifier
               staticElement: self::@class::Annotation
@@ -4100,7 +4100,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @75
               rightParenthesis: ) @76
-            atSign.offset: 68
+            atSign: @ @68
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -4117,7 +4117,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @109
               rightParenthesis: ) @110
-            atSign.offset: 102
+            atSign: @ @102
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -4134,7 +4134,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @211
               rightParenthesis: ) @212
-            atSign.offset: 204
+            atSign: @ @204
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -4151,7 +4151,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @268
               rightParenthesis: ) @269
-            atSign.offset: 261
+            atSign: @ @261
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -4250,7 +4250,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @133
               rightParenthesis: ) @134
-            atSign.offset: 126
+            atSign: @ @126
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -4278,7 +4278,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @184
               rightParenthesis: ) @185
-            atSign.offset: 177
+            atSign: @ @177
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -4306,7 +4306,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @303
               rightParenthesis: ) @304
-            atSign.offset: 296
+            atSign: @ @296
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -4334,7 +4334,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @377
               rightParenthesis: ) @378
-            atSign.offset: 370
+            atSign: @ @370
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -4419,7 +4419,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @99
                   rightParenthesis: ) @100
-                atSign.offset: 92
+                atSign: @ @92
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -4436,7 +4436,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @135
                   rightParenthesis: ) @136
-                atSign.offset: 128
+                atSign: @ @128
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -4453,7 +4453,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @247
                   rightParenthesis: ) @248
-                atSign.offset: 240
+                atSign: @ @240
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -4470,7 +4470,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @308
                   rightParenthesis: ) @309
-                atSign.offset: 301
+                atSign: @ @301
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -4544,7 +4544,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @152
                   rightParenthesis: ) @153
-                atSign.offset: 145
+                atSign: @ @145
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -4561,7 +4561,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @205
                   rightParenthesis: ) @206
-                atSign.offset: 198
+                atSign: @ @198
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -4578,7 +4578,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @334
                   rightParenthesis: ) @335
-                atSign.offset: 327
+                atSign: @ @327
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -4595,7 +4595,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @412
                   rightParenthesis: ) @413
-                atSign.offset: 405
+                atSign: @ @405
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -4714,7 +4714,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @105
               rightParenthesis: ) @106
-            atSign.offset: 98
+            atSign: @ @98
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -4730,7 +4730,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @148
               rightParenthesis: ) @149
-            atSign.offset: 141
+            atSign: @ @141
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -4746,7 +4746,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @259
               rightParenthesis: ) @260
-            atSign.offset: 252
+            atSign: @ @252
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -4762,7 +4762,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @325
               rightParenthesis: ) @326
-            atSign.offset: 318
+            atSign: @ @318
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -4909,7 +4909,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @91
                   rightParenthesis: ) @92
-                atSign.offset: 84
+                atSign: @ @84
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -4924,7 +4924,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @91
                   rightParenthesis: ) @92
-                atSign.offset: 84
+                atSign: @ @84
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -4940,7 +4940,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @141
                   rightParenthesis: ) @142
-                atSign.offset: 134
+                atSign: @ @134
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -4956,7 +4956,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @141
                   rightParenthesis: ) @142
-                atSign.offset: 134
+                atSign: @ @134
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -4972,7 +4972,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @275
                   rightParenthesis: ) @276
-                atSign.offset: 268
+                atSign: @ @268
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -4988,7 +4988,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @275
                   rightParenthesis: ) @276
-                atSign.offset: 268
+                atSign: @ @268
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -5004,7 +5004,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @358
                   rightParenthesis: ) @359
-                atSign.offset: 351
+                atSign: @ @351
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -5020,7 +5020,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @358
                   rightParenthesis: ) @359
-                atSign.offset: 351
+                atSign: @ @351
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -5153,7 +5153,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @77
               rightParenthesis: ) @78
-            atSign.offset: 70
+            atSign: @ @70
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5169,7 +5169,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @112
               rightParenthesis: ) @113
-            atSign.offset: 105
+            atSign: @ @105
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5185,7 +5185,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @215
               rightParenthesis: ) @216
-            atSign.offset: 208
+            atSign: @ @208
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5201,7 +5201,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @273
               rightParenthesis: ) @274
-            atSign.offset: 266
+            atSign: @ @266
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5265,7 +5265,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @79
               rightParenthesis: ) @80
-            atSign.offset: 72
+            atSign: @ @72
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5283,7 +5283,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @115
               rightParenthesis: ) @116
-            atSign.offset: 108
+            atSign: @ @108
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5301,7 +5301,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @219
               rightParenthesis: ) @220
-            atSign.offset: 212
+            atSign: @ @212
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5319,7 +5319,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @278
               rightParenthesis: ) @279
-            atSign.offset: 271
+            atSign: @ @271
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5385,7 +5385,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @101
               rightParenthesis: ) @102
-            atSign.offset: 94
+            atSign: @ @94
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5403,7 +5403,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @148
               rightParenthesis: ) @149
-            atSign.offset: 141
+            atSign: @ @141
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5421,7 +5421,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @263
               rightParenthesis: ) @264
-            atSign.offset: 256
+            atSign: @ @256
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5439,7 +5439,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @333
               rightParenthesis: ) @334
-            atSign.offset: 326
+            atSign: @ @326
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5509,7 +5509,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @97
                   rightParenthesis: ) @98
-                atSign.offset: 90
+                atSign: @ @90
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -5525,7 +5525,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @136
                   rightParenthesis: ) @137
-                atSign.offset: 129
+                atSign: @ @129
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -5541,7 +5541,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @251
                   rightParenthesis: ) @252
-                atSign.offset: 244
+                atSign: @ @244
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -5557,7 +5557,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @315
                   rightParenthesis: ) @316
-                atSign.offset: 308
+                atSign: @ @308
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -5615,7 +5615,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @12
                   rightParenthesis: ) @13
-                atSign.offset: 5
+                atSign: @ @5
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -5630,7 +5630,7 @@
                 arguments: ArgumentList
                   leftParenthesis: ( @36
                   rightParenthesis: ) @37
-                atSign.offset: 29
+                atSign: @ @29
                 element: dart:core::@class::Object::@constructor::•
                 name: SimpleIdentifier
                   staticElement: dart:core::@class::Object
@@ -5760,7 +5760,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @73
               rightParenthesis: ) @74
-            atSign.offset: 66
+            atSign: @ @66
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5775,7 +5775,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @73
               rightParenthesis: ) @74
-            atSign.offset: 66
+            atSign: @ @66
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5791,7 +5791,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @119
               rightParenthesis: ) @120
-            atSign.offset: 112
+            atSign: @ @112
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5807,7 +5807,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @119
               rightParenthesis: ) @120
-            atSign.offset: 112
+            atSign: @ @112
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5823,7 +5823,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @241
               rightParenthesis: ) @242
-            atSign.offset: 234
+            atSign: @ @234
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5839,7 +5839,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @241
               rightParenthesis: ) @242
-            atSign.offset: 234
+            atSign: @ @234
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5855,7 +5855,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @318
               rightParenthesis: ) @319
-            atSign.offset: 311
+            atSign: @ @311
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -5871,7 +5871,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @318
               rightParenthesis: ) @319
-            atSign.offset: 311
+            atSign: @ @311
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -10660,19 +10660,19 @@
         type: int
         constantInitializer
           IntegerLiteral
-            literal: 9223372036854775807 @137
+            literal: 0x7FFFFFFFFFFFFFFF @137
             staticType: int
       static const vIntLong2 @163
         type: int
         constantInitializer
           IntegerLiteral
-            literal: -1 @175
+            literal: 0xFFFFFFFFFFFFFFFF @175
             staticType: int
       static const vIntLong3 @201
         type: int
         constantInitializer
           IntegerLiteral
-            literal: -9223372036854775808 @213
+            literal: 0x8000000000000000 @213
             staticType: int
       static const vDouble @239
         type: double
@@ -10689,7 +10689,7 @@
         type: String
         constantInitializer
           AdjacentStrings
-            staticType: null
+            staticType: String
             stringValue: aaabbb
             strings
               SimpleStringLiteral
@@ -10719,7 +10719,7 @@
                 rightBracket: } @358
               InterpolationString
                 contents:  bbb' @359
-            staticType: null
+            staticType: String
             stringValue: null
       static const vSymbol @372
         type: Symbol
@@ -10727,12 +10727,12 @@
           SymbolLiteral
             components
               components: aaa
-                offset: 0
+                offset: 383
               components: bbb
-                offset: 0
+                offset: 387
               components: ccc
-                offset: 0
-            poundSign: # @0
+                offset: 391
+            poundSign: # @382
     accessors
       synthetic static get vNull @-1
         returnType: dynamic
@@ -14748,7 +14748,7 @@
             documentationComment: /**\n   * aaa\n   */
             metadata
               Annotation
-                atSign.offset: 32
+                atSign: @ @32
                 element: self::@getter::annotation
                 name: SimpleIdentifier
                   staticElement: self::@getter::annotation
@@ -14759,7 +14759,7 @@
             documentationComment: /// bbb
             metadata
               Annotation
-                atSign.offset: 61
+                atSign: @ @61
                 element: self::@getter::annotation
                 name: SimpleIdentifier
                   staticElement: self::@getter::annotation
@@ -17243,7 +17243,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @55
               rightParenthesis: ) @56
-            atSign.offset: 29
+            atSign: @ @29
             element: ConstructorMember
               base: self::@class::A::@constructor::•
               substitution: {T: dynamic}
@@ -17317,7 +17317,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @55
               rightParenthesis: ) @56
-            atSign.offset: 29
+            atSign: @ @29
             element: ConstructorMember
               base: self::@class::A::@constructor::•
               substitution: {T: dynamic}
@@ -18320,7 +18320,7 @@
 library
   metadata
     Annotation
-      atSign.offset: 0
+      atSign: @ @0
       element: <null>
       name: SimpleIdentifier
         staticElement: <null>
@@ -18330,7 +18330,7 @@
     <unresolved>
       metadata
         Annotation
-          atSign.offset: 0
+          atSign: @ @0
           element: <null>
           name: SimpleIdentifier
             staticElement: <null>
@@ -20640,7 +20640,7 @@
       class C @39
         metadata
           Annotation
-            atSign.offset: 22
+            atSign: @ @22
             constructorName: SimpleIdentifier
               staticElement: package:test/a.dart::@class::A::@constructor::named
               staticType: null
@@ -20684,7 +20684,7 @@
       class C @32
         metadata
           Annotation
-            atSign.offset: 17
+            atSign: @ @17
             element: package:test/a.dart::@class::A::@constructor::named
             name: PrefixedIdentifier
               identifier: SimpleIdentifier
@@ -21354,7 +21354,7 @@
           x @34
             metadata
               Annotation
-                atSign.offset: 25
+                atSign: @ @25
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
@@ -21402,7 +21402,7 @@
       class C @27
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::foo
             name: SimpleIdentifier
               staticElement: self::@getter::foo
@@ -21413,7 +21413,7 @@
             defaultType: dynamic
             metadata
               Annotation
-                atSign.offset: 29
+                atSign: @ @29
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -21435,7 +21435,7 @@
           bar @77
             metadata
               Annotation
-                atSign.offset: 65
+                atSign: @ @65
                 element: self::@class::C::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@class::C::@getter::foo
@@ -21469,14 +21469,14 @@
       class C @44
         metadata
           Annotation
-            atSign.offset: 32
+            atSign: @ @32
             element: self::@getter::a
             name: SimpleIdentifier
               staticElement: self::@getter::a
               staticType: null
               token: a @33
           Annotation
-            atSign.offset: 35
+            atSign: @ @35
             element: self::@getter::b
             name: SimpleIdentifier
               staticElement: self::@getter::b
@@ -21515,7 +21515,7 @@
       class alias C @25
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::a
             name: SimpleIdentifier
               staticElement: self::@getter::a
@@ -21583,7 +21583,7 @@
                   staticType: int
               leftParenthesis: ( @44
               rightParenthesis: ) @46
-            atSign.offset: 36
+            atSign: @ @36
             element: self::@class::A::@constructor::named
             name: PrefixedIdentifier
               identifier: SimpleIdentifier
@@ -21637,7 +21637,7 @@
                   staticType: int
               leftParenthesis: ( @46
               rightParenthesis: ) @48
-            atSign.offset: 38
+            atSign: @ @38
             element: ConstructorMember
               base: self::@class::A::@constructor::named
               substitution: {T: int}
@@ -21690,7 +21690,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @48
               rightParenthesis: ) @49
-            atSign.offset: 35
+            atSign: @ @35
             constructorName: SimpleIdentifier
               staticElement: ConstructorMember
                 base: self::@class::A::@constructor::named
@@ -21746,7 +21746,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @48
               rightParenthesis: ) @49
-            atSign.offset: 35
+            atSign: @ @35
             constructorName: SimpleIdentifier
               staticElement: ConstructorMember
                 base: self::@class::A::@constructor::named
@@ -21803,7 +21803,7 @@
                   staticType: int
               leftParenthesis: ( @38
               rightParenthesis: ) @40
-            atSign.offset: 26
+            atSign: @ @26
             constructorName: SimpleIdentifier
               staticElement: package:test/foo.dart::@class::A::@constructor::named
               staticType: null
@@ -21855,7 +21855,7 @@
                   staticType: int
               leftParenthesis: ( @38
               rightParenthesis: ) @40
-            atSign.offset: 26
+            atSign: @ @26
             constructorName: SimpleIdentifier
               staticElement: ConstructorMember
                 base: package:test/foo.dart::@class::A::@constructor::named
@@ -21907,7 +21907,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @43
               rightParenthesis: ) @44
-            atSign.offset: 26
+            atSign: @ @26
             constructorName: SimpleIdentifier
               staticElement: ConstructorMember
                 base: package:test/foo.dart::@class::A::@constructor::named
@@ -21993,7 +21993,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @76
               rightParenthesis: ) @77
-            atSign.offset: 68
+            atSign: @ @68
             element: ConstructorMember
               base: self::@class::C::@constructor::named
               substitution: {T: dynamic}
@@ -22053,7 +22053,7 @@
                   staticType: int
               leftParenthesis: ( @32
               rightParenthesis: ) @34
-            atSign.offset: 30
+            atSign: @ @30
             element: self::@class::A::@constructor::•
             name: SimpleIdentifier
               staticElement: self::@class::A
@@ -22097,7 +22097,7 @@
                   staticType: int
               leftParenthesis: ( @34
               rightParenthesis: ) @36
-            atSign.offset: 32
+            atSign: @ @32
             element: ConstructorMember
               base: self::@class::A::@constructor::•
               substitution: {T: int}
@@ -22136,7 +22136,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @36
               rightParenthesis: ) @37
-            atSign.offset: 29
+            atSign: @ @29
             element: ConstructorMember
               base: self::@class::A::@constructor::•
               substitution: {T: int}
@@ -22180,7 +22180,7 @@
                   staticType: int
               leftParenthesis: ( @32
               rightParenthesis: ) @34
-            atSign.offset: 26
+            atSign: @ @26
             element: package:test/foo.dart::@class::A::@constructor::•
             name: PrefixedIdentifier
               identifier: SimpleIdentifier
@@ -22228,7 +22228,7 @@
                   staticType: int
               leftParenthesis: ( @32
               rightParenthesis: ) @34
-            atSign.offset: 26
+            atSign: @ @26
             element: ConstructorMember
               base: package:test/foo.dart::@class::A::@constructor::•
               substitution: {T: int}
@@ -22274,7 +22274,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @37
               rightParenthesis: ) @38
-            atSign.offset: 26
+            atSign: @ @26
             element: ConstructorMember
               base: package:test/foo.dart::@class::A::@constructor::•
               substitution: {T: int}
@@ -22347,7 +22347,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @64
               rightParenthesis: ) @65
-            atSign.offset: 62
+            atSign: @ @62
             element: ConstructorMember
               base: self::@class::C::@constructor::•
               substitution: {T: dynamic}
@@ -22389,7 +22389,7 @@
                   staticType: Null
               leftParenthesis: ( @26
               rightParenthesis: ) @31
-            atSign.offset: 24
+            atSign: @ @24
             element: self::@class::A::@constructor::•
             name: SimpleIdentifier
               staticElement: self::@class::A
@@ -22412,7 +22412,7 @@
           named @31
             metadata
               Annotation
-                atSign.offset: 26
+                atSign: @ @26
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
@@ -22444,7 +22444,7 @@
           @29
             metadata
               Annotation
-                atSign.offset: 26
+                atSign: @ @26
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
@@ -22478,7 +22478,7 @@
           static const v @26
             metadata
               Annotation
-                atSign.offset: 23
+                atSign: @ @23
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
@@ -22554,7 +22554,7 @@
                       staticType: int
                   leftParenthesis: ( @72
                   rightParenthesis: ) @76
-                atSign.offset: 70
+                atSign: @ @70
                 element: self::@class::A::@constructor::•
                 name: SimpleIdentifier
                   staticElement: self::@class::A
@@ -22573,7 +22573,7 @@
                       staticType: int
                   leftParenthesis: ( @90
                   rightParenthesis: ) @94
-                atSign.offset: 88
+                atSign: @ @88
                 element: self::@class::A::@constructor::•
                 name: SimpleIdentifier
                   staticElement: self::@class::A
@@ -22606,7 +22606,7 @@
       enum E @22
         metadata
           Annotation
-            atSign.offset: 14
+            atSign: @ @14
             element: self::@getter::a
             name: SimpleIdentifier
               staticElement: self::@getter::a
@@ -22649,7 +22649,7 @@
 library
   metadata
     Annotation
-      atSign.offset: 0
+      atSign: @ @0
       element: self::@getter::a
       name: SimpleIdentifier
         staticElement: self::@getter::a
@@ -22659,7 +22659,7 @@
     foo.dart
       metadata
         Annotation
-          atSign.offset: 0
+          atSign: @ @0
           element: self::@getter::a
           name: SimpleIdentifier
             staticElement: self::@getter::a
@@ -22697,7 +22697,7 @@
       E @31
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::foo
             name: SimpleIdentifier
               staticElement: self::@getter::foo
@@ -22707,7 +22707,7 @@
           covariant T @38
             metadata
               Annotation
-                atSign.offset: 33
+                atSign: @ @33
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -22728,7 +22728,7 @@
           bar @88
             metadata
               Annotation
-                atSign.offset: 76
+                atSign: @ @76
                 element: self::@extension::E::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@extension::E::@getter::foo
@@ -22766,7 +22766,7 @@
       E @50
         metadata
           Annotation
-            atSign.offset: 27
+            atSign: @ @27
             element: self::@getter::a
             name: SimpleIdentifier
               staticElement: self::@getter::a
@@ -22776,7 +22776,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @37
               rightParenthesis: ) @38
-            atSign.offset: 30
+            atSign: @ @30
             element: dart:core::@class::Object::@constructor::•
             name: SimpleIdentifier
               staticElement: dart:core::@class::Object
@@ -22807,7 +22807,7 @@
           x @33
             metadata
               Annotation
-                atSign.offset: 26
+                atSign: @ @26
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
@@ -22860,7 +22860,7 @@
                 type: dynamic
                 metadata
                   Annotation
-                    atSign.offset: 39
+                    atSign: @ @39
                     element: self::@getter::a
                     name: SimpleIdentifier
                       staticElement: self::@getter::a
@@ -22905,7 +22905,7 @@
                 type: dynamic
                 metadata
                   Annotation
-                    atSign.offset: 36
+                    atSign: @ @36
                     element: self::@getter::a
                     name: SimpleIdentifier
                       staticElement: self::@getter::a
@@ -22959,7 +22959,7 @@
       f @19
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::a
             name: SimpleIdentifier
               staticElement: self::@getter::a
@@ -22989,7 +22989,7 @@
       get f @23
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::a
             name: SimpleIdentifier
               staticElement: self::@getter::a
@@ -23019,7 +23019,7 @@
       set f @23
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::a
             name: SimpleIdentifier
               staticElement: self::@getter::a
@@ -23041,7 +23041,7 @@
       functionTypeAliasBased F @27
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::a
             name: SimpleIdentifier
               staticElement: self::@getter::a
@@ -23085,7 +23085,7 @@
             type: dynamic Function()
             metadata
               Annotation
-                atSign.offset: 18
+                atSign: @ @18
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
@@ -23117,7 +23117,7 @@
             type: dynamic Function()
             metadata
               Annotation
-                atSign.offset: 19
+                atSign: @ @19
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
@@ -23145,14 +23145,14 @@
       F @46
         metadata
           Annotation
-            atSign.offset: 32
+            atSign: @ @32
             element: self::@getter::a
             name: SimpleIdentifier
               staticElement: self::@getter::a
               staticType: null
               token: a @33
           Annotation
-            atSign.offset: 35
+            atSign: @ @35
             element: self::@getter::b
             name: SimpleIdentifier
               staticElement: self::@getter::b
@@ -23192,7 +23192,7 @@
 library
   metadata
     Annotation
-      atSign.offset: 0
+      atSign: @ @0
       element: self::@getter::a
       name: SimpleIdentifier
         staticElement: self::@getter::a
@@ -23202,7 +23202,7 @@
     dart:math
       metadata
         Annotation
-          atSign.offset: 0
+          atSign: @ @0
           element: self::@getter::a
           name: SimpleIdentifier
             staticElement: self::@getter::a
@@ -23233,7 +23233,7 @@
 library
   metadata
     Annotation
-      atSign.offset: 0
+      atSign: @ @0
       element: self::@getter::a
       name: SimpleIdentifier
         staticElement: self::@getter::a
@@ -23243,7 +23243,7 @@
     dart:math
       metadata
         Annotation
-          atSign.offset: 0
+          atSign: @ @0
           element: self::@getter::a
           name: SimpleIdentifier
             staticElement: self::@getter::a
@@ -23282,7 +23282,7 @@
               type: int
               metadata
                 Annotation
-                  atSign.offset: 40
+                  atSign: @ @40
                   element: self::@getter::a
                   name: SimpleIdentifier
                     staticElement: self::@getter::a
@@ -23322,7 +23322,7 @@
                   type: int
                   metadata
                     Annotation
-                      atSign.offset: 48
+                      atSign: @ @48
                       element: self::@getter::a
                       name: SimpleIdentifier
                         staticElement: self::@getter::a
@@ -23358,7 +23358,7 @@
             covariant T @43
               metadata
                 Annotation
-                  atSign.offset: 40
+                  atSign: @ @40
                   element: self::@getter::a
                   name: SimpleIdentifier
                     staticElement: self::@getter::a
@@ -23397,7 +23397,7 @@
                   staticType: int
               leftParenthesis: ( @10
               rightParenthesis: ) @13
-            atSign.offset: 8
+            atSign: @ @8
             element: self::@function::f
             name: SimpleIdentifier
               staticElement: self::@function::f
@@ -23422,7 +23422,7 @@
   nameOffset: 11
   metadata
     Annotation
-      atSign.offset: 0
+      atSign: @ @0
       element: self::@getter::a
       name: SimpleIdentifier
         staticElement: self::@getter::a
@@ -23459,7 +23459,7 @@
           get m @33
             metadata
               Annotation
-                atSign.offset: 26
+                atSign: @ @26
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
@@ -23500,14 +23500,14 @@
           m @54
             metadata
               Annotation
-                atSign.offset: 44
+                atSign: @ @44
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
                   staticType: null
                   token: a @45
               Annotation
-                atSign.offset: 49
+                atSign: @ @49
                 element: self::@getter::b
                 name: SimpleIdentifier
                   staticElement: self::@getter::b
@@ -23558,14 +23558,14 @@
           m @54
             metadata
               Annotation
-                atSign.offset: 44
+                atSign: @ @44
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
                   staticType: null
                   token: a @45
               Annotation
-                atSign.offset: 49
+                atSign: @ @49
                 element: self::@getter::b
                 name: SimpleIdentifier
                   staticElement: self::@getter::b
@@ -23615,7 +23615,7 @@
           set m @37
             metadata
               Annotation
-                atSign.offset: 28
+                atSign: @ @28
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
@@ -23656,7 +23656,7 @@
       mixin M @27
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::foo
             name: SimpleIdentifier
               staticElement: self::@getter::foo
@@ -23667,7 +23667,7 @@
             defaultType: dynamic
             metadata
               Annotation
-                atSign.offset: 29
+                atSign: @ @29
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -23691,7 +23691,7 @@
           bar @77
             metadata
               Annotation
-                atSign.offset: 65
+                atSign: @ @65
                 element: self::@mixin::M::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@mixin::M::@getter::foo
@@ -23725,14 +23725,14 @@
       mixin M @44
         metadata
           Annotation
-            atSign.offset: 32
+            atSign: @ @32
             element: self::@getter::a
             name: SimpleIdentifier
               staticElement: self::@getter::a
               staticType: null
               token: a @33
           Annotation
-            atSign.offset: 35
+            atSign: @ @35
             element: self::@getter::b
             name: SimpleIdentifier
               staticElement: self::@getter::b
@@ -23777,7 +23777,7 @@
       class A @27
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::foo
             name: SimpleIdentifier
               staticElement: self::@getter::foo
@@ -23788,7 +23788,7 @@
             defaultType: dynamic
             metadata
               Annotation
-                atSign.offset: 29
+                atSign: @ @29
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -23828,7 +23828,7 @@
           @35
             metadata
               Annotation
-                atSign.offset: 28
+                atSign: @ @28
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -23839,7 +23839,7 @@
                 type: int
                 metadata
                   Annotation
-                    atSign.offset: 37
+                    atSign: @ @37
                     element: self::@getter::foo
                     name: SimpleIdentifier
                       staticElement: self::@getter::foo
@@ -23881,7 +23881,7 @@
           get getter @43
             metadata
               Annotation
-                atSign.offset: 28
+                atSign: @ @28
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -23922,7 +23922,7 @@
           method @40
             metadata
               Annotation
-                atSign.offset: 28
+                atSign: @ @28
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -23932,7 +23932,7 @@
               covariant T @52
                 metadata
                   Annotation
-                    atSign.offset: 47
+                    atSign: @ @47
                     element: self::@getter::foo
                     name: SimpleIdentifier
                       staticElement: self::@getter::foo
@@ -23943,7 +23943,7 @@
                 type: int
                 metadata
                   Annotation
-                    atSign.offset: 55
+                    atSign: @ @55
                     element: self::@getter::foo
                     name: SimpleIdentifier
                       staticElement: self::@getter::foo
@@ -23987,7 +23987,7 @@
           set setter @39
             metadata
               Annotation
-                atSign.offset: 28
+                atSign: @ @28
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -23998,7 +23998,7 @@
                 type: int
                 metadata
                   Annotation
-                    atSign.offset: 46
+                    atSign: @ @46
                     element: self::@getter::foo
                     name: SimpleIdentifier
                       staticElement: self::@getter::foo
@@ -24038,7 +24038,7 @@
       class alias B @50
         metadata
           Annotation
-            atSign.offset: 39
+            atSign: @ @39
             element: self::@getter::foo
             name: SimpleIdentifier
               staticElement: self::@getter::foo
@@ -24049,7 +24049,7 @@
             defaultType: dynamic
             metadata
               Annotation
-                atSign.offset: 52
+                atSign: @ @52
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -24104,7 +24104,7 @@
       enum E @26
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::foo
             name: SimpleIdentifier
               staticElement: self::@getter::foo
@@ -24118,7 +24118,7 @@
           static const e1 @37
             metadata
               Annotation
-                atSign.offset: 32
+                atSign: @ @32
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -24130,7 +24130,7 @@
           static const e3 @54
             metadata
               Annotation
-                atSign.offset: 49
+                atSign: @ @49
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -24178,7 +24178,7 @@
       E @31
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::foo
             name: SimpleIdentifier
               staticElement: self::@getter::foo
@@ -24188,7 +24188,7 @@
           covariant T @38
             metadata
               Annotation
-                atSign.offset: 33
+                atSign: @ @33
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -24232,7 +24232,7 @@
           static isStatic @42
             metadata
               Annotation
-                atSign.offset: 28
+                atSign: @ @28
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -24242,7 +24242,7 @@
           static const isStaticConst @79
             metadata
               Annotation
-                atSign.offset: 59
+                atSign: @ @59
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -24256,7 +24256,7 @@
           isInstance @112
             metadata
               Annotation
-                atSign.offset: 101
+                atSign: @ @101
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -24310,7 +24310,7 @@
   documentationComment: /// Some documentation.
   metadata
     Annotation
-      atSign.offset: 24
+      atSign: @ @24
       element: self::@getter::foo
       name: SimpleIdentifier
         staticElement: self::@getter::foo
@@ -24344,7 +24344,7 @@
       mixin A @27
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::foo
             name: SimpleIdentifier
               staticElement: self::@getter::foo
@@ -24355,7 +24355,7 @@
             defaultType: dynamic
             metadata
               Annotation
-                atSign.offset: 29
+                atSign: @ @29
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -24392,7 +24392,7 @@
       functionTypeAliasBased F @34
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::foo
             name: SimpleIdentifier
               staticElement: self::@getter::foo
@@ -24403,7 +24403,7 @@
             defaultType: dynamic
             metadata
               Annotation
-                atSign.offset: 36
+                atSign: @ @36
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -24416,7 +24416,7 @@
               type: int
               metadata
                 Annotation
-                  atSign.offset: 44
+                  atSign: @ @44
                   element: self::@getter::foo
                   name: SimpleIdentifier
                     staticElement: self::@getter::foo
@@ -24450,7 +24450,7 @@
       A @29
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::foo
             name: SimpleIdentifier
               staticElement: self::@getter::foo
@@ -24461,7 +24461,7 @@
             defaultType: dynamic
             metadata
               Annotation
-                atSign.offset: 31
+                atSign: @ @31
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -24473,7 +24473,7 @@
             covariant U @60
               metadata
                 Annotation
-                  atSign.offset: 55
+                  atSign: @ @55
                   element: self::@getter::foo
                   name: SimpleIdentifier
                     staticElement: self::@getter::foo
@@ -24484,7 +24484,7 @@
               type: int
               metadata
                 Annotation
-                  atSign.offset: 63
+                  atSign: @ @63
                   element: self::@getter::foo
                   name: SimpleIdentifier
                     staticElement: self::@getter::foo
@@ -24543,7 +24543,7 @@
     a.dart
       metadata
         Annotation
-          atSign.offset: 17
+          atSign: @ @17
           element: self::@getter::foo
           name: SimpleIdentifier
             staticElement: self::@getter::foo
@@ -24552,7 +24552,7 @@
     b.dart
       metadata
         Annotation
-          atSign.offset: 38
+          atSign: @ @38
           element: self::@getter::foo
           name: SimpleIdentifier
             staticElement: self::@getter::foo
@@ -24586,7 +24586,7 @@
       f @26
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::foo
             name: SimpleIdentifier
               staticElement: self::@getter::foo
@@ -24596,7 +24596,7 @@
           covariant T @33
             metadata
               Annotation
-                atSign.offset: 28
+                atSign: @ @28
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -24607,7 +24607,7 @@
             type: int?
             metadata
               Annotation
-                atSign.offset: 37
+                atSign: @ @37
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -24646,7 +24646,7 @@
       get getter @29
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::foo
             name: SimpleIdentifier
               staticElement: self::@getter::foo
@@ -24682,7 +24682,7 @@
       set setter @25
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::foo
             name: SimpleIdentifier
               staticElement: self::@getter::foo
@@ -24693,7 +24693,7 @@
             type: int
             metadata
               Annotation
-                atSign.offset: 32
+                atSign: @ @32
                 element: self::@getter::foo
                 name: SimpleIdentifier
                   staticElement: self::@getter::foo
@@ -24726,7 +24726,7 @@
       static isNotConst @25
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::foo
             name: SimpleIdentifier
               staticElement: self::@getter::foo
@@ -24736,7 +24736,7 @@
       static const isConst @53
         metadata
           Annotation
-            atSign.offset: 42
+            atSign: @ @42
             element: self::@getter::foo
             name: SimpleIdentifier
               staticElement: self::@getter::foo
@@ -24788,7 +24788,7 @@
     foo.dart
       metadata
         Annotation
-          atSign.offset: 11
+          atSign: @ @11
           element: self::@getter::a
           name: SimpleIdentifier
             staticElement: self::@getter::a
@@ -24826,7 +24826,7 @@
       class C @33
         metadata
           Annotation
-            atSign.offset: 22
+            atSign: @ @22
             element: a.dart::@getter::b
             name: PrefixedIdentifier
               identifier: SimpleIdentifier
@@ -24867,7 +24867,7 @@
             type: dynamic
             metadata
               Annotation
-                atSign.offset: 18
+                atSign: @ @18
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
@@ -24899,7 +24899,7 @@
                 type: dynamic
                 metadata
                   Annotation
-                    atSign.offset: 31
+                    atSign: @ @31
                     element: self::@getter::a
                     name: SimpleIdentifier
                       staticElement: self::@getter::a
@@ -24946,7 +24946,7 @@
             type: int
             metadata
               Annotation
-                atSign.offset: 25
+                atSign: @ @25
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
@@ -24978,7 +24978,7 @@
             type: dynamic
             metadata
               Annotation
-                atSign.offset: 19
+                atSign: @ @19
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
@@ -25007,7 +25007,7 @@
       static v @23
         metadata
           Annotation
-            atSign.offset: 16
+            atSign: @ @16
             element: self::@getter::a
             name: SimpleIdentifier
               staticElement: self::@getter::a
@@ -25039,7 +25039,7 @@
             defaultType: dynamic
             metadata
               Annotation
-                atSign.offset: 24
+                atSign: @ @24
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
@@ -25076,7 +25076,7 @@
             defaultType: dynamic
             metadata
               Annotation
-                atSign.offset: 24
+                atSign: @ @24
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
@@ -25134,7 +25134,7 @@
           covariant T @21
             metadata
               Annotation
-                atSign.offset: 18
+                atSign: @ @18
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
@@ -25156,7 +25156,7 @@
             defaultType: dynamic
             metadata
               Annotation
-                atSign.offset: 26
+                atSign: @ @26
                 element: self::@getter::a
                 name: SimpleIdentifier
                   staticElement: self::@getter::a
@@ -25202,7 +25202,7 @@
       static x @20
         metadata
           Annotation
-            atSign.offset: 13
+            atSign: @ @13
             element: self::@getter::a
             name: SimpleIdentifier
               staticElement: self::@getter::a
@@ -25251,7 +25251,7 @@
       class C @45
         metadata
           Annotation
-            atSign.offset: 34
+            atSign: @ @34
             element: self::@class::A::@getter::x
             name: PrefixedIdentifier
               identifier: SimpleIdentifier
@@ -25284,7 +25284,7 @@
       class C @28
         metadata
           Annotation
-            atSign.offset: 17
+            atSign: @ @17
             element: self::@enum::E::@getter::b
             name: PrefixedIdentifier
               identifier: SimpleIdentifier
@@ -25346,7 +25346,7 @@
       class C @56
         metadata
           Annotation
-            atSign.offset: 45
+            atSign: @ @45
             element: self::@extension::E::@getter::x
             name: PrefixedIdentifier
               identifier: SimpleIdentifier
@@ -25399,7 +25399,7 @@
       class C @41
         metadata
           Annotation
-            atSign.offset: 26
+            atSign: @ @26
             constructorName: SimpleIdentifier
               staticElement: package:test/foo.dart::@extension::E::@getter::x
               staticType: null
@@ -32261,7 +32261,7 @@
                   superKeyword: super @30
               leftParenthesis: ( @29
               rightParenthesis: ) @35
-            atSign.offset: 27
+            atSign: @ @27
             element: self::@class::A::@constructor::•
             name: SimpleIdentifier
               staticElement: self::@class::A
@@ -32301,7 +32301,7 @@
                   thisKeyword: this @30
               leftParenthesis: ( @29
               rightParenthesis: ) @34
-            atSign.offset: 27
+            atSign: @ @27
             element: self::@class::A::@constructor::•
             name: SimpleIdentifier
               staticElement: self::@class::A
@@ -32325,7 +32325,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @8
               rightParenthesis: ) @9
-            atSign.offset: 0
+            atSign: @ @0
             element: <null>
             name: PrefixedIdentifier
               identifier: SimpleIdentifier
@@ -32357,7 +32357,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @11
               rightParenthesis: ) @12
-            atSign.offset: 0
+            atSign: @ @0
             element: <null>
             name: PrefixedIdentifier
               identifier: SimpleIdentifier
@@ -32385,7 +32385,7 @@
       class C @15
         metadata
           Annotation
-            atSign.offset: 0
+            atSign: @ @0
             element: <null>
             name: PrefixedIdentifier
               identifier: SimpleIdentifier
@@ -32417,7 +32417,7 @@
       class C @43
         metadata
           Annotation
-            atSign.offset: 28
+            atSign: @ @28
             element: <null>
             name: PrefixedIdentifier
               identifier: SimpleIdentifier
@@ -32449,7 +32449,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @12
               rightParenthesis: ) @13
-            atSign.offset: 0
+            atSign: @ @0
             constructorName: SimpleIdentifier
               staticElement: <null>
               staticType: null
@@ -32488,7 +32488,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @40
               rightParenthesis: ) @41
-            atSign.offset: 28
+            atSign: @ @28
             constructorName: SimpleIdentifier
               staticElement: <null>
               staticType: null
@@ -32527,7 +32527,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @43
               rightParenthesis: ) @44
-            atSign.offset: 28
+            atSign: @ @28
             constructorName: SimpleIdentifier
               staticElement: <null>
               staticType: null
@@ -32563,7 +32563,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @8
               rightParenthesis: ) @9
-            atSign.offset: 0
+            atSign: @ @0
             element: <null>
             name: PrefixedIdentifier
               identifier: SimpleIdentifier
@@ -32598,7 +32598,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @36
               rightParenthesis: ) @37
-            atSign.offset: 28
+            atSign: @ @28
             element: <null>
             name: PrefixedIdentifier
               identifier: SimpleIdentifier
@@ -32626,7 +32626,7 @@
       class C @11
         metadata
           Annotation
-            atSign.offset: 0
+            atSign: @ @0
             element: <null>
             name: SimpleIdentifier
               staticElement: <null>
@@ -32657,7 +32657,7 @@
       class C @44
         metadata
           Annotation
-            atSign.offset: 35
+            atSign: @ @35
             element: <null>
             name: SimpleIdentifier
               staticElement: <null>
@@ -32680,7 +32680,7 @@
             arguments: ArgumentList
               leftParenthesis: ( @4
               rightParenthesis: ) @5
-            atSign.offset: 0
+            atSign: @ @0
             element: <null>
             name: SimpleIdentifier
               staticElement: <null>
diff --git a/pkg/analyzer/test/src/workspace/package_build_test.dart b/pkg/analyzer/test/src/workspace/package_build_test.dart
index 8ce842f..b7a9650 100644
--- a/pkg/analyzer/test/src/workspace/package_build_test.dart
+++ b/pkg/analyzer/test/src/workspace/package_build_test.dart
@@ -640,6 +640,17 @@
         workspace.findFile(convertPath('/workspace/web/file.dart')), webFile);
   }
 
+  void test_isConsistentWithFileSystem() {
+    newFolder('/workspace/.dart_tool/build/generated/project/bin');
+    newPubspecYamlFile('/workspace', 'name: project');
+    PackageBuildWorkspace workspace =
+        _createWorkspace('/workspace', ['project']);
+    expect(workspace.isConsistentWithFileSystem, isTrue);
+
+    newPubspecYamlFile('/workspace', 'name: my2');
+    expect(workspace.isConsistentWithFileSystem, isFalse);
+  }
+
   PackageBuildWorkspace _createWorkspace(
       String root, List<String> packageNames) {
     return PackageBuildWorkspace.find(
diff --git a/pkg/analyzer/test/src/workspace/pub_test.dart b/pkg/analyzer/test/src/workspace/pub_test.dart
index f69f1c2..5f68d58 100644
--- a/pkg/analyzer/test/src/workspace/pub_test.dart
+++ b/pkg/analyzer/test/src/workspace/pub_test.dart
@@ -111,4 +111,14 @@
         resourceProvider, {}, convertPath('/workspace/lib/lib1.dart'));
     expect(workspace, isNull);
   }
+
+  void test_isConsistentWithFileSystem() {
+    newPubspecYamlFile('/workspace', 'name: my');
+    var workspace =
+        PubWorkspace.find(resourceProvider, {}, convertPath('/workspace'))!;
+    expect(workspace.isConsistentWithFileSystem, isTrue);
+
+    newPubspecYamlFile('/workspace', 'name: my2');
+    expect(workspace.isConsistentWithFileSystem, isFalse);
+  }
 }
diff --git a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
index f14d9c0..12c88aa 100644
--- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
@@ -4,8 +4,12 @@
 
 library dart2js.js_emitter.class_stub_generator;
 
+import 'package:js_runtime/shared/embedded_names.dart'
+    show TearOffParametersPropertyNames;
+
 import '../common/names.dart' show Identifiers, Selectors;
 import '../common_elements.dart' show CommonElements;
+import '../constants/values.dart';
 import '../elements/entities.dart';
 import '../js/js.dart' as jsAst;
 import '../js/js.dart' show js;
@@ -197,6 +201,65 @@
     }
     return new StubMethod(name, function);
   }
+
+  /// Generates a getter for the given [field].
+  Method generateGetter(Field field) {
+    assert(field.needsGetter);
+
+    jsAst.Expression code;
+    if (field.isElided) {
+      ConstantValue constantValue = field.constantValue;
+      assert(
+          constantValue != null, "No constant value for elided field: $field");
+      if (constantValue == null) {
+        // This should never occur because codegen member usage is now limited
+        // by closed world member usage. In the case we've missed a spot we
+        // cautiously generate a null constant.
+        constantValue = NullConstantValue();
+      }
+      code = js("function() { return #; }",
+          _emitter.constantReference(constantValue));
+    } else {
+      String template;
+      if (field.needsInterceptedGetterOnReceiver) {
+        template = "function(receiver) { return receiver[#]; }";
+      } else if (field.needsInterceptedGetterOnThis) {
+        template = "function(receiver) { return this[#]; }";
+      } else {
+        assert(!field.needsInterceptedGetter);
+        template = "function() { return this[#]; }";
+      }
+      jsAst.Expression fieldName = js.quoteName(field.name);
+      code = js(template, fieldName);
+    }
+    jsAst.Name getterName = _namer.deriveGetterName(field.accessorName);
+    return StubMethod(getterName, code);
+  }
+
+  /// Generates a setter for the given [field].
+  Method generateSetter(Field field) {
+    assert(field.needsUncheckedSetter);
+
+    String template;
+    jsAst.Expression code;
+    if (field.isElided) {
+      code = js("function() { }");
+    } else {
+      if (field.needsInterceptedSetterOnReceiver) {
+        template = "function(receiver, val) { return receiver[#] = val; }";
+      } else if (field.needsInterceptedSetterOnThis) {
+        template = "function(receiver, val) { return this[#] = val; }";
+      } else {
+        assert(!field.needsInterceptedSetter);
+        template = "function(val) { return this[#] = val; }";
+      }
+      jsAst.Expression fieldName = js.quoteName(field.name);
+      code = js(template, fieldName);
+    }
+
+    jsAst.Name setterName = _namer.deriveSetterName(field.accessorName);
+    return StubMethod(setterName, code);
+  }
 }
 
 /// Creates two JavaScript functions: `tearOffGetter` and `tearOff`.
@@ -232,18 +295,16 @@
   if (options.useContentSecurityPolicy) {
     instanceTearOffGetter = js.statement(
       '''
-      function instanceTearOffGetter(funcs, applyTrampolineIndex, reflectionInfo, name, isIntercepted, needsDirectAccess) {
+      function instanceTearOffGetter(isIntercepted, parameters) {
         var cache = null;
         return isIntercepted
             ? function(receiver) {
-                if (cache === null) cache = #createTearOffClass(
-                    funcs, applyTrampolineIndex, reflectionInfo, false, true, name, needsDirectAccess);
-                return new cache(this, funcs[0], receiver, name);
+                if (cache === null) cache = #createTearOffClass(parameters);
+                return new cache(this, receiver);
               }
             : function() {
-                if (cache === null) cache = #createTearOffClass(
-                    funcs, applyTrampolineIndex, reflectionInfo, false, false, name, needsDirectAccess);
-                return new cache(this, funcs[0], null, name);
+                if (cache === null) cache = #createTearOffClass(parameters);
+                return new cache(this, null);
               };
       }''',
       {'createTearOffClass': closureFromTearOffAccessExpression},
@@ -272,33 +333,35 @@
     // variable all in one context (passing `null` to initialize `cache`).
     instanceTearOffGetter = js.statement(
       '''
-function instanceTearOffGetter(funcs, applyTrampolineIndex, reflectionInfo, name, isIntercepted, needsDirectAccess) {
+function instanceTearOffGetter(isIntercepted, parameters) {
+  var name = parameters.#tpFunctionsOrNames[0];
   if (isIntercepted)
-    return new Function("funcs, applyTrampolineIndex, reflectionInfo, name, needsDirectAccess, createTearOffClass, cache",
-          "return function tearOff_" + name + (functionCounter++) + "(receiver) {" +
-            "if (cache === null) cache = createTearOffClass(" +
-                "funcs, applyTrampolineIndex, reflectionInfo, false, true, name, needsDirectAccess);" +
-                "return new cache(this, funcs[0], receiver, name);" +
-           "}")(funcs, applyTrampolineIndex, reflectionInfo, name, needsDirectAccess, #createTearOffClass, null);
+    return new Function("parameters, createTearOffClass, cache",
+        "return function tearOff_" + name + (functionCounter++) + "(receiver) {" +
+          "if (cache === null) cache = createTearOffClass(parameters);" +
+            "return new cache(this, receiver);" +
+        "}")(parameters, #createTearOffClass, null);
   else
-    return new Function("funcs, applyTrampolineIndex, reflectionInfo, name, needsDirectAccess, createTearOffClass, cache",
-          "return function tearOff_" + name + (functionCounter++)+ "() {" +
-            "if (cache === null) cache = createTearOffClass(" +
-                "funcs, applyTrampolineIndex, reflectionInfo, false, false, name, needsDirectAccess);" +
-                "return new cache(this, funcs[0], null, name);" +
-             "}")(funcs, applyTrampolineIndex, reflectionInfo, name, needsDirectAccess, #createTearOffClass, null);
+    return new Function("parameters, createTearOffClass, cache",
+        "return function tearOff_" + name + (functionCounter++)+ "() {" +
+          "if (cache === null) cache = createTearOffClass(parameters);" +
+            "return new cache(this, null);" +
+        "}")(parameters, #createTearOffClass, null);
 }''',
-      {'createTearOffClass': closureFromTearOffAccessExpression},
+      {
+        'tpFunctionsOrNames':
+            js.string(TearOffParametersPropertyNames.funsOrNames),
+        'createTearOffClass': closureFromTearOffAccessExpression
+      },
     );
   }
 
   jsAst.Statement staticTearOffGetter = js.statement(
     '''
-function staticTearOffGetter(funcs, applyTrampolineIndex, reflectionInfo, name) {
+function staticTearOffGetter(parameters) {
   var cache = null;
   return function() {
-    if (cache === null) cache = #createTearOffClass(
-        funcs, applyTrampolineIndex, reflectionInfo, true, false, name).prototype;
+    if (cache === null) cache = #createTearOffClass(parameters).prototype;
     return cache;
   }
 }''',
diff --git a/pkg/compiler/lib/src/js_emitter/model.dart b/pkg/compiler/lib/src/js_emitter/model.dart
index d5579b2..fd4296e 100644
--- a/pkg/compiler/lib/src/js_emitter/model.dart
+++ b/pkg/compiler/lib/src/js_emitter/model.dart
@@ -228,6 +228,7 @@
   final List<Field> fields;
   final List<StubMethod> isChecks;
   final List<StubMethod> checkedSetters;
+  final List<StubMethod> gettersSetters;
 
   /// Stub methods for this class that are call stubs for getters.
   final List<StubMethod> callStubs;
@@ -269,6 +270,7 @@
       this.callStubs,
       this.noSuchMethodStubs,
       this.checkedSetters,
+      this.gettersSetters,
       this.isChecks,
       this.functionTypeIndex,
       {this.hasRtiField,
@@ -313,6 +315,7 @@
       List<Field> instanceFields,
       List<StubMethod> callStubs,
       List<StubMethod> checkedSetters,
+      List<StubMethod> gettersSetters,
       List<StubMethod> isChecks,
       js.Expression functionTypeIndex,
       {bool hasRtiField,
@@ -328,6 +331,7 @@
             callStubs,
             const <StubMethod>[],
             checkedSetters,
+            gettersSetters,
             isChecks,
             functionTypeIndex,
             hasRtiField: hasRtiField,
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 2c8489f..6c581a5 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -560,7 +560,7 @@
     bool isClosureBaseClass = cls == _commonElements.closureClass;
 
     List<Method> methods = [];
-    List<StubMethod> callStubs = <StubMethod>[];
+    List<StubMethod> callStubs = [];
 
     ClassStubGenerator classStubGenerator = new ClassStubGenerator(
         _task.emitter, _commonElements, _namer, _codegenWorld, _closedWorld,
@@ -652,6 +652,16 @@
         ? const []
         : _buildFields(cls: cls, isHolderInterceptedClass: isInterceptedClass);
 
+    List<StubMethod> gettersSetters = onlyForConstructorOrRti
+        ? const []
+        : [
+            for (Field field in instanceFields)
+              if (field.needsGetter) classStubGenerator.generateGetter(field),
+            for (Field field in instanceFields)
+              if (field.needsUncheckedSetter)
+                classStubGenerator.generateSetter(field),
+          ];
+
     TypeTestProperties typeTests = runtimeTypeGenerator.generateIsTests(
         cls, _generatedCode,
         storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata);
@@ -704,7 +714,7 @@
       assert(!isClosureBaseClass);
 
       result = MixinApplication(cls, typeData, name, instanceFields, callStubs,
-          checkedSetters, isChecks, typeTests.functionTypeIndex,
+          checkedSetters, gettersSetters, isChecks, typeTests.functionTypeIndex,
           isDirectlyInstantiated: isInstantiated,
           hasRtiField: hasRtiField,
           onlyForRti: onlyForRti,
@@ -719,6 +729,7 @@
           callStubs,
           noSuchMethodStubs,
           checkedSetters,
+          gettersSetters,
           isChecks,
           typeTests.functionTypeIndex,
           isDirectlyInstantiated: isInstantiated,
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index 8c806eb..78f3727 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -226,80 +226,73 @@
 // offset at which the new types will be added.
 var typesOffset = 0;
 
-// Adapts the stored data, so it's suitable for a tearOff call.
-//
-// Stores the tear-off getter-function in the [container]'s [getterName]
-// property.
-//
-// The [container] is either a class (that is, its prototype), or the holder for
-// static functions.
-//
-// The argument [funsOrNames] is an array of strings or functions. If it is a
-// name, then the function should be fetched from the container. The first
-// entry in that array *must* be a string.
-//
-// TODO(floitsch): Change tearOffCode to accept the data directly, or create a
-// different tearOffCode?
-function installTearOff(
-    container, getterName, isStatic, isIntercepted, requiredParameterCount,
-    optionalParameterDefaultValues, callNames, funsOrNames, funType, applyIndex,
-    needsDirectAccess) {
-  // A function can have several stubs (for example to fill in optional
-  // arguments). We collect these functions in the `funs` array.
-  var funs = [];
-  for (var i = 0; i < funsOrNames.length; i++) {
-    var fun = funsOrNames[i];
-    if ((typeof fun) == "string") {
-      var stubName = fun;
-      fun = container[fun];
-      fun.#stubName = stubName;
-    }
-    fun.#callName = callNames[i];
-    funs.push(fun);
-  }
-
-  // The main function to which all stubs redirect.
-  var fun = funs[0];
-
-  fun[#argumentCount] = requiredParameterCount;
-  fun[#defaultArgumentValues] = optionalParameterDefaultValues;
-  var reflectionInfo = funType;
-  if (typeof reflectionInfo == "number") {
-    // The reflectionInfo can be a string type recipe or an index into the types
-    // table.  If it points into the types-table we need to update the index, in
-    // case the tear-off is part of a deferred hunk.
-    reflectionInfo = reflectionInfo + typesOffset;
-  }
-  var name = funsOrNames[0];
-  applyIndex = applyIndex || 0;
-  var getterFunction = isStatic
-      ? staticTearOffGetter(funs, applyIndex, reflectionInfo, name)
-      : instanceTearOffGetter(funs, applyIndex, reflectionInfo, name,
-          isIntercepted, needsDirectAccess);
-  container[getterName] = getterFunction;
-}
-
-function installStaticTearOff(
-    container, getterName,
-    requiredParameterCount, optionalParameterDefaultValues,
-    callNames, funsOrNames, funType, applyIndex) {
-  // TODO(sra): Specialize installTearOff for static methods. It might be
-  // possible to handle some very common simple cases directly.
-  return installTearOff(
-      container, getterName, true, false,
-      requiredParameterCount, optionalParameterDefaultValues,
-      callNames, funsOrNames, funType, applyIndex, false);
-}
-
-function installInstanceTearOff(
-    container, getterName, isIntercepted,
+/// Collect and canonicalize tear-off parameters.
+///
+/// [container] is either the `prototype` of a class constructor, or the holder
+/// for static functions.
+///
+/// [funsOrNames] is an array of strings or functions. If it is a
+/// name, then the function should be fetched from the container. The first
+/// entry in that array *must* be a string.
+// TODO(sra): It might be more readable to manually inline and simplify at the
+// two calls. It would need to be assessed as it would likely make the object
+// references polymorphic.
+function tearOffParameters(
+    container, isStatic, isIntercepted,
     requiredParameterCount, optionalParameterDefaultValues,
     callNames, funsOrNames, funType, applyIndex, needsDirectAccess) {
-  // TODO(sra): Specialize installTearOff for instance methods.
-  return installTearOff(
-      container, getterName, false, isIntercepted,
+  if (typeof funType == "number") {
+    // The [funType] can be a string type recipe or an index into the types
+    // table.  If it points into the types-table we need to update the index, in
+    // case the tear-off is part of a deferred hunk.
+    funType += typesOffset;
+  }
+  return {
+    #tpContainer: container,
+    #tpIsStatic: isStatic,
+    #tpIsIntercepted: isIntercepted,
+    #tpRequiredParameterCount: requiredParameterCount,
+    #tpOptionalParamaterDefaultValues: optionalParameterDefaultValues,
+    #tpCallNames: callNames,
+    #tpFunctionsOrNames: funsOrNames,
+    #tpFunctionType: funType,
+    #tpApplyIndex: applyIndex || 0,
+    #tpNeedsDirectAccess: needsDirectAccess,
+  }
+}
+
+/// Stores the static tear-off getter-function in the [holder]'s [getterName]
+/// property.
+function installStaticTearOff(
+    holder, getterName,
+    requiredParameterCount, optionalParameterDefaultValues,
+    callNames, funsOrNames, funType, applyIndex) {
+  // TODO(sra): Specialize for very common simple cases.
+  var parameters = tearOffParameters(
+      holder, true, false,
+      requiredParameterCount, optionalParameterDefaultValues,
+      callNames, funsOrNames, funType, applyIndex, false);
+  var getterFunction = staticTearOffGetter(parameters);
+  // TODO(sra): Returning [getterFunction] would be more versatile. We might
+  // want to store the static tearoff getter in a different holder, or in no
+  // holder if it is immediately called from the constant pool and otherwise
+  // unreferenced.
+  holder[getterName] = getterFunction;
+}
+
+/// Stores the instance tear-off getter-function in the [prototype]'s
+/// [getterName] property.
+function installInstanceTearOff(
+    prototype, getterName, isIntercepted,
+    requiredParameterCount, optionalParameterDefaultValues,
+    callNames, funsOrNames, funType, applyIndex, needsDirectAccess) {
+  isIntercepted = !!isIntercepted; // force to Boolean.
+  var parameters = tearOffParameters(
+      prototype, false, isIntercepted,
       requiredParameterCount, optionalParameterDefaultValues,
       callNames, funsOrNames, funType, applyIndex, !!needsDirectAccess);
+  var getterFunction = instanceTearOffGetter(isIntercepted, parameters);
+  prototype[getterName] = getterFunction;
 }
 
 // Instead of setting the interceptor tags directly we use this update
@@ -724,10 +717,28 @@
       'staticStateDeclaration': DeferredHolderParameter(),
       'staticState': DeferredHolderParameter(),
       'holders': holderDeclaration,
-      'callName': js.string(_namer.fixedNames.callNameField),
-      'stubName': js.string(_namer.stubNameField),
-      'argumentCount': js.string(_namer.fixedNames.requiredParameterField),
-      'defaultArgumentValues': js.string(_namer.fixedNames.defaultValuesField),
+
+      // Tearoff parameters:
+      'tpContainer': js.string(TearOffParametersPropertyNames.container),
+      'tpIsStatic': js.string(TearOffParametersPropertyNames.isStatic),
+      'tpIsIntercepted':
+          js.string(TearOffParametersPropertyNames.isIntercepted),
+      'tpRequiredParameterCount':
+          js.string(TearOffParametersPropertyNames.requiredParameterCount),
+      'tpOptionalParamaterDefaultValues': js.string(
+          TearOffParametersPropertyNames.optionalParameterDefaultValues),
+      'tpCallNames': js.string(TearOffParametersPropertyNames.callNames),
+      'tpFunctionsOrNames':
+          js.string(TearOffParametersPropertyNames.funsOrNames),
+      'tpFunctionType': js.string(TearOffParametersPropertyNames.funType),
+      'tpApplyIndex': js.string(TearOffParametersPropertyNames.applyIndex),
+      'tpNeedsDirectAccess':
+          js.string(TearOffParametersPropertyNames.needsDirectAccess),
+
+      //'callName': js.string(_namer.fixedNames.callNameField),
+      //'stubName': js.string(_namer.stubNameField),
+      //'argumentCount': js.string(_namer.fixedNames.requiredParameterField),
+      //'defaultArgumentValues': js.string(_namer.fixedNames.defaultValuesField),
       'deferredGlobal': ModelEmitter.deferredInitializersGlobal,
       'isTrackingAllocations': _options.experimentalTrackAllocations,
       'prototypes': emitPrototypes(fragment),
@@ -1028,7 +1039,7 @@
     Iterable<Method> isChecks = cls.isChecks;
     Iterable<Method> callStubs = cls.callStubs;
     Iterable<Method> noSuchMethodStubs = cls.noSuchMethodStubs;
-    Iterable<Method> gettersSetters = generateGettersSetters(cls);
+    Iterable<Method> gettersSetters = cls.gettersSetters;
     Iterable<Method> allMethods = [
       ...methods,
       ...checkedSetters,
@@ -1084,75 +1095,6 @@
     return new js.ObjectInitializer(properties);
   }
 
-  /// Generates a getter for the given [field].
-  Method generateGetter(Field field) {
-    assert(field.needsGetter);
-
-    js.Expression code;
-    if (field.isElided) {
-      ConstantValue constantValue = field.constantValue;
-      assert(
-          constantValue != null, "No constant value for elided field: $field");
-      if (constantValue == null) {
-        // This should never occur because codegen member usage is now limited
-        // by closed world member usage. In the case we've missed a spot we
-        // cautiously generate a null constant.
-        constantValue = new NullConstantValue();
-      }
-      code = js.js(
-          "function() { return #; }", generateConstantReference(constantValue));
-    } else {
-      String template;
-      if (field.needsInterceptedGetterOnReceiver) {
-        template = "function(receiver) { return receiver[#]; }";
-      } else if (field.needsInterceptedGetterOnThis) {
-        template = "function(receiver) { return this[#]; }";
-      } else {
-        assert(!field.needsInterceptedGetter);
-        template = "function() { return this[#]; }";
-      }
-      js.Expression fieldName = js.quoteName(field.name);
-      code = js.js(template, fieldName);
-    }
-    js.Name getterName = _namer.deriveGetterName(field.accessorName);
-    return new StubMethod(getterName, code);
-  }
-
-  /// Generates a setter for the given [field].
-  Method generateSetter(Field field) {
-    assert(field.needsUncheckedSetter);
-
-    String template;
-    js.Expression code;
-    if (field.isElided) {
-      code = js.js("function() { }");
-    } else {
-      if (field.needsInterceptedSetterOnReceiver) {
-        template = "function(receiver, val) { return receiver[#] = val; }";
-      } else if (field.needsInterceptedSetterOnThis) {
-        template = "function(receiver, val) { return this[#] = val; }";
-      } else {
-        assert(!field.needsInterceptedSetter);
-        template = "function(val) { return this[#] = val; }";
-      }
-      js.Expression fieldName = js.quoteName(field.name);
-      code = js.js(template, fieldName);
-    }
-
-    js.Name setterName = _namer.deriveSetterName(field.accessorName);
-    return new StubMethod(setterName, code);
-  }
-
-  /// Generates all getters and setters the given class [cls] needs.
-  Iterable<Method> generateGettersSetters(Class cls) {
-    return [
-      for (Field field in cls.fields)
-        if (field.needsGetter) generateGetter(field),
-      for (Field field in cls.fields)
-        if (field.needsUncheckedSetter) generateSetter(field),
-    ];
-  }
-
   /// Emits the given instance [method].
   ///
   /// The given method may be a stub-method (for example for is-checks).
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index 6cacacb..d660d94 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -25,6 +25,7 @@
         NATIVE_SUPERCLASS_TAG_NAME,
         RTI_UNIVERSE,
         RtiUniverseFieldNames,
+        TearOffParametersPropertyNames,
         TYPE_TO_INTERCEPTOR_MAP,
         TYPES;
 
@@ -34,11 +35,7 @@
 import '../../common.dart';
 import '../../common/tasks.dart';
 import '../../constants/values.dart'
-    show
-        ConstantValue,
-        FunctionConstantValue,
-        LateSentinelConstantValue,
-        NullConstantValue;
+    show ConstantValue, FunctionConstantValue, LateSentinelConstantValue;
 import '../../common_elements.dart' show CommonElements, JElementEnvironment;
 import '../../deferred_load.dart' show OutputUnit;
 import '../../dump_info.dart';
diff --git a/pkg/js_runtime/lib/shared/embedded_names.dart b/pkg/js_runtime/lib/shared/embedded_names.dart
index 6d6de2d..ec45847 100644
--- a/pkg/js_runtime/lib/shared/embedded_names.dart
+++ b/pkg/js_runtime/lib/shared/embedded_names.dart
@@ -275,3 +275,22 @@
   static String typeParameterVariances = 'tPV';
   static String sharedEmptyArray = 'sEA';
 }
+
+/// Names of fields of collected tear-off parameters object.
+///
+/// Tear-off getters are created before the Dart classes are initialized, so a
+/// plain JavaScript object is used to group the parameters. The object has a
+/// fixed shape, with the following properties. The names are short since there
+/// is no minifier for these property names.
+class TearOffParametersPropertyNames {
+  static const String container = 'co';
+  static const String isStatic = 'iS';
+  static const String isIntercepted = 'iI';
+  static const String requiredParameterCount = 'rC';
+  static const String optionalParameterDefaultValues = 'dV';
+  static const String callNames = 'cs';
+  static const String funsOrNames = 'fs';
+  static const String funType = 'fT';
+  static const String applyIndex = 'aI';
+  static const String needsDirectAccess = 'nDA';
+}
diff --git a/pkg/test_runner/lib/src/multitest.dart b/pkg/test_runner/lib/src/multitest.dart
index 0b3040e..f6b5a87 100644
--- a/pkg/test_runner/lib/src/multitest.dart
+++ b/pkg/test_runner/lib/src/multitest.dart
@@ -5,9 +5,6 @@
 /// Multitests are Dart test scripts containing lines of the form
 /// " [some dart code] //# [key]: [error type]"
 ///
-/// To support legacy multi tests we also handle lines of the form
-/// " [some dart code] /// [key]: [error type]"
-///
 /// For each key in the file, a new test file is made containing all the normal
 /// lines of the file, and all of the multitest lines containing that key, in
 /// the same order as in the source file. The new test is expected to pass if
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart
index 73935cf..cf1bdbd 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart
@@ -11,6 +11,16 @@
 import 'dart:convert' show json;
 import 'dart:isolate';
 
+var _issuedPostEventWarning = false;
+var _issuedRegisterExtensionWarning = false;
+final _developerSupportWarning = 'from dart:developer is only supported in '
+    'build/run/test environments where the developer event method hooks have '
+    'been set.';
+
+/// Returns `true` if the debugger service has been attached to the app.
+// TODO(46377) Update this check when we have a documented API for DDC apps.
+bool get _debuggerAttached => JS<bool>('!', r'!!#.$dwdsVersion', dart.global_);
+
 @patch
 @ForceInline()
 bool debugger({bool when = true, String? message}) {
@@ -59,7 +69,24 @@
 
 @patch
 _registerExtension(String method, ServiceExtensionHandler handler) {
-  _extensions[method] = handler;
+  if (!_debuggerAttached) {
+    if (!_issuedRegisterExtensionWarning) {
+      var message = 'registerExtension() $_developerSupportWarning';
+      JS('', 'console.warn(#)', message);
+      _issuedRegisterExtensionWarning = true;
+    }
+    return;
+  }
+  // TODO(46377) Update this check when we have a documented API for DDC apps.
+  if (JS<bool>('!', r'!!#.$emitRegisterEvent', dart.global_)) {
+    _extensions[method] = handler;
+    // See hooks assigned by package:dwds:
+    // https://github.com/dart-lang/webdev/blob/de05cf9fbbfe088be74bb61df4a138289a94d902/dwds/web/client.dart#L223
+    JS('', r'#.$emitRegisterEvent(#)', dart.global_, method);
+    return;
+  }
+  // TODO(nshahan) Remove use of debug log after package:dwds removes support.
+  // https://github.com/dart-lang/webdev/issues/1342
   JS('', 'console.debug("dart.developer.registerExtension", #)', method);
 }
 
@@ -92,6 +119,23 @@
 
 @patch
 void _postEvent(String eventKind, String eventData) {
+  if (!_debuggerAttached) {
+    if (!_issuedPostEventWarning) {
+      var message = 'postEvent() $_developerSupportWarning';
+      JS('', 'console.warn(#)', message);
+      _issuedPostEventWarning = true;
+    }
+    return;
+  }
+  // TODO(46377) Update this check when we have a documented API for DDC apps.
+  if (JS<bool>('!', r'!!#.$emitDebugEvent', dart.global_)) {
+    // See hooks assigned by package:dwds:
+    // https://github.com/dart-lang/webdev/blob/de05cf9fbbfe088be74bb61df4a138289a94d902/dwds/web/client.dart#L220
+    JS('', r'#.$emitDebugEvent(#, #)', dart.global_, eventKind, eventData);
+    return;
+  }
+  // TODO(nshahan) Remove use of debug log after package:dwds removes support.
+  // https://github.com/dart-lang/webdev/issues/1342
   JS('', 'console.debug("dart.developer.postEvent", #, #)', eventKind,
       eventData);
 }
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 0706331..4ef1735 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -21,7 +21,8 @@
         JsGetName,
         LEAF_TAGS,
         NATIVE_SUPERCLASS_TAG_NAME,
-        STATIC_FUNCTION_NAME_PROPERTY_NAME;
+        STATIC_FUNCTION_NAME_PROPERTY_NAME,
+        TearOffParametersPropertyNames;
 
 import 'dart:collection';
 
@@ -1856,31 +1857,14 @@
   /// Creates a new closure class for use by implicit getters associated with a
   /// method.
   ///
-  /// In other words, creates a tear-off closure.
+  /// Called from [closureFromTearOff], which is called from code generated by
+  /// the emitter.
   ///
-  /// Called from [closureFromTearOff] as well as from reflection when tearing
-  /// of a method via `getField`.
-  ///
-  /// This method assumes that [functions] was created by the JavaScript
-  /// function `addStubs` in `reflection_data_parser.dart`. That is, a list of
-  /// JavaScript function objects with properties `$stubName` and `$callName`.
-  ///
-  /// Further assumes that [reflectionInfo] is the end of the array created by
-  /// [dart2js.js_emitter.ContainerBuilder.addMemberMethod] starting with
-  /// required parameter count or, in case of the new emitter, the runtime
-  /// representation of the function's type.
-  ///
-  /// Caution: this function may be called when building constants.
+  /// Caution: This function is used to create static tearoffs which, being
+  /// constants, may be referred to by other constants. This means that this
+  /// code cannot refer to the constant pool since it does not exist.
   /// TODO(ahe): Don't call this function when building constants.
-  static fromTearOff(
-    List functions,
-    int applyTrampolineIndex,
-    var reflectionInfo,
-    bool isStatic,
-    bool isIntercepted,
-    String propertyName,
-    bool needsDirectAccess,
-  ) {
+  static fromTearOff(Object? parameters) {
     JS_EFFECT(() {
       // The functions are called here to model the calls from JS forms below.
       // The types in the JS forms in the arguments are propagated in type
@@ -1893,17 +1877,37 @@
       BoundClosure.evalRecipe(aBoundClosure, aString);
       getType(JS('int', '0'));
     });
-    // TODO(ahe): All the place below using \$ should be rewritten to go
-    // through the namer.
-    var function = JS('', '#[#]', functions, 0);
-    String? name = JS('String|Null', '#.\$stubName', function);
-    String? callName = JS('String|Null', '#[#]', function,
-        JS_GET_NAME(JsGetName.CALL_NAME_PROPERTY));
 
-    // This variable holds either an index into the types-table, or a function
-    // that can compute a function-rti. (The latter is necessary if the type
-    // is dependent on generic arguments).
-    var functionType = reflectionInfo;
+    Object? container =
+        JS('', '#.#', parameters, TearOffParametersPropertyNames.container);
+
+    bool isStatic =
+        JS('', '#.#', parameters, TearOffParametersPropertyNames.isStatic);
+    bool isIntercepted =
+        JS('', '#.#', parameters, TearOffParametersPropertyNames.isIntercepted);
+    bool needsDirectAccess = JS('', '#.#', parameters,
+        TearOffParametersPropertyNames.needsDirectAccess);
+    int applyTrampolineIndex =
+        JS('', '#.#', parameters, TearOffParametersPropertyNames.applyIndex);
+
+    JSArray funsOrNames =
+        JS('', '#.#', parameters, TearOffParametersPropertyNames.funsOrNames);
+    JSArray callNames =
+        JS('', '#.#', parameters, TearOffParametersPropertyNames.callNames);
+
+    // The first function is the primary entry point. It is always a string, the
+    // property name of the first function within the container.
+    assert(JS('', '#[#]', funsOrNames, 0) is String);
+    String name = JS('', '#[#]', funsOrNames, 0);
+    String? callName = JS('', '#[#]', callNames, 0);
+    Object? function = JS('', '#[#]', container, name);
+
+    // [functionType] is either an index into the types-table, a String type
+    // recipe (for types that are dependent on the tear-off class type
+    // variables), or a function that can compute an Rti. (The latter is
+    // necessary if the type is dependent on generic arguments).
+    Object? functionType =
+        JS('', '#.#', parameters, TearOffParametersPropertyNames.funType)!;
 
     // function tmp() {};
     // tmp.prototype = BC.prototype;
@@ -1935,7 +1939,7 @@
         ? JS('StaticClosure', 'Object.create(#.constructor.prototype)',
             new StaticClosure())
         : JS('BoundClosure', 'Object.create(#.constructor.prototype)',
-            new BoundClosure(null, null, null, ''));
+            new BoundClosure(null, null));
 
     JS('', '#.\$initialize = #', prototype, JS('', '#.constructor', prototype));
 
@@ -1945,11 +1949,11 @@
     var constructor = isStatic
         ? JS('', 'function static_tear_off(){this.\$initialize()}')
         : isCsp
-            ? JS('', 'function tear_off(a,b,c,d) {this.\$initialize(a,b,c,d)}')
+            ? JS('', 'function tear_off(a,b) {this.\$initialize(a,b)}')
             : JS(
                 '',
-                'new Function("a,b,c,d" + #,'
-                    ' "this.\$initialize(a,b,c,d" + # + ")")',
+                'new Function("a,b" + #,'
+                    ' "this.\$initialize(a,b" + # + ")")',
                 functionCounter,
                 functionCounter++);
 
@@ -1959,14 +1963,17 @@
 
     JS('', '#.prototype = #', constructor, prototype);
 
+    JS('', '#.# = #', prototype, BoundClosure.nameProperty, name);
+    JS('', '#.# = #', prototype, BoundClosure.targetProperty, function);
+
     // Create a closure and "monkey" patch it with call stubs.
     var trampoline = function;
     if (!isStatic) {
-      trampoline = forwardCallTo(function, isIntercepted, needsDirectAccess);
-      JS('', '#.\$reflectionInfo = #', trampoline, reflectionInfo);
+      trampoline =
+          forwardCallTo(name, function, isIntercepted, needsDirectAccess);
     } else {
-      JS('', '#[#] = #', prototype, STATIC_FUNCTION_NAME_PROPERTY_NAME,
-          propertyName);
+      // TODO(sra): Can this be removed?
+      JS('', '#[#] = #', prototype, STATIC_FUNCTION_NAME_PROPERTY_NAME, name);
     }
 
     var signatureFunction =
@@ -1976,28 +1983,44 @@
         signatureFunction);
     var applyTrampoline = trampoline;
     JS('', '#[#] = #', prototype, callName, trampoline);
-    for (int i = 1; i < functions.length; i++) {
-      var stub = functions[i];
-      var stubCallName = JS('String|Null', '#[#]', stub,
-          JS_GET_NAME(JsGetName.CALL_NAME_PROPERTY));
+
+    for (int i = 1; i < funsOrNames.length; i++) {
+      Object? stub = JS('', '#[#]', funsOrNames, i);
+
+      String stubName = '';
+      if (stub is String) {
+        stubName = stub;
+        stub = JS('', '#[#]', container, stubName);
+      }
+
+      Object? stubCallName = JS('', '#[#]', callNames, i);
+      // stubCallName can be null if the applyTrampoline has a selector that is
+      // otherwise unused, e.g. `foo<T>({bool strange = true})...`
       if (stubCallName != null) {
-        stub = isStatic
-            ? stub
-            : forwardCallTo(stub, isIntercepted, needsDirectAccess);
+        if (!isStatic) {
+          stub =
+              forwardCallTo(stubName, stub, isIntercepted, needsDirectAccess);
+        }
         JS('', '#[#] = #', prototype, stubCallName, stub);
       }
       if (i == applyTrampolineIndex) {
         applyTrampoline = stub;
-        JS('', '#.\$reflectionInfo = #', applyTrampoline, reflectionInfo);
       }
     }
 
     JS('', '#[#] = #', prototype, JS_GET_NAME(JsGetName.CALL_CATCH_ALL),
         applyTrampoline);
+
     String reqArgProperty = JS_GET_NAME(JsGetName.REQUIRED_PARAMETER_PROPERTY);
+    Object? requiredParameterCount = JS('', '#.#', parameters,
+        TearOffParametersPropertyNames.requiredParameterCount);
+    JS('', '#.# = #', prototype, reqArgProperty, requiredParameterCount);
+
     String defValProperty = JS_GET_NAME(JsGetName.DEFAULT_VALUES_PROPERTY);
-    JS('', '#.# = #.#', prototype, reqArgProperty, function, reqArgProperty);
-    JS('', '#.# = #.#', prototype, defValProperty, function, defValProperty);
+    Object? optionalParameterDefaultValues = JS('', '#.#', parameters,
+        TearOffParametersPropertyNames.optionalParameterDefaultValues);
+    JS('', '#.# = #', prototype, defValProperty,
+        optionalParameterDefaultValues);
 
     return constructor;
   }
@@ -2120,6 +2143,7 @@
             stubName,
             getSelf);
       default:
+        // Here we use `Function.prototype.apply`.
         return JS(
             '',
             'function(f,s){'
@@ -2134,10 +2158,10 @@
 
   static bool get isCsp => JS_GET_FLAG('USE_CONTENT_SECURITY_POLICY');
 
-  static forwardCallTo(function, bool isIntercepted, bool needsDirectAccess) {
+  static forwardCallTo(
+      String stubName, function, bool isIntercepted, bool needsDirectAccess) {
     if (isIntercepted)
-      return forwardInterceptedCallTo(function, needsDirectAccess);
-    String? stubName = JS('String|Null', '#.\$stubName', function);
+      return forwardInterceptedCallTo(stubName, function, needsDirectAccess);
     int arity = JS('int', '#.length', function);
 
     if (isCsp || needsDirectAccess || arity >= 27) {
@@ -2260,10 +2284,10 @@
     }
   }
 
-  static forwardInterceptedCallTo(function, bool needsDirectAccess) {
+  static forwardInterceptedCallTo(
+      String stubName, function, bool needsDirectAccess) {
     String selfField = BoundClosure.selfFieldName();
     String receiverField = BoundClosure.receiverFieldName();
-    String? stubName = JS('String|Null', '#.\$stubName', function);
     int arity = JS('int', '#.length', function);
     bool isCsp = JS_GET_FLAG('USE_CONTENT_SECURITY_POLICY');
 
@@ -2312,18 +2336,10 @@
   }
 }
 
-/// Called from implicit method getter (aka tear-off).
-closureFromTearOff(functions, applyTrampolineIndex, reflectionInfo, isStatic,
-    isIntercepted, name, needsDirectAccess) {
-  return Closure.fromTearOff(
-    JS('JSArray', '#', functions),
-    JS('int', '#||0', applyTrampolineIndex),
-    reflectionInfo,
-    JS('bool', '!!#', isStatic),
-    JS('bool', '!!#', isIntercepted),
-    JS('String', '#', name),
-    JS('bool', '!!#', needsDirectAccess),
-  );
+/// This is called by the fragment emitter.
+// TODO(sra): The fragment emitter could call `Closure.fromTearOff` directly.
+closureFromTearOff(parameters) {
+  return Closure.fromTearOff(parameters);
 }
 
 /// Represents an implicit closure of a function.
@@ -2340,22 +2356,29 @@
 
 /// Represents a 'tear-off' or property extraction closure of an instance
 /// method, that is an instance method bound to a specific receiver (instance).
+///
+/// This is a base class that is extended to create a separate closure class for
+/// each instance method. The subclass is created at run time.
 class BoundClosure extends TearOffClosure {
   /// The JavaScript receiver, which is the Dart receiver or the interceptor.
   final _self;
 
-  /// The method.
-  final _target;
-
   /// The Dart receiver if [_target] is an intercepted method (in which case
   /// [_self] is the interceptor), otherwise `null`.
   final _receiver;
 
-  /// The name of the function. Only used by `toString()`.
-  // TODO(sra): This should be part of the generated tear-off class.
-  final String _name;
+  /// The [_name] and [_target] of the bound closure are stored in the prototype
+  /// of the closure class (i.e. the subclass of BoundClosure).
+  static const nameProperty = r'$_name';
+  static const targetProperty = r'$_target';
 
-  BoundClosure(this._self, this._target, this._receiver, this._name);
+  /// The name of the function. Only used by `toString()`.
+  String get _name => JS('', '#.#', this, nameProperty);
+
+  /// The primary entry point for the instance method, used by `==`/`hashCode`.
+  Object get _target => JS('', '#.#', this, targetProperty);
+
+  BoundClosure(this._self, this._receiver);
 
   bool operator ==(other) {
     if (identical(this, other)) return true;
@@ -2405,38 +2428,22 @@
   @pragma('dart2js:parameter:trust')
   static selfOf(BoundClosure closure) => closure._self;
 
-  @pragma('dart2js:parameter:trust')
-  static targetOf(BoundClosure closure) => closure._target;
-
   @pragma('dart2js:noInline')
   @pragma('dart2js:parameter:trust')
   static receiverOf(BoundClosure closure) => closure._receiver;
 
-  @pragma('dart2js:parameter:trust')
-  static nameOf(BoundClosure closure) => closure._name;
+  static String? _selfFieldNameCache;
+  static String selfFieldName() =>
+      _selfFieldNameCache ??= _computeFieldNamed('self');
 
-  static String? selfFieldNameCache;
-
-  static String selfFieldName() {
-    if (selfFieldNameCache == null) {
-      selfFieldNameCache = computeFieldNamed('self');
-    }
-    return selfFieldNameCache!;
-  }
-
-  static String? receiverFieldNameCache;
-
-  static String receiverFieldName() {
-    if (receiverFieldNameCache == null) {
-      receiverFieldNameCache = computeFieldNamed('receiver');
-    }
-    return receiverFieldNameCache!;
-  }
+  static String? _receiverFieldNameCache;
+  static String receiverFieldName() =>
+      _receiverFieldNameCache ??= _computeFieldNamed('receiver');
 
   @pragma('dart2js:noInline')
   @pragma('dart2js:noSideEffects')
-  static String computeFieldNamed(String fieldName) {
-    var template = new BoundClosure('self', 'target', 'receiver', 'name');
+  static String _computeFieldNamed(String fieldName) {
+    var template = new BoundClosure('self', 'receiver');
     var names = JSArray.markFixedList(
         JS('', 'Object.getOwnPropertyNames(#)', template));
     for (int i = 0; i < names.length; i++) {
@@ -2445,7 +2452,7 @@
         return JS('String', '#', name);
       }
     }
-    throw new ArgumentError("Field name $fieldName not found.");
+    throw ArgumentError("Field name $fieldName not found.");
   }
 }
 
diff --git a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
index 6d6de2d..ec45847 100644
--- a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
+++ b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
@@ -275,3 +275,22 @@
   static String typeParameterVariances = 'tPV';
   static String sharedEmptyArray = 'sEA';
 }
+
+/// Names of fields of collected tear-off parameters object.
+///
+/// Tear-off getters are created before the Dart classes are initialized, so a
+/// plain JavaScript object is used to group the parameters. The object has a
+/// fixed shape, with the following properties. The names are short since there
+/// is no minifier for these property names.
+class TearOffParametersPropertyNames {
+  static const String container = 'co';
+  static const String isStatic = 'iS';
+  static const String isIntercepted = 'iI';
+  static const String requiredParameterCount = 'rC';
+  static const String optionalParameterDefaultValues = 'dV';
+  static const String callNames = 'cs';
+  static const String funsOrNames = 'fs';
+  static const String funType = 'fT';
+  static const String applyIndex = 'aI';
+  static const String needsDirectAccess = 'nDA';
+}
diff --git a/tests/dartdevc/developer_events_test.dart b/tests/dartdevc/developer_events_test.dart
new file mode 100644
index 0000000..907d801
--- /dev/null
+++ b/tests/dartdevc/developer_events_test.dart
@@ -0,0 +1,233 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library developer_events_test;
+
+import 'dart:developer'
+    show postEvent, registerExtension, ServiceExtensionResponse;
+import 'dart:convert';
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+@JS(r'$emitDebugEvent')
+external set emitDebugEvent(void Function(String, String)? func);
+
+@JS(r'$emitDebugEvent')
+external void Function(String, String)? get emitDebugEvent;
+
+@JS(r'$emitRegisterEvent')
+external set emitRegisterEvent(void Function(String)? func);
+
+@JS(r'$emitRegisterEvent')
+external void Function(String)? get emitRegisterEvent;
+
+@JS(r'console.warn')
+external set consoleWarn(void Function(String) func);
+
+@JS(r'console.warn')
+external void Function(String) get consoleWarn;
+
+@JS(r'console.debug')
+external set consoleDebug(void Function(String) func);
+
+@JS(r'console.debug')
+external void Function(String) get consoleDebug;
+
+@JS(r'$dwdsVersion')
+external set dwdsVersion(String? s);
+
+@JS(r'$dwdsVersion')
+external String? get dwdsVersion;
+
+class _TestDebugEvent {
+  final String kind;
+  final String eventData;
+  _TestDebugEvent(this.kind, this.eventData);
+}
+
+void main() {
+  testBackwardsCompatibility();
+  testWarningMessages();
+  testPostEvent();
+  testRegisterExtension();
+}
+
+/// Verify backwards compatibility for sending messages on the console.debug log
+/// in the chrome browser when the hooks have not been set.
+// TODO(nshahan) Remove testing of debug log after package:dwds removes support.
+// https://github.com/dart-lang/webdev/issues/1342`
+void testBackwardsCompatibility() {
+  var consoleDebugLog = <List>[];
+  var savedConsoleDebug = consoleDebug;
+  var savedDwdsVersion = dwdsVersion;
+
+  try {
+    // Patch our own console.debug function for testing.
+    consoleDebug = allowInterop((arg1, [arg2, arg3]) => consoleDebugLog.add([
+          arg1,
+          if (arg2 != null) arg2,
+          if (arg3 != null) arg3,
+        ]));
+    // Provide a version to signal there is an attached debugger.
+    dwdsVersion = '1.0.0-for-test';
+
+    // All post and register events should go to the console debug log.
+    var data0 = {'key0': 'value0'};
+    postEvent('kind0', data0);
+
+    expect(consoleDebugLog.single[0], 'dart.developer.postEvent');
+    expect(consoleDebugLog.single[1], 'kind0');
+    expect(consoleDebugLog.single[2], jsonEncode(data0));
+
+    var testHandler = (String s, Map<String, String> m) async =>
+        ServiceExtensionResponse.result('test result');
+
+    registerExtension('ext.method0', testHandler);
+    expect(consoleDebugLog.length, 2);
+    expect(consoleDebugLog[1].first, 'dart.developer.registerExtension');
+    expect(consoleDebugLog[1].last, 'ext.method0');
+
+    var data1 = {'key1': 'value1'};
+    postEvent('kind1', data1);
+
+    expect(consoleDebugLog.length, 3);
+    expect(consoleDebugLog[2][0], 'dart.developer.postEvent');
+    expect(consoleDebugLog[2][1], 'kind1');
+    expect(consoleDebugLog[2][2], jsonEncode(data1));
+
+    registerExtension('ext.method1', testHandler);
+    expect(consoleDebugLog.length, 4);
+    expect(consoleDebugLog[3].first, 'dart.developer.registerExtension');
+    expect(consoleDebugLog[3].last, 'ext.method1');
+  } finally {
+    // Restore actual console.debug function.
+    consoleDebug = savedConsoleDebug;
+    dwdsVersion = savedDwdsVersion;
+  }
+}
+
+/// Verify that warning messages are printed on the first call of postEvent()
+/// and registerExtension() when the hooks are undefined.
+void testWarningMessages() {
+  final consoleWarnLog = <String>[];
+  var savedConsoleWarn = consoleWarn;
+  try {
+    // Patch our own console.warn function for testing.
+    consoleWarn = allowInterop((String s) => consoleWarnLog.add(s));
+    expect(consoleWarnLog.isEmpty, true);
+
+    var data0 = {'key0': 'value0'};
+    postEvent('kind0', data0);
+
+    // A warning message was issued about calling `postEvent()` from
+    // dart:developer.
+    expect(consoleWarnLog.single.contains('postEvent() from dart:developer'),
+        true);
+
+    postEvent('kind0', data0);
+    var data1 = {'key1': 'value1'};
+    postEvent('kind1', data1);
+
+    // A warning is only issued on the first call of `postEvent()`.
+    expect(consoleWarnLog.length, 1);
+
+    consoleWarnLog.clear();
+
+    var testHandler = (String s, Map<String, String> m) async =>
+        ServiceExtensionResponse.result('test result');
+
+    expect(consoleWarnLog.isEmpty, true);
+
+    registerExtension('ext.method0', testHandler);
+
+    // A warning message was issued about calling `registerExtension()` from
+    // dart:developer.
+    expect(
+        consoleWarnLog.single
+            .contains('registerExtension() from dart:developer'),
+        true);
+
+    registerExtension('ext.method1', testHandler);
+    registerExtension('ext.method2', testHandler);
+
+    // A warning is only issued on the first call of `registerExtension()`.
+    expect(consoleWarnLog.length, 1);
+  } finally {
+    // Restore actual console.warn function.
+    consoleWarn = savedConsoleWarn;
+  }
+}
+
+void testPostEvent() {
+  final debugEventLog = <_TestDebugEvent>[];
+  var savedEmitDebugEvent = emitDebugEvent;
+  var savedDwdsVersion = dwdsVersion;
+
+  try {
+    // Provide a test version of the $emitDebugEvent hook.
+    emitDebugEvent = allowInterop((String kind, String eventData) {
+      debugEventLog.add(_TestDebugEvent(kind, eventData));
+    });
+    // Provide a version to signal there is an attached debugger.
+    dwdsVersion = '1.0.0-for-test';
+    expect(debugEventLog.isEmpty, true);
+
+    var data0 = {'key0': 'value0'};
+    postEvent('kind0', data0);
+
+    expect(debugEventLog.single.kind, 'kind0');
+    expect(debugEventLog.single.eventData, jsonEncode(data0));
+
+    var data1 = {'key1': 'value1'};
+    var data2 = {'key2': 'value2'};
+    postEvent('kind1', data1);
+    postEvent('kind2', data2);
+
+    expect(debugEventLog.length, 3);
+    expect(debugEventLog[0].kind, 'kind0');
+    expect(debugEventLog[0].eventData, jsonEncode(data0));
+    expect(debugEventLog[1].kind, 'kind1');
+    expect(debugEventLog[1].eventData, jsonEncode(data1));
+    expect(debugEventLog[2].kind, 'kind2');
+    expect(debugEventLog[2].eventData, jsonEncode(data2));
+  } finally {
+    emitDebugEvent = savedEmitDebugEvent;
+    dwdsVersion = savedDwdsVersion;
+  }
+}
+
+void testRegisterExtension() {
+  final registerEventLog = <String>[];
+  var savedEmitRegisterEvent = emitRegisterEvent;
+  var savedDwdsVersion = dwdsVersion;
+
+  try {
+    // Provide a test version of the $emitRegisterEvent hook.
+    emitRegisterEvent = allowInterop((String eventData) {
+      registerEventLog.add(eventData);
+    });
+    // Provide a version to signal there is an attached debugger.
+    dwdsVersion = '1.0.0-for-test';
+    expect(registerEventLog.isEmpty, true);
+
+    var testHandler = (String s, Map<String, String> m) async =>
+        ServiceExtensionResponse.result('test result');
+    registerExtension('ext.method0', testHandler);
+
+    expect(registerEventLog.single, 'ext.method0');
+
+    registerExtension('ext.method1', testHandler);
+    registerExtension('ext.method2', testHandler);
+
+    expect(registerEventLog.length, 3);
+    expect(registerEventLog[0], 'ext.method0');
+    expect(registerEventLog[1], 'ext.method1');
+    expect(registerEventLog[2], 'ext.method2');
+  } finally {
+    emitRegisterEvent = savedEmitRegisterEvent;
+    dwdsVersion = savedDwdsVersion;
+  }
+}
diff --git a/tests/dartdevc_2/developer_events_test.dart b/tests/dartdevc_2/developer_events_test.dart
new file mode 100644
index 0000000..8bc5ed8
--- /dev/null
+++ b/tests/dartdevc_2/developer_events_test.dart
@@ -0,0 +1,233 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library developer_events_test;
+
+import 'dart:developer'
+    show postEvent, registerExtension, ServiceExtensionResponse;
+import 'dart:convert';
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+@JS(r'$emitDebugEvent')
+external set emitDebugEvent(void Function(String, String) func);
+
+@JS(r'$emitDebugEvent')
+external void Function(String, String) get emitDebugEvent;
+
+@JS(r'$emitRegisterEvent')
+external set emitRegisterEvent(void Function(String)? func);
+
+@JS(r'$emitRegisterEvent')
+external void Function(String) get emitRegisterEvent;
+
+@JS(r'console.warn')
+external set consoleWarn(void Function(String) func);
+
+@JS(r'console.warn')
+external void Function(String) get consoleWarn;
+
+@JS(r'console.debug')
+external set consoleDebug(void Function(String) func);
+
+@JS(r'console.debug')
+external void Function(String) get consoleDebug;
+
+@JS(r'$dwdsVersion')
+external set dwdsVersion(String s);
+
+@JS(r'$dwdsVersion')
+external String get dwdsVersion;
+
+class _TestDebugEvent {
+  final String kind;
+  final String eventData;
+  _TestDebugEvent(this.kind, this.eventData);
+}
+
+void main() {
+  testBackwardsCompatibility();
+  testWarningMessages();
+  testPostEvent();
+  testRegisterExtension();
+}
+
+/// Verify backwards compatibility for sending messages on the console.debug log
+/// in the chrome browser when the hooks have not been set.
+// TODO(nshahan) Remove testing of debug log after package:dwds removes support.
+// https://github.com/dart-lang/webdev/issues/1342`
+void testBackwardsCompatibility() {
+  var consoleDebugLog = <List>[];
+  var savedConsoleDebug = consoleDebug;
+  var savedDwdsVersion = dwdsVersion;
+
+  try {
+    // Patch our own console.debug function for testing.
+    consoleDebug = allowInterop((arg1, [arg2, arg3]) => consoleDebugLog.add([
+          arg1,
+          if (arg2 != null) arg2,
+          if (arg3 != null) arg3,
+        ]));
+    // Provide a version to signal there is an attached debugger.
+    dwdsVersion = '1.0.0-for-test';
+
+    // All post and register events should go to the console debug log.
+    var data0 = {'key0': 'value0'};
+    postEvent('kind0', data0);
+
+    expect(consoleDebugLog.single[0], 'dart.developer.postEvent');
+    expect(consoleDebugLog.single[1], 'kind0');
+    expect(consoleDebugLog.single[2], jsonEncode(data0));
+
+    var testHandler = (String s, Map<String, String> m) async =>
+        ServiceExtensionResponse.result('test result');
+
+    registerExtension('ext.method0', testHandler);
+    expect(consoleDebugLog.length, 2);
+    expect(consoleDebugLog[1].first, 'dart.developer.registerExtension');
+    expect(consoleDebugLog[1].last, 'ext.method0');
+
+    var data1 = {'key1': 'value1'};
+    postEvent('kind1', data1);
+
+    expect(consoleDebugLog.length, 3);
+    expect(consoleDebugLog[2][0], 'dart.developer.postEvent');
+    expect(consoleDebugLog[2][1], 'kind1');
+    expect(consoleDebugLog[2][2], jsonEncode(data1));
+
+    registerExtension('ext.method1', testHandler);
+    expect(consoleDebugLog.length, 4);
+    expect(consoleDebugLog[3].first, 'dart.developer.registerExtension');
+    expect(consoleDebugLog[3].last, 'ext.method1');
+  } finally {
+    // Restore actual console.debug function.
+    consoleDebug = savedConsoleDebug;
+    dwdsVersion = savedDwdsVersion;
+  }
+}
+
+/// Verify that warning messages are printed on the first call of postEvent()
+/// and registerExtension() when the hooks are undefined.
+void testWarningMessages() {
+  final consoleWarnLog = <String>[];
+  var savedConsoleWarn = consoleWarn;
+  try {
+    // Patch our own console.warn function for testing.
+    consoleWarn = allowInterop((String s) => consoleWarnLog.add(s));
+    expect(consoleWarnLog.isEmpty, true);
+
+    var data0 = {'key0': 'value0'};
+    postEvent('kind0', data0);
+
+    // A warning message was issued about calling `postEvent()` from
+    // dart:developer.
+    expect(consoleWarnLog.single.contains('postEvent() from dart:developer'),
+        true);
+
+    postEvent('kind0', data0);
+    var data1 = {'key1': 'value1'};
+    postEvent('kind1', data1);
+
+    // A warning is only issued on the first call of `postEvent()`.
+    expect(consoleWarnLog.length, 1);
+
+    consoleWarnLog.clear();
+
+    var testHandler = (String s, Map<String, String> m) async =>
+        ServiceExtensionResponse.result('test result');
+
+    expect(consoleWarnLog.isEmpty, true);
+
+    registerExtension('ext.method0', testHandler);
+
+    // A warning message was issued about calling `registerExtension()` from
+    // dart:developer.
+    expect(
+        consoleWarnLog.single
+            .contains('registerExtension() from dart:developer'),
+        true);
+
+    registerExtension('ext.method1', testHandler);
+    registerExtension('ext.method2', testHandler);
+
+    // A warning is only issued on the first call of `registerExtension()`.
+    expect(consoleWarnLog.length, 1);
+  } finally {
+    // Restore actual console.warn function.
+    consoleWarn = savedConsoleWarn;
+  }
+}
+
+void testPostEvent() {
+  final debugEventLog = <_TestDebugEvent>[];
+  var savedEmitDebugEvent = emitDebugEvent;
+  var savedDwdsVersion = dwdsVersion;
+
+  try {
+    // Provide a test version of the $emitDebugEvent hook.
+    emitDebugEvent = allowInterop((String kind, String eventData) {
+      debugEventLog.add(_TestDebugEvent(kind, eventData));
+    });
+    // Provide a version to signal there is an attached debugger.
+    dwdsVersion = '1.0.0-for-test';
+    expect(debugEventLog.isEmpty, true);
+
+    var data0 = {'key0': 'value0'};
+    postEvent('kind0', data0);
+
+    expect(debugEventLog.single.kind, 'kind0');
+    expect(debugEventLog.single.eventData, jsonEncode(data0));
+
+    var data1 = {'key1': 'value1'};
+    var data2 = {'key2': 'value2'};
+    postEvent('kind1', data1);
+    postEvent('kind2', data2);
+
+    expect(debugEventLog.length, 3);
+    expect(debugEventLog[0].kind, 'kind0');
+    expect(debugEventLog[0].eventData, jsonEncode(data0));
+    expect(debugEventLog[1].kind, 'kind1');
+    expect(debugEventLog[1].eventData, jsonEncode(data1));
+    expect(debugEventLog[2].kind, 'kind2');
+    expect(debugEventLog[2].eventData, jsonEncode(data2));
+  } finally {
+    emitDebugEvent = savedEmitDebugEvent;
+    dwdsVersion = savedDwdsVersion;
+  }
+}
+
+void testRegisterExtension() {
+  final registerEventLog = <String>[];
+  var savedEmitRegisterEvent = emitRegisterEvent;
+  var savedDwdsVersion = dwdsVersion;
+
+  try {
+    // Provide a test version of the $emitRegisterEvent hook.
+    emitRegisterEvent = allowInterop((String eventData) {
+      registerEventLog.add(eventData);
+    });
+    // Provide a version to signal there is an attached debugger.
+    dwdsVersion = '1.0.0-for-test';
+    expect(registerEventLog.isEmpty, true);
+
+    var testHandler = (String s, Map<String, String> m) async =>
+        ServiceExtensionResponse.result('test result');
+    registerExtension('ext.method0', testHandler);
+
+    expect(registerEventLog.single, 'ext.method0');
+
+    registerExtension('ext.method1', testHandler);
+    registerExtension('ext.method2', testHandler);
+
+    expect(registerEventLog.length, 3);
+    expect(registerEventLog[0], 'ext.method0');
+    expect(registerEventLog[1], 'ext.method1');
+    expect(registerEventLog[2], 'ext.method2');
+  } finally {
+    emitRegisterEvent = savedEmitRegisterEvent;
+    dwdsVersion = savedDwdsVersion;
+  }
+}
diff --git a/tools/VERSION b/tools/VERSION
index 9da0255..5632a42 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 216
+PRERELEASE 217
 PRERELEASE_PATCH 0
\ No newline at end of file