Version 2.16.0-127.0.dev

Merge commit '6b719d726e3189cb188a05606d4e5958b7905704' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index e95c948..284ed91 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-12-16T12:51:36.232645",
+  "generated": "2021-12-10T17:31:54.553345",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
@@ -372,6 +372,12 @@
       "languageVersion": "2.12"
     },
     {
+      "name": "intl",
+      "rootUri": "../third_party/pkg/intl",
+      "packageUri": "lib/",
+      "languageVersion": "2.11"
+    },
+    {
       "name": "js",
       "rootUri": "../pkg/js",
       "packageUri": "lib/",
@@ -811,4 +817,4 @@
       "languageVersion": "2.12"
     }
   ]
-}
+}
\ No newline at end of file
diff --git a/DEPS b/DEPS
index 1cb6ae4..727fe76 100644
--- a/DEPS
+++ b/DEPS
@@ -120,6 +120,7 @@
   "http_parser_rev": "202391286ddc13c4c3c284ac5b511f04697250ed",
   "http_rev": "f35d1e1467092f6a5edb2abf7071c4a99e8c737a",
   "icu_rev" : "81d656878ec611cb0b42d52c82e9dae93920d9ba",
+  "intl_tag": "0.17.0-nullsafety",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_rev": "7e00f893440a72de0637970325e4ea44bd1e8c8e",
   "linter_tag": "1.17.1",
@@ -364,6 +365,8 @@
       "@" + Var("http_multi_server_rev"),
   Var("dart_root") + "/third_party/pkg/http_parser":
       Var("dart_git") + "http_parser.git" + "@" + Var("http_parser_rev"),
+  Var("dart_root") + "/third_party/pkg/intl":
+      Var("dart_git") + "intl.git" + "@" + Var("intl_tag"),
   Var("dart_root") + "/third_party/pkg/json_rpc_2":
       Var("dart_git") + "json_rpc_2.git" + "@" + Var("json_rpc_2_rev"),
   Var("dart_root") + "/third_party/pkg/linter":
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index 5ab8cff..b7f2f61 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -333,9 +333,8 @@
         latencyCount > 0 ? (perf.slowRequestCount / latencyCount) : 0.0;
 
     buf.write('<table>');
-    writeRow([printInteger(requestCount), 'requests'],
-        classes: ['right', null]);
-    writeRow([printInteger(latencyCount), 'requests with latency information'],
+    writeRow(['$requestCount', 'requests'], classes: ['right', null]);
+    writeRow(['$latencyCount', 'requests with latency information'],
         classes: ['right', null]);
     if (latencyCount > 0) {
       writeRow([printMilliseconds(averageLatency), 'average latency'],
@@ -431,7 +430,7 @@
                 'An analysis context defines the options and the set of sources being analyzed.');
 
   @override
-  String get navDetail => printInteger(server.driverMap.length);
+  String get navDetail => '${server.driverMap.length}';
 
   String describe(AnalysisOptionsImpl options) {
     var b = StringBuffer();
@@ -898,7 +897,7 @@
   Iterable<ServerException> get exceptions => server.exceptions.items;
 
   @override
-  String get navDetail => printInteger(exceptions.length);
+  String get navDetail => '${exceptions.length}';
 
   @override
   Future generateContent(Map<String, String> params) async {
@@ -1064,8 +1063,7 @@
     if (usage != null) {
       buf.writeln(
           writeOption('CPU', printPercentage(usage.cpuPercentage / 100.0)));
-      buf.writeln(
-          writeOption('Memory', '${printInteger(usage.memoryMB.round())} MB'));
+      buf.writeln(writeOption('Memory', '${usage.memoryMB.round()} MB'));
 
       h3('VM');
 
diff --git a/pkg/analysis_server/lib/src/status/pages.dart b/pkg/analysis_server/lib/src/status/pages.dart
index 894d446..d2c6bb3 100644
--- a/pkg/analysis_server/lib/src/status/pages.dart
+++ b/pkg/analysis_server/lib/src/status/pages.dart
@@ -7,8 +7,6 @@
 
 String escape(String? text) => text == null ? '' : htmlEscape.convert(text);
 
-String printInteger(int value) => '$value';
-
 String printMilliseconds(int value) => '$value ms';
 
 String printPercentage(num value, [int fractionDigits = 1]) =>
diff --git a/pkg/dartdev/lib/src/commands/fix.dart b/pkg/dartdev/lib/src/commands/fix.dart
index f8659f6..1bdb252 100644
--- a/pkg/dartdev/lib/src/commands/fix.dart
+++ b/pkg/dartdev/lib/src/commands/fix.dart
@@ -149,16 +149,16 @@
 
       if (dryRun) {
         log.stdout('');
-        log.stdout('${_format(fixCount)} proposed ${_pluralFix(fixCount)} '
-            'in ${_format(fileCount)} ${pluralize("file", fileCount)}.');
+        log.stdout('$fixCount proposed ${_pluralFix(fixCount)} '
+            'in $fileCount ${pluralize("file", fileCount)}.');
         _printDetails(detailsMap, dir);
       } else {
         var applyFixesProgress = log.progress('Applying fixes');
         _writeFiles();
         applyFixesProgress.finish(showTiming: true);
         _printDetails(detailsMap, dir);
-        log.stdout('${_format(fixCount)} ${_pluralFix(fixCount)} made in '
-            '${_format(fileCount)} ${pluralize("file", fileCount)}.');
+        log.stdout('$fixCount ${_pluralFix(fixCount)} made in '
+            '$fileCount ${pluralize("file", fileCount)}.');
       }
     }
 
@@ -311,7 +311,7 @@
       fixes.sort((a, b) => a.code.compareTo(b.code));
       for (var fix in fixes) {
         log.stdout('  ${fix.code} $bullet '
-            '${_format(fix.occurrences)} ${_pluralFix(fix.occurrences)}');
+            '${fix.occurrences} ${_pluralFix(fix.occurrences)}');
       }
       log.stdout('');
     }
@@ -340,8 +340,6 @@
       file.writeAsStringSync(entry.value);
     }
   }
-
-  static String _format(int value) => '$value';
 }
 
 /// The result of running tests in a given directory.
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 5dace80..82bbe12 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -837,7 +837,9 @@
               'macros', libraryBuilder.enableMacrosVersionInLibrary.toText()),
           macroToken.next!.charOffset,
           macroToken.next!.length);
+      macroToken = null;
     }
+    push(macroToken ?? NullValue.Token);
   }
 
   @override
@@ -927,7 +929,9 @@
               'macros', libraryBuilder.enableMacrosVersionInLibrary.toText()),
           macroToken.next!.charOffset,
           macroToken.next!.length);
+      macroToken = null;
     }
+    push(macroToken ?? NullValue.Token);
   }
 
   @override
@@ -1060,10 +1064,26 @@
   @override
   void endClassDeclaration(Token beginToken, Token endToken) {
     debugEvent("endClassDeclaration");
+    assert(checkState(beginToken, [
+      /* interfaces */ ValueKinds.TypeBuilderListOrNull,
+      /* supertype offset */ ValueKinds.Integer,
+      /* supertype */ unionOfKinds([
+        ValueKinds.TypeBuilderOrNull,
+        ValueKinds.ParserRecovery,
+      ]),
+      /* macro token */ ValueKinds.TokenOrNull,
+      /* modifiers */ ValueKinds.Integer,
+      /* type variables */ ValueKinds.TypeVariableListOrNull,
+      /* name offset */ ValueKinds.Integer,
+      /* name */ ValueKinds.NameOrParserRecovery,
+      /* metadata */ ValueKinds.MetadataListOrNull,
+    ]));
+
     List<TypeBuilder>? interfaces =
         pop(NullValue.TypeBuilderList) as List<TypeBuilder>?;
     int supertypeOffset = popCharOffset();
     TypeBuilder? supertype = nullIfParserRecovery(pop()) as TypeBuilder?;
+    Token? macroToken = pop(NullValue.Token) as Token?;
     int modifiers = pop() as int;
     List<TypeVariableBuilder>? typeVariables =
         pop() as List<TypeVariableBuilder>?;
@@ -1140,7 +1160,8 @@
           startCharOffset,
           nameOffset,
           endToken.charOffset,
-          supertypeOffset);
+          supertypeOffset,
+          isMacro: macroToken != null);
     }
     libraryBuilder.setCurrentClassName(null);
     popDeclarationContext(DeclarationContext.Class);
@@ -1898,9 +1919,25 @@
   void endNamedMixinApplication(Token beginToken, Token classKeyword,
       Token equals, Token? implementsKeyword, Token endToken) {
     debugEvent("endNamedMixinApplication");
+    assert(checkState(beginToken, [
+      if (implementsKeyword != null)
+        /* interfaces */ ValueKinds.TypeBuilderListOrNull,
+      /* mixin application */ unionOfKinds([
+        ValueKinds.ParserRecovery,
+        ValueKinds.TypeBuilder,
+      ]),
+      /* macro token */ ValueKinds.TokenOrNull,
+      /* modifiers */ ValueKinds.Integer,
+      /* type variables */ ValueKinds.TypeVariableListOrNull,
+      /* name offset */ ValueKinds.Integer,
+      /* name */ ValueKinds.NameOrParserRecovery,
+      /* metadata */ ValueKinds.MetadataListOrNull,
+    ]));
+
     List<TypeBuilder>? interfaces =
         popIfNotNull(implementsKeyword) as List<TypeBuilder>?;
     Object? mixinApplication = pop();
+    Token? macroToken = pop(NullValue.Token) as Token?;
     int modifiers = pop() as int;
     List<TypeVariableBuilder>? typeVariables =
         pop() as List<TypeVariableBuilder>?;
@@ -1968,7 +2005,8 @@
           interfaces,
           startCharOffset,
           charOffset,
-          charEndOffset);
+          charEndOffset,
+          isMacro: macroToken != null);
     }
     popDeclarationContext(DeclarationContext.NamedMixinApplication);
   }
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 23ad100..f9033bb 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -100,26 +100,29 @@
 
   final IndexedClass? referencesFromIndexed;
 
+  final bool isMacro;
+
   SourceClassBuilder(
-    List<MetadataBuilder>? metadata,
-    int modifiers,
-    String name,
-    List<TypeVariableBuilder>? typeVariables,
-    TypeBuilder? supertype,
-    List<TypeBuilder>? interfaces,
-    List<TypeBuilder>? onTypes,
-    Scope scope,
-    ConstructorScope constructors,
-    SourceLibraryBuilder parent,
-    this.constructorReferences,
-    int startCharOffset,
-    int nameOffset,
-    int charEndOffset,
-    this.referencesFromIndexed, {
-    Class? cls,
-    this.mixedInTypeBuilder,
-    this.isMixinDeclaration = false,
-  })  : actualCls = initializeClass(cls, typeVariables, name, parent,
+      List<MetadataBuilder>? metadata,
+      int modifiers,
+      String name,
+      List<TypeVariableBuilder>? typeVariables,
+      TypeBuilder? supertype,
+      List<TypeBuilder>? interfaces,
+      List<TypeBuilder>? onTypes,
+      Scope scope,
+      ConstructorScope constructors,
+      SourceLibraryBuilder parent,
+      this.constructorReferences,
+      int startCharOffset,
+      int nameOffset,
+      int charEndOffset,
+      this.referencesFromIndexed,
+      {Class? cls,
+      this.mixedInTypeBuilder,
+      this.isMixinDeclaration = false,
+      this.isMacro: false})
+      : actualCls = initializeClass(cls, typeVariables, name, parent,
             startCharOffset, nameOffset, charEndOffset, referencesFromIndexed),
         super(metadata, modifiers, name, typeVariables, supertype, interfaces,
             onTypes, scope, constructors, parent, nameOffset) {
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 5089e47..3c68b27 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -1764,7 +1764,8 @@
       int startOffset,
       int nameOffset,
       int endOffset,
-      int supertypeOffset) {
+      int supertypeOffset,
+      {required bool isMacro}) {
     _addClass(
         TypeParameterScopeKind.classDeclaration,
         metadata,
@@ -1776,7 +1777,8 @@
         startOffset,
         nameOffset,
         endOffset,
-        supertypeOffset);
+        supertypeOffset,
+        isMacro: isMacro);
   }
 
   void addMixinDeclaration(
@@ -1801,7 +1803,8 @@
         startOffset,
         nameOffset,
         endOffset,
-        supertypeOffset);
+        supertypeOffset,
+        isMacro: false);
   }
 
   void _addClass(
@@ -1815,7 +1818,8 @@
       int startOffset,
       int nameOffset,
       int endOffset,
-      int supertypeOffset) {
+      int supertypeOffset,
+      {required bool isMacro}) {
     _checkBadFunctionDeclUse(className, kind, nameOffset);
     _checkBadFunctionParameter(typeVariables);
     // Nested declaration began in `OutlineBuilder.beginClassDeclaration`.
@@ -1853,7 +1857,7 @@
         typeVariables,
         applyMixins(supertype, startOffset, nameOffset, endOffset, className,
             isMixinDeclaration,
-            typeVariables: typeVariables),
+            typeVariables: typeVariables, isMacro: false),
         interfaces,
         // TODO(johnniwinther): Add the `on` clause types of a mixin declaration
         // here.
@@ -1866,7 +1870,8 @@
         nameOffset,
         endOffset,
         _currentClassReferencesFromIndexed,
-        isMixinDeclaration: isMixinDeclaration);
+        isMixinDeclaration: isMixinDeclaration,
+        isMacro: isMacro);
 
     constructorReferences.clear();
     Map<String, TypeVariableBuilder>? typeVariablesByName =
@@ -2126,7 +2131,8 @@
       String? name,
       List<TypeVariableBuilder>? typeVariables,
       int modifiers: 0,
-      List<TypeBuilder>? interfaces}) {
+      List<TypeBuilder>? interfaces,
+      required bool isMacro}) {
     if (name == null) {
       // The following parameters should only be used when building a named
       // mixin application.
@@ -2318,34 +2324,34 @@
         }
 
         SourceClassBuilder application = new SourceClassBuilder(
-          isNamedMixinApplication ? metadata : null,
-          isNamedMixinApplication
-              ? modifiers | namedMixinApplicationMask
-              : abstractMask,
-          fullname,
-          applicationTypeVariables,
-          isMixinDeclaration ? null : supertype,
-          isNamedMixinApplication
-              ? interfaces
-              : isMixinDeclaration
-                  ? [supertype, mixin]
-                  : null,
-          null, // No `on` clause types.
-          new Scope(
-              local: <String, MemberBuilder>{},
-              setters: <String, MemberBuilder>{},
-              parent: scope.withTypeVariables(typeVariables),
-              debugName: "mixin $fullname ",
-              isModifiable: false),
-          new ConstructorScope(fullname, <String, MemberBuilder>{}),
-          this,
-          <ConstructorReferenceBuilder>[],
-          computedStartCharOffset,
-          charOffset,
-          charEndOffset,
-          referencesFromIndexedClass,
-          mixedInTypeBuilder: isMixinDeclaration ? null : mixin,
-        );
+            isNamedMixinApplication ? metadata : null,
+            isNamedMixinApplication
+                ? modifiers | namedMixinApplicationMask
+                : abstractMask,
+            fullname,
+            applicationTypeVariables,
+            isMixinDeclaration ? null : supertype,
+            isNamedMixinApplication
+                ? interfaces
+                : isMixinDeclaration
+                    ? [supertype, mixin]
+                    : null,
+            null, // No `on` clause types.
+            new Scope(
+                local: <String, MemberBuilder>{},
+                setters: <String, MemberBuilder>{},
+                parent: scope.withTypeVariables(typeVariables),
+                debugName: "mixin $fullname ",
+                isModifiable: false),
+            new ConstructorScope(fullname, <String, MemberBuilder>{}),
+            this,
+            <ConstructorReferenceBuilder>[],
+            computedStartCharOffset,
+            charOffset,
+            charEndOffset,
+            referencesFromIndexedClass,
+            mixedInTypeBuilder: isMixinDeclaration ? null : mixin,
+            isMacro: isNamedMixinApplication && isMacro);
         // TODO(ahe, kmillikin): Should always be true?
         // pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart can't
         // handle that :(
@@ -2372,7 +2378,8 @@
       List<TypeBuilder>? interfaces,
       int startCharOffset,
       int charOffset,
-      int charEndOffset) {
+      int charEndOffset,
+      {required bool isMacro}) {
     // Nested declaration began in `OutlineBuilder.beginNamedMixinApplication`.
     endNestedDeclaration(TypeParameterScopeKind.namedMixinApplication, name)
         .resolveNamedTypes(typeVariables, this);
@@ -2382,7 +2389,8 @@
         name: name,
         typeVariables: typeVariables,
         modifiers: modifiers,
-        interfaces: interfaces)!;
+        interfaces: interfaces,
+        isMacro: isMacro)!;
     checkTypeVariables(typeVariables, supertype.declaration);
   }
 
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 4ec6c32..2f6b52c 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -35,7 +35,6 @@
 import '../../base/common.dart';
 import '../../base/instrumentation.dart' show Instrumentation;
 import '../../base/nnbd_mode.dart';
-import '../dill/dill_class_builder.dart';
 import '../dill/dill_library_builder.dart';
 import '../builder_graph.dart';
 import '../builder/builder.dart';
@@ -1324,36 +1323,8 @@
     Set<ClassBuilder> macroClasses = {macroClassBuilder};
     Set<Uri> macroLibraries = {macroLibraryBuilder.importUri};
 
-    bool isMacroClass(TypeDeclarationBuilder? typeDeclarationBuilder) {
-      if (typeDeclarationBuilder == null) return false;
-      while (typeDeclarationBuilder is TypeAliasBuilder) {
-        typeDeclarationBuilder =
-            typeDeclarationBuilder.unaliasDeclaration(null);
-      }
-      if (typeDeclarationBuilder is ClassBuilder) {
-        if (macroClasses.contains(typeDeclarationBuilder)) return true;
-        if (typeDeclarationBuilder is DillClassBuilder) {
-          // TODO(johnniwinther): Recognize macro classes from dill.
-        }
-      }
-      return false;
-    }
-
     for (SourceClassBuilder sourceClassBuilder in sourceClassBuilders) {
-      bool isMacro =
-          isMacroClass(sourceClassBuilder.supertypeBuilder?.declaration);
-      if (!isMacro && sourceClassBuilder.interfaceBuilders != null) {
-        for (TypeBuilder interfaceBuilder
-            in sourceClassBuilder.interfaceBuilders!) {
-          if (isMacroClass(interfaceBuilder.declaration)) {
-            isMacro = true;
-            break;
-          }
-        }
-      }
-      isMacro = isMacro ||
-          isMacroClass(sourceClassBuilder.mixedInTypeBuilder?.declaration);
-      if (isMacro) {
+      if (sourceClassBuilder.isMacro) {
         macroClasses.add(sourceClassBuilder);
         macroLibraries.add(sourceClassBuilder.library.importUri);
         if (retainDataForTesting) {
diff --git a/pkg/front_end/test/macros/data/pkgs/macro/lib/macro.dart b/pkg/front_end/test/macros/data/pkgs/macro/lib/macro.dart
index bfe0285..f79b175 100644
--- a/pkg/front_end/test/macros/data/pkgs/macro/lib/macro.dart
+++ b/pkg/front_end/test/macros/data/pkgs/macro/lib/macro.dart
@@ -4,15 +4,15 @@
 
 import 'package:macro_builder/macro_builder.dart';
 
-class Macro1 implements Macro {
+macro class Macro1 implements Macro {
   const Macro1();
 }
 
-class Macro2 implements Macro {
+macro class Macro2 implements Macro {
   const Macro2();
 }
 
-class Macro3 implements Macro {
+macro class Macro3 implements Macro {
   const Macro3();
 }
 
diff --git a/pkg/front_end/test/macros/data/tests/declare_macro.dart b/pkg/front_end/test/macros/data/tests/declare_macro.dart
index 5d396f7..e6d329e 100644
--- a/pkg/front_end/test/macros/data/tests/declare_macro.dart
+++ b/pkg/front_end/test/macros/data/tests/declare_macro.dart
@@ -12,6 +12,6 @@
 
 import 'package:macro_builder/macro_builder.dart';
 
-class MyMacro implements Macro {}
+macro class MyMacro implements Macro {}
 
 void main() {}
diff --git a/pkg/front_end/test/macros/data/tests/declare_vs_apply/macro_lib.dart b/pkg/front_end/test/macros/data/tests/declare_vs_apply/macro_lib.dart
index 149d512..f1aac83 100644
--- a/pkg/front_end/test/macros/data/tests/declare_vs_apply/macro_lib.dart
+++ b/pkg/front_end/test/macros/data/tests/declare_vs_apply/macro_lib.dart
@@ -10,6 +10,6 @@
 import 'package:macro_builder/macro_builder.dart';
 import 'macro_lib_dep.dart';
 
-class Macro1 extends MacroBase implements Macro {
+macro class Macro1 extends MacroBase implements Macro {
   const Macro1();
 }
diff --git a/pkg/front_end/test/macros/data/tests/import_macro_source/macro_lib.dart b/pkg/front_end/test/macros/data/tests/import_macro_source/macro_lib.dart
index a05f387..c08cbcd 100644
--- a/pkg/front_end/test/macros/data/tests/import_macro_source/macro_lib.dart
+++ b/pkg/front_end/test/macros/data/tests/import_macro_source/macro_lib.dart
@@ -9,6 +9,6 @@
 
 import 'package:macro_builder/macro_builder.dart';
 
-class Macro1 implements Macro {
+macro class Macro1 implements Macro {
   const Macro1();
 }
diff --git a/pkg/front_end/test/macros/data/tests/macro_declarations.dart b/pkg/front_end/test/macros/data/tests/macro_declarations.dart
index 872dad84..f5f5a5f 100644
--- a/pkg/front_end/test/macros/data/tests/macro_declarations.dart
+++ b/pkg/front_end/test/macros/data/tests/macro_declarations.dart
@@ -13,25 +13,47 @@
   ImplementsAlias,
   Mixin,
   MixinAlias,
-  _Mixin&Object&Macro,
-  _MixinAlias&Object&Alias],
+  NamedMixin1,
+  NamedMixin2],
  macrosAreAvailable
 */
 
 import 'package:macro_builder/macro_builder.dart';
 
-class Extends extends Macro {}
+macro class Extends extends Macro {}
 
-class Implements implements Macro {}
+macro class Implements implements Macro {}
 
-class Mixin with Macro {}
+macro class Mixin with Macro {}
+
+mixin _Mixin {}
+
+macro class NamedMixin1 = Macro with _Mixin;
+
+macro class NamedMixin2 = Object with Macro;
 
 typedef Alias = Macro;
 
-class ExtendsAlias extends Alias {}
+macro class ExtendsAlias extends Alias {}
 
-class ImplementsAlias implements Alias {}
+macro class ImplementsAlias implements Alias {}
 
-class MixinAlias with Alias {}
+macro class MixinAlias with Alias {}
+
+class ExtendsNoKeyword extends Macro {}
+
+class ImplementsNoKeyword implements Macro {}
+
+class MixinNoKeyword with Macro {}
+
+class ExtendsAliasNoKeyword extends Alias {}
+
+class ImplementsAliasNoKeyword implements Alias {}
+
+class MixinAliasNoKeyword with Alias {}
+
+class NamedMixin1NoKeyword = Macro with _Mixin;
+
+class NamedMixin2NoKeyword = Object with Macro;
 
 void main() {}
diff --git a/pkg/front_end/test/macros/data/tests/multiple_macros/macro_lib1.dart b/pkg/front_end/test/macros/data/tests/multiple_macros/macro_lib1.dart
index a05f387..c08cbcd 100644
--- a/pkg/front_end/test/macros/data/tests/multiple_macros/macro_lib1.dart
+++ b/pkg/front_end/test/macros/data/tests/multiple_macros/macro_lib1.dart
@@ -9,6 +9,6 @@
 
 import 'package:macro_builder/macro_builder.dart';
 
-class Macro1 implements Macro {
+macro class Macro1 implements Macro {
   const Macro1();
 }
diff --git a/pkg/front_end/test/macros/data/tests/multiple_macros/macro_lib2a.dart b/pkg/front_end/test/macros/data/tests/multiple_macros/macro_lib2a.dart
index 967801f..729e7f1 100644
--- a/pkg/front_end/test/macros/data/tests/multiple_macros/macro_lib2a.dart
+++ b/pkg/front_end/test/macros/data/tests/multiple_macros/macro_lib2a.dart
@@ -9,6 +9,6 @@
 
 import 'package:macro_builder/macro_builder.dart';
 
-class Macro2a implements Macro {
+macro class Macro2a implements Macro {
   const Macro2a();
 }
diff --git a/pkg/front_end/test/macros/data/tests/multiple_macros/macro_lib2b.dart b/pkg/front_end/test/macros/data/tests/multiple_macros/macro_lib2b.dart
index b9bc7d2..df143f5 100644
--- a/pkg/front_end/test/macros/data/tests/multiple_macros/macro_lib2b.dart
+++ b/pkg/front_end/test/macros/data/tests/multiple_macros/macro_lib2b.dart
@@ -16,6 +16,6 @@
  appliedMacros=[Macro2a],
  macrosAreApplied
 */
-class Macro2b implements Macro {
+macro class Macro2b implements Macro {
   const Macro2b();
 }
diff --git a/pkg/front_end/test/macros/data/tests/use_macro_source/macro_lib.dart b/pkg/front_end/test/macros/data/tests/use_macro_source/macro_lib.dart
index 3f926a8..f3767a5 100644
--- a/pkg/front_end/test/macros/data/tests/use_macro_source/macro_lib.dart
+++ b/pkg/front_end/test/macros/data/tests/use_macro_source/macro_lib.dart
@@ -11,11 +11,11 @@
 
 import 'package:macro_builder/macro_builder.dart';
 
-class Macro1 implements Macro {
+macro class Macro1 implements Macro {
   const Macro1();
 }
 
-class Macro2 implements Macro {
+macro class Macro2 implements Macro {
   const Macro2();
 }
 
diff --git a/pkg/front_end/test/macros/macro_test.dart b/pkg/front_end/test/macros/macro_test.dart
index 82fe62d..c1aa33e 100644
--- a/pkg/front_end/test/macros/macro_test.dart
+++ b/pkg/front_end/test/macros/macro_test.dart
@@ -8,6 +8,7 @@
 import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
 
 import 'package:_fe_analyzer_shared/src/testing/features.dart';
+import 'package:front_end/src/api_prototype/experimental_flags.dart';
 import 'package:front_end/src/fasta/kernel/macro.dart';
 import 'package:front_end/src/testing/id_testing_helper.dart';
 import 'package:kernel/ast.dart';
@@ -23,6 +24,7 @@
       onFailure: onFailure,
       runTest: runTestFor(const MacroDataComputer(), [
         new TestConfig(cfeMarker, 'cfe',
+            explicitExperimentalFlags: {ExperimentalFlag.macros: true},
             packageConfigUri:
                 Platform.script.resolve('data/package_config.json'))
       ]));
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 7a1fd28..ea9623a 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -675,6 +675,8 @@
 misspelled
 mistake
 mistakes
+mixin1
+mixin2
 mmethod
 mod
 modelled
diff --git a/pkg/smith/analysis_options.yaml b/pkg/smith/analysis_options.yaml
index 1a46de2..55af634 100644
--- a/pkg/smith/analysis_options.yaml
+++ b/pkg/smith/analysis_options.yaml
@@ -1,3 +1,3 @@
 analyzer:
-  strong-mode:
-    implicit-casts: false
+  language:
+    strict-casts: true
diff --git a/pkg/smith/lib/builder.dart b/pkg/smith/lib/builder.dart
index ebe550c..6f27730 100644
--- a/pkg/smith/lib/builder.dart
+++ b/pkg/smith/lib/builder.dart
@@ -73,11 +73,12 @@
         throw FormatException("Step tests multiple configurations: $arguments");
       }
     }
+    var environment = map["environment"] as Map<Object?, Object?>?;
     return Step(
         map["name"] as String,
         script,
         arguments,
-        <String, String>{...?map["environment"]},
+        {...?environment?.cast<String, String>()},
         map["fileset"] as String?,
         map["shards"] as int?,
         isTestRunner,
@@ -192,14 +193,17 @@
   var names = <String>{};
   for (var builderConfiguration in builderConfigurations) {
     var meta = builderConfiguration["meta"] as Map? ?? <String, String>{};
-    var builderNames = <String>[...?builderConfiguration["builders"]];
-    var steps = <Map>[...?builderConfiguration["steps"]];
-    for (var builderName in builderNames) {
-      if (!names.add(builderName)) {
-        throw FormatException('Duplicate builder name: "$builderName"');
+    var builderNames = builderConfiguration["builders"] as List<Object?>?;
+    if (builderNames != null) {
+      var steps = ((builderConfiguration["steps"] ?? []) as List<Object?>)
+          .cast<Map<Object?, Object?>>();
+      for (var builderName in builderNames.cast<String>()) {
+        if (!names.add(builderName)) {
+          throw FormatException('Duplicate builder name: "$builderName"');
+        }
+        builders.add(Builder.parse(builderName, steps, configurations,
+            meta["description"] as String?));
       }
-      builders.add(Builder.parse(
-          builderName, steps, configurations, meta["description"] as String?));
     }
   }
   return builders;
diff --git a/pkg/smith/lib/test_matrix.dart b/pkg/smith/lib/test_matrix.dart
index 0af1ca8..a81a0e3 100644
--- a/pkg/smith/lib/test_matrix.dart
+++ b/pkg/smith/lib/test_matrix.dart
@@ -52,9 +52,13 @@
       }
     });
 
-    var builderConfigurations = <Map>[...?json["builder_configurations"]];
+    var builderConfigurations = [
+      ...?(json["builder_configurations"] as List<Object?>?)
+          ?.cast<Map<Object?, Object?>>()
+    ];
     var builders = parseBuilders(builderConfigurations, configurations);
-    var branches = <String>[...?json["branches"]];
+    var branchesValue = json["branches"] as List?;
+    var branches = [...?branchesValue?.cast<String>()];
 
     // Check that each configuration is tested on at most one builder.
     var testedOn = <Configuration, Builder>{};
diff --git a/runtime/tests/vm/dart/print_object_layout_test.dart b/runtime/tests/vm/dart/print_object_layout_test.dart
index 5aa0ee3..36620d6 100644
--- a/runtime/tests/vm/dart/print_object_layout_test.dart
+++ b/runtime/tests/vm/dart/print_object_layout_test.dart
@@ -12,7 +12,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:path/path.dart' as path;
-import 'snapshot_test_helper.dart';
+import 'use_flag_test_helper.dart';
 
 verifyObjectLayout(String path) {
   final classes = jsonDecode(File(path).readAsStringSync());
@@ -43,7 +43,7 @@
 
   Expect.isNotNull(sizeB);
   Expect.isTrue(sizeB > 0);
-  Expect.isTrue(sizeA < sizeB);
+  Expect.isTrue(sizeA <= sizeB);
   Expect.isTrue(fieldsB.length == 3);
   for (var field in fieldsB) {
     String fieldName = field['field'];
@@ -59,28 +59,38 @@
 }
 
 main() async {
-  // We don't have access to the SDK on Android.
+  if (!isAOTRuntime) {
+    return; // Running in JIT: AOT binaries not available.
+  }
+
   if (Platform.isAndroid) {
-    print('Skipping test on Android');
-    return;
+    return; // SDK tree not available on the test device.
+  }
+
+  // These are the tools we need to be available to run on a given platform:
+  if (!File(platformDill).existsSync()) {
+    throw "Cannot run test as $platformDill does not exist";
+  }
+  if (!await testExecutable(genSnapshot)) {
+    throw "Cannot run test as $genSnapshot not available";
   }
 
   final testScriptUri =
       Platform.script.resolve('print_object_layout_script.dart');
 
-  await withTempDir((String temp) async {
+  await withTempDir('print-object-layout-test', (String temp) async {
     final appDillPath = path.join(temp, 'app.dill');
     final snapshotPath = path.join(temp, 'aot.snapshot');
     final objectLayoutPath = path.join(temp, 'layout.json');
 
-    await runGenKernel('BUILD DILL FILE', [
+    await run(genKernel, <String>[
       '--aot',
-      '--link-platform',
+      '--platform=$platformDill',
       '--output=$appDillPath',
       testScriptUri.toFilePath(),
     ]);
 
-    await runGenSnapshot('GENERATE SNAPSHOT', [
+    await run(genSnapshot, <String>[
       '--snapshot-kind=app-aot-elf',
       '--elf=$snapshotPath',
       '--print-object-layout-to=$objectLayoutPath',
diff --git a/runtime/tests/vm/dart_2/print_object_layout_test.dart b/runtime/tests/vm/dart_2/print_object_layout_test.dart
index 5f0f43e..e082bea 100644
--- a/runtime/tests/vm/dart_2/print_object_layout_test.dart
+++ b/runtime/tests/vm/dart_2/print_object_layout_test.dart
@@ -14,7 +14,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:path/path.dart' as path;
-import 'snapshot_test_helper.dart';
+import 'use_flag_test_helper.dart';
 
 verifyObjectLayout(String path) {
   final classes = jsonDecode(File(path).readAsStringSync());
@@ -45,7 +45,7 @@
 
   Expect.isNotNull(sizeB);
   Expect.isTrue(sizeB > 0);
-  Expect.isTrue(sizeA < sizeB);
+  Expect.isTrue(sizeA <= sizeB);
   Expect.isTrue(fieldsB.length == 3);
   for (var field in fieldsB) {
     String fieldName = field['field'];
@@ -61,28 +61,38 @@
 }
 
 main() async {
-  // We don't have access to the SDK on Android.
+  if (!isAOTRuntime) {
+    return; // Running in JIT: AOT binaries not available.
+  }
+
   if (Platform.isAndroid) {
-    print('Skipping test on Android');
-    return;
+    return; // SDK tree not available on the test device.
+  }
+
+  // These are the tools we need to be available to run on a given platform:
+  if (!File(platformDill).existsSync()) {
+    throw "Cannot run test as $platformDill does not exist";
+  }
+  if (!await testExecutable(genSnapshot)) {
+    throw "Cannot run test as $genSnapshot not available";
   }
 
   final testScriptUri =
       Platform.script.resolve('print_object_layout_script.dart');
 
-  await withTempDir((String temp) async {
+  await withTempDir('print-object-layout-test', (String temp) async {
     final appDillPath = path.join(temp, 'app.dill');
     final snapshotPath = path.join(temp, 'aot.snapshot');
     final objectLayoutPath = path.join(temp, 'layout.json');
 
-    await runGenKernel('BUILD DILL FILE', [
+    await run(genKernel, <String>[
       '--aot',
-      '--link-platform',
+      '--platform=$platformDill',
       '--output=$appDillPath',
       testScriptUri.toFilePath(),
     ]);
 
-    await runGenSnapshot('GENERATE SNAPSHOT', [
+    await run(genSnapshot, <String>[
       '--snapshot-kind=app-aot-elf',
       '--elf=$snapshotPath',
       '--print-object-layout-to=$objectLayoutPath',
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 6380213..0685477 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -57,12 +57,10 @@
 dart/kernel_determinism_test: SkipSlow
 dart/minimal_kernel_test: SkipSlow # gen_kernel is too slow with optimization_counter_threshold
 dart/null_safety_autodetection_in_kernel_compiler_test: SkipSlow # gen_kernel is too slow with optimization_counter_threshold
-dart/print_object_layout_test: SkipSlow # gen_kernel is too slow with optimization_counter_threshold
 dart_2/appjit*: SkipByDesign # Test needs to a particular opt-counter value
 dart_2/kernel_determinism_test: SkipSlow
 dart_2/minimal_kernel_test: SkipSlow # gen_kernel is too slow with optimization_counter_threshold
 dart_2/null_safety_autodetection_in_kernel_compiler_test: SkipSlow # gen_kernel is too slow with optimization_counter_threshold
-dart_2/print_object_layout_test: SkipSlow # gen_kernel is too slow with optimization_counter_threshold
 
 [ $builder_tag == tsan ]
 dart/appjit_cha_deopt_test: SkipSlow
@@ -131,14 +129,12 @@
 dart/b162922506_test: SkipSlow # Generates very large input file
 dart/minimal_kernel_test: SkipSlow # gen_kernel is too slow in debug mode
 dart/null_safety_autodetection_in_kernel_compiler_test: SkipSlow # gen_kernel is too slow in debug mode
-dart/print_object_layout_test: SkipSlow # gen_kernel is too slow in debug mode
 dart/spawn_shutdown_test: Pass, Slow # VM Shutdown test, It can take some time for all the isolates to shutdown in a Debug build.
 dart/type_casts_with_null_safety_autodetection_test: Pass, Slow # Very slow in debug mode, uses --optimization-counter-threshold=10
 dart_2/appjit_cha_deopt_test: Pass, Slow # Quite slow in debug mode, uses --optimization-counter-threshold=100
 dart_2/b162922506_test: SkipSlow # Generates very large input file
 dart_2/minimal_kernel_test: SkipSlow # gen_kernel is too slow in debug mode
 dart_2/null_safety_autodetection_in_kernel_compiler_test: SkipSlow # gen_kernel is too slow in debug mode
-dart_2/print_object_layout_test: SkipSlow # gen_kernel is too slow in debug mode
 dart_2/spawn_shutdown_test: Pass, Slow # VM Shutdown test, It can take some time for all the isolates to shutdown in a Debug build.
 
 [ $mode == product ]
@@ -251,14 +247,12 @@
 dart/data_uri_spawn_test: Skip # Please triage.
 dart/minimal_kernel_test: SkipSlow # gen_kernel is too slow on simulated architectures
 dart/null_safety_autodetection_in_kernel_compiler_test: SkipSlow # gen_kernel is too slow on simulated architectures
-dart/print_object_layout_test: SkipSlow # gen_kernel is too slow on simulated architectures
 dart/snapshot_version_test: RuntimeError # Please triage.
 dart_2/appjit*: SkipSlow # DFE too slow
 dart_2/b162922506_test: SkipSlow # Generates large input file
 dart_2/data_uri_spawn_test: Skip # Please triage.
 dart_2/minimal_kernel_test: SkipSlow # gen_kernel is too slow on simulated architectures
 dart_2/null_safety_autodetection_in_kernel_compiler_test: SkipSlow # gen_kernel is too slow on simulated architectures
-dart_2/print_object_layout_test: SkipSlow # gen_kernel is too slow on simulated architectures
 dart_2/snapshot_version_test: RuntimeError # Please triage.
 
 [ $compiler == dartk && ($hot_reload || $hot_reload_rollback) ]
@@ -272,7 +266,6 @@
 dart/kernel_determinism_test: SkipByDesign # Test needs to run from source
 dart/minimal_kernel_test: SkipByDesign # Test needs to run from source
 dart/null_safety_autodetection_in_kernel_compiler_test: SkipByDesign # Test needs to run from source
-dart/print_object_layout_test: SkipByDesign # Test needs to run from source
 dart/regress_44026_test: SkipByDesign # Test needs to run from source
 dart/snapshot_depfile_test: SkipByDesign # Test needs to run from source
 dart/type_casts_with_null_safety_autodetection_test: SkipByDesign # Test needs to run from source
@@ -280,7 +273,6 @@
 dart_2/kernel_determinism_test: SkipByDesign # Test needs to run from source
 dart_2/minimal_kernel_test: SkipByDesign # Test needs to run from source
 dart_2/null_safety_autodetection_in_kernel_compiler_test: SkipByDesign # Test needs to run from source
-dart_2/print_object_layout_test: SkipByDesign # Test needs to run from source
 dart_2/snapshot_depfile_test: SkipByDesign # Test needs to run from source
 
 [ $compiler == dartkp && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
@@ -440,7 +432,6 @@
 dart/minimal_kernel_test: SkipSlow # gen_kernel is too slow in hot reload testing mode
 dart/null_safety_autodetection_in_kernel_compiler_test: SkipSlow # gen_kernel is too slow in hot reload testing mode
 dart/print_flow_graph_determinism_test: SkipSlow
-dart/print_object_layout_test: SkipSlow # gen_kernel is too slow in hot reload testing mode
 dart/slow_path_shared_stub_test: SkipSlow # Too slow with --shared-slow-path-triggers-gc flag and not relevant outside precompiled.
 dart/spawn_infinite_loop_test: Skip # We can shutdown an isolate before it reloads.
 dart/spawn_shutdown_test: Skip # We can shutdown an isolate before it reloads.
@@ -452,7 +443,6 @@
 dart_2/minimal_kernel_test: SkipSlow # gen_kernel is too slow in hot reload testing mode
 dart_2/null_safety_autodetection_in_kernel_compiler_test: SkipSlow # gen_kernel is too slow in hot reload testing mode
 dart_2/print_flow_graph_determinism_test: SkipSlow
-dart_2/print_object_layout_test: SkipSlow # gen_kernel is too slow in hot reload testing mode
 dart_2/slow_path_shared_stub_test: SkipSlow # Too slow with --shared-slow-path-triggers-gc flag and not relevant outside precompiled.
 dart_2/spawn_infinite_loop_test: Skip # We can shutdown an isolate before it reloads.
 dart_2/spawn_shutdown_test: Skip # We can shutdown an isolate before it reloads.
diff --git a/tools/VERSION b/tools/VERSION
index 5031272..c705869 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 16
 PATCH 0
-PRERELEASE 126
+PRERELEASE 127
 PRERELEASE_PATCH 0
\ No newline at end of file