Version 2.14.0-355.0.dev

Merge commit '5de7dfb90bf1d006c64992938a9e2a2a0908d4d4' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 06c07a9..13301b6 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
     "constraint, update this by running tools/generate_package_config.dart."
   ],
   "configVersion": 2,
-  "generated": "2021-07-23T12:33:04.456358",
+  "generated": "2021-07-26T14:57:34.624319",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 6c1563b..2df5ebb 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -2471,7 +2471,7 @@
 
   /// Return `true` if the given [name] is visible only within the library in
   /// which it is declared.
-  static bool isPrivateName(String name) => name.startsWith('_');
+  static bool isPrivateName(String name) => name.isNotEmpty && name[0] == "_";
 }
 
 /// The basic structure of an if element.
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 5342239..ed78b2e 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -80,7 +80,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 = 166;
+  static const int DATA_VERSION = 167;
 
   /// 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/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 7660639..f362f93 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1404,7 +1404,7 @@
 /// A concrete implementation of a [ConstructorElement].
 class ConstructorElementImpl extends ExecutableElementImpl
     with ConstructorElementMixin
-    implements ConstructorElement {
+    implements ConstructorElement, HasMacroGenerationData {
   /// The constructor to which this constructor is redirecting.
   ConstructorElement? _redirectedConstructor;
 
@@ -1413,6 +1413,9 @@
   List<ConstructorInitializer> _constantInitializers = const [];
 
   @override
+  MacroGenerationData? macro;
+
+  @override
   int? periodOffset;
 
   @override
@@ -2704,22 +2707,6 @@
   }
 }
 
-/// Information about a macro-produced [Element].
-class ElementMacro {
-  /// The sequential id of this macro-produced element.
-  final int id;
-
-  /// The code that for produced by the macro.
-  final String code;
-
-  /// When we build elements from macro-produced code, we remember informative
-  /// data, such as offsets - to store it into bytes. This field is set to
-  /// an empty list when reading from bytes.
-  final Uint8List informative;
-
-  ElementMacro(this.id, this.code, this.informative);
-}
-
 /// An [AbstractClassElementImpl] which is an enum.
 class EnumElementImpl extends AbstractClassElementImpl {
   ElementLinkedData? linkedData;
@@ -3486,10 +3473,10 @@
 }
 
 /// This interface is implemented by [Element]s that can be added by macros.
-abstract class HasElementMacro {
+abstract class HasMacroGenerationData {
   /// If this element was added by a macro, the code of a declaration that
   /// was produced by the macro.
-  ElementMacro? macro;
+  MacroGenerationData? macro;
 }
 
 /// A concrete implementation of a [HideElementCombinator].
@@ -4109,8 +4096,36 @@
       visitor.visitLocalVariableElement(this);
 }
 
+/// Information about a macro-produced [Element].
+class MacroGenerationData {
+  /// The sequential id of this macro-produced element, for an element created
+  /// for a declaration that was macro-generated later this value is greater.
+  ///
+  /// This is different from [ElementImpl.id], which is also incrementing,
+  /// but shows the order in which elements were built from declarations,
+  /// not the order of declarations, and we process all field declarations
+  /// before method declarations.
+  final int id;
+
+  /// The code that was produced by the macro. It is used to compose full
+  /// code of a unit to display to the user, so that new declarations are
+  /// added to the unit or existing classes.
+  ///
+  /// When a class is generated, its code might have some members, or might
+  /// be empty, and new elements might be macro-generated into it.
+  final String code;
+
+  /// When we build elements from macro-produced code, we remember informative
+  /// data, such as offsets - to store it into bytes. This field is set to
+  /// an empty list when reading from bytes.
+  final Uint8List informative;
+
+  MacroGenerationData(this.id, this.code, this.informative);
+}
+
 /// A concrete implementation of a [MethodElement].
-class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
+class MethodElementImpl extends ExecutableElementImpl
+    implements MethodElement, HasMacroGenerationData {
   /// Is `true` if this method is `operator==`, and there is no explicit
   /// type specified for its formal parameter, in this method or in any
   /// overridden methods other than the one declared in `Object`.
@@ -4120,6 +4135,9 @@
   /// this variable is not a subject of type inference, or there was no error.
   TopLevelInferenceError? typeInferenceError;
 
+  @override
+  MacroGenerationData? macro;
+
   /// Initialize a newly created method element to have the given [name] at the
   /// given [offset].
   MethodElementImpl(String name, int offset) : super(name, offset);
@@ -4923,13 +4941,13 @@
 
 /// A concrete implementation of a [PropertyAccessorElement].
 class PropertyAccessorElementImpl extends ExecutableElementImpl
-    implements PropertyAccessorElement, HasElementMacro {
+    implements PropertyAccessorElement, HasMacroGenerationData {
   /// The variable associated with this accessor.
   @override
   late PropertyInducingElement variable;
 
   @override
-  ElementMacro? macro;
+  MacroGenerationData? macro;
 
   /// Initialize a newly created property accessor element to have the given
   /// [name] and [offset].
diff --git a/pkg/analyzer/lib/src/macro/api/macro.dart b/pkg/analyzer/lib/src/macro/api/macro.dart
index 0f65d38..78eb6c0 100644
--- a/pkg/analyzer/lib/src/macro/api/macro.dart
+++ b/pkg/analyzer/lib/src/macro/api/macro.dart
@@ -15,6 +15,12 @@
   void addToClass(Declaration declaration);
 }
 
+/// The interface for [DeclarationMacro]s that can be applied to classes.
+abstract class ClassDeclarationMacro implements DeclarationMacro {
+  void visitClassDeclaration(
+      ast.ClassDeclaration declaration, ClassDeclarationBuilder builder);
+}
+
 /// The api used by [DeclarationMacro]s to contribute new declarations to the
 /// current library.
 abstract class DeclarationBuilder {
diff --git a/pkg/analyzer/lib/src/macro/builders/data_class.dart b/pkg/analyzer/lib/src/macro/builders/data_class.dart
new file mode 100644
index 0000000..664f5d8
--- /dev/null
+++ b/pkg/analyzer/lib/src/macro/builders/data_class.dart
@@ -0,0 +1,89 @@
+// 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.
+
+import 'package:analyzer/dart/ast/ast.dart' as ast;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/macro/api/code.dart';
+import 'package:analyzer/src/macro/api/macro.dart';
+
+class AutoConstructorMacro implements ClassDeclarationMacro {
+  const AutoConstructorMacro();
+
+  @override
+  void visitClassDeclaration(
+    ast.ClassDeclaration node,
+    ClassDeclarationBuilder builder,
+  ) {
+    // TODO(scheglov) Should we provide the element as a parameter?
+    var classElement = node.declaredElement!;
+    var typeSystem = classElement.library.typeSystem;
+
+    if (classElement.unnamedConstructor != null) {
+      throw ArgumentError(
+        'Cannot generate a constructor because one already exists',
+      );
+    }
+
+    var fieldsCode = classElement.fields.map((field) {
+      var isNullable = typeSystem.isNullable(field.type);
+      var requiredKeyword = isNullable ? '' : 'required ';
+      return '${requiredKeyword}this.${field.name}';
+    }).join(', ');
+
+    // TODO(scheglov) super constructor
+
+    builder.addToClass(
+      Declaration('${classElement.name}({$fieldsCode});'),
+    );
+  }
+}
+
+class HashCodeMacro implements ClassDeclarationMacro {
+  const HashCodeMacro();
+
+  @override
+  void visitClassDeclaration(
+    ast.ClassDeclaration node,
+    ClassDeclarationBuilder builder,
+  ) {
+    var expression = node.declaredElement!.allFields
+        .map((e) => '${e.name}.hashCode')
+        .join(' ^ ');
+    builder.addToClass(
+      Declaration('''
+@override
+int get hashCode => $expression;'''),
+    );
+  }
+}
+
+class ToStringMacro implements ClassDeclarationMacro {
+  const ToStringMacro();
+
+  @override
+  void visitClassDeclaration(
+    ast.ClassDeclaration node,
+    ClassDeclarationBuilder builder,
+  ) {
+    var classElement = node.declaredElement!;
+    var fieldsCode = classElement.allFields.map((field) {
+      var name = field.name;
+      return '$name: \$$name';
+    }).join(', ');
+    builder.addToClass(
+      Declaration('''
+@override
+String toString() => '${classElement.name}($fieldsCode)';'''),
+    );
+  }
+}
+
+extension on ClassElement {
+  Iterable<FieldElement> get allFields sync* {
+    for (ClassElement? class_ = this; class_ != null;) {
+      yield* class_.fields.where((e) => !e.isSynthetic);
+      class_ = class_.supertype?.element;
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/macro/impl/macro.dart b/pkg/analyzer/lib/src/macro/impl/macro.dart
index ddb1a2b..73e10f7 100644
--- a/pkg/analyzer/lib/src/macro/impl/macro.dart
+++ b/pkg/analyzer/lib/src/macro/impl/macro.dart
@@ -74,9 +74,9 @@
       var node = entry.key;
       if (node is ast.Declaration) {
         var element = node.declaredElement;
-        if (element is HasElementMacro) {
+        if (element is HasMacroGenerationData) {
           var collectedDeclaration = entry.value;
-          (element as HasElementMacro).macro = ElementMacro(
+          (element as HasMacroGenerationData).macro = MacroGenerationData(
             collectedDeclaration.id,
             collectedDeclaration.declaration.code,
             collectedDeclaration.informative,
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index 13b33b1..51a33b6 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -592,6 +592,7 @@
       element.setLinkedData(reference, linkedData);
       ConstructorElementFlags.read(_reader, element);
       element.parameters = _readParameters(element, reference);
+      _readMacro(element, element);
       return element;
     });
   }
@@ -852,9 +853,9 @@
     return LibraryLanguageVersion(package: package, override: override);
   }
 
-  void _readMacro(Element element, HasElementMacro hasMacro) {
+  void _readMacro(Element element, HasMacroGenerationData hasMacro) {
     if (_reader.readBool()) {
-      hasMacro.macro = ElementMacro(
+      hasMacro.macro = MacroGenerationData(
         _reader.readUInt30(),
         _reader.readStringUtf8(),
         Uint8List(0),
@@ -889,6 +890,7 @@
       element.typeParameters = _readTypeParameters();
       element.parameters = _readParameters(element, reference);
       element.typeInferenceError = _readTopLevelInferenceError();
+      _readMacro(element, element);
       return element;
     });
   }
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index b9be7f8..5fd0bf8 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -164,6 +164,7 @@
     _resolutionSink.localElements.declareAll(element.parameters);
     try {
       _writeList(element.parameters, _writeParameterElement);
+      _writeMacro(element.macro);
       if (element.isConst || element.isFactory) {
         _resolutionSink.writeElement(element.redirectedConstructor);
         _resolutionSink._writeNodeList(element.constantInitializers);
@@ -280,7 +281,7 @@
     }
   }
 
-  void _writeMacro(ElementMacro? macro) {
+  void _writeMacro(MacroGenerationData? macro) {
     _sink.writeBool(macro != null);
     if (macro != null) {
       _sink.writeUInt30(macro.id);
@@ -302,6 +303,8 @@
       _sink._writeTopLevelInferenceError(element.typeInferenceError);
       _resolutionSink.writeType(element.returnType);
     });
+
+    _writeMacro(element.macro);
   }
 
   void _writeMixinElement(ClassElement element) {
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index 790c470..7bb241f 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -897,29 +897,9 @@
     var element = node.declaredElement as ClassElementImpl;
     var holder = _buildClassMembers(element, node.members);
     element.accessors = holder.propertyAccessors;
+    element.constructors = holder.constructors;
     element.fields = holder.properties.whereType<FieldElement>().toList();
     element.methods = holder.methods;
-
-    var constructors = holder.constructors;
-    if (constructors.isEmpty) {
-      var containerRef = element.reference!.getChild('@constructor');
-      constructors = [
-        ConstructorElementImpl('', -1)
-          ..isSynthetic = true
-          ..reference = containerRef.getChild(''),
-      ];
-    }
-    element.constructors = constructors;
-
-    // We have all fields and constructors.
-    // Now we can resolve field formal parameters.
-    for (var constructor in constructors) {
-      for (var parameter in constructor.parameters) {
-        if (parameter is FieldFormalParameterElementImpl) {
-          parameter.field = element.getField(parameter.name);
-        }
-      }
-    }
   }
 
   void _buildExecutableElementChildren({
diff --git a/pkg/analyzer/lib/src/summary2/informative_data.dart b/pkg/analyzer/lib/src/summary2/informative_data.dart
index ca9e274..f14a0f2 100644
--- a/pkg/analyzer/lib/src/summary2/informative_data.dart
+++ b/pkg/analyzer/lib/src/summary2/informative_data.dart
@@ -161,7 +161,15 @@
     var kindIndex = reader.readByte();
     var kind = _DeclarationKind.values[kindIndex];
 
-    if (kind == _DeclarationKind.methodDeclaration &&
+    if (kind == _DeclarationKind.constructorDeclaration &&
+        element is ConstructorElement) {
+      var info = _InfoConstructorDeclaration(reader);
+      _applyToConstructor(element, info);
+    } else if (kind == _DeclarationKind.methodDeclaration &&
+        element is MethodElement) {
+      var info = _InfoMethodDeclaration(reader);
+      _applyToMethod(element, info);
+    } else if (kind == _DeclarationKind.methodDeclaration &&
         element is PropertyAccessorElement) {
       var info = _InfoMethodDeclaration(reader);
       _applyToPropertyAccessor(element, info);
@@ -254,6 +262,32 @@
     );
   }
 
+  void _applyToConstructor(
+    ConstructorElement element,
+    _InfoConstructorDeclaration info,
+  ) {
+    element as ConstructorElementImpl;
+    element.setCodeRange(info.codeOffset, info.codeLength);
+    element.periodOffset = info.periodOffset;
+    element.nameOffset = info.nameOffset;
+    element.nameEnd = info.nameEnd;
+    element.documentationComment = info.documentationComment;
+    _applyToFormalParameters(
+      element.parameters_unresolved,
+      info.parameters,
+    );
+
+    var linkedData = element.linkedData as ConstructorElementLinkedData;
+    linkedData.applyConstantOffsets = ApplyConstantOffsets(
+      info.constantOffsets,
+      (applier) {
+        applier.applyToMetadata(element);
+        applier.applyToFormalParameters(element.parameters);
+        applier.applyToConstructorInitializers(element);
+      },
+    );
+  }
+
   void _applyToConstructors(
     List<ConstructorElement> elementList,
     List<_InfoConstructorDeclaration> infoList,
@@ -261,28 +295,7 @@
     forCorrespondingPairs<ConstructorElement, _InfoConstructorDeclaration>(
       elementList,
       infoList,
-      (element, info) {
-        element as ConstructorElementImpl;
-        element.setCodeRange(info.codeOffset, info.codeLength);
-        element.periodOffset = info.periodOffset;
-        element.nameOffset = info.nameOffset;
-        element.nameEnd = info.nameEnd;
-        element.documentationComment = info.documentationComment;
-        _applyToFormalParameters(
-          element.parameters_unresolved,
-          info.parameters,
-        );
-
-        var linkedData = element.linkedData as ConstructorElementLinkedData;
-        linkedData.applyConstantOffsets = ApplyConstantOffsets(
-          info.constantOffsets,
-          (applier) {
-            applier.applyToMetadata(element);
-            applier.applyToFormalParameters(element.parameters);
-            applier.applyToConstructorInitializers(element);
-          },
-        );
-      },
+      _applyToConstructor,
     );
   }
 
@@ -672,6 +685,7 @@
 }
 
 enum _DeclarationKind {
+  constructorDeclaration,
   methodDeclaration,
 }
 
@@ -1336,7 +1350,10 @@
   }
 
   void writeDeclaration(AstNode node) {
-    if (node is MethodDeclaration) {
+    if (node is ConstructorDeclaration) {
+      sink.addByte(_DeclarationKind.constructorDeclaration.index);
+      _writeConstructor(node);
+    } else if (node is MethodDeclaration) {
       sink.addByte(_DeclarationKind.methodDeclaration.index);
       _writeMethod(node);
     } else {
@@ -1360,22 +1377,24 @@
     });
   }
 
+  void _writeConstructor(ConstructorDeclaration node) {
+    sink.writeUInt30(node.offset);
+    sink.writeUInt30(node.length);
+    sink.writeOptionalUInt30(node.period?.offset);
+    var nameNode = node.name ?? node.returnType;
+    sink.writeUInt30(nameNode.offset);
+    sink.writeUInt30(nameNode.end);
+    _writeDocumentationComment(node);
+    _writeFormalParameters(node.parameters);
+    _writeOffsets(
+      metadata: node.metadata,
+      formalParameters: node.parameters,
+      constructorInitializers: node.initializers,
+    );
+  }
+
   void _writeConstructors(List<ClassMember> members) {
-    sink.writeList2<ConstructorDeclaration>(members, (node) {
-      sink.writeUInt30(node.offset);
-      sink.writeUInt30(node.length);
-      sink.writeOptionalUInt30(node.period?.offset);
-      var nameNode = node.name ?? node.returnType;
-      sink.writeUInt30(nameNode.offset);
-      sink.writeUInt30(nameNode.end);
-      _writeDocumentationComment(node);
-      _writeFormalParameters(node.parameters);
-      _writeOffsets(
-        metadata: node.metadata,
-        formalParameters: node.parameters,
-        constructorInitializers: node.initializers,
-      );
-    });
+    sink.writeList2<ConstructorDeclaration>(members, _writeConstructor);
   }
 
   void _writeDocumentationComment(AnnotatedNode node) {
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 8e1064e..c1eb205 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer/src/dart/ast/mixin_super_invoked_names.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
+import 'package:analyzer/src/macro/builders/data_class.dart' as macro;
 import 'package:analyzer/src/macro/builders/observable.dart' as macro;
 import 'package:analyzer/src/macro/impl/macro.dart' as macro;
 import 'package:analyzer/src/summary2/combinator.dart';
@@ -143,6 +144,38 @@
     }
   }
 
+  /// We don't create default constructors during building elements from AST,
+  /// there might be macros that will add one later. So, this method is
+  /// invoked after all macros that affect element models.
+  void processClassConstructors() {
+    // TODO(scheglov) We probably don't need constructors for mixins.
+    var classes = element.topLevelElements
+        .whereType<ClassElementImpl>()
+        .where((e) => !e.isMixinApplication)
+        .toList();
+
+    for (var element in classes) {
+      if (element.constructors.isEmpty) {
+        var containerRef = element.reference!.getChild('@constructor');
+        element.constructors = [
+          ConstructorElementImpl('', -1)
+            ..isSynthetic = true
+            ..reference = containerRef.getChild(''),
+        ];
+      }
+
+      // We have all fields and constructors.
+      // Now we can resolve field formal parameters.
+      for (var constructor in element.constructors) {
+        for (var parameter in constructor.parameters) {
+          if (parameter is FieldFormalParameterElementImpl) {
+            parameter.field = element.getField(parameter.name);
+          }
+        }
+      }
+    }
+  }
+
   void resolveConstructors() {
     ConstructorInitializerResolver(linker, element).resolve();
   }
@@ -207,6 +240,24 @@
             collector,
             declaration,
           );
+          if (hasMacroAnnotation(declaration, 'autoConstructor')) {
+            macro.AutoConstructorMacro().visitClassDeclaration(
+              declaration,
+              classBuilder,
+            );
+          }
+          if (hasMacroAnnotation(declaration, 'hashCode')) {
+            macro.HashCodeMacro().visitClassDeclaration(
+              declaration,
+              classBuilder,
+            );
+          }
+          if (hasMacroAnnotation(declaration, 'toString')) {
+            macro.ToStringMacro().visitClassDeclaration(
+              declaration,
+              classBuilder,
+            );
+          }
           for (var member in members) {
             if (member is ast.FieldDeclarationImpl) {
               if (hasMacroAnnotation(member, 'observable')) {
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index d0fe559..7a33308 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -217,6 +217,7 @@
   void _runDeclarationMacros() {
     for (var library in builders.values) {
       library.runDeclarationMacros();
+      library.processClassConstructors();
     }
   }
 
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 42f8774..f8366c5 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -361,6 +361,7 @@
     });
 
     _withIndent(() {
+      _writeMacro(e);
       _writeDocumentation(e);
       _writeMetadata(e);
       _writeCodeRange(e);
@@ -395,7 +396,7 @@
       expect(e.nameOffset, -1);
       expect(e.nonSynthetic, same(e.enclosingElement));
     } else {
-      expect(e.nameOffset, isPositive);
+      expect(e.nameOffset, isNonNegative);
     }
   }
 
@@ -530,8 +531,8 @@
   }
 
   void _writeMacro(Element e) {
-    if (e is HasElementMacro) {
-      var macro = (e as HasElementMacro).macro;
+    if (e is HasMacroGenerationData) {
+      var macro = (e as HasMacroGenerationData).macro;
       if (macro != null) {
         _writelnWithIndent('macro');
         _withIndent(() {
@@ -567,6 +568,7 @@
     });
 
     _withIndent(() {
+      _writeMacro(e);
       _writeDocumentation(e);
       _writeMetadata(e);
       _writeCodeRange(e);
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index bc3a7da..8473b16 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -21246,6 +21246,183 @@
 ''');
   }
 
+  test_macro_autoConstructor() async {
+    addLibrarySource('/macro_annotations.dart', r'''
+library analyzer.macro.annotations;
+const autoConstructor = 0;
+''');
+    var library = await checkLibrary(r'''
+import 'macro_annotations.dart';
+@autoConstructor
+class A {
+  final int a;
+  final int? b;
+}
+''');
+    checkElementText(library, r'''
+library
+  imports
+    macro_annotations.dart
+  definingUnit
+    classes
+      class A @56
+        metadata
+          Annotation
+            atSign: @ @33
+            element: macro_annotations.dart::@getter::autoConstructor
+            name: SimpleIdentifier
+              staticElement: macro_annotations.dart::@getter::autoConstructor
+              staticType: null
+              token: autoConstructor @34
+        fields
+          final a @72
+            type: int
+          final b @88
+            type: int?
+        constructors
+          @0
+            macro
+              id: 0
+              code: A({required this.a, this.b});
+            parameters
+              requiredName final this.a @17
+                type: int
+              optionalNamed final this.b @25
+                type: int?
+        accessors
+          synthetic get a @-1
+            returnType: int
+          synthetic get b @-1
+            returnType: int?
+''');
+  }
+
+  test_macro_hashCode() async {
+    addLibrarySource('/macro_annotations.dart', r'''
+library analyzer.macro.annotations;
+const hashCode = 0;
+''');
+    var library = await checkLibrary(r'''
+import 'macro_annotations.dart';
+@hashCode
+class A {
+  final int a;
+  final int b;
+}
+''');
+    checkElementText(library, r'''
+library
+  imports
+    macro_annotations.dart
+  definingUnit
+    classes
+      class A @49
+        metadata
+          Annotation
+            atSign: @ @33
+            element: macro_annotations.dart::@getter::hashCode
+            name: SimpleIdentifier
+              staticElement: macro_annotations.dart::@getter::hashCode
+              staticType: null
+              token: hashCode @34
+        fields
+          final a @65
+            type: int
+          final b @80
+            type: int
+          synthetic hashCode @-1
+            type: int
+        constructors
+          synthetic @-1
+        accessors
+          synthetic get a @-1
+            returnType: int
+          synthetic get b @-1
+            returnType: int
+          get hashCode @18
+            macro
+              id: 0
+              code: @override\nint get hashCode => a.hashCode ^ b.hashCode;
+            metadata
+              Annotation
+                atSign: @ @0
+                element: dart:core::@getter::override
+                name: SimpleIdentifier
+                  staticElement: dart:core::@getter::override
+                  staticType: null
+                  token: override @1
+            returnType: int
+''');
+  }
+
+  test_macro_hashCode_withSuper() async {
+    addLibrarySource('/macro_annotations.dart', r'''
+library analyzer.macro.annotations;
+const hashCode = 0;
+''');
+    var library = await checkLibrary(r'''
+import 'macro_annotations.dart';
+
+class A {
+  final int a;
+}
+
+@hashCode
+class B extends A {
+  final int b;
+}
+''');
+    checkElementText(library, r'''
+library
+  imports
+    macro_annotations.dart
+  definingUnit
+    classes
+      class A @40
+        fields
+          final a @56
+            type: int
+        constructors
+          synthetic @-1
+        accessors
+          synthetic get a @-1
+            returnType: int
+      class B @78
+        metadata
+          Annotation
+            atSign: @ @62
+            element: macro_annotations.dart::@getter::hashCode
+            name: SimpleIdentifier
+              staticElement: macro_annotations.dart::@getter::hashCode
+              staticType: null
+              token: hashCode @63
+        supertype: A
+        fields
+          final b @104
+            type: int
+          synthetic hashCode @-1
+            type: int
+        constructors
+          synthetic @-1
+        accessors
+          synthetic get b @-1
+            returnType: int
+          get hashCode @18
+            macro
+              id: 0
+              code: @override\nint get hashCode => b.hashCode ^ a.hashCode;
+            metadata
+              Annotation
+                atSign: @ @0
+                element: dart:core::@getter::override
+                name: SimpleIdentifier
+                  staticElement: dart:core::@getter::override
+                  staticType: null
+                  token: override @1
+            returnType: int
+''');
+  }
+
   test_macro_observable() async {
     addLibrarySource('/macro_annotations.dart', r'''
 library analyzer.macro.annotations;
@@ -21365,6 +21542,63 @@
 ''');
   }
 
+  test_macro_toString() async {
+    addLibrarySource('/macro_annotations.dart', r'''
+library analyzer.macro.annotations;
+const toString = 0;
+''');
+    var library = await checkLibrary(r'''
+import 'macro_annotations.dart';
+@toString
+class A {
+  final int a;
+  final int b;
+}
+''');
+    checkElementText(library, r'''
+library
+  imports
+    macro_annotations.dart
+  definingUnit
+    classes
+      class A @49
+        metadata
+          Annotation
+            atSign: @ @33
+            element: macro_annotations.dart::@getter::toString
+            name: SimpleIdentifier
+              staticElement: macro_annotations.dart::@getter::toString
+              staticType: null
+              token: toString @34
+        fields
+          final a @65
+            type: int
+          final b @80
+            type: int
+        constructors
+          synthetic @-1
+        accessors
+          synthetic get a @-1
+            returnType: int
+          synthetic get b @-1
+            returnType: int
+        methods
+          toString @17
+            macro
+              id: 0
+              code: @override\nString toString() => 'A(a: $a, b: $b)';
+            metadata
+              Annotation
+                atSign: @ @0
+                element: dart:core::@getter::override
+                name: SimpleIdentifier
+                  staticElement: dart:core::@getter::override
+                  staticType: null
+                  token: override @1
+            returnType: String
+''');
+  }
+
   test_main_class() async {
     var library = await checkLibrary('class main {}');
     checkElementText(library, r'''
diff --git a/pkg/analyzer_plugin/pubspec.yaml b/pkg/analyzer_plugin/pubspec.yaml
index b5304b9..7b0003e 100644
--- a/pkg/analyzer_plugin/pubspec.yaml
+++ b/pkg/analyzer_plugin/pubspec.yaml
@@ -1,6 +1,6 @@
 name: analyzer_plugin
 description: A framework and support code for building plugins for the analysis server.
-version: 0.7.0-dev
+version: 0.7.0
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_plugin
 
 environment:
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index 18f96cd..6525880 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -15,6 +15,8 @@
 import '../js_backend/backend.dart' show CodegenInputs;
 import '../js_backend/inferred_data.dart';
 import '../js_backend/namer.dart' show Namer;
+import '../js_backend/runtime_types.dart'
+    show RuntimeTypesChecks;
 import '../js_model/js_strategy.dart';
 import '../options.dart';
 import '../universe/codegen_world_builder.dart';
@@ -26,14 +28,13 @@
 import 'metadata_collector.dart' show MetadataCollector;
 import 'model.dart';
 import 'native_emitter.dart' show NativeEmitter;
-import 'type_test_registry.dart' show TypeTestRegistry;
 
 /// Generates the code for all used classes in the program. Static fields (even
 /// in classes) are ignored, since they can be treated as non-class elements.
 ///
 /// The code for the containing (used) methods must exist in the `universe`.
 class CodeEmitterTask extends CompilerTask {
-  TypeTestRegistry typeTestRegistry;
+  RuntimeTypesChecks _rtiChecks;
   NativeEmitter _nativeEmitter;
   MetadataCollector metadataCollector;
   Emitter _emitter;
@@ -77,8 +78,7 @@
   void _finalizeRti(CodegenInputs codegen, CodegenWorld codegenWorld) {
     // Compute the required type checks to know which classes need a
     // 'is$' method.
-    typeTestRegistry.computeRequiredTypeChecks(
-        _backendStrategy.rtiChecksBuilder, codegenWorld);
+    _rtiChecks = _backendStrategy.rtiChecksBuilder.computeRequiredChecks(codegenWorld, options);
   }
 
   /// Creates the [Emitter] for this task.
@@ -101,7 +101,6 @@
           _generateSourceMap);
       metadataCollector = new MetadataCollector(
           _compiler.reporter, _emitter, codegen.rtiRecipeEncoder);
-      typeTestRegistry = new TypeTestRegistry(_compiler.options);
     });
   }
 
@@ -126,7 +125,7 @@
           closedWorld.nativeData,
           closedWorld.rtiNeed,
           closedWorld.interceptorData,
-          typeTestRegistry.rtiChecks,
+          _rtiChecks,
           codegenInputs.rtiRecipeEncoder,
           codegenWorld.oneShotInterceptorData,
           _backendStrategy.customElementsCodegenAnalysis,
@@ -138,7 +137,7 @@
           inferredData,
           _backendStrategy.sourceInformationStrategy,
           closedWorld.sorter,
-          typeTestRegistry.rtiNeededClasses,
+          _rtiChecks.requiredClasses,
           closedWorld.elementEnvironment.mainFunction);
       int size = emitter.emitProgram(programBuilder, codegenWorld);
       // TODO(floitsch): we shouldn't need the `neededClasses` anymore.
diff --git a/pkg/compiler/lib/src/js_emitter/js_emitter.dart b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
index 7ad49b8..b5d4f85 100644
--- a/pkg/compiler/lib/src/js_emitter/js_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
@@ -14,4 +14,3 @@
 export 'native_generator.dart';
 export 'parameter_stub_generator.dart';
 export 'runtime_type_generator.dart';
-export 'type_test_registry.dart';
diff --git a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
deleted file mode 100644
index c61de53..0000000
--- a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.js_emitter.type_test_registry;
-
-import '../common.dart';
-import '../elements/entities.dart';
-import '../js_backend/runtime_types.dart'
-    show RuntimeTypesChecks, RuntimeTypesChecksBuilder;
-import '../options.dart';
-import '../universe/codegen_world_builder.dart';
-
-/// TODO(joshualitt): Delete this class and store [RuntimeTypeChecks] on
-/// [CodeEmitterTask] directly.
-class TypeTestRegistry {
-  final CompilerOptions _options;
-
-  RuntimeTypesChecks _rtiChecks;
-
-  TypeTestRegistry(this._options);
-
-  RuntimeTypesChecks get rtiChecks {
-    assert(
-        _rtiChecks != null,
-        failedAt(NO_LOCATION_SPANNABLE,
-            "RuntimeTypesChecks has not been computed yet."));
-    return _rtiChecks;
-  }
-
-  Iterable<ClassEntity> get rtiNeededClasses {
-    return rtiChecks.requiredClasses;
-  }
-
-  void computeRequiredTypeChecks(
-      RuntimeTypesChecksBuilder rtiChecksBuilder, CodegenWorld codegenWorld) {
-    _rtiChecks = rtiChecksBuilder.computeRequiredChecks(codegenWorld, _options);
-  }
-}
diff --git a/pkg/dev_compiler/lib/src/kernel/constants.dart b/pkg/dev_compiler/lib/src/kernel/constants.dart
index d5b538f..87df7e3 100644
--- a/pkg/dev_compiler/lib/src/kernel/constants.dart
+++ b/pkg/dev_compiler/lib/src/kernel/constants.dart
@@ -2,8 +2,7 @@
 // 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.
 
-// @dart = 2.9
-
+import 'package:collection/collection.dart';
 import 'package:kernel/kernel.dart';
 import 'package:kernel/target/targets.dart';
 
@@ -21,7 +20,7 @@
   /// failed, or if the constant was unavailable.
   ///
   /// Returns [NullConstant] to represent the `null` value.
-  Constant evaluate(Expression e) {
+  Constant? evaluate(Expression e) {
     return e is ConstantExpression ? e.constant : null;
   }
 
@@ -43,13 +42,12 @@
   ///     main() { ... }
   ///
   /// Given the node for `@MyAnnotation('FooBar')` this will return `'FooBar'`.
-  Object getFieldValueFromAnnotation(Expression node, String name) {
+  Object? getFieldValueFromAnnotation(Expression node, String name) {
     if (node is ConstantExpression) {
       var constant = node.constant;
       if (constant is InstanceConstant) {
         var value = constant.fieldValues.entries
-            .firstWhere((e) => e.key.asField.name.text == name,
-                orElse: () => null)
+            .firstWhereOrNull((e) => e.key.asField.name.text == name)
             ?.value;
         if (value is PrimitiveConstant) return value.value;
         if (value is UnevaluatedConstant) {
@@ -64,11 +62,10 @@
     //
     // We may need to address this in the kernel outline files.
     if (node is ConstructorInvocation) {
-      Expression first;
+      Expression? first;
       var named = node.arguments.named;
       if (named.isNotEmpty) {
-        first =
-            named.firstWhere((n) => n.name == name, orElse: () => null)?.value;
+        first = named.firstWhereOrNull((n) => n.name == name)?.value;
       }
       var positional = node.arguments.positional;
       if (positional.isNotEmpty) first ??= positional[0];
@@ -79,7 +76,7 @@
     return null;
   }
 
-  Object _evaluateAnnotationArgument(Expression node) {
+  Object? _evaluateAnnotationArgument(Expression node) {
     if (node is ConstantExpression) {
       var constant = node.constant;
       if (constant is PrimitiveConstant) return constant.value;
@@ -87,7 +84,7 @@
     if (node is StaticGet) {
       var target = node.target;
       if (target is Field) {
-        return _evaluateAnnotationArgument(target.initializer);
+        return _evaluateAnnotationArgument(target.initializer!);
       }
     }
     return node is BasicLiteral ? node.value : null;
diff --git a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
index 0c4e313..0e4ae0e 100644
--- a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
+++ b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
@@ -2,19 +2,18 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:collection';
+import 'package:collection/collection.dart';
 import 'package:front_end/src/api_unstable/ddc.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/kernel.dart';
 
-Constructor unnamedConstructor(Class c) =>
-    c.constructors.firstWhere((c) => c.name.text == '', orElse: () => null);
+Constructor? unnamedConstructor(Class c) =>
+    c.constructors.firstWhereOrNull((c) => c.name.text == '');
 
 /// Returns the enclosing library for reference [node].
-Library getLibrary(NamedNode node) {
-  for (TreeNode n = node; n != null; n = n.parent) {
+Library? getLibrary(NamedNode node) {
+  for (TreeNode? n = node; n != null; n = n.parent) {
     if (n is Library) return n;
   }
   return null;
@@ -22,14 +21,14 @@
 
 final Pattern _syntheticTypeCharacters = RegExp('[&^#.|]');
 
-String escapeIdentifier(String identifier) {
+String? escapeIdentifier(String? identifier) {
   // Remove the special characters used to encode mixin application class names
   // and extension method / parameter names which are legal in Kernel, but not
   // in JavaScript.
   //
   // Note, there is an implicit assumption here that we won't have
   // collisions since everything is mapped to \$.  That may work out fine given
-  // how these are sythesized, but may need to revisit.
+  // how these are synthesized, but may need to revisit.
   return identifier?.replaceAll(_syntheticTypeCharacters, r'$');
 }
 
@@ -40,15 +39,15 @@
 ///
 /// In the current encoding, generic classes are generated in a function scope
 /// which avoids name clashes of the escaped class name.
-String getLocalClassName(Class node) => escapeIdentifier(node.name);
+String getLocalClassName(Class node) => escapeIdentifier(node.name)!;
 
 /// Returns the escaped name for the type parameter [node].
 ///
 /// In the current encoding, generic classes are generated in a function scope
 /// which avoids name clashes of the escaped parameter name.
-String getTypeParameterName(TypeParameter node) => escapeIdentifier(node.name);
+String? getTypeParameterName(TypeParameter node) => escapeIdentifier(node.name);
 
-String getTopLevelName(NamedNode n) {
+String? getTopLevelName(NamedNode n) {
   if (n is Procedure) return n.name.text;
   if (n is Class) return n.name;
   if (n is Typedef) return n.name;
@@ -69,7 +68,7 @@
 ///
 ///    (v) => v.type.name == 'Deprecated' && v.type.element.library.isDartCore
 ///
-Expression findAnnotation(TreeNode node, bool Function(Expression) test) {
+Expression? findAnnotation(TreeNode node, bool Function(Expression) test) {
   List<Expression> annotations;
   if (node is Class) {
     annotations = node.annotations;
@@ -84,7 +83,7 @@
   } else {
     return null;
   }
-  return annotations.firstWhere(test, orElse: () => null);
+  return annotations.firstWhereOrNull(test);
 }
 
 /// Returns true if [value] represents an annotation for class [className] in
@@ -108,7 +107,7 @@
 ///
 /// This function works regardless of whether the CFE is evaluating constants,
 /// or whether the constant is a field reference (such as "anonymous" above).
-Class getAnnotationClass(Expression node) {
+Class? getAnnotationClass(Expression node) {
   if (node is ConstantExpression) {
     var constant = node.constant;
     if (constant is InstanceConstant) return constant.classNode;
@@ -165,9 +164,9 @@
 /// A mixin alias class is a mixin application, that can also be itself used as
 /// a mixin.
 bool isMixinAliasClass(Class c) =>
-    c.isMixinApplication && c.superclass.superclass == null;
+    c.isMixinApplication && c.superclass!.superclass == null;
 
-List<Class> getSuperclasses(Class c) {
+List<Class> getSuperclasses(Class? c) {
   var result = <Class>[];
   var visited = HashSet<Class>();
   while (c != null && visited.add(c)) {
@@ -191,7 +190,7 @@
   return result;
 }
 
-Expression getInvocationReceiver(InvocationExpression node) {
+Expression? getInvocationReceiver(InvocationExpression node) {
   if (node is MethodInvocation) {
     return node.receiver;
   } else if (node is InstanceInvocation) {
@@ -251,7 +250,7 @@
 
 /// Returns the redirecting factory constructors for the enclosing class,
 /// if the field [f] is storing that information, otherwise returns `null`.
-Iterable<Member> getRedirectingFactories(Field f) {
+Iterable<Member>? getRedirectingFactories(Field f) {
   // TODO(jmesserly): this relies on implementation details in Kernel
   if (isRedirectingFactoryField(f)) {
     assert(f.isStatic);
@@ -269,14 +268,15 @@
 // TODO(jmesserly): consider replacing this with Kernel's mixin unrolling
 Class getSuperclassAndMixins(Class c, List<Class> mixins) {
   assert(mixins.isEmpty);
+  assert(c.superclass != null);
 
   var mixedInClass = c.mixedInClass;
   if (mixedInClass != null) mixins.add(mixedInClass);
 
-  var sc = c.superclass;
-  for (; sc.isAnonymousMixin; sc = sc.superclass) {
+  var sc = c.superclass!;
+  for (; sc.isAnonymousMixin; sc = sc.superclass!) {
     mixedInClass = sc.mixedInClass;
-    if (mixedInClass != null) mixins.add(sc.mixedInClass);
+    if (mixedInClass != null) mixins.add(sc.mixedInClass!);
   }
   return sc;
 }
@@ -291,7 +291,7 @@
 class LabelContinueFinder extends StatementVisitor<void> {
   var found = false;
 
-  void visit(Statement s) {
+  void visit(Statement? s) {
     if (!found && s != null) s.accept(this);
   }
 
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index b6020ee..5bc10c1 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.9
-
 import 'dart:collection';
 
 import 'package:_fe_analyzer_shared/src/messages/codes.dart'
@@ -28,9 +26,9 @@
   @override
   final TargetFlags flags;
 
-  WidgetCreatorTracker _widgetTracker;
+  WidgetCreatorTracker? _widgetTracker;
 
-  Map<String, Class> _nativeClasses;
+  Map<String, Class>? _nativeClasses;
 
   @override
   bool get enableSuperMixins => true;
@@ -156,11 +154,11 @@
       CoreTypes coreTypes,
       ClassHierarchy hierarchy,
       List<Library> libraries,
-      Map<String, String> environmentDefines,
+      Map<String, String>? environmentDefines,
       DiagnosticReporter diagnosticReporter,
-      ReferenceFromIndex referenceFromIndex,
-      {void Function(String msg) logger,
-      ChangedStructureNotifier changedStructureNotifier}) {
+      ReferenceFromIndex? referenceFromIndex,
+      {void Function(String msg)? logger,
+      ChangedStructureNotifier? changedStructureNotifier}) {
     _nativeClasses ??= JsInteropChecks.getNativeClasses(component);
     var jsUtilOptimizer = JsUtilOptimizer(coreTypes, hierarchy);
     for (var library in libraries) {
@@ -169,7 +167,7 @@
       JsInteropChecks(
               coreTypes,
               diagnosticReporter as DiagnosticReporter<Message, LocatedMessage>,
-              _nativeClasses)
+              _nativeClasses!)
           .visitLibrary(library);
     }
   }
@@ -180,11 +178,11 @@
       CoreTypes coreTypes,
       List<Library> libraries,
       DiagnosticReporter diagnosticReporter,
-      {void Function(String msg) logger,
-      ChangedStructureNotifier changedStructureNotifier}) {
+      {void Function(String msg)? logger,
+      ChangedStructureNotifier? changedStructureNotifier}) {
     if (flags.trackWidgetCreation) {
       _widgetTracker ??= WidgetCreatorTracker();
-      _widgetTracker.transform(component, libraries, changedStructureNotifier);
+      _widgetTracker!.transform(component, libraries, changedStructureNotifier);
     }
   }
 
@@ -352,7 +350,7 @@
   /// If the member needs a check it will be stored in [_checkedMembers].
   ///
   /// See [transform] for more information.
-  void _checkTarget(Expression receiver, Member target) {
+  void _checkTarget(Expression receiver, Member? target) {
     if (target != null &&
         target.name.isPrivate &&
         target.isInstanceMember &&
@@ -370,7 +368,7 @@
   /// escape, and it also has a different runtime type.
   ///
   /// See [transform] for more information.
-  void _checkTearoff(Member target) {
+  void _checkTearoff(Member? target) {
     if (target != null &&
         target.name.isPrivate &&
         target.isInstanceMember &&
diff --git a/pkg/dev_compiler/pubspec.yaml b/pkg/dev_compiler/pubspec.yaml
index 41826b5..e0271f3 100644
--- a/pkg/dev_compiler/pubspec.yaml
+++ b/pkg/dev_compiler/pubspec.yaml
@@ -16,6 +16,7 @@
   build_integration:
     path: ../build_integration
   cli_util: any
+  collection: ^1.15.0
   front_end:
     path: ../front_end
   kernel:
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart
index 041dfd5..882f10c 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart
@@ -364,8 +364,8 @@
       Map<String, String>? environment,
       bool includeParentEnvironment = true,
       bool runInShell = false,
-      Encoding stdoutEncoding = systemEncoding,
-      Encoding stderrEncoding = systemEncoding}) {
+      Encoding? stdoutEncoding = systemEncoding,
+      Encoding? stderrEncoding = systemEncoding}) {
     throw UnsupportedError("Process.run");
   }
 
@@ -375,8 +375,8 @@
       Map<String, String>? environment,
       bool includeParentEnvironment = true,
       bool runInShell = false,
-      Encoding stdoutEncoding = systemEncoding,
-      Encoding stderrEncoding = systemEncoding}) {
+      Encoding? stdoutEncoding = systemEncoding,
+      Encoding? stderrEncoding = systemEncoding}) {
     throw UnsupportedError("Process.runSync");
   }
 
diff --git a/sdk/lib/_internal/js_runtime/lib/io_patch.dart b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
index 77a2530..2ee566b 100644
--- a/sdk/lib/_internal/js_runtime/lib/io_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
@@ -364,8 +364,8 @@
       Map<String, String>? environment,
       bool includeParentEnvironment: true,
       bool runInShell: false,
-      Encoding stdoutEncoding: systemEncoding,
-      Encoding stderrEncoding: systemEncoding}) {
+      Encoding? stdoutEncoding: systemEncoding,
+      Encoding? stderrEncoding: systemEncoding}) {
     throw new UnsupportedError("Process.run");
   }
 
@@ -375,8 +375,8 @@
       Map<String, String>? environment,
       bool includeParentEnvironment: true,
       bool runInShell: false,
-      Encoding stdoutEncoding: systemEncoding,
-      Encoding stderrEncoding: systemEncoding}) {
+      Encoding? stdoutEncoding: systemEncoding,
+      Encoding? stderrEncoding: systemEncoding}) {
     throw new UnsupportedError("Process.runSync");
   }
 
diff --git a/sdk/lib/internal/symbol.dart b/sdk/lib/internal/symbol.dart
index 2ccb071..e494ff6 100644
--- a/sdk/lib/internal/symbol.dart
+++ b/sdk/lib/internal/symbol.dart
@@ -17,89 +17,6 @@
   @pragma('vm:entry-point')
   final String _name;
 
-  /**
-   * Source of RegExp matching Dart reserved words.
-   *
-   * Reserved words are not allowed as identifiers.
-   */
-  static const String reservedWordRE =
-      r'(?:assert|break|c(?:a(?:se|tch)|lass|on(?:st|tinue))|d(?:efault|o)|'
-      r'e(?:lse|num|xtends)|f(?:alse|inal(?:ly)?|or)|i[fns]|n(?:ew|ull)|'
-      r'ret(?:hrow|urn)|s(?:uper|witch)|t(?:h(?:is|row)|r(?:ue|y))|'
-      r'v(?:ar|oid)|w(?:hile|ith))';
-  /**
-   * Source of RegExp matching any public identifier.
-   *
-   * A public identifier is a valid identifier (not a reserved word)
-   * that doesn't start with '_'.
-   */
-  static const String publicIdentifierRE =
-      r'(?!' '$reservedWordRE' r'\b(?!\$))[a-zA-Z$][\w$]*';
-  /**
-   * Source of RegExp matching any identifier.
-   *
-   * It matches identifiers but not reserved words. The identifiers
-   * may start with '_'.
-   */
-  static const String identifierRE =
-      r'(?!' '$reservedWordRE' r'\b(?!\$))[a-zA-Z$_][\w$]*';
-  /**
-   * Source of RegExp matching a declarable operator names.
-   *
-   * The operators that can be declared using `operator` declarations are
-   * also the only ones allowed as symbols. The name of the operators is
-   * the same as the operator itself except for unary minus, where the name
-   * is "unary-".
-   */
-  static const String operatorRE =
-      r'(?:[\-+*/%&|^]|\[\]=?|==|~/?|<[<=]?|>(?:|=|>>?)|unary-)';
-
-  // Grammar if symbols:
-  //    symbol ::= qualifiedName | <empty>
-  //    qualifiedName ::= publicIdentifier '.' qualifiedName | name
-  //    name ::= publicIdentifier
-  //           | publicIdentifier '='
-  //           | operator
-  // where publicIdentifier is any valid identifier (not a reserved word)
-  // that isn't private (doesn't start with '_').
-  //
-  // Railroad diagram of the accepted grammar:
-  //
-  //    /----------------\
-  //    |                |
-  //    |          /-[.]-/     /-[=]-\
-  //    \         /           /       \
-  //  -------[id]------------------------->
-  //       \                     /
-  //        \------[operator]---/
-  //            \              /
-  //             \------------/
-  //
-
-  /**
-   * RegExp that validates a non-empty non-private symbol.
-   *
-   * The empty symbol is handled before this regexp is used, and is not
-   * accepted.
-   */
-  static final RegExp publicSymbolPattern = new RegExp(
-      '^(?:$operatorRE\$|$publicIdentifierRE(?:=?\$|[.](?!\$)))+?\$');
-
-  // The grammar of symbols that may be private is the same as for public
-  // symbols, except that "publicIdentifier" is replaced by "identifier",
-  // which matches any identifier.
-
-  /**
-   * RegExp that validates a non-empty symbol.
-   *
-   * Private symbols are accepted.
-   *
-   * The empty symbol is handled before this regexp is used, and is not
-   * accepted.
-   */
-  static final RegExp symbolPattern =
-      new RegExp('^(?:$operatorRE\$|$identifierRE(?:=?\$|[.](?!\$)))+?\$');
-
   external const Symbol(String name);
 
   /**
@@ -117,25 +34,5 @@
   /// Platform-private accessor which cannot be called from user libraries.
   static String getName(Symbol symbol) => symbol._name;
 
-  static String validatePublicSymbol(String name) {
-    if (name.isEmpty || publicSymbolPattern.hasMatch(name)) return name;
-    if (name.startsWith('_')) {
-      // There may be other private parts in a qualified name than the first
-      // one, but this is a common case that deserves a specific error
-      // message.
-      throw new ArgumentError('"$name" is a private identifier');
-    }
-    throw new ArgumentError('"$name" is not a valid (qualified) symbol name');
-  }
-
-  /**
-   * Checks whether name is a valid symbol name.
-   *
-   * This test allows both private and non-private symbols.
-   */
-  static bool isValidSymbol(String name) {
-    return (name.isEmpty || symbolPattern.hasMatch(name));
-  }
-
   external static String computeUnmangledName(Symbol symbol);
 }
diff --git a/tools/VERSION b/tools/VERSION
index b155add..0149fdb 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 354
+PRERELEASE 355
 PRERELEASE_PATCH 0
\ No newline at end of file