Version 2.17.0-43.0.dev

Merge commit '5183ba3ca4fe3787cae3c0a6cc7f8748ff01bcf5' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0776b8b..aa16e28 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,19 @@
 - `IdbFactory.supportsDatabaseNames` has been deprecated. It will always return
   `false`.
 
+### Tools
+
+#### Dart command line
+
+- **Breaking Change** [#46100](https://github.com/dart-lang/sdk/issues/46100):
+  The standalone `dart2js` tool has been
+  marked deprecated as previously announced.
+  Its replacement is the `dart compile js` command.
+  Should you find any issues, or missing features, in the replacement
+  command, kindly file [an issue][].
+
+[an issue]: https://github.com/dart-lang/sdk/issues/new
+
 ## 2.16.0
 
 ### Core libraries
diff --git a/benchmarks/FfiMemory/dart/FfiMemory.dart b/benchmarks/FfiMemory/dart/FfiMemory.dart
index 6178f24..881eff2 100644
--- a/benchmarks/FfiMemory/dart/FfiMemory.dart
+++ b/benchmarks/FfiMemory/dart/FfiMemory.dart
@@ -15,6 +15,36 @@
 import 'package:ffi/ffi.dart';
 import 'package:benchmark_harness/benchmark_harness.dart';
 
+/// Represents a native unsigned pointer-sized integer in C.
+///
+/// [UintPtr] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+  Abi.androidArm: Uint32(),
+  Abi.androidArm64: Uint64(),
+  Abi.androidIA32: Uint32(),
+  Abi.androidX64: Uint64(),
+  Abi.fuchsiaArm64: Uint64(),
+  Abi.fuchsiaX64: Uint64(),
+  Abi.iosArm: Uint32(),
+  Abi.iosArm64: Uint64(),
+  Abi.iosX64: Uint64(),
+  Abi.linuxArm: Uint32(),
+  Abi.linuxArm64: Uint64(),
+  Abi.linuxIA32: Uint32(),
+  Abi.linuxX64: Uint64(),
+  Abi.linuxRiscv32: Uint32(),
+  Abi.linuxRiscv64: Uint64(),
+  Abi.macosArm64: Uint64(),
+  Abi.macosX64: Uint64(),
+  Abi.windowsArm64: Uint64(),
+  Abi.windowsIA32: Uint32(),
+  Abi.windowsX64: Uint64(),
+})
+class UintPtr extends AbiSpecificInteger {
+  const UintPtr();
+}
+
 //
 // Pointer store.
 //
diff --git a/benchmarks/FfiMemory/dart2/FfiMemory.dart b/benchmarks/FfiMemory/dart2/FfiMemory.dart
index b3a6cf9..86f7e1f 100644
--- a/benchmarks/FfiMemory/dart2/FfiMemory.dart
+++ b/benchmarks/FfiMemory/dart2/FfiMemory.dart
@@ -17,6 +17,36 @@
 import 'package:ffi/ffi.dart';
 import 'package:benchmark_harness/benchmark_harness.dart';
 
+/// Represents a native unsigned pointer-sized integer in C.
+///
+/// [UintPtr] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+  Abi.androidArm: Uint32(),
+  Abi.androidArm64: Uint64(),
+  Abi.androidIA32: Uint32(),
+  Abi.androidX64: Uint64(),
+  Abi.fuchsiaArm64: Uint64(),
+  Abi.fuchsiaX64: Uint64(),
+  Abi.iosArm: Uint32(),
+  Abi.iosArm64: Uint64(),
+  Abi.iosX64: Uint64(),
+  Abi.linuxArm: Uint32(),
+  Abi.linuxArm64: Uint64(),
+  Abi.linuxIA32: Uint32(),
+  Abi.linuxX64: Uint64(),
+  Abi.linuxRiscv32: Uint32(),
+  Abi.linuxRiscv64: Uint64(),
+  Abi.macosArm64: Uint64(),
+  Abi.macosX64: Uint64(),
+  Abi.windowsArm64: Uint64(),
+  Abi.windowsIA32: Uint32(),
+  Abi.windowsX64: Uint64(),
+})
+class UintPtr extends AbiSpecificInteger {
+  const UintPtr();
+}
+
 //
 // Pointer store.
 //
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
index 2bfd7e8..868e62f 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
@@ -87,11 +87,6 @@
   void declareInClass(DeclarationCode declaration);
 }
 
-/// The api used by [Macro]s to reflect on the currently available
-/// members, superclass, and mixins for a given [ClassDeclaration]
-abstract class ClassDeclarationBuilder
-    implements ClassMemberDeclarationBuilder, ClassIntrospector {}
-
 /// The interface used by [Macro]s to resolve any [NamedStaticType] to its
 /// declaration.
 ///
@@ -117,23 +112,25 @@
   /// Retrieve a [VariableDefinitionBuilder] for a field by [name].
   ///
   /// Throws an [ArgumentError] if there is no field by that name.
-  VariableDefinitionBuilder buildField(String name);
+  Future<VariableDefinitionBuilder> buildField(String name);
 
   /// Retrieve a [FunctionDefinitionBuilder] for a method by [name].
   ///
   /// Throws an [ArgumentError] if there is no method by that name.
-  FunctionDefinitionBuilder buildMethod(String name);
+  Future<FunctionDefinitionBuilder> buildMethod(String name);
 
   /// Retrieve a [ConstructorDefinitionBuilder] for a constructor by [name].
   ///
   /// Throws an [ArgumentError] if there is no constructor by that name.
-  ConstructorDefinitionBuilder buildConstructor(String name);
+  Future<ConstructorDefinitionBuilder> buildConstructor(String name);
 }
 
 /// The apis used by [Macro]s to define the body of a constructor
 /// or wrap the body of an existing constructor with additional statements.
 abstract class ConstructorDefinitionBuilder implements DefinitionBuilder {
-  /// Augments an existing constructor body with [body].
+  /// Augments an existing constructor body with [body] and [initializers].
+  ///
+  /// The [initializers] should not contain trailing or preceding commas.
   ///
   /// TODO: Link the library augmentations proposal to describe the semantics.
   void augment({FunctionBodyCode? body, List<Code>? initializers});
@@ -151,6 +148,9 @@
 abstract class VariableDefinitionBuilder implements DefinitionBuilder {
   /// Augments the field.
   ///
+  /// For [getter] and [setter] the full function declaration should be
+  /// provided, minus the `augment` keyword (which will be implicitly added).
+  ///
   /// TODO: Link the library augmentations proposal to describe the semantics.
   void augment({
     DeclarationCode? getter,
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart
index 10ccafa..fae7630 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart
@@ -69,6 +69,9 @@
 ///
 /// See subtypes [ClassDeclaration] and [TypeAliasDeclaration].
 abstract class TypeDeclaration implements Declaration {
+  // TODO: Change this to a [StaticType]? https://github.com/dart-lang/language/issues/2072
+  TypeAnnotation get type;
+
   /// The type parameters defined for this type declaration.
   Iterable<TypeParameterDeclaration> get typeParameters;
 
@@ -144,7 +147,7 @@
 /// Method introspection information.
 abstract class MethodDeclaration implements FunctionDeclaration {
   /// The class that defines this method.
-  TypeAnnotation get definingClass;
+  NamedTypeAnnotation get definingClass;
 }
 
 /// Constructor introspection information.
@@ -155,23 +158,27 @@
 
 /// Variable introspection information.
 abstract class VariableDeclaration implements Declaration {
-  /// Whether this function has an `abstract` modifier.
-  bool get isAbstract;
-
-  /// Whether this function has an `external` modifier.
+  /// Whether this field has an `external` modifier.
   bool get isExternal;
 
+  /// Whether this field has a `final` modifier.
+  bool get isFinal;
+
+  /// Whether this field has a `late` modifier.
+  bool get isLate;
+
   /// The type of this field.
   TypeAnnotation get type;
 
-  /// A [Code] object representing the initializer for this field, if present.
-  Code? get initializer;
+  /// A [ExpressionCode] object representing the initializer for this field, if
+  /// present.
+  ExpressionCode? get initializer;
 }
 
 /// Field introspection information ..
 abstract class FieldDeclaration implements VariableDeclaration {
   /// The class that defines this method.
-  TypeAnnotation get definingClass;
+  NamedTypeAnnotation get definingClass;
 }
 
 /// Parameter introspection information.
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/macros.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/macros.dart
index 7685589a..5ab073a 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/api/macros.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/macros.dart
@@ -50,7 +50,7 @@
 /// The interface for [Macro]s that can be applied to any top level variable
 /// or instance field, and wants to augment the variable definition.
 abstract class VariableDefinitionMacro implements Macro {
-  FutureOr<void> buildDefinitionForFunction(
+  FutureOr<void> buildDefinitionForVariable(
       VariableDeclaration variable, VariableDefinitionBuilder builder);
 }
 
@@ -65,7 +65,7 @@
 /// contribute new non-type declarations to the program.
 abstract class ClassDeclarationsMacro implements Macro {
   FutureOr<void> buildDeclarationsForClass(
-      ClassDeclaration clazz, ClassDeclarationBuilder builder);
+      ClassDeclaration clazz, ClassMemberDeclarationBuilder builder);
 }
 
 /// The interface for [Macro]s that can be applied to any class, and wants to
@@ -85,13 +85,13 @@
 /// The interface for [Macro]s that can be applied to any field, and wants to
 /// contribute new type declarations to the program.
 abstract class FieldDeclarationsMacro implements Macro {
-  FutureOr<void> buildTypesForField(
+  FutureOr<void> buildDeclarationsForField(
       FieldDeclaration field, ClassMemberDeclarationBuilder builder);
 }
 
 /// The interface for [Macro]s that can be applied to any field, and wants to
 /// augment the field definition.
-abstract class FieldDefinitionsMacro implements Macro {
+abstract class FieldDefinitionMacro implements Macro {
   FutureOr<void> buildDefinitionForField(
       FieldDeclaration field, VariableDefinitionBuilder builder);
 }
@@ -105,7 +105,7 @@
 
 /// The interface for [Macro]s that can be applied to any method, and wants to
 /// contribute new non-type declarations to the program.
-abstract class MethodDeclarationDeclarationsMacro implements Macro {
+abstract class MethodDeclarationsMacro implements Macro {
   FutureOr<void> buildDeclarationsForMethod(
       MethodDeclaration method, ClassMemberDeclarationBuilder builder);
 }
@@ -121,19 +121,20 @@
 /// to contribute new type declarations to the program.
 abstract class ConstructorTypesMacro implements Macro {
   FutureOr<void> buildTypesForConstructor(
-      ConstructorDeclaration method, TypeBuilder builder);
+      ConstructorDeclaration constructor, TypeBuilder builder);
 }
 
 /// The interface for [Macro]s that can be applied to any constructors, and
 /// wants to contribute new non-type declarations to the program.
-abstract class ConstructorDeclarationDeclarationsMacro implements Macro {
+abstract class ConstructorDeclarationsMacro implements Macro {
   FutureOr<void> buildDeclarationsForConstructor(
-      ConstructorDeclaration method, ClassMemberDeclarationBuilder builder);
+      ConstructorDeclaration constructor,
+      ClassMemberDeclarationBuilder builder);
 }
 
 /// The interface for [Macro]s that can be applied to any constructor, and wants
 /// to augment the function definition.
 abstract class ConstructorDefinitionMacro implements Macro {
   FutureOr<void> buildDefinitionForConstructor(
-      ConstructorDeclaration method, ConstructorDefinitionBuilder builder);
+      ConstructorDeclaration constructor, ConstructorDefinitionBuilder builder);
 }
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
index 4d2f6a1..1c50b6a 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
@@ -37,6 +37,7 @@
 import 'dart:async';
 import 'dart:isolate';
 
+import 'package:_fe_analyzer_shared/src/macros/executor_shared/execute_macro.dart';
 import 'package:_fe_analyzer_shared/src/macros/executor_shared/introspection_impls.dart';
 import 'package:_fe_analyzer_shared/src/macros/executor_shared/remote_instance.dart';
 import 'package:_fe_analyzer_shared/src/macros/executor_shared/response_impls.dart';
@@ -70,6 +71,10 @@
           var request = new InstantiateMacroRequest.deserialize(deserializer, zoneId);
           (await _instantiateMacro(request)).serialize(serializer);
           break;
+        case MessageType.executeDeclarationsPhaseRequest:
+          var request = new ExecuteDeclarationsPhaseRequest.deserialize(deserializer, zoneId);
+          (await _executeDeclarationsPhase(request, sendRequest)).serialize(serializer);
+          break;
         case MessageType.executeDefinitionsPhaseRequest:
           var request = new ExecuteDefinitionsPhaseRequest.deserialize(deserializer, zoneId);
           (await _executeDefinitionsPhase(request, sendRequest)).serialize(serializer);
@@ -130,6 +135,41 @@
   }
 }
 
+Future<SerializableResponse> _executeDeclarationsPhase(
+    ExecuteDeclarationsPhaseRequest request,
+    Future<Response> Function(Request request) sendRequest) async {
+  try {
+    Macro? instance = _macroInstances[request.macro];
+    if (instance == null) {
+      throw new StateError('Unrecognized macro instance \${request.macro}\\n'
+          'Known instances: \$_macroInstances)');
+    }
+    var classIntrospector = ClientClassIntrospector(
+        sendRequest,
+        remoteInstance: request.classIntrospector,
+        serializationZoneId: request.serializationZoneId);
+    var typeResolver = ClientTypeResolver(
+        sendRequest,
+        remoteInstance: request.typeResolver,
+        serializationZoneId: request.serializationZoneId);
+
+    var result = await executeDeclarationsMacro(
+        instance, request.declaration, classIntrospector, typeResolver);
+    return new SerializableResponse(
+        responseType: MessageType.macroExecutionResult,
+        response: result,
+        requestId: request.id,
+        serializationZoneId: request.serializationZoneId);
+  } catch (e, s) {
+    return new SerializableResponse(
+      responseType: MessageType.error,
+      error: e.toString(),
+      stackTrace: s.toString(),
+      requestId: request.id,
+      serializationZoneId: request.serializationZoneId);
+  }
+}
+
 Future<SerializableResponse> _executeDefinitionsPhase(
     ExecuteDefinitionsPhaseRequest request,
     Future<Response> Function(Request request) sendRequest) async {
@@ -152,54 +192,14 @@
         remoteInstance: request.classIntrospector,
         serializationZoneId: request.serializationZoneId);
 
-    Declaration declaration = request.declaration;
-    if (instance is FunctionDefinitionMacro &&
-        declaration is FunctionDeclarationImpl) {
-      FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
-          declaration,
-          typeResolver,
-          typeDeclarationResolver,
-          classIntrospector);
-      await instance.buildDefinitionForFunction(declaration, builder);
-      return new SerializableResponse(
-          responseType: MessageType.macroExecutionResult,
-          response: builder.result,
-          requestId: request.id,
-          serializationZoneId: request.serializationZoneId);
-    } else if (instance is MethodDefinitionMacro
-        && declaration is MethodDeclarationImpl) {
-      FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
-          declaration,
-          typeResolver,
-          typeDeclarationResolver,
-          classIntrospector);
-      await instance.buildDefinitionForMethod(declaration, builder);
-      var result = builder.result;
-      // Wrap augmentations up as a part of the class
-      if (result.augmentations.isNotEmpty) {
-        result = MacroExecutionResultImpl(
-          augmentations: [
-            DeclarationCode.fromParts([
-              'augment class ',
-              declaration.definingClass,
-              ' {\\n',
-              ...result.augmentations,
-              '\\n}',
-            ]),
-          ],
-          imports: result.imports,
-        );
-      }
-      return new SerializableResponse(
-          responseType: MessageType.macroExecutionResult,
-          response: result,
-          requestId: request.id,
-          serializationZoneId: request.serializationZoneId);
-    } else {
-      throw new UnsupportedError(
-          'Unsupported macro type, only Method and Function Definition '
-          'Macros are supported currently');
-    }
+    var result = await executeDefinitionMacro(
+        instance, request.declaration, classIntrospector, typeResolver,
+        typeDeclarationResolver);
+    return new SerializableResponse(
+        responseType: MessageType.macroExecutionResult,
+        response: result,
+        requestId: request.id,
+        serializationZoneId: request.serializationZoneId);
   } catch (e, s) {
     return new SerializableResponse(
       responseType: MessageType.error,
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/builder_impls.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/builder_impls.dart
new file mode 100644
index 0000000..59a6376
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/builder_impls.dart
@@ -0,0 +1,398 @@
+// 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 'dart:async';
+
+import '../executor.dart';
+import '../api.dart';
+import 'response_impls.dart';
+
+class TypeBuilderBase {
+  /// The final result, will be built up over `augment` calls.
+  final List<DeclarationCode> _augmentations;
+
+  /// Creates and returns a [MacroExecutionResult] out of the [_augmentations]
+  /// created by this builder.
+  MacroExecutionResult get result => new MacroExecutionResultImpl(
+        augmentations: _augmentations,
+        // TODO: Implement `imports`, or possibly drop it?
+        imports: [],
+      );
+
+  TypeBuilderBase({List<DeclarationCode>? parentAugmentations})
+      : _augmentations = parentAugmentations ?? [];
+}
+
+/// Base class for all [DeclarationBuilder]s.
+class DeclarationBuilderBase extends TypeBuilderBase
+    implements ClassIntrospector, TypeResolver {
+  final ClassIntrospector classIntrospector;
+  final TypeResolver typeResolver;
+
+  DeclarationBuilderBase(this.classIntrospector, this.typeResolver,
+      {List<DeclarationCode>? parentAugmentations})
+      : super(parentAugmentations: parentAugmentations);
+
+  @override
+  Future<List<ConstructorDeclaration>> constructorsOf(ClassDeclaration clazz) =>
+      classIntrospector.constructorsOf(clazz);
+
+  @override
+  Future<List<FieldDeclaration>> fieldsOf(ClassDeclaration clazz) =>
+      classIntrospector.fieldsOf(clazz);
+
+  @override
+  Future<List<ClassDeclaration>> interfacesOf(ClassDeclaration clazz) =>
+      classIntrospector.interfacesOf(clazz);
+
+  @override
+  Future<List<MethodDeclaration>> methodsOf(ClassDeclaration clazz) =>
+      classIntrospector.methodsOf(clazz);
+
+  @override
+  Future<List<ClassDeclaration>> mixinsOf(ClassDeclaration clazz) =>
+      classIntrospector.mixinsOf(clazz);
+
+  @override
+  Future<ClassDeclaration?> superclassOf(ClassDeclaration clazz) =>
+      classIntrospector.superclassOf(clazz);
+
+  @override
+  Future<StaticType> resolve(TypeAnnotation typeAnnotation) =>
+      typeResolver.resolve(typeAnnotation);
+}
+
+class DeclarationBuilderImpl extends DeclarationBuilderBase
+    implements DeclarationBuilder {
+  DeclarationBuilderImpl(
+      ClassIntrospector classIntrospector, TypeResolver typeResolver,
+      {List<DeclarationCode>? parentAugmentations})
+      : super(classIntrospector, typeResolver,
+            parentAugmentations: parentAugmentations);
+
+  @override
+  void declareInLibrary(DeclarationCode declaration) {
+    _augmentations.add(declaration);
+  }
+}
+
+class ClassMemberDeclarationBuilderImpl extends DeclarationBuilderImpl
+    implements ClassMemberDeclarationBuilder {
+  final TypeAnnotation definingClass;
+
+  ClassMemberDeclarationBuilderImpl(this.definingClass,
+      ClassIntrospector classIntrospector, TypeResolver typeResolver,
+      {List<DeclarationCode>? parentAugmentations})
+      : super(classIntrospector, typeResolver,
+            parentAugmentations: parentAugmentations);
+
+  @override
+  void declareInClass(DeclarationCode declaration) {
+    _augmentations.add(_buildClassAugmentation(definingClass, [declaration]));
+  }
+}
+
+/// Base class for all [DefinitionBuilder]s.
+class DefinitionBuilderBase extends DeclarationBuilderBase
+    implements TypeDeclarationResolver {
+  final TypeDeclarationResolver typeDeclarationResolver;
+
+  DefinitionBuilderBase(ClassIntrospector classIntrospector,
+      TypeResolver typeResolver, this.typeDeclarationResolver,
+      {List<DeclarationCode>? parentAugmentations})
+      : super(classIntrospector, typeResolver,
+            parentAugmentations: parentAugmentations);
+
+  @override
+  Future<TypeDeclaration> declarationOf(NamedStaticType annotation) =>
+      typeDeclarationResolver.declarationOf(annotation);
+}
+
+class ClassDefinitionBuilderImpl extends DefinitionBuilderBase
+    implements ClassDefinitionBuilder {
+  /// The declaration this is a builder for.
+  final ClassDeclaration declaration;
+
+  ClassDefinitionBuilderImpl(
+      this.declaration,
+      ClassIntrospector classIntrospector,
+      TypeResolver typeResolver,
+      TypeDeclarationResolver typeDeclarationResolver,
+      {List<DeclarationCode>? parentAugmentations})
+      : super(classIntrospector, typeResolver, typeDeclarationResolver,
+            parentAugmentations: parentAugmentations);
+
+  @override
+  Future<ConstructorDefinitionBuilder> buildConstructor(String name) async {
+    ConstructorDeclaration constructor =
+        (await classIntrospector.constructorsOf(declaration))
+            .firstWhere((constructor) => constructor.name == name);
+    return new ConstructorDefinitionBuilderImpl(
+        constructor, classIntrospector, typeResolver, typeDeclarationResolver,
+        parentAugmentations: _augmentations);
+  }
+
+  @override
+  Future<VariableDefinitionBuilder> buildField(String name) async {
+    FieldDeclaration field = (await classIntrospector.fieldsOf(declaration))
+        .firstWhere((field) => field.name == name);
+    return new FieldDefinitionBuilderImpl(
+        field, classIntrospector, typeResolver, typeDeclarationResolver,
+        parentAugmentations: _augmentations);
+  }
+
+  @override
+  Future<FunctionDefinitionBuilder> buildMethod(String name) async {
+    MethodDeclaration method = (await classIntrospector.methodsOf(declaration))
+        .firstWhere((method) => method.name == name);
+    return new MethodDefinitionBuilderImpl(
+        method, classIntrospector, typeResolver, typeDeclarationResolver,
+        parentAugmentations: _augmentations);
+  }
+}
+
+/// Implementation of [FunctionDefinitionBuilder].
+class FunctionDefinitionBuilderImpl extends DefinitionBuilderBase
+    implements FunctionDefinitionBuilder {
+  final FunctionDeclaration declaration;
+
+  FunctionDefinitionBuilderImpl(
+      this.declaration,
+      ClassIntrospector classIntrospector,
+      TypeResolver typeResolver,
+      TypeDeclarationResolver typeDeclarationResolver,
+      {List<DeclarationCode>? parentAugmentations})
+      : super(classIntrospector, typeResolver, typeDeclarationResolver,
+            parentAugmentations: parentAugmentations);
+
+  @override
+  void augment(FunctionBodyCode body) {
+    _augmentations.add(_buildFunctionAugmentation(body, declaration));
+  }
+}
+
+/// Implementation of [MethodDefinitionBuilderImpl].
+class MethodDefinitionBuilderImpl extends FunctionDefinitionBuilderImpl {
+  @override
+  final MethodDeclaration declaration;
+
+  MethodDefinitionBuilderImpl(
+      this.declaration,
+      ClassIntrospector classIntrospector,
+      TypeResolver typeResolver,
+      TypeDeclarationResolver typeDeclarationResolver,
+      {List<DeclarationCode>? parentAugmentations})
+      : super(declaration, classIntrospector, typeResolver,
+            typeDeclarationResolver,
+            parentAugmentations: parentAugmentations);
+
+  @override
+  void augment(FunctionBodyCode body) {
+    _augmentations.add(_buildClassAugmentation(
+      declaration.definingClass,
+      [_buildFunctionAugmentation(body, declaration)],
+    ));
+  }
+}
+
+class ConstructorDefinitionBuilderImpl extends DefinitionBuilderBase
+    implements ConstructorDefinitionBuilder {
+  final ConstructorDeclaration declaration;
+
+  ConstructorDefinitionBuilderImpl(
+      this.declaration,
+      ClassIntrospector classIntrospector,
+      TypeResolver typeResolver,
+      TypeDeclarationResolver typeDeclarationResolver,
+      {List<DeclarationCode>? parentAugmentations})
+      : super(classIntrospector, typeResolver, typeDeclarationResolver,
+            parentAugmentations: parentAugmentations);
+
+  @override
+  void augment({FunctionBodyCode? body, List<Code>? initializers}) {
+    body ??= new FunctionBodyCode.fromString('''{
+      augment super();
+    }''');
+    _augmentations.add(_buildClassAugmentation(declaration.definingClass, [
+      _buildFunctionAugmentation(body, declaration, initializers: initializers)
+    ]));
+  }
+}
+
+class VariableDefinitionBuilderImpl extends DefinitionBuilderBase
+    implements VariableDefinitionBuilder {
+  final VariableDeclaration declaration;
+
+  VariableDefinitionBuilderImpl(
+      this.declaration,
+      ClassIntrospector classIntrospector,
+      TypeResolver typeResolver,
+      TypeDeclarationResolver typeDeclarationResolver,
+      {List<DeclarationCode>? parentAugmentations})
+      : super(classIntrospector, typeResolver, typeDeclarationResolver,
+            parentAugmentations: parentAugmentations);
+
+  @override
+  void augment(
+      {DeclarationCode? getter,
+      DeclarationCode? setter,
+      ExpressionCode? initializer}) {
+    _augmentations.addAll(_buildVariableAugmentations(declaration,
+        getter: getter, setter: setter, initializer: initializer));
+  }
+}
+
+class FieldDefinitionBuilderImpl extends DefinitionBuilderBase
+    implements VariableDefinitionBuilder {
+  final FieldDeclaration declaration;
+
+  FieldDefinitionBuilderImpl(
+      this.declaration,
+      ClassIntrospector classIntrospector,
+      TypeResolver typeResolver,
+      TypeDeclarationResolver typeDeclarationResolver,
+      {List<DeclarationCode>? parentAugmentations})
+      : super(classIntrospector, typeResolver, typeDeclarationResolver,
+            parentAugmentations: parentAugmentations);
+
+  @override
+  void augment(
+      {DeclarationCode? getter,
+      DeclarationCode? setter,
+      ExpressionCode? initializer}) {
+    _augmentations.add(_buildClassAugmentation(
+        declaration.definingClass,
+        _buildVariableAugmentations(declaration,
+            getter: getter, setter: setter, initializer: initializer)));
+  }
+}
+
+/// Creates an augmentation of [clazz] with member [augmentations].
+DeclarationCode _buildClassAugmentation(
+        TypeAnnotation clazz, List<DeclarationCode> augmentations) =>
+    new DeclarationCode.fromParts([
+      'augment class ',
+      clazz,
+      ' {\n',
+      ...augmentations.joinAsCode('\n'),
+      '\n}',
+    ]);
+
+/// Builds all the possible augmentations for a variable.
+List<DeclarationCode> _buildVariableAugmentations(
+    VariableDeclaration declaration,
+    {DeclarationCode? getter,
+    DeclarationCode? setter,
+    ExpressionCode? initializer}) {
+  List<DeclarationCode> augmentations = [];
+  if (getter != null) {
+    augmentations.add(new DeclarationCode.fromParts([
+      'augment ',
+      getter,
+    ]));
+  }
+  if (setter != null) {
+    augmentations.add(new DeclarationCode.fromParts([
+      'augment ',
+      setter,
+    ]));
+  }
+  if (initializer != null) {
+    augmentations.add(new DeclarationCode.fromParts([
+      'augment ',
+      if (declaration.isFinal) 'final ',
+      declaration.type,
+      ' ',
+      declaration.name,
+      ' = ',
+      initializer,
+      ';',
+    ]));
+  }
+
+  return augmentations;
+}
+
+/// Builds the code to augment a function, method, or constructor with a new
+/// body.
+///
+/// The [initializers] parameter can only be used if [declaration] is a
+/// constructor.
+DeclarationCode _buildFunctionAugmentation(
+    FunctionBodyCode body, FunctionDeclaration declaration,
+    {List<Code>? initializers}) {
+  assert(initializers == null || declaration is ConstructorDeclaration);
+
+  return new DeclarationCode.fromParts([
+    'augment ',
+    if (declaration is ConstructorDeclaration) ...[
+      declaration.definingClass.name,
+      if (declaration.name.isNotEmpty) '.',
+    ] else ...[
+      declaration.returnType.code,
+      ' ',
+    ],
+    declaration.name,
+    if (declaration.typeParameters.isNotEmpty) ...[
+      '<',
+      for (TypeParameterDeclaration typeParam
+          in declaration.typeParameters) ...[
+        typeParam.name,
+        if (typeParam.bounds != null) ...['extends ', typeParam.bounds!.code],
+        if (typeParam != declaration.typeParameters.last) ', ',
+      ],
+      '>',
+    ],
+    '(',
+    for (ParameterDeclaration positionalRequired
+        in declaration.positionalParameters.where((p) => p.isRequired)) ...[
+      new ParameterCode.fromParts([
+        positionalRequired.type.code,
+        ' ',
+        positionalRequired.name,
+      ]),
+      ', '
+    ],
+    if (declaration.positionalParameters.any((p) => !p.isRequired)) ...[
+      '[',
+      for (ParameterDeclaration positionalOptional
+          in declaration.positionalParameters.where((p) => !p.isRequired)) ...[
+        new ParameterCode.fromParts([
+          positionalOptional.type.code,
+          ' ',
+          positionalOptional.name,
+        ]),
+        ', ',
+      ],
+      ']',
+    ],
+    if (declaration.namedParameters.isNotEmpty) ...[
+      '{',
+      for (ParameterDeclaration named in declaration.namedParameters) ...[
+        new ParameterCode.fromParts([
+          if (named.isRequired) 'required ',
+          named.type.code,
+          ' ',
+          named.name,
+          if (named.defaultValue != null) ...[
+            ' = ',
+            named.defaultValue!,
+          ],
+        ]),
+        ', ',
+      ],
+      '}',
+    ],
+    ') ',
+    if (initializers != null && initializers.isNotEmpty) ...[
+      ' : ',
+      initializers.first,
+      for (Code initializer in initializers.skip(1)) ...[
+        ',\n',
+        initializer,
+      ],
+    ],
+    body,
+  ]);
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/execute_macro.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/execute_macro.dart
new file mode 100644
index 0000000..f94470d
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/execute_macro.dart
@@ -0,0 +1,120 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:_fe_analyzer_shared/src/macros/executor.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor_shared/builder_impls.dart';
+import 'package:_fe_analyzer_shared/src/macros/api.dart';
+
+/// Runs [macro] in the declaration phase and returns a  [MacroExecutionResult].
+Future<MacroExecutionResult> executeDeclarationsMacro(
+    Macro macro,
+    Declaration declaration,
+    ClassIntrospector classIntrospector,
+    TypeResolver typeResolver) async {
+  if (declaration is FunctionDeclaration) {
+    if (macro is ConstructorDeclarationsMacro &&
+        declaration is ConstructorDeclaration) {
+      ClassMemberDeclarationBuilderImpl builder =
+          new ClassMemberDeclarationBuilderImpl(
+              declaration.definingClass, classIntrospector, typeResolver);
+      await macro.buildDeclarationsForConstructor(declaration, builder);
+      return builder.result;
+    } else if (macro is MethodDeclarationsMacro &&
+        declaration is MethodDeclaration) {
+      ClassMemberDeclarationBuilderImpl builder =
+          new ClassMemberDeclarationBuilderImpl(
+              declaration.definingClass, classIntrospector, typeResolver);
+      await macro.buildDeclarationsForMethod(declaration, builder);
+      return builder.result;
+    } else if (macro is FunctionDeclarationsMacro) {
+      DeclarationBuilderImpl builder =
+          new DeclarationBuilderImpl(classIntrospector, typeResolver);
+      await macro.buildDeclarationsForFunction(declaration, builder);
+      return builder.result;
+    }
+  } else if (declaration is VariableDeclaration) {
+    if (macro is FieldDeclarationsMacro && declaration is FieldDeclaration) {
+      ClassMemberDeclarationBuilderImpl builder =
+          new ClassMemberDeclarationBuilderImpl(
+              declaration.definingClass, classIntrospector, typeResolver);
+      await macro.buildDeclarationsForField(declaration, builder);
+      return builder.result;
+    } else if (macro is VariableDeclarationsMacro) {
+      DeclarationBuilderImpl builder =
+          new DeclarationBuilderImpl(classIntrospector, typeResolver);
+      await macro.buildDeclarationsForVariable(declaration, builder);
+      return builder.result;
+    }
+  } else if (macro is ClassDeclarationsMacro &&
+      declaration is ClassDeclaration) {
+    ClassMemberDeclarationBuilderImpl builder =
+        new ClassMemberDeclarationBuilderImpl(
+            declaration.type, classIntrospector, typeResolver);
+    await macro.buildDeclarationsForClass(declaration, builder);
+    return builder.result;
+  }
+  throw new UnsupportedError('Unsupported macro type or invalid declaration:\n'
+      'macro: $macro\ndeclaration: $declaration');
+}
+
+/// Runs [macro] in the definition phase and returns a  [MacroExecutionResult].
+Future<MacroExecutionResult> executeDefinitionMacro(
+    Macro macro,
+    Declaration declaration,
+    ClassIntrospector classIntrospector,
+    TypeResolver typeResolver,
+    TypeDeclarationResolver typeDeclarationResolver) async {
+  if (declaration is FunctionDeclaration) {
+    if (macro is ConstructorDefinitionMacro &&
+        declaration is ConstructorDeclaration) {
+      ConstructorDefinitionBuilderImpl builder =
+          new ConstructorDefinitionBuilderImpl(declaration, classIntrospector,
+              typeResolver, typeDeclarationResolver);
+      await macro.buildDefinitionForConstructor(declaration, builder);
+      return builder.result;
+    } else if (macro is MethodDefinitionMacro &&
+        declaration is MethodDeclaration) {
+      MethodDefinitionBuilderImpl builder = new MethodDefinitionBuilderImpl(
+          declaration,
+          classIntrospector,
+          typeResolver,
+          typeDeclarationResolver);
+      await macro.buildDefinitionForMethod(declaration, builder);
+      return builder.result;
+    } else if (macro is FunctionDefinitionMacro) {
+      FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
+          declaration,
+          classIntrospector,
+          typeResolver,
+          typeDeclarationResolver);
+      await macro.buildDefinitionForFunction(declaration, builder);
+      return builder.result;
+    }
+  } else if (declaration is VariableDeclaration) {
+    if (macro is FieldDefinitionMacro && declaration is FieldDeclaration) {
+      FieldDefinitionBuilderImpl builder = new FieldDefinitionBuilderImpl(
+          declaration,
+          classIntrospector,
+          typeResolver,
+          typeDeclarationResolver);
+      await macro.buildDefinitionForField(declaration, builder);
+      return builder.result;
+    } else if (macro is VariableDefinitionMacro) {
+      VariableDefinitionBuilderImpl builder = new VariableDefinitionBuilderImpl(
+          declaration,
+          classIntrospector,
+          typeResolver,
+          typeDeclarationResolver);
+      await macro.buildDefinitionForVariable(declaration, builder);
+      return builder.result;
+    }
+  } else if (macro is ClassDefinitionMacro && declaration is ClassDeclaration) {
+    ClassDefinitionBuilderImpl builder = new ClassDefinitionBuilderImpl(
+        declaration, classIntrospector, typeResolver, typeDeclarationResolver);
+    await macro.buildDefinitionForClass(declaration, builder);
+    return builder.result;
+  }
+  throw new UnsupportedError('Unsupported macro type or invalid declaration:\n'
+      'macro: $macro\ndeclaration: $declaration');
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/introspection_impls.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/introspection_impls.dart
index a3f6fb4..9bdd740 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/introspection_impls.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/introspection_impls.dart
@@ -334,7 +334,7 @@
 class MethodDeclarationImpl extends FunctionDeclarationImpl
     implements MethodDeclaration {
   @override
-  final TypeAnnotationImpl definingClass;
+  final NamedTypeAnnotationImpl definingClass;
 
   @override
   RemoteInstanceKind get kind => RemoteInstanceKind.methodDeclaration;
@@ -401,7 +401,7 @@
     required TypeAnnotationImpl returnType,
     required List<TypeParameterDeclarationImpl> typeParameters,
     // Method fields
-    required TypeAnnotationImpl definingClass,
+    required NamedTypeAnnotationImpl definingClass,
     // Constructor fields
     required this.isFactory,
   }) : super(
@@ -433,15 +433,18 @@
 class VariableDeclarationImpl extends DeclarationImpl
     implements VariableDeclaration {
   @override
-  final Code? initializer;
-
-  @override
-  final bool isAbstract;
+  final ExpressionCode? initializer;
 
   @override
   final bool isExternal;
 
   @override
+  final bool isFinal;
+
+  @override
+  final bool isLate;
+
+  @override
   final TypeAnnotationImpl type;
 
   @override
@@ -451,8 +454,9 @@
     required int id,
     required String name,
     required this.initializer,
-    required this.isAbstract,
     required this.isExternal,
+    required this.isFinal,
+    required this.isLate,
     required this.type,
   }) : super(id: id, name: name);
 
@@ -466,8 +470,9 @@
 
     initializer.serializeNullable(serializer);
     serializer
-      ..addBool(isAbstract)
-      ..addBool(isExternal);
+      ..addBool(isExternal)
+      ..addBool(isFinal)
+      ..addBool(isLate);
     type.serialize(serializer);
   }
 }
@@ -475,16 +480,17 @@
 class FieldDeclarationImpl extends VariableDeclarationImpl
     implements FieldDeclaration {
   @override
-  final TypeAnnotationImpl definingClass;
+  final NamedTypeAnnotationImpl definingClass;
 
   FieldDeclarationImpl({
     // Declaration fields
     required int id,
     required String name,
     // Variable fields
-    required Code? initializer,
-    required bool isAbstract,
+    required ExpressionCode? initializer,
     required bool isExternal,
+    required bool isFinal,
+    required bool isLate,
     required TypeAnnotationImpl type,
     // Field fields
     required this.definingClass,
@@ -492,8 +498,9 @@
             id: id,
             name: name,
             initializer: initializer,
-            isAbstract: isAbstract,
             isExternal: isExternal,
+            isFinal: isFinal,
+            isLate: isLate,
             type: type);
 
   @override
@@ -513,11 +520,15 @@
 abstract class TypeDeclarationImpl extends DeclarationImpl
     implements TypeDeclaration {
   @override
+  final TypeAnnotationImpl type;
+
+  @override
   final List<TypeParameterDeclarationImpl> typeParameters;
 
   TypeDeclarationImpl({
     required int id,
     required String name,
+    required this.type,
     required this.typeParameters,
   }) : super(id: id, name: name);
 
@@ -535,6 +546,7 @@
       return;
     }
 
+    type.serialize(serializer);
     serializer..startList();
     for (TypeParameterDeclarationImpl param in typeParameters) {
       param.serialize(serializer);
@@ -568,6 +580,7 @@
     required int id,
     required String name,
     // TypeDeclaration fields
+    required TypeAnnotationImpl type,
     required List<TypeParameterDeclarationImpl> typeParameters,
     // ClassDeclaration fields
     required this.interfaces,
@@ -575,7 +588,7 @@
     required this.isExternal,
     required this.mixins,
     required this.superclass,
-  }) : super(id: id, name: name, typeParameters: typeParameters);
+  }) : super(id: id, name: name, type: type, typeParameters: typeParameters);
 
   @override
   void serialize(Serializer serializer) {
@@ -604,21 +617,22 @@
 
 class TypeAliasDeclarationImpl extends TypeDeclarationImpl
     implements TypeAliasDeclaration {
-  @override
-  RemoteInstanceKind get kind => RemoteInstanceKind.typeAliasDeclaration;
+  /// The type being aliased.
+  final TypeAnnotationImpl aliasedType;
 
   @override
-  final TypeAnnotationImpl type;
+  RemoteInstanceKind get kind => RemoteInstanceKind.typeAliasDeclaration;
 
   TypeAliasDeclarationImpl({
     // Declaration fields
     required int id,
     required String name,
     // TypeDeclaration fields
+    required TypeAnnotationImpl type,
     required List<TypeParameterDeclarationImpl> typeParameters,
     // TypeAlias fields
-    required this.type,
-  }) : super(id: id, name: name, typeParameters: typeParameters);
+    required this.aliasedType,
+  }) : super(id: id, name: name, type: type, typeParameters: typeParameters);
 
   @override
   void serialize(Serializer serializer) {
@@ -628,6 +642,6 @@
       return;
     }
 
-    type.serialize(serializer);
+    aliasedType.serialize(serializer);
   }
 }
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart
index f16daf9..3eae69c 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart
@@ -239,6 +239,41 @@
 
 /// A request to execute a macro on a particular declaration in the definition
 /// phase.
+class ExecuteDeclarationsPhaseRequest extends Request {
+  final MacroInstanceIdentifier macro;
+  final DeclarationImpl declaration;
+
+  final RemoteInstanceImpl typeResolver;
+  final RemoteInstanceImpl classIntrospector;
+
+  ExecuteDeclarationsPhaseRequest(
+      this.macro, this.declaration, this.typeResolver, this.classIntrospector,
+      {required int serializationZoneId})
+      : super(serializationZoneId: serializationZoneId);
+
+  /// When deserializing we have already consumed the message type, so we don't
+  /// consume it again.
+  ExecuteDeclarationsPhaseRequest.deserialize(
+      Deserializer deserializer, int serializationZoneId)
+      : macro = new MacroInstanceIdentifierImpl.deserialize(deserializer),
+        declaration = RemoteInstance.deserialize(deserializer),
+        typeResolver = RemoteInstance.deserialize(deserializer),
+        classIntrospector = RemoteInstance.deserialize(deserializer),
+        super.deserialize(deserializer, serializationZoneId);
+
+  void serialize(Serializer serializer) {
+    serializer.addNum(MessageType.executeDeclarationsPhaseRequest.index);
+    macro.serialize(serializer);
+    declaration.serialize(serializer);
+    typeResolver.serialize(serializer);
+    classIntrospector.serialize(serializer);
+
+    super.serialize(serializer);
+  }
+}
+
+/// A request to execute a macro on a particular declaration in the definition
+/// phase.
 class ExecuteDefinitionsPhaseRequest extends Request {
   final MacroInstanceIdentifier macro;
   final DeclarationImpl declaration;
@@ -627,6 +662,7 @@
   mixinsOfRequest,
   superclassOfRequest,
   error,
+  executeDeclarationsPhaseRequest,
   executeDefinitionsPhaseRequest,
   instantiateMacroRequest,
   isExactlyTypeRequest,
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/response_impls.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/response_impls.dart
index 77556ad..f829357 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/response_impls.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/response_impls.dart
@@ -2,13 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
-import 'package:_fe_analyzer_shared/src/macros/executor_shared/remote_instance.dart';
-
 import '../executor.dart';
 import '../api.dart';
-import 'introspection_impls.dart';
 import 'serialization.dart';
 import 'serialization_extensions.dart';
 
@@ -55,10 +50,9 @@
   final List<DeclarationCode> imports;
 
   MacroExecutionResultImpl({
-    List<DeclarationCode>? augmentations,
-    List<DeclarationCode>? imports,
-  })  : augmentations = augmentations ?? [],
-        imports = imports ?? [];
+    required this.augmentations,
+    required this.imports,
+  });
 
   factory MacroExecutionResultImpl.deserialize(Deserializer deserializer) {
     deserializer.moveNext();
@@ -97,128 +91,3 @@
     serializer.endList();
   }
 }
-
-/// Implementation of [FunctionDefinitionBuilder].
-class FunctionDefinitionBuilderImpl implements FunctionDefinitionBuilder {
-  final TypeResolver typeResolver;
-  final TypeDeclarationResolver typeDeclarationResolver;
-  final ClassIntrospector classIntrospector;
-
-  /// The declaration this is a builder for.
-  final FunctionDeclarationImpl declaration;
-
-  /// The final result, will be built up over `augment` calls.
-  final MacroExecutionResultImpl result;
-
-  FunctionDefinitionBuilderImpl(this.declaration, this.typeResolver,
-      this.typeDeclarationResolver, this.classIntrospector)
-      : result = new MacroExecutionResultImpl();
-
-  FunctionDefinitionBuilderImpl.deserialize(Deserializer deserializer,
-      this.typeResolver, this.typeDeclarationResolver, this.classIntrospector)
-      : declaration = RemoteInstance.deserialize(deserializer),
-        result = new MacroExecutionResultImpl.deserialize(deserializer);
-
-  void serialize(Serializer serializer) {
-    // Note that the `typeResolver`, `typeDeclarationResolver`, and
-    // `classIntrospector` are not serialized. These have custom implementations
-    // on the client/server side.
-    declaration.serialize(serializer);
-    result.serialize(serializer);
-  }
-
-  @override
-  void augment(FunctionBodyCode body) {
-    result.augmentations.add(new DeclarationCode.fromParts([
-      'augment ',
-      declaration.returnType.code,
-      ' ',
-      declaration.name,
-      if (declaration.typeParameters.isNotEmpty) ...[
-        '<',
-        for (TypeParameterDeclaration typeParam
-            in declaration.typeParameters) ...[
-          typeParam.name,
-          if (typeParam.bounds != null) ...['extends ', typeParam.bounds!.code],
-          if (typeParam != declaration.typeParameters.last) ', ',
-        ],
-        '>',
-      ],
-      '(',
-      for (ParameterDeclaration positionalRequired
-          in declaration.positionalParameters.where((p) => p.isRequired)) ...[
-        new ParameterCode.fromParts([
-          positionalRequired.type.code,
-          ' ',
-          positionalRequired.name,
-        ]),
-        ', '
-      ],
-      if (declaration.positionalParameters.any((p) => !p.isRequired)) ...[
-        '[',
-        for (ParameterDeclaration positionalOptional in declaration
-            .positionalParameters
-            .where((p) => !p.isRequired)) ...[
-          new ParameterCode.fromParts([
-            positionalOptional.type.code,
-            ' ',
-            positionalOptional.name,
-          ]),
-          ', ',
-        ],
-        ']',
-      ],
-      if (declaration.namedParameters.isNotEmpty) ...[
-        '{',
-        for (ParameterDeclaration named in declaration.namedParameters) ...[
-          new ParameterCode.fromParts([
-            if (named.isRequired) 'required ',
-            named.type.code,
-            ' ',
-            named.name,
-            if (named.defaultValue != null) ...[
-              ' = ',
-              named.defaultValue!,
-            ],
-          ]),
-          ', ',
-        ],
-        '}',
-      ],
-      ') ',
-      body,
-    ]));
-  }
-
-  @override
-  Future<List<ConstructorDeclaration>> constructorsOf(ClassDeclaration clazz) =>
-      classIntrospector.constructorsOf(clazz);
-
-  @override
-  Future<List<FieldDeclaration>> fieldsOf(ClassDeclaration clazz) =>
-      classIntrospector.fieldsOf(clazz);
-
-  @override
-  Future<List<ClassDeclaration>> interfacesOf(ClassDeclaration clazz) =>
-      classIntrospector.interfacesOf(clazz);
-
-  @override
-  Future<List<MethodDeclaration>> methodsOf(ClassDeclaration clazz) =>
-      classIntrospector.methodsOf(clazz);
-
-  @override
-  Future<List<ClassDeclaration>> mixinsOf(ClassDeclaration clazz) =>
-      classIntrospector.mixinsOf(clazz);
-
-  @override
-  Future<TypeDeclaration> declarationOf(NamedStaticType annotation) =>
-      typeDeclarationResolver.declarationOf(annotation);
-
-  @override
-  Future<ClassDeclaration?> superclassOf(ClassDeclaration clazz) =>
-      classIntrospector.superclassOf(clazz);
-
-  @override
-  Future<StaticType> resolve(TypeAnnotation typeAnnotation) =>
-      typeResolver.resolve(typeAnnotation);
-}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization_extensions.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization_extensions.dart
index b7df0be..33464d7 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization_extensions.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization_extensions.dart
@@ -152,8 +152,9 @@
         id: id,
         name: expectString(),
         initializer: (this..moveNext()).expectNullableCode(),
-        isAbstract: (this..moveNext()).expectBool(),
         isExternal: (this..moveNext()).expectBool(),
+        isFinal: (this..moveNext()).expectBool(),
+        isLate: (this..moveNext()).expectBool(),
         type: RemoteInstance.deserialize(this),
       );
 
@@ -161,8 +162,9 @@
         id: id,
         name: expectString(),
         initializer: (this..moveNext()).expectNullableCode(),
-        isAbstract: (this..moveNext()).expectBool(),
         isExternal: (this..moveNext()).expectBool(),
+        isFinal: (this..moveNext()).expectBool(),
+        isLate: (this..moveNext()).expectBool(),
         type: RemoteInstance.deserialize(this),
         definingClass: RemoteInstance.deserialize(this),
       );
@@ -170,6 +172,7 @@
   ClassDeclaration _expectClassDeclaration(int id) => new ClassDeclarationImpl(
         id: id,
         name: expectString(),
+        type: RemoteInstance.deserialize(this),
         typeParameters: (this..moveNext())._expectRemoteInstanceList(),
         interfaces: (this..moveNext())._expectRemoteInstanceList(),
         isAbstract: (this..moveNext()).expectBool(),
@@ -183,8 +186,9 @@
       new TypeAliasDeclarationImpl(
         id: id,
         name: expectString(),
-        typeParameters: (this..moveNext())._expectRemoteInstanceList(),
         type: RemoteInstance.deserialize(this),
+        typeParameters: (this..moveNext())._expectRemoteInstanceList(),
+        aliasedType: RemoteInstance.deserialize(this),
       );
 
   T expectCode<T extends Code>() {
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart
index 91b1125..e1e12fe 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart
@@ -6,6 +6,7 @@
 import 'dart:isolate';
 import 'dart:mirrors';
 
+import '../executor_shared/builder_impls.dart';
 import '../executor_shared/introspection_impls.dart';
 import '../executor_shared/response_impls.dart';
 import '../executor_shared/protocol.dart';
@@ -97,9 +98,9 @@
         declaration is FunctionDeclarationImpl) {
       FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
           declaration,
+          request.classIntrospector.instance as ClassIntrospector,
           request.typeResolver.instance as TypeResolver,
-          request.typeDeclarationResolver.instance as TypeDeclarationResolver,
-          request.classIntrospector.instance as ClassIntrospector);
+          request.typeDeclarationResolver.instance as TypeDeclarationResolver);
       await instance.buildDefinitionForFunction(declaration, builder);
       return new Response(
           response: builder.result,
@@ -109,9 +110,9 @@
         declaration is MethodDeclarationImpl) {
       FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
           declaration,
+          request.classIntrospector.instance as ClassIntrospector,
           request.typeResolver.instance as TypeResolver,
-          request.typeDeclarationResolver.instance as TypeDeclarationResolver,
-          request.classIntrospector.instance as ClassIntrospector);
+          request.typeDeclarationResolver.instance as TypeDeclarationResolver);
       await instance.buildDefinitionForMethod(declaration, builder);
       return new SerializableResponse(
           responseType: MessageType.macroExecutionResult,
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
index 57f0ec8..9194c7f 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
@@ -377,13 +377,22 @@
 
   @override
   Future<MacroExecutionResult> executeDeclarationsPhase(
-      MacroInstanceIdentifier macro,
-      DeclarationImpl declaration,
-      TypeResolver typeResolver,
-      ClassIntrospector classIntrospector) {
-    // TODO: implement executeDeclarationsPhase
-    throw new UnimplementedError();
-  }
+          MacroInstanceIdentifier macro,
+          DeclarationImpl declaration,
+          TypeResolver typeResolver,
+          ClassIntrospector classIntrospector) =>
+      _sendRequest((zoneId) => new ExecuteDeclarationsPhaseRequest(
+          macro,
+          declaration,
+          new RemoteInstanceImpl(
+              instance: typeResolver,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.typeResolver),
+          new RemoteInstanceImpl(
+              instance: classIntrospector,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.classIntrospector),
+          serializationZoneId: zoneId));
 
   @override
   Future<MacroExecutionResult> executeDefinitionsPhase(
diff --git a/pkg/_fe_analyzer_shared/test/macros/executor_shared/serialization_test.dart b/pkg/_fe_analyzer_shared/test/macros/executor_shared/serialization_test.dart
index 6a3807b..b9efa16 100644
--- a/pkg/_fe_analyzer_shared/test/macros/executor_shared/serialization_test.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/executor_shared/serialization_test.dart
@@ -207,9 +207,10 @@
         var bar = VariableDeclarationImpl(
           id: RemoteInstance.uniqueId,
           name: 'bar',
-          isAbstract: false,
           isExternal: true,
-          initializer: Code.fromString('Bar()'),
+          isFinal: false,
+          isLate: true,
+          initializer: ExpressionCode.fromString('Bar()'),
           type: barType,
         );
         expectSerializationEquality(bar);
@@ -219,8 +220,9 @@
         var bar = FieldDeclarationImpl(
           id: RemoteInstance.uniqueId,
           name: 'bar',
-          isAbstract: false,
           isExternal: false,
+          isFinal: true,
+          isLate: false,
           initializer: null,
           type: barType,
           definingClass: fooType,
@@ -250,6 +252,7 @@
           isExternal: false,
           mixins: [serializableType],
           superclass: objectType,
+          type: fooType,
           typeParameters: [zapTypeParam],
         );
         expectSerializationEquality(fooClass);
@@ -262,9 +265,14 @@
           type: NamedTypeAnnotationImpl(
               id: RemoteInstance.uniqueId,
               isNullable: false,
+              name: 'FooOfBar',
+              typeArguments: []),
+          typeParameters: [zapTypeParam],
+          aliasedType: NamedTypeAnnotationImpl(
+              id: RemoteInstance.uniqueId,
+              isNullable: false,
               name: 'Foo',
               typeArguments: [barType]),
-          typeParameters: [zapTypeParam],
         );
         expectSerializationEquality(typeAlias);
       });
diff --git a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart
index 7c242a4..81aa97f 100644
--- a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart
@@ -18,31 +18,23 @@
 
 void main() {
   late MacroExecutor executor;
-  late Directory tmpDir;
+  late File kernelOutputFile;
+  final macroName = 'SimpleMacro';
+  late MacroInstanceIdentifier instanceId;
+  late Uri macroUri;
   late File simpleMacroFile;
+  late Directory tmpDir;
 
-  setUpAll(() {
+  setUpAll(() async {
     // We support running from either the root of the SDK or the package root.
     simpleMacroFile = File(
         'pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart');
     if (!simpleMacroFile.existsSync()) {
       simpleMacroFile = File('test/macros/isolated_executor/simple_macro.dart');
     }
-  });
-
-  setUp(() async {
     executor = await isolatedExecutor.start();
     tmpDir = Directory.systemTemp.createTempSync('isolated_executor_test');
-  });
-
-  tearDown(() {
-    if (tmpDir.existsSync()) tmpDir.deleteSync(recursive: true);
-    executor.close();
-  });
-
-  test('can load and run macros', () async {
-    var macroUri = simpleMacroFile.absolute.uri;
-    var macroName = 'SimpleMacro';
+    macroUri = simpleMacroFile.absolute.uri;
 
     var bootstrapContent = bootstrapMacroIsolate({
       macroUri.toString(): {
@@ -51,22 +43,22 @@
     });
     var bootstrapFile = File(tmpDir.uri.resolve('main.dart').toFilePath())
       ..writeAsStringSync(bootstrapContent);
-    var kernelOutputFile =
-        File(tmpDir.uri.resolve('main.dart.dill').toFilePath());
-    var result = await Process.run(Platform.resolvedExecutable, [
+    kernelOutputFile = File(tmpDir.uri.resolve('main.dart.dill').toFilePath());
+    var buildSnapshotResult = await Process.run(Platform.resolvedExecutable, [
       '--snapshot=${kernelOutputFile.uri.toFilePath()}',
       '--snapshot-kind=kernel',
       '--packages=${(await Isolate.packageConfig)!}',
       bootstrapFile.uri.toFilePath(),
     ]);
-    expect(result.exitCode, 0,
-        reason: 'stdout: ${result.stdout}\nstderr: ${result.stderr}');
+    expect(buildSnapshotResult.exitCode, 0,
+        reason: 'stdout: ${buildSnapshotResult.stdout}\n'
+            'stderr: ${buildSnapshotResult.stderr}');
 
     var clazzId = await executor.loadMacro(macroUri, macroName,
         precompiledKernelUri: kernelOutputFile.uri);
     expect(clazzId, isNotNull, reason: 'Can load a macro.');
 
-    var instanceId =
+    instanceId =
         await executor.instantiateMacro(clazzId, '', Arguments([], {}));
     expect(instanceId, isNotNull,
         reason: 'Can create an instance with no arguments.');
@@ -80,7 +72,14 @@
         clazzId, 'named', Arguments([], {'x': 1, 'y': 2}));
     expect(instanceId, isNotNull,
         reason: 'Can create an instance with named arguments.');
+  });
 
+  tearDownAll(() {
+    if (tmpDir.existsSync()) tmpDir.deleteSync(recursive: true);
+    executor.close();
+  });
+
+  group('run macros', () {
     var stringType = NamedTypeAnnotationImpl(
         id: RemoteInstance.uniqueId,
         name: 'String',
@@ -111,6 +110,7 @@
     var myClass = ClassDeclarationImpl(
         id: RemoteInstance.uniqueId,
         name: myClassType.name,
+        type: myClassType,
         typeParameters: [],
         interfaces: [myInterfaceType],
         isAbstract: false,
@@ -134,13 +134,15 @@
         id: RemoteInstance.uniqueId,
         name: 'myField',
         initializer: null,
-        isAbstract: false,
         isExternal: false,
+        isFinal: false,
+        isLate: false,
         type: stringType,
         definingClass: myClassType);
     var myInterface = ClassDeclarationImpl(
         id: RemoteInstance.uniqueId,
         name: myInterfaceType.name,
+        type: myInterfaceType,
         typeParameters: [],
         interfaces: [],
         isAbstract: false,
@@ -162,6 +164,7 @@
     var myMixin = ClassDeclarationImpl(
         id: RemoteInstance.uniqueId,
         name: myMixinType.name,
+        type: myMixinType,
         typeParameters: [],
         interfaces: [],
         isAbstract: false,
@@ -171,6 +174,7 @@
     var mySuperclass = ClassDeclarationImpl(
         id: RemoteInstance.uniqueId,
         name: mySuperclassType.name,
+        type: mySuperclassType,
         typeParameters: [],
         interfaces: [],
         isAbstract: false,
@@ -181,61 +185,189 @@
     var myClassStaticType = TestNamedStaticType(
         'package:my_package/my_package.dart', myClassType.name, []);
 
-    var definitionResult = await executor.executeDefinitionsPhase(
-        instanceId,
-        MethodDeclarationImpl(
-          id: RemoteInstance.uniqueId,
-          definingClass: myClassType,
-          isAbstract: false,
-          isExternal: false,
-          isGetter: false,
-          isSetter: false,
-          name: 'foo',
-          namedParameters: [],
-          positionalParameters: [],
-          returnType: stringType,
-          typeParameters: [],
-        ),
-        TestTypeResolver({
-          stringType: TestNamedStaticType('dart:core', stringType.name, []),
-          myClassType: myClassStaticType,
-        }),
-        TestClassIntrospector(
-          constructors: {
-            myClass: [myConstructor],
-          },
-          fields: {
-            myClass: [myField],
-          },
-          interfaces: {
-            myClass: [myInterface],
-          },
-          methods: {
-            myClass: [myMethod],
-          },
-          mixins: {
-            myClass: [myMixin],
-          },
-          superclass: {
-            myClass: mySuperclass,
-          },
-        ),
-        TestTypeDeclarationResolver({myClassStaticType: myClass}));
-    expect(definitionResult.augmentations, hasLength(1));
-    expect(definitionResult.augmentations.first.debugString().toString(),
-        equalsIgnoringWhitespace('''
-          augment class MyClass {
-            augment String foo() {
-              print('x: 1, y: 2');
-              print('parentClass: MyClass');
-              print('superClass: MySuperclass');
-              print('interface: MyInterface');
-              print('mixin: MyMixin');
-              print('field: myField');
-              print('method: myMethod');
-              print('constructor: myConstructor');
-              return augment super();
-            }
-          }'''));
+    var testTypeResolver = TestTypeResolver({
+      stringType: TestNamedStaticType('dart:core', stringType.name, []),
+      myClassType: myClassStaticType,
+    });
+    var testClassIntrospector = TestClassIntrospector(
+      constructors: {
+        myClass: [myConstructor],
+      },
+      fields: {
+        myClass: [myField],
+      },
+      interfaces: {
+        myClass: [myInterface],
+      },
+      methods: {
+        myClass: [myMethod],
+      },
+      mixins: {
+        myClass: [myMixin],
+      },
+      superclass: {
+        myClass: mySuperclass,
+      },
+    );
+    var testTypeDeclarationResolver =
+        TestTypeDeclarationResolver({myClassStaticType: myClass});
+
+    group('in the declaration phase', () {
+      test('on methods', () async {
+        var result = await executor.executeDeclarationsPhase(
+            instanceId, myMethod, testTypeResolver, testClassIntrospector);
+        expect(
+            result.augmentations.single.debugString().toString(),
+            equalsIgnoringWhitespace(
+                'String delegateMemberMyMethod() => myMethod();'));
+      });
+
+      test('on constructors', () async {
+        var result = await executor.executeDeclarationsPhase(
+            instanceId, myConstructor, testTypeResolver, testClassIntrospector);
+        expect(result.augmentations.single.debugString().toString(),
+            equalsIgnoringWhitespace('''
+              augment class MyClass {
+                factory MyClass.myConstructorDelegate() => MyClass.myConstructor();
+              }'''));
+      });
+
+      test('on fields', () async {
+        var result = await executor.executeDeclarationsPhase(
+            instanceId, myField, testTypeResolver, testClassIntrospector);
+        expect(result.augmentations.single.debugString().toString(),
+            equalsIgnoringWhitespace('''
+              augment class MyClass {
+                String get delegateMyField => myField;
+              }'''));
+      });
+
+      test('on classes', () async {
+        var result = await executor.executeDeclarationsPhase(
+            instanceId, myClass, testTypeResolver, testClassIntrospector);
+        expect(result.augmentations.single.debugString().toString(),
+            equalsIgnoringWhitespace('''
+              augment class MyClass {
+                static const List<String> fieldNames = ['myField',];
+              }'''));
+      });
+    });
+
+    group('in the definition phase', () {
+      test('on methods', () async {
+        var definitionResult = await executor.executeDefinitionsPhase(
+            instanceId,
+            myMethod,
+            testTypeResolver,
+            testClassIntrospector,
+            testTypeDeclarationResolver);
+        expect(definitionResult.augmentations, hasLength(2));
+        var augmentationStrings = definitionResult.augmentations
+            .map((a) => a.debugString().toString())
+            .toList();
+        expect(augmentationStrings, unorderedEquals(methodDefinitionMatchers));
+      });
+
+      test('on constructors', () async {
+        var definitionResult = await executor.executeDefinitionsPhase(
+            instanceId,
+            myConstructor,
+            testTypeResolver,
+            testClassIntrospector,
+            testTypeDeclarationResolver);
+        expect(definitionResult.augmentations, hasLength(1));
+        expect(definitionResult.augmentations.first.debugString().toString(),
+            constructorDefinitionMatcher);
+      });
+
+      test('on fields', () async {
+        var definitionResult = await executor.executeDefinitionsPhase(
+            instanceId,
+            myField,
+            testTypeResolver,
+            testClassIntrospector,
+            testTypeDeclarationResolver);
+        expect(definitionResult.augmentations, hasLength(1));
+        expect(definitionResult.augmentations.first.debugString().toString(),
+            fieldDefinitionMatcher);
+      });
+
+      test('on classes', () async {
+        var definitionResult = await executor.executeDefinitionsPhase(
+            instanceId,
+            myClass,
+            testTypeResolver,
+            testClassIntrospector,
+            testTypeDeclarationResolver);
+        var augmentationStrings = definitionResult.augmentations
+            .map((a) => a.debugString().toString())
+            .toList();
+        expect(
+            augmentationStrings,
+            unorderedEquals([
+              ...methodDefinitionMatchers,
+              constructorDefinitionMatcher,
+              fieldDefinitionMatcher
+            ]));
+      });
+    });
   });
 }
+
+final constructorDefinitionMatcher = equalsIgnoringWhitespace('''
+augment class MyClass {
+  augment MyClass.myConstructor() {
+    print('definingClass: MyClass');
+    print('isFactory: false');
+    print('isAbstract: false');
+    print('isExternal: false');
+    print('isGetter: false');
+    print('isSetter: false');
+    print('returnType: MyClass');
+    return augment super();
+  }
+}''');
+
+final fieldDefinitionMatcher = equalsIgnoringWhitespace('''
+augment class MyClass {
+  augment String get myField {
+    print('parentClass: MyClass');
+    print('isExternal: false');
+    print('isFinal: false');
+    print('isLate: false');
+    return augment super;
+  }
+  augment set (String value) {
+    augment super(value);
+  }
+}''');
+
+final methodDefinitionMatchers = [
+  equalsIgnoringWhitespace('''
+    augment class MyClass {
+      augment String myMethod() {
+        print('definingClass: MyClass');
+        print('isAbstract: false');
+        print('isExternal: false');
+        print('isGetter: false');
+        print('isSetter: false');
+        print('returnType: String');
+        return augment super();
+      }
+    }
+    '''),
+  equalsIgnoringWhitespace('''
+    augment class MyClass {
+      augment String myMethod() {
+        print('x: 1, y: 2');
+        print('parentClass: MyClass');
+        print('superClass: MySuperclass');
+        print('interface: MyInterface');
+        print('mixin: MyMixin');
+        print('field: myField');
+        print('method: myMethod');
+        print('constructor: myConstructor');
+        return augment super();
+      }
+    }'''),
+];
diff --git a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart
index 84ddb7a..b5681aa 100644
--- a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart
@@ -6,9 +6,26 @@
 
 import 'package:_fe_analyzer_shared/src/macros/api.dart';
 
-/// A very simple macro that annotates functions (or getters) with no arguments
-/// and adds a print statement to the top of them.
-class SimpleMacro implements MethodDefinitionMacro {
+/// A very simple macro that augments any declaration it is given, usually
+/// adding print statements and inlining values from the declaration object
+/// for comparision with expected values in tests.
+///
+/// When applied to [MethodDeclaration]s there is some extra work that happens
+/// to validate the introspection APIs work as expected.
+class SimpleMacro
+    implements
+        ClassDeclarationsMacro,
+        ClassDefinitionMacro,
+        ConstructorDeclarationsMacro,
+        ConstructorDefinitionMacro,
+        FieldDeclarationsMacro,
+        FieldDefinitionMacro,
+        FunctionDeclarationsMacro,
+        FunctionDefinitionMacro,
+        MethodDeclarationsMacro,
+        MethodDefinitionMacro,
+        VariableDeclarationsMacro,
+        VariableDefinitionMacro {
   final int? x;
   final int? y;
 
@@ -17,14 +34,132 @@
   SimpleMacro.named({this.x, this.y});
 
   @override
-  FutureOr<void> buildDefinitionForMethod(
-      MethodDeclaration method, FunctionDefinitionBuilder builder) async {
-    if (method.namedParameters
-        .followedBy(method.positionalParameters)
-        .isNotEmpty) {
-      throw ArgumentError(
-          'This macro can only be run on functions with no arguments!');
+  FutureOr<void> buildDeclarationsForClass(
+      ClassDeclaration clazz, ClassMemberDeclarationBuilder builder) async {
+    var fields = await builder.fieldsOf(clazz);
+    builder.declareInClass(DeclarationCode.fromParts([
+      'static const List<String> fieldNames = [',
+      for (var field in fields) "'${field.name}',",
+      '];',
+    ]));
+  }
+
+  @override
+  FutureOr<void> buildDeclarationsForConstructor(
+      ConstructorDeclaration constructor,
+      ClassMemberDeclarationBuilder builder) {
+    if (constructor.positionalParameters.isNotEmpty ||
+        constructor.namedParameters.isNotEmpty) {
+      throw new UnsupportedError(
+          'Can only run on constructors with no parameters!');
     }
+    builder.declareInClass(
+        DeclarationCode.fromString('factory ${constructor.definingClass.name}'
+            '.${constructor.name}Delegate() => '
+            '${constructor.definingClass.name}.${constructor.name}();'));
+  }
+
+  @override
+  FutureOr<void> buildDeclarationsForFunction(
+      FunctionDeclaration function, DeclarationBuilder builder) {
+    if (function.positionalParameters.isNotEmpty ||
+        function.namedParameters.isNotEmpty) {
+      throw new UnsupportedError(
+          'Can only run on functions with no parameters!');
+    }
+    builder.declareInLibrary(DeclarationCode.fromParts([
+      function.returnType,
+      ' delegate${function.name.capitalize()}() => ${function.name}();',
+    ]));
+  }
+
+  @override
+  FutureOr<void> buildDeclarationsForMethod(
+      MethodDeclaration method, ClassMemberDeclarationBuilder builder) {
+    if (method.positionalParameters.isNotEmpty ||
+        method.namedParameters.isNotEmpty) {
+      throw new UnsupportedError('Can only run on method with no parameters!');
+    }
+    builder.declareInLibrary(DeclarationCode.fromParts([
+      method.returnType,
+      ' delegateMember${method.name.capitalize()}() => ${method.name}();',
+    ]));
+  }
+
+  @override
+  FutureOr<void> buildDeclarationsForVariable(
+      VariableDeclaration variable, DeclarationBuilder builder) {
+    builder.declareInLibrary(DeclarationCode.fromParts([
+      variable.type,
+      ' get delegate${variable.name.capitalize()} => ${variable.name};',
+    ]));
+  }
+
+  @override
+  FutureOr<void> buildDeclarationsForField(
+      FieldDeclaration field, ClassMemberDeclarationBuilder builder) {
+    builder.declareInClass(DeclarationCode.fromParts([
+      field.type,
+      ' get delegate${field.name.capitalize()} => ${field.name};',
+    ]));
+  }
+
+  @override
+  Future<void> buildDefinitionForClass(
+      ClassDeclaration clazz, ClassDefinitionBuilder builder) async {
+    // Apply ourself to all our members
+    var fields = (await builder.fieldsOf(clazz));
+    for (var field in fields) {
+      await buildDefinitionForField(
+          field, await builder.buildField(field.name));
+    }
+    var methods = (await builder.methodsOf(clazz));
+    for (var method in methods) {
+      await buildDefinitionForMethod(
+          method, await builder.buildMethod(method.name));
+    }
+    var constructors = (await builder.constructorsOf(clazz));
+    for (var constructor in constructors) {
+      await buildDefinitionForConstructor(
+          constructor, await builder.buildConstructor(constructor.name));
+    }
+  }
+
+  @override
+  Future<void> buildDefinitionForConstructor(ConstructorDeclaration constructor,
+      ConstructorDefinitionBuilder builder) async {
+    var clazz = await builder.declarationOf(
+            await builder.resolve(constructor.definingClass) as NamedStaticType)
+        as ClassDeclaration;
+    var fields = (await builder.fieldsOf(clazz));
+
+    builder.augment(
+      body: _buildFunctionAugmentation(constructor),
+      initializers: [
+        for (var field in fields)
+          // TODO: Compare against actual `int` type.
+          if (field.isFinal &&
+              (field.type as NamedTypeAnnotation).name == 'int')
+            Code.fromString('${field.name} = ${x!}'),
+      ],
+    );
+  }
+
+  @override
+  Future<void> buildDefinitionForField(
+          FieldDeclaration field, VariableDefinitionBuilder builder) async =>
+      buildDefinitionForVariable(field, builder);
+
+  @override
+  Future<void> buildDefinitionForFunction(
+      FunctionDeclaration function, FunctionDefinitionBuilder builder) async {
+    builder.augment(_buildFunctionAugmentation(function));
+  }
+
+  @override
+  Future<void> buildDefinitionForMethod(
+      MethodDeclaration method, FunctionDefinitionBuilder builder) async {
+    await buildDefinitionForFunction(method, builder);
 
     // Test the type resolver and static type interfaces
     var staticReturnType = await builder.resolve(method.returnType);
@@ -48,6 +183,9 @@
     // Test the type declaration resolver
     var parentClass =
         await builder.declarationOf(classType) as ClassDeclaration;
+    // Should be able to find ourself in the methods of the parent class.
+    (await builder.methodsOf(parentClass))
+        .singleWhere((m) => m.name == method.name);
 
     // Test the class introspector
     var superClass = (await builder.superclassOf(parentClass))!;
@@ -74,4 +212,71 @@
     }''',
     ]));
   }
+
+  @override
+  Future<void> buildDefinitionForVariable(
+      VariableDeclaration variable, VariableDefinitionBuilder builder) async {
+    var definingClass =
+        variable is FieldDeclaration ? variable.definingClass.name : '';
+    builder.augment(
+      getter: DeclarationCode.fromParts([
+        variable.type,
+        ' get ',
+        variable.name,
+        ''' {
+          print('parentClass: $definingClass');
+          print('isExternal: ${variable.isExternal}');
+          print('isFinal: ${variable.isFinal}');
+          print('isLate: ${variable.isLate}');
+          return augment super;
+        }''',
+      ]),
+      setter: DeclarationCode.fromParts(
+          ['set (', variable.type, ' value) { augment super(value); }']),
+      initializer: variable.initializer,
+    );
+  }
+}
+
+FunctionBodyCode _buildFunctionAugmentation(FunctionDeclaration function) =>
+    FunctionBodyCode.fromParts([
+      '{\n',
+      if (function is MethodDeclaration)
+        "print('definingClass: ${function.definingClass.name}');\n",
+      if (function is ConstructorDeclaration)
+        "print('isFactory: ${function.isFactory}');\n",
+      '''
+      print('isAbstract: ${function.isAbstract}');
+      print('isExternal: ${function.isExternal}');
+      print('isGetter: ${function.isGetter}');
+      print('isSetter: ${function.isSetter}');
+      print('returnType: ''',
+      function.returnType,
+      "');\n",
+      for (var param in function.positionalParameters) ...[
+        "print('positionalParam: ",
+        param.type,
+        ' ${param.name}',
+        if (param.defaultValue != null) ...[' = ', param.defaultValue!],
+        "');\n",
+      ],
+      for (var param in function.namedParameters) ...[
+        "print('namedParam: ",
+        param.type,
+        ' ${param.name}',
+        if (param.defaultValue != null) ...[' = ', param.defaultValue!],
+        "');\n",
+      ],
+      for (var param in function.typeParameters) ...[
+        "print('typeParam: ${param.name} ",
+        if (param.bounds != null) param.bounds!,
+        "');\n",
+      ],
+      '''
+      return augment super();
+    }''',
+    ]);
+
+extension _ on String {
+  String capitalize() => '${this[0].toUpperCase()}${this.substring(1)}';
 }
diff --git a/pkg/analysis_server/test/client/completion_driver_test.dart b/pkg/analysis_server/test/client/completion_driver_test.dart
index 732e5bb..a12950d 100644
--- a/pkg/analysis_server/test/client/completion_driver_test.dart
+++ b/pkg/analysis_server/test/client/completion_driver_test.dart
@@ -15,8 +15,10 @@
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(BasicCompletionTest);
-    defineReflectiveTests(CompletionWithSuggestionsTest);
+    defineReflectiveTests(BasicCompletionTest1);
+    defineReflectiveTests(BasicCompletionTest2);
+    defineReflectiveTests(CompletionWithSuggestionsTest1);
+    defineReflectiveTests(CompletionWithSuggestionsTest2);
   });
 }
 
@@ -29,6 +31,8 @@
 
   String get projectPath => '/$projectName';
 
+  TestingCompletionProtocol get protocol;
+
   AnalysisServerOptions get serverOptions => AnalysisServerOptions();
 
   bool get supportsAvailableSuggestions;
@@ -108,7 +112,14 @@
       await driver.waitForSetWithUri('dart:async');
     }
 
-    suggestions = await driver.getSuggestions();
+    switch (protocol) {
+      case TestingCompletionProtocol.version1:
+        suggestions = await driver.getSuggestions();
+        break;
+      case TestingCompletionProtocol.version2:
+        suggestions = await driver.getSuggestions2();
+        break;
+    }
     return suggestions;
   }
 
@@ -199,7 +210,20 @@
 }
 
 @reflectiveTest
-class BasicCompletionTest extends AbstractCompletionDriverTest {
+class BasicCompletionTest1 extends AbstractCompletionDriverTest
+    with BasicCompletionTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class BasicCompletionTest2 extends AbstractCompletionDriverTest
+    with BasicCompletionTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin BasicCompletionTestCases on AbstractCompletionDriverTest {
   @override
   bool get supportsAvailableSuggestions => false;
 
@@ -233,7 +257,40 @@
 }
 
 @reflectiveTest
-class CompletionWithSuggestionsTest extends AbstractCompletionDriverTest {
+class CompletionWithSuggestionsTest1 extends AbstractCompletionDriverTest
+    with CompletionWithSuggestionsTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+
+  @failingTest
+  @override
+  Future<void> test_project_lib_multipleExports() async {
+    return super.test_project_lib_multipleExports();
+  }
+}
+
+@reflectiveTest
+class CompletionWithSuggestionsTest2 extends AbstractCompletionDriverTest
+    with CompletionWithSuggestionsTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+
+  @FailingTest(reason: 'Not implemented yet')
+  @override
+  Future<void> test_project_lib_fields_static() {
+    // TODO: implement test_project_lib_fields_static
+    return super.test_project_lib_fields_static();
+  }
+
+  @FailingTest(reason: 'Not implemented yet')
+  @override
+  Future<void> test_project_lib_getters_static() {
+    // TODO: implement test_project_lib_getters_static
+    return super.test_project_lib_getters_static();
+  }
+}
+
+mixin CompletionWithSuggestionsTestCases on AbstractCompletionDriverTest {
   @override
   bool get supportsAvailableSuggestions => true;
 
@@ -507,7 +564,6 @@
     assertNoSuggestion(completion: 'A.foo');
   }
 
-  @failingTest
   Future<void> test_project_lib_multipleExports() async {
     await addProjectFile('lib/a.dart', r'''
 class A {}
@@ -732,3 +788,5 @@
     // (No typedefs, enums, extensions defined in the Mock SDK.)
   }
 }
+
+enum TestingCompletionProtocol { version1, version2 }
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart
index 13a02b0..8577738 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart
@@ -5,16 +5,50 @@
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../../client/completion_driver_test.dart';
 import 'completion_relevance.dart';
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(BoolAssignmentTest);
+    // defineReflectiveTests(BoolAssignmentTest1);
+    defineReflectiveTests(BoolAssignmentTest2);
   });
 }
 
 @reflectiveTest
-class BoolAssignmentTest extends CompletionRelevanceTest {
+class BoolAssignmentTest1 extends CompletionRelevanceTest
+    with BoolAssignmentTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class BoolAssignmentTest2 extends CompletionRelevanceTest
+    with BoolAssignmentTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+
+  @FailingTest(reason: r'''
+The actual relevances are:
+[completion: bool.fromEnvironment][relevance: 591]
+[completion: bool.hasEnvironment][relevance: 591]
+[completion: b][relevance: 587]
+[completion: bool][relevance: 578]
+[completion: true][relevance: 574]
+[completion: false][relevance: 572]
+[completion: identical][relevance: 563]
+  for (var e in result) {
+    print('[completion: ${e.completion}][relevance: ${e.relevance}]');
+  }
+''')
+  @override
+  Future<void> test_boolLiterals_imported() {
+    // TODO: implement test_boolLiterals_imported
+    return super.test_boolLiterals_imported();
+  }
+}
+
+mixin BoolAssignmentTestCases on CompletionRelevanceTest {
   Future<void> test_boolLiterals_imported() async {
     await addTestFile('''
 foo() {
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/completion_relevance.dart b/pkg/analysis_server/test/services/completion/dart/relevance/completion_relevance.dart
index 81532df..f353b8d 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/completion_relevance.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/completion_relevance.dart
@@ -7,7 +7,7 @@
 
 import '../../../../client/completion_driver_test.dart';
 
-class CompletionRelevanceTest extends AbstractCompletionDriverTest {
+abstract class CompletionRelevanceTest extends AbstractCompletionDriverTest {
   @override
   bool get supportsAvailableSuggestions => true;
 
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/deprecated_member_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/deprecated_member_test.dart
index 44d0f92..40826b7 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/deprecated_member_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/deprecated_member_test.dart
@@ -5,16 +5,31 @@
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../../client/completion_driver_test.dart';
 import 'completion_relevance.dart';
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(DeprecatedMemberTest);
+    defineReflectiveTests(DeprecatedMemberTest1);
+    defineReflectiveTests(DeprecatedMemberTest2);
   });
 }
 
 @reflectiveTest
-class DeprecatedMemberTest extends CompletionRelevanceTest {
+class DeprecatedMemberTest1 extends CompletionRelevanceTest
+    with DeprecatedMemberTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class DeprecatedMemberTest2 extends CompletionRelevanceTest
+    with DeprecatedMemberTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin DeprecatedMemberTestCases on CompletionRelevanceTest {
   Future<void> test_deprecated() async {
     await addTestFile('''
 class A {
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_test.dart
index de08d73..b6ad9fc 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_test.dart
@@ -4,16 +4,31 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../../client/completion_driver_test.dart';
 import 'completion_relevance.dart';
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(InstanceMemberTest);
+    defineReflectiveTests(InstanceMemberTest1);
+    defineReflectiveTests(InstanceMemberTest2);
   });
 }
 
 @reflectiveTest
-class InstanceMemberTest extends CompletionRelevanceTest {
+class InstanceMemberTest1 extends CompletionRelevanceTest
+    with InstanceMemberTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class InstanceMemberTest2 extends CompletionRelevanceTest
+    with InstanceMemberTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin InstanceMemberTestCases on CompletionRelevanceTest {
   @override
   bool get supportsAvailableSuggestions => true;
 
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/is_no_such_method_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/is_no_such_method_test.dart
index 388a377..0a02b82 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/is_no_such_method_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/is_no_such_method_test.dart
@@ -5,16 +5,31 @@
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../../client/completion_driver_test.dart';
 import 'completion_relevance.dart';
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(IsNoSuchMethodTest);
+    defineReflectiveTests(IsNoSuchMethodTest1);
+    defineReflectiveTests(IsNoSuchMethodTest2);
   });
 }
 
 @reflectiveTest
-class IsNoSuchMethodTest extends CompletionRelevanceTest {
+class IsNoSuchMethodTest1 extends CompletionRelevanceTest
+    with IsNoSuchMethodTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class IsNoSuchMethodTest2 extends CompletionRelevanceTest
+    with IsNoSuchMethodTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin IsNoSuchMethodTestCases on CompletionRelevanceTest {
   Future<void> test_notSuper() async {
     await addTestFile('''
 void foo(Object o) {
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/local_variable_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/local_variable_test.dart
index 8fe61ae..c5a3d1a 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/local_variable_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/local_variable_test.dart
@@ -5,16 +5,31 @@
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../../client/completion_driver_test.dart';
 import 'completion_relevance.dart';
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(LocalVariableTest);
+    defineReflectiveTests(LocalVariableTest1);
+    defineReflectiveTests(LocalVariableTest2);
   });
 }
 
 @reflectiveTest
-class LocalVariableTest extends CompletionRelevanceTest {
+class LocalVariableTest1 extends CompletionRelevanceTest
+    with LocalVariableTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class LocalVariableTest2 extends CompletionRelevanceTest
+    with LocalVariableTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin LocalVariableTestCases on CompletionRelevanceTest {
   Future<void> test_localVariables() async {
     await addTestFile('''
 int f() {
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_test.dart
index a8a5607..018a020 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_test.dart
@@ -4,18 +4,32 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../../client/completion_driver_test.dart';
 import '../../../../src/utilities/mock_packages.dart';
 import 'completion_relevance.dart';
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(NamedArgumentTest);
-    defineReflectiveTests(NamedArgumentWithNullSafetyTest);
+    defineReflectiveTests(NamedArgumentTest1);
+    defineReflectiveTests(NamedArgumentTest2);
   });
 }
 
 @reflectiveTest
-class NamedArgumentTest extends CompletionRelevanceTest {
+class NamedArgumentTest1 extends CompletionRelevanceTest
+    with NamedArgumentTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class NamedArgumentTest2 extends CompletionRelevanceTest
+    with NamedArgumentTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin NamedArgumentTestCases on CompletionRelevanceTest {
   @override
   Future<void> setUp() async {
     await super.setUp();
@@ -28,11 +42,9 @@
 ''');
   }
 
-  Future<void> test_requiredAnnotation() async {
+  Future<void> test_required() async {
     await addTestFile('''
-import 'package:meta/meta.dart';
-
-void f({int a, @required int b}) {}
+void f({int a = 0, required int b}) {}
 
 void g() => f(^);
 ''');
@@ -41,13 +53,12 @@
       suggestionWith(completion: 'a: '),
     ]);
   }
-}
 
-@reflectiveTest
-class NamedArgumentWithNullSafetyTest extends NamedArgumentTest {
-  Future<void> test_required() async {
+  Future<void> test_requiredAnnotation() async {
     await addTestFile('''
-void f({int a = 0, required int b}) {}
+import 'package:meta/meta.dart';
+
+void f({int a, @required int b}) {}
 
 void g() => f(^);
 ''');
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/non_type_member_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/non_type_member_test.dart
index 084c91c..c582a1c 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/non_type_member_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/non_type_member_test.dart
@@ -5,16 +5,31 @@
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../../client/completion_driver_test.dart';
 import 'completion_relevance.dart';
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(NonTypeMemberTest);
+    defineReflectiveTests(NonTypeMemberTest1);
+    defineReflectiveTests(NonTypeMemberTest2);
   });
 }
 
 @reflectiveTest
-class NonTypeMemberTest extends CompletionRelevanceTest {
+class NonTypeMemberTest1 extends CompletionRelevanceTest
+    with NonTypeMemberTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class NonTypeMemberTest2 extends CompletionRelevanceTest
+    with NonTypeMemberTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin NonTypeMemberTestCases on CompletionRelevanceTest {
   Future<void> test_contextType_constructorInvocation_before_type() async {
     await addTestFile('''
 class StrWrap {
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/static_member_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/static_member_test.dart
index 314b1e0..a9e1de8 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/static_member_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/static_member_test.dart
@@ -4,16 +4,31 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../../client/completion_driver_test.dart';
 import 'completion_relevance.dart';
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(StaticMemberTest);
+    defineReflectiveTests(StaticMemberTest1);
+    defineReflectiveTests(StaticMemberTest2);
   });
 }
 
 @reflectiveTest
-class StaticMemberTest extends CompletionRelevanceTest {
+class StaticMemberTest1 extends CompletionRelevanceTest
+    with StaticMemberTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class StaticMemberTest2 extends CompletionRelevanceTest
+    with StaticMemberTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin StaticMemberTestCases on CompletionRelevanceTest {
   Future<void> test_contextType() async {
     await addTestFile(r'''
 class A {}
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 18fa4cb..55ad35e 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -142,6 +142,10 @@
 
   static const String cfeInvocationModes = '--cfe-invocation-modes';
 
+  /// Flag to indicate how the compiler is invoked. Used to ensure
+  /// dart2js is only invoked from supported tools and through the Dart CLI.
+  static const String invoker = '--invoker';
+
   /// Flag to stop after splitting the program.
   static const String stopAfterProgramSplit = '--stop-after-program-split';
 
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index d8ec77f..1913f4e 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -139,6 +139,7 @@
   ReadStrategy readStrategy = ReadStrategy.fromDart;
   WriteStrategy writeStrategy = WriteStrategy.toJs;
   FeatureOptions features = FeatureOptions();
+  String invoker;
 
   void passThrough(String argument) => options.add(argument);
   void ignoreOption(String argument) {}
@@ -480,6 +481,10 @@
     passThrough(argument);
   }
 
+  void setInvoker(String argument) {
+    invoker = extractParameter(argument);
+  }
+
   void handleThrowOnError(String argument) {
     throwOnError = true;
     String parameter = extractParameter(argument, isOptionalArgument: true);
@@ -645,6 +650,7 @@
     OptionHandler(Flags.testMode, passThrough),
     OptionHandler('${Flags.dumpSsa}=.+', passThrough),
     OptionHandler('${Flags.cfeInvocationModes}=.+', passThrough),
+    OptionHandler('${Flags.invoker}=.+', setInvoker),
     OptionHandler('${Flags.verbosity}=.+', passThrough),
 
     // Experimental features.
@@ -694,6 +700,13 @@
 
   parseCommandLine(handlers, argv);
 
+  if (invoker == null) {
+    warning("The 'dart2js' entrypoint script is deprecated, "
+        "please use 'dart compile js' instead.");
+  } else if (verbose != null) {
+    print("Compiler invoked from: '$invoker'");
+  }
+
   // TODO(johnniwinther): Measure time for reading files.
   SourceFileProvider inputProvider;
   if (bazelPaths != null) {
@@ -1128,7 +1141,7 @@
   // before and after running the compiler. Another two lines may be
   // used to print an error message.
   print('''
-Usage: dart2js [options] dartfile
+Usage: dart compile js [options] dartfile
 
 Compiles Dart to JavaScript.
 
@@ -1140,7 +1153,7 @@
 
 void verboseHelp() {
   print(r'''
-Usage: dart2js [options] dartfile
+Usage: dart compile js [options] dartfile
 
 Compiles Dart to JavaScript.
 
@@ -1352,6 +1365,15 @@
   fail(message);
 }
 
+void warning(String message) {
+  if (diagnosticHandler != null) {
+    diagnosticHandler.report(
+        null, null, -1, -1, message, api.Diagnostic.WARNING);
+  } else {
+    print('Warning: $message');
+  }
+}
+
 Future<void> main(List<String> arguments) async {
   // Expand `@path/to/file`
   // When running from bazel, argument of the form `@path/to/file` might be
diff --git a/pkg/dartdev/lib/src/commands/compile.dart b/pkg/dartdev/lib/src/commands/compile.dart
index 4198a79..bd48713 100644
--- a/pkg/dartdev/lib/src/commands/compile.dart
+++ b/pkg/dartdev/lib/src/commands/compile.dart
@@ -90,6 +90,7 @@
         [
           '--libraries-spec=$librariesPath',
           '--cfe-invocation-modes=compile',
+          '--invoker=dart_cli',
           ...argResults.arguments,
         ],
         packageConfigOverride: null);
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.weak.expect b/pkg/front_end/testcases/general/ffi_sample.dart.weak.expect
index d92782a..8c513a4 100644
--- a/pkg/front_end/testcases/general/ffi_sample.dart.weak.expect
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.weak.expect
@@ -40,7 +40,7 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
 - _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
 - NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.weak.modular.expect b/pkg/front_end/testcases/general/ffi_sample.dart.weak.modular.expect
index d92782a..8c513a4 100644
--- a/pkg/front_end/testcases/general/ffi_sample.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.weak.modular.expect
@@ -40,7 +40,7 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
 - _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
 - NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.weak.transformed.expect b/pkg/front_end/testcases/general/ffi_sample.dart.weak.transformed.expect
index 0765c4c..ae497d5a 100644
--- a/pkg/front_end/testcases/general/ffi_sample.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.weak.transformed.expect
@@ -74,7 +74,7 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
 - _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
 - NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.1.expect
index 7e198e7..6c37a20d 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.1.expect
@@ -51,7 +51,6 @@
   ffi::Bool,
   ffi::BoolArray,
   ffi::BoolPointer,
-  ffi::Char,
   ffi::DartRepresentationOf,
   ffi::Dart_CObject,
   ffi::Double,
@@ -64,7 +63,6 @@
   ffi::FloatArray,
   ffi::FloatPointer,
   ffi::Handle,
-  ffi::Int,
   ffi::Int16,
   ffi::Int16Array,
   ffi::Int16Pointer,
@@ -78,8 +76,6 @@
   ffi::Int8Array,
   ffi::Int8Pointer,
   ffi::IntPtr,
-  ffi::Long,
-  ffi::LongLong,
   ffi::NativeApi,
   ffi::NativeFunction,
   ffi::NativeFunctionPointer,
@@ -90,9 +86,6 @@
   ffi::Pointer,
   ffi::PointerArray,
   ffi::PointerPointer,
-  ffi::Short,
-  ffi::SignedChar,
-  ffi::Size,
   ffi::Struct,
   ffi::StructArray,
   ffi::StructPointer,
@@ -108,18 +101,11 @@
   ffi::Uint8,
   ffi::Uint8Array,
   ffi::Uint8Pointer,
-  ffi::UintPtr,
   ffi::Union,
   ffi::UnionArray,
   ffi::UnionPointer,
-  ffi::UnsignedChar,
-  ffi::UnsignedInt,
-  ffi::UnsignedLong,
-  ffi::UnsignedLongLong,
-  ffi::UnsignedShort,
   ffi::Unsized,
-  ffi::Void,
-  ffi::WChar)
+  ffi::Void)
 
   export "org-dartlang-test:///lib3.dart";
 
@@ -141,7 +127,6 @@
   ffi::Bool,
   ffi::BoolArray,
   ffi::BoolPointer,
-  ffi::Char,
   ffi::DartRepresentationOf,
   ffi::Dart_CObject,
   ffi::Double,
@@ -154,7 +139,6 @@
   ffi::FloatArray,
   ffi::FloatPointer,
   ffi::Handle,
-  ffi::Int,
   ffi::Int16,
   ffi::Int16Array,
   ffi::Int16Pointer,
@@ -168,8 +152,6 @@
   ffi::Int8Array,
   ffi::Int8Pointer,
   ffi::IntPtr,
-  ffi::Long,
-  ffi::LongLong,
   ffi::NativeApi,
   ffi::NativeFunction,
   ffi::NativeFunctionPointer,
@@ -180,9 +162,6 @@
   ffi::Pointer,
   ffi::PointerArray,
   ffi::PointerPointer,
-  ffi::Short,
-  ffi::SignedChar,
-  ffi::Size,
   ffi::Struct,
   ffi::StructArray,
   ffi::StructPointer,
@@ -198,18 +177,11 @@
   ffi::Uint8,
   ffi::Uint8Array,
   ffi::Uint8Pointer,
-  ffi::UintPtr,
   ffi::Union,
   ffi::UnionArray,
   ffi::UnionPointer,
-  ffi::UnsignedChar,
-  ffi::UnsignedInt,
-  ffi::UnsignedLong,
-  ffi::UnsignedLongLong,
-  ffi::UnsignedShort,
   ffi::Unsized,
-  ffi::Void,
-  ffi::WChar)
+  ffi::Void)
 
   export "dart:ffi";
 
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.2.expect
index 934102e..e7c047a 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.2.expect
@@ -51,7 +51,6 @@
   ffi::Bool,
   ffi::BoolArray,
   ffi::BoolPointer,
-  ffi::Char,
   ffi::DartRepresentationOf,
   ffi::Dart_CObject,
   ffi::Double,
@@ -64,7 +63,6 @@
   ffi::FloatArray,
   ffi::FloatPointer,
   ffi::Handle,
-  ffi::Int,
   ffi::Int16,
   ffi::Int16Array,
   ffi::Int16Pointer,
@@ -78,8 +76,6 @@
   ffi::Int8Array,
   ffi::Int8Pointer,
   ffi::IntPtr,
-  ffi::Long,
-  ffi::LongLong,
   ffi::NativeApi,
   ffi::NativeFunction,
   ffi::NativeFunctionPointer,
@@ -90,9 +86,6 @@
   ffi::Pointer,
   ffi::PointerArray,
   ffi::PointerPointer,
-  ffi::Short,
-  ffi::SignedChar,
-  ffi::Size,
   ffi::Struct,
   ffi::StructArray,
   ffi::StructPointer,
@@ -108,18 +101,11 @@
   ffi::Uint8,
   ffi::Uint8Array,
   ffi::Uint8Pointer,
-  ffi::UintPtr,
   ffi::Union,
   ffi::UnionArray,
   ffi::UnionPointer,
-  ffi::UnsignedChar,
-  ffi::UnsignedInt,
-  ffi::UnsignedLong,
-  ffi::UnsignedLongLong,
-  ffi::UnsignedShort,
   ffi::Unsized,
-  ffi::Void,
-  ffi::WChar)
+  ffi::Void)
 
   export "org-dartlang-test:///lib3.dart";
 
@@ -141,7 +127,6 @@
   ffi::Bool,
   ffi::BoolArray,
   ffi::BoolPointer,
-  ffi::Char,
   ffi::DartRepresentationOf,
   ffi::Dart_CObject,
   ffi::Double,
@@ -154,7 +139,6 @@
   ffi::FloatArray,
   ffi::FloatPointer,
   ffi::Handle,
-  ffi::Int,
   ffi::Int16,
   ffi::Int16Array,
   ffi::Int16Pointer,
@@ -168,8 +152,6 @@
   ffi::Int8Array,
   ffi::Int8Pointer,
   ffi::IntPtr,
-  ffi::Long,
-  ffi::LongLong,
   ffi::NativeApi,
   ffi::NativeFunction,
   ffi::NativeFunctionPointer,
@@ -180,9 +162,6 @@
   ffi::Pointer,
   ffi::PointerArray,
   ffi::PointerPointer,
-  ffi::Short,
-  ffi::SignedChar,
-  ffi::Size,
   ffi::Struct,
   ffi::StructArray,
   ffi::StructPointer,
@@ -198,18 +177,11 @@
   ffi::Uint8,
   ffi::Uint8Array,
   ffi::Uint8Pointer,
-  ffi::UintPtr,
   ffi::Union,
   ffi::UnionArray,
   ffi::UnionPointer,
-  ffi::UnsignedChar,
-  ffi::UnsignedInt,
-  ffi::UnsignedLong,
-  ffi::UnsignedLongLong,
-  ffi::UnsignedShort,
   ffi::Unsized,
-  ffi::Void,
-  ffi::WChar)
+  ffi::Void)
 
   export "dart:ffi";
 
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.expect
index b190b3a..35dda10 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.expect
@@ -34,7 +34,7 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
 - _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
 - NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.transformed.expect
index fccf634..02dfd2a 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.transformed.expect
@@ -65,7 +65,7 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
 - _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
 - NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.expect
index b190b3a..35dda10 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.expect
@@ -34,7 +34,7 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
 - _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
 - NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.modular.expect
index b190b3a..35dda10 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.modular.expect
@@ -34,7 +34,7 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
 - _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
 - NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.transformed.expect
index fccf634..02dfd2a 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.transformed.expect
@@ -65,7 +65,7 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
 - _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
 - NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.expect
index 4d771b3..0db513d 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.expect
@@ -25,5 +25,5 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect
index f3903c0..525cfd9 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect
@@ -52,5 +52,5 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.expect
index e179ab5..e6c0f95 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.expect
@@ -25,5 +25,5 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.modular.expect
index e179ab5..e6c0f95 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.modular.expect
@@ -25,5 +25,5 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect
index 24cfa96..b38ad34 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect
@@ -52,5 +52,5 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.expect
index dd7fa30..0e058b1 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.expect
@@ -33,5 +33,5 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.transformed.expect
index a16945b..ecf21c0 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.transformed.expect
@@ -84,5 +84,5 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.expect
index be09548..5e4b756 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.expect
@@ -33,5 +33,5 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.modular.expect
index be09548..5e4b756 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.modular.expect
@@ -33,5 +33,5 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.transformed.expect
index a83a86b..a9ba39c 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.transformed.expect
@@ -84,5 +84,5 @@
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
 - Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/test_runner/lib/src/command.dart b/pkg/test_runner/lib/src/command.dart
index da28355..c14af03 100644
--- a/pkg/test_runner/lib/src/command.dart
+++ b/pkg/test_runner/lib/src/command.dart
@@ -124,7 +124,9 @@
         (io.Platform.operatingSystem == 'windows')
             ? env.write('set $key=${escapeCommandLineArgument(value)} & ')
             : env.write('$key=${escapeCommandLineArgument(value)} '));
-    var command = ([executable]..addAll(batchArguments)..addAll(arguments))
+    var command = ([executable]
+          ..addAll(nonBatchArguments)
+          ..addAll(arguments))
         .map(escapeCommandLineArgument)
         .join(' ');
     if (workingDirectory != null) {
@@ -135,10 +137,13 @@
 
   bool get outputIsUpToDate => false;
 
-  /// Arguments that are passed to the process when starting batch mode.
-  ///
-  /// In non-batch mode, they should be passed before [arguments].
+  /// Additional arguments to prepend before [arguments] when running the
+  /// process in batch mode.
   List<String> get batchArguments => const [];
+
+  /// Additional arguments to prepend before [arguments] when running the
+  /// process in non-batch mode.
+  List<String> get nonBatchArguments => const [];
 }
 
 class CompilationCommand extends ProcessCommand {
@@ -243,6 +248,61 @@
       deepJsonCompare(_bootstrapDependencies, other._bootstrapDependencies);
 }
 
+class Dart2jsCompilationCommand extends CompilationCommand {
+  final bool useSdk;
+
+  Dart2jsCompilationCommand(
+      String outputFile,
+      List<Uri> bootstrapDependencies,
+      String executable,
+      List<String> arguments,
+      Map<String, String> environmentOverrides,
+      {this.useSdk,
+      bool alwaysCompile,
+      String workingDirectory,
+      int index = 0})
+      : super("dart2js", outputFile, bootstrapDependencies, executable,
+            arguments, environmentOverrides,
+            alwaysCompile: alwaysCompile || true,
+            workingDirectory: workingDirectory,
+            index: index);
+
+  @override
+  CommandOutput createOutput(int exitCode, bool timedOut, List<int> stdout,
+      List<int> stderr, Duration time, bool compilationSkipped,
+      [int pid = 0]) {
+    return Dart2jsCompilerCommandOutput(
+        this, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
+  }
+
+  @override
+  List<String> get batchArguments {
+    return <String>[
+      if (useSdk) ...['compile', 'js'],
+      ...super.batchArguments,
+    ];
+  }
+
+  @override
+  List<String> get nonBatchArguments {
+    return <String>[
+      if (useSdk) ...['compile', 'js'],
+      ...super.nonBatchArguments,
+    ];
+  }
+
+  @override
+  void _buildHashCode(HashCodeBuilder builder) {
+    super._buildHashCode(builder);
+    builder.addJson(useSdk);
+  }
+
+  @override
+  bool _equal(Dart2jsCompilationCommand other) {
+    return super._equal(other) && useSdk == other.useSdk;
+  }
+}
+
 class FastaCompilationCommand extends CompilationCommand {
   final Uri _compilerLocation;
 
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index 16ac923..1ef049d 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -378,37 +378,34 @@
   }
 }
 
-/// Common configuration for dart2js-based tools, such as dart2js.
-class Dart2xCompilerConfiguration extends CompilerConfiguration {
+/// Configuration for dart2js.
+class Dart2jsCompilerConfiguration extends CompilerConfiguration {
   static final Map<String, List<Uri>> _bootstrapDependenciesCache = {};
 
-  final String moniker;
-
-  Dart2xCompilerConfiguration(this.moniker, TestConfiguration configuration)
+  Dart2jsCompilerConfiguration(TestConfiguration configuration)
       : super._subclass(configuration);
 
   String computeCompilerPath() {
-    var prefix = 'sdk/bin';
-    var suffix = shellScriptExtension;
-
-    if (_isHostChecked) {
-      if (_useSdk) {
-        // Note: when [_useSdk] is true, dart2js is run from a snapshot that was
-        // built without checked mode. The VM cannot make such snapshot run in
-        // checked mode later. These two flags could be used together if we also
-        // build an sdk with checked snapshots.
-        throw "--host-checked and --use-sdk cannot be used together";
-      }
-      // The script dart2js_developer is not included in the
-      // shipped SDK, that is the script is not installed in
-      // "$buildDir/dart-sdk/bin/"
-      return '$prefix/dart2js_developer$suffix';
+    if (_isHostChecked && _useSdk) {
+      // When [_useSdk] is true, dart2js is compiled into a snapshot that was
+      // built without checked mode. The VM cannot make such snapshot run in
+      // checked mode later. These two flags could be used together if we also
+      // build an sdk with checked snapshots.
+      throw "--host-checked and --use-sdk cannot be used together";
     }
 
     if (_useSdk) {
-      prefix = '${_configuration.buildDirectory}/dart-sdk/bin';
+      var dartSdk = '${_configuration.buildDirectory}/dart-sdk';
+      // When using the shipped sdk, we invoke dart2js via the dart CLI using
+      // `dart compile js`.  The additional `compile js` arguments are added
+      // within [Dart2jsCompilationCommand]. This is because the arguments are
+      // added differently depending on whether the command is executed in batch
+      // mode or not.
+      return '$dartSdk/bin/dart$executableExtension';
+    } else {
+      var scriptName = _isHostChecked ? 'dart2js_developer' : 'dart2js';
+      return 'sdk/bin/$scriptName$shellScriptExtension';
     }
-    return '$prefix/dart2js$suffix';
   }
 
   Command computeCompilationCommand(String outputFileName,
@@ -416,9 +413,9 @@
     arguments = arguments.toList();
     arguments.add('--out=$outputFileName');
 
-    return CompilationCommand(moniker, outputFileName, bootstrapDependencies(),
+    return Dart2jsCompilationCommand(outputFileName, bootstrapDependencies(),
         computeCompilerPath(), arguments, environmentOverrides,
-        alwaysCompile: !_useSdk);
+        useSdk: _useSdk, alwaysCompile: !_useSdk);
   }
 
   List<Uri> bootstrapDependencies() {
@@ -431,12 +428,6 @@
                   .resolve('dart-sdk/bin/snapshots/dart2js.dart.snapshot')
             ]);
   }
-}
-
-/// Configuration for dart2js.
-class Dart2jsCompilerConfiguration extends Dart2xCompilerConfiguration {
-  Dart2jsCompilerConfiguration(TestConfiguration configuration)
-      : super('dart2js', configuration);
 
   List<String> computeCompilerArguments(
       TestFile testFile, List<String> vmOptions, List<String> args) {
diff --git a/pkg/test_runner/lib/src/test_case.dart b/pkg/test_runner/lib/src/test_case.dart
index 2597e45..72ed102 100644
--- a/pkg/test_runner/lib/src/test_case.dart
+++ b/pkg/test_runner/lib/src/test_case.dart
@@ -260,7 +260,7 @@
       _commandComplete(0);
     } else {
       var processEnvironment = _createProcessEnvironment();
-      var args = command.arguments;
+      var args = [...command.nonBatchArguments, ...command.arguments];
       var processFuture = io.Process.start(command.executable, args,
           environment: processEnvironment,
           workingDirectory: command.workingDirectory);
diff --git a/runtime/bin/ffi_test/ffi_test_functions.cc b/runtime/bin/ffi_test/ffi_test_functions.cc
index 1545f8e..dd5e41f 100644
--- a/runtime/bin/ffi_test/ffi_test_functions.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions.cc
@@ -1138,36 +1138,27 @@
 typedef intptr_t ssize_t;
 #endif
 
-#define DEFINE_SIZE_OF_AND_SIGN_OF(type_modifier, type, type2)                 \
-  DART_EXPORT uint64_t FfiSizeOf_##type_modifier##_##type##_##type2() {        \
-    return sizeof(type_modifier type type2);                                   \
-  }                                                                            \
-                                                                               \
-  DART_EXPORT uint64_t FfiSignOf_##type_modifier##_##type##_##type2() {        \
-    return std::numeric_limits<type_modifier type type2>::is_signed;           \
+#define DEFINE_SIZE_OF(type_modifier, type)                                    \
+  DART_EXPORT uint64_t FfiSizeOf_##type_modifier##_##type() {                  \
+    return sizeof(type_modifier type);                                         \
   }
 
-#define TYPES(F)                                                               \
-  F(, char, )             /* NOLINT */                                         \
-  F(signed, char, )       /* NOLINT */                                         \
-  F(unsigned, char, )     /* NOLINT */                                         \
-  F(, short, )            /* NOLINT */                                         \
-  F(unsigned, short, )    /* NOLINT */                                         \
-  F(, int, )              /* NOLINT */                                         \
-  F(unsigned, int, )      /* NOLINT */                                         \
-  F(, long, )             /* NOLINT */                                         \
-  F(unsigned, long, )     /* NOLINT */                                         \
-  F(, long, long)         /* NOLINT */                                         \
-  F(unsigned, long, long) /* NOLINT */                                         \
-  F(, intptr_t, )         /* NOLINT */                                         \
-  F(, uintptr_t, )        /* NOLINT */                                         \
-  F(, size_t, )           /* NOLINT */                                         \
-  F(, wchar_t, )          /* NOLINT */
+#define SIZES(F)                                                               \
+  F(, intptr_t)                                                                \
+  F(, uintptr_t)                                                               \
+  F(, int)                                                                     \
+  F(unsigned, int)                                                             \
+  F(, long)         /* NOLINT */                                               \
+  F(unsigned, long) /* NOLINT */                                               \
+  F(, wchar_t)                                                                 \
+  F(, size_t)                                                                  \
+  F(, ssize_t)                                                                 \
+  F(, off_t)
 
-TYPES(DEFINE_SIZE_OF_AND_SIGN_OF)
+SIZES(DEFINE_SIZE_OF)
 
-#undef DEFINE_SIZE_OF_AND_SIGN_OF
-#undef TYPES
+#undef DEFINE_SIZE_OF
+#undef SIZES
 
 DART_EXPORT int64_t WCharMinValue() {
   return WCHAR_MIN;
diff --git a/sdk/bin/dart2js b/sdk/bin/dart2js
index cfc91b1..750f20d 100755
--- a/sdk/bin/dart2js
+++ b/sdk/bin/dart2js
@@ -25,6 +25,7 @@
 unset EXTRA_OPTIONS
 declare -a EXTRA_OPTIONS
 
+EXTRA_OPTIONS+=('--invoker=development_script')
 if test -t 1; then
   # Stdout is a terminal.
   if test 8 -le `tput colors`; then
diff --git a/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart b/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart
index ca47a83..92e23c1 100644
--- a/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart
+++ b/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart
@@ -55,6 +55,11 @@
 @pragma("vm:entry-point")
 class Uint64 extends _NativeInteger {}
 
+// TODO(http://dartbug.com/47938): Implement as AbiSpecificInteger.
+@patch
+@pragma("vm:entry-point")
+class IntPtr extends _NativeInteger {}
+
 @patch
 @pragma("vm:entry-point")
 class Float extends _NativeDouble {}
diff --git a/sdk/lib/ffi/abi_specific.dart b/sdk/lib/ffi/abi_specific.dart
index a41308c..d84f74e 100644
--- a/sdk/lib/ffi/abi_specific.dart
+++ b/sdk/lib/ffi/abi_specific.dart
@@ -13,12 +13,10 @@
 /// For example:
 ///
 /// ```
-/// /// The C `uintptr_t` type.
+/// /// Represents a `uintptr_t` in C.
 /// ///
-/// /// The [UintPtr] type is a native type, and should not be constructed in
-/// /// Dart code.
-/// /// It occurs only in native type signatures and as annotation on [Struct]
-/// /// and [Union] fields.
+/// /// [UintPtr] is not constructible in the Dart code and serves purely as
+/// /// marker in type signatures.
 /// @AbiSpecificIntegerMapping({
 ///   Abi.androidArm: Uint32(),
 ///   Abi.androidArm64: Uint64(),
diff --git a/sdk/lib/ffi/c_type.dart b/sdk/lib/ffi/c_type.dart
deleted file mode 100644
index 9370fdc..0000000
--- a/sdk/lib/ffi/c_type.dart
+++ /dev/null
@@ -1,541 +0,0 @@
-// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// This library defines [NativeType]s for common C types.
-///
-/// Many C types only define a minimal size in the C standard, but they are
-/// consistent per [Abi]. Therefore we use [AbiSpecificInteger]s to define
-/// these C types in this library.
-part of dart.ffi;
-
-/// The C `char` type.
-///
-/// Typically a signed or unsigned 8-bit integer.
-/// For a guaranteed 8-bit integer, use [Int8] with the C `int8_t` type
-/// or [Uint8] with the C `uint8_t` type.
-/// For a specifically `signed` or `unsigned` `char`, use [SignedChar] or
-/// [UnsignedChar].
-///
-/// The [Char] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
-  Abi.androidArm: Uint8(),
-  Abi.androidArm64: Uint8(),
-  Abi.androidIA32: Uint8(),
-  Abi.androidX64: Uint8(),
-  Abi.fuchsiaArm64: Int8(),
-  Abi.fuchsiaX64: Int8(),
-  Abi.iosArm: Uint8(),
-  Abi.iosArm64: Int8(),
-  Abi.iosX64: Int8(),
-  Abi.linuxArm: Uint8(),
-  Abi.linuxArm64: Int8(),
-  Abi.linuxIA32: Int8(),
-  Abi.linuxX64: Int8(),
-  Abi.linuxRiscv32: Int8(),
-  Abi.linuxRiscv64: Int8(),
-  Abi.macosArm64: Int8(),
-  Abi.macosX64: Int8(),
-  Abi.windowsArm64: Int8(),
-  Abi.windowsIA32: Int8(),
-  Abi.windowsX64: Int8(),
-})
-class Char extends AbiSpecificInteger {
-  const Char();
-}
-
-/// The C `signed char` type.
-///
-/// Typically a signed 8-bit integer.
-/// For a guaranteed 8-bit integer, use [Int8] with the C `int8_t` type.
-/// For an `unsigned char`, use [UnsignedChar].
-///
-/// The [SignedChar] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
-  Abi.androidArm: Int8(),
-  Abi.androidArm64: Int8(),
-  Abi.androidIA32: Int8(),
-  Abi.androidX64: Int8(),
-  Abi.fuchsiaArm64: Int8(),
-  Abi.fuchsiaX64: Int8(),
-  Abi.iosArm: Int8(),
-  Abi.iosArm64: Int8(),
-  Abi.iosX64: Int8(),
-  Abi.linuxArm: Int8(),
-  Abi.linuxArm64: Int8(),
-  Abi.linuxIA32: Int8(),
-  Abi.linuxX64: Int8(),
-  Abi.linuxRiscv32: Int8(),
-  Abi.linuxRiscv64: Int8(),
-  Abi.macosArm64: Int8(),
-  Abi.macosX64: Int8(),
-  Abi.windowsArm64: Int8(),
-  Abi.windowsIA32: Int8(),
-  Abi.windowsX64: Int8(),
-})
-class SignedChar extends AbiSpecificInteger {
-  const SignedChar();
-}
-
-/// The C `unsigned char` type.
-///
-/// Typically an unsigned 8-bit integer.
-/// For a guaranteed 8-bit integer, use [Uint8] with the C `uint8_t` type.
-/// For a `signed char`, use [Char].
-///
-/// The [UnsignedChar] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
-  Abi.androidArm: Uint8(),
-  Abi.androidArm64: Uint8(),
-  Abi.androidIA32: Uint8(),
-  Abi.androidX64: Uint8(),
-  Abi.fuchsiaArm64: Uint8(),
-  Abi.fuchsiaX64: Uint8(),
-  Abi.iosArm: Uint8(),
-  Abi.iosArm64: Uint8(),
-  Abi.iosX64: Uint8(),
-  Abi.linuxArm: Uint8(),
-  Abi.linuxArm64: Uint8(),
-  Abi.linuxIA32: Uint8(),
-  Abi.linuxX64: Uint8(),
-  Abi.linuxRiscv32: Uint8(),
-  Abi.linuxRiscv64: Uint8(),
-  Abi.macosArm64: Uint8(),
-  Abi.macosX64: Uint8(),
-  Abi.windowsArm64: Uint8(),
-  Abi.windowsIA32: Uint8(),
-  Abi.windowsX64: Uint8(),
-})
-class UnsignedChar extends AbiSpecificInteger {
-  const UnsignedChar();
-}
-
-/// The C `short` type.
-///
-/// Typically a signed 16-bit integer.
-/// For a guaranteed 16-bit integer, use [Int16] with the C `int16_t` type.
-/// For an `unsigned short`, use [UnsignedShort].
-///
-/// The [Short] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
-  Abi.androidArm: Int16(),
-  Abi.androidArm64: Int16(),
-  Abi.androidIA32: Int16(),
-  Abi.androidX64: Int16(),
-  Abi.fuchsiaArm64: Int16(),
-  Abi.fuchsiaX64: Int16(),
-  Abi.iosArm: Int16(),
-  Abi.iosArm64: Int16(),
-  Abi.iosX64: Int16(),
-  Abi.linuxArm: Int16(),
-  Abi.linuxArm64: Int16(),
-  Abi.linuxIA32: Int16(),
-  Abi.linuxX64: Int16(),
-  Abi.linuxRiscv32: Int16(),
-  Abi.linuxRiscv64: Int16(),
-  Abi.macosArm64: Int16(),
-  Abi.macosX64: Int16(),
-  Abi.windowsArm64: Int16(),
-  Abi.windowsIA32: Int16(),
-  Abi.windowsX64: Int16(),
-})
-class Short extends AbiSpecificInteger {
-  const Short();
-}
-
-/// The C `unsigned short` type.
-///
-/// Typically an unsigned 16-bit integer.
-/// For a guaranteed 16-bit integer, use [Uint16] with the C `uint16_t` type.
-/// For a signed `short`, use [Short].
-///
-/// The [UnsignedShort] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
-  Abi.androidArm: Uint16(),
-  Abi.androidArm64: Uint16(),
-  Abi.androidIA32: Uint16(),
-  Abi.androidX64: Uint16(),
-  Abi.fuchsiaArm64: Uint16(),
-  Abi.fuchsiaX64: Uint16(),
-  Abi.iosArm: Uint16(),
-  Abi.iosArm64: Uint16(),
-  Abi.iosX64: Uint16(),
-  Abi.linuxArm: Uint16(),
-  Abi.linuxArm64: Uint16(),
-  Abi.linuxIA32: Uint16(),
-  Abi.linuxX64: Uint16(),
-  Abi.linuxRiscv32: Uint16(),
-  Abi.linuxRiscv64: Uint16(),
-  Abi.macosArm64: Uint16(),
-  Abi.macosX64: Uint16(),
-  Abi.windowsArm64: Uint16(),
-  Abi.windowsIA32: Uint16(),
-  Abi.windowsX64: Uint16(),
-})
-class UnsignedShort extends AbiSpecificInteger {
-  const UnsignedShort();
-}
-
-/// The C `int` type.
-///
-/// Typically a signed 32-bit integer.
-/// For a guaranteed 32-bit integer, use [Int32] with the C `int32_t` type.
-/// For an `unsigned int`, use [UnsignedInt].
-///
-/// The [Int] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
-  Abi.androidArm: Int32(),
-  Abi.androidArm64: Int32(),
-  Abi.androidIA32: Int32(),
-  Abi.androidX64: Int32(),
-  Abi.fuchsiaArm64: Int32(),
-  Abi.fuchsiaX64: Int32(),
-  Abi.iosArm: Int32(),
-  Abi.iosArm64: Int32(),
-  Abi.iosX64: Int32(),
-  Abi.linuxArm: Int32(),
-  Abi.linuxArm64: Int32(),
-  Abi.linuxIA32: Int32(),
-  Abi.linuxX64: Int32(),
-  Abi.linuxRiscv32: Int32(),
-  Abi.linuxRiscv64: Int32(),
-  Abi.macosArm64: Int32(),
-  Abi.macosX64: Int32(),
-  Abi.windowsArm64: Int32(),
-  Abi.windowsIA32: Int32(),
-  Abi.windowsX64: Int32(),
-})
-class Int extends AbiSpecificInteger {
-  const Int();
-}
-
-/// The C `unsigned int` type.
-///
-/// Typically an unsigned 32-bit integer.
-/// For a guaranteed 32-bit integer, use [Uint32] with the C `uint32_t` type.
-/// For a signed `int`, use [Int].
-///
-/// The [UnsignedInt] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
-  Abi.androidArm: Uint32(),
-  Abi.androidArm64: Uint32(),
-  Abi.androidIA32: Uint32(),
-  Abi.androidX64: Uint32(),
-  Abi.fuchsiaArm64: Uint32(),
-  Abi.fuchsiaX64: Uint32(),
-  Abi.iosArm: Uint32(),
-  Abi.iosArm64: Uint32(),
-  Abi.iosX64: Uint32(),
-  Abi.linuxArm: Uint32(),
-  Abi.linuxArm64: Uint32(),
-  Abi.linuxIA32: Uint32(),
-  Abi.linuxX64: Uint32(),
-  Abi.linuxRiscv32: Uint32(),
-  Abi.linuxRiscv64: Uint32(),
-  Abi.macosArm64: Uint32(),
-  Abi.macosX64: Uint32(),
-  Abi.windowsArm64: Uint32(),
-  Abi.windowsIA32: Uint32(),
-  Abi.windowsX64: Uint32(),
-})
-class UnsignedInt extends AbiSpecificInteger {
-  const UnsignedInt();
-}
-
-/// The C `long int`, aka. `long`, type.
-///
-/// Typically a signed 32- or 64-bit integer.
-/// For a guaranteed 32-bit integer, use [Int32] with the C `int32_t` type.
-/// For a guaranteed 64-bit integer, use [Int64] with the C `int64_t` type.
-/// For an `unsigned long`, use [UnsignedLong].
-///
-/// The [Long] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
-  Abi.androidArm: Int32(),
-  Abi.androidArm64: Int64(),
-  Abi.androidIA32: Int32(),
-  Abi.androidX64: Int64(),
-  Abi.fuchsiaArm64: Int64(),
-  Abi.fuchsiaX64: Int64(),
-  Abi.iosArm: Int32(),
-  Abi.iosArm64: Int64(),
-  Abi.iosX64: Int64(),
-  Abi.linuxArm: Int32(),
-  Abi.linuxArm64: Int64(),
-  Abi.linuxIA32: Int32(),
-  Abi.linuxX64: Int64(),
-  Abi.linuxRiscv32: Int32(),
-  Abi.linuxRiscv64: Int64(),
-  Abi.macosArm64: Int64(),
-  Abi.macosX64: Int64(),
-  Abi.windowsArm64: Int32(),
-  Abi.windowsIA32: Int32(),
-  Abi.windowsX64: Int32(),
-})
-class Long extends AbiSpecificInteger {
-  const Long();
-}
-
-/// The C `unsigned long int`, aka. `unsigned long`, type.
-///
-/// Typically an unsigned 32- or 64-bit integer.
-/// For a guaranteed 32-bit integer, use [Uint32] with the C `uint32_t` type.
-/// For a guaranteed 64-bit integer, use [Uint64] with the C `uint64_t` type.
-/// For a signed `long`, use [Long].
-///
-/// The [UnsignedLong] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
-  Abi.androidArm: Uint32(),
-  Abi.androidArm64: Uint64(),
-  Abi.androidIA32: Uint32(),
-  Abi.androidX64: Uint64(),
-  Abi.fuchsiaArm64: Uint64(),
-  Abi.fuchsiaX64: Uint64(),
-  Abi.iosArm: Uint32(),
-  Abi.iosArm64: Uint64(),
-  Abi.iosX64: Uint64(),
-  Abi.linuxArm: Uint32(),
-  Abi.linuxArm64: Uint64(),
-  Abi.linuxIA32: Uint32(),
-  Abi.linuxX64: Uint64(),
-  Abi.linuxRiscv32: Uint32(),
-  Abi.linuxRiscv64: Uint64(),
-  Abi.macosArm64: Uint64(),
-  Abi.macosX64: Uint64(),
-  Abi.windowsArm64: Uint32(),
-  Abi.windowsIA32: Uint32(),
-  Abi.windowsX64: Uint32(),
-})
-class UnsignedLong extends AbiSpecificInteger {
-  const UnsignedLong();
-}
-
-/// The C `long long` type.
-///
-/// Typically a signed 64-bit integer.
-/// For a guaranteed 64-bit integer, use [Int64] with the C `int64_t` type.
-/// For an `unsigned long long`, use [UnsignedLongLong].
-///
-/// The [LongLong] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
-  Abi.androidArm: Int64(),
-  Abi.androidArm64: Int64(),
-  Abi.androidIA32: Int64(),
-  Abi.androidX64: Int64(),
-  Abi.fuchsiaArm64: Int64(),
-  Abi.fuchsiaX64: Int64(),
-  Abi.iosArm: Int64(),
-  Abi.iosArm64: Int64(),
-  Abi.iosX64: Int64(),
-  Abi.linuxArm: Int64(),
-  Abi.linuxArm64: Int64(),
-  Abi.linuxIA32: Int64(),
-  Abi.linuxX64: Int64(),
-  Abi.linuxRiscv32: Int64(),
-  Abi.linuxRiscv64: Int64(),
-  Abi.macosArm64: Int64(),
-  Abi.macosX64: Int64(),
-  Abi.windowsArm64: Int64(),
-  Abi.windowsIA32: Int64(),
-  Abi.windowsX64: Int64(),
-})
-class LongLong extends AbiSpecificInteger {
-  const LongLong();
-}
-
-/// The C `unsigned long long` type.
-///
-/// Typically an unsigned 64-bit integer.
-/// For a guaranteed 64-bit integer, use [Uint64] with the C `uint64_t` type.
-/// For a signed `long long`, use [LongLong].
-///
-/// The [UnsignedLongLong] type is a native type, and should not be constructed
-/// in Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
-  Abi.androidArm: Uint64(),
-  Abi.androidArm64: Uint64(),
-  Abi.androidIA32: Uint64(),
-  Abi.androidX64: Uint64(),
-  Abi.fuchsiaArm64: Uint64(),
-  Abi.fuchsiaX64: Uint64(),
-  Abi.iosArm: Uint64(),
-  Abi.iosArm64: Uint64(),
-  Abi.iosX64: Uint64(),
-  Abi.linuxArm: Uint64(),
-  Abi.linuxArm64: Uint64(),
-  Abi.linuxIA32: Uint64(),
-  Abi.linuxX64: Uint64(),
-  Abi.linuxRiscv32: Uint64(),
-  Abi.linuxRiscv64: Uint64(),
-  Abi.macosArm64: Uint64(),
-  Abi.macosX64: Uint64(),
-  Abi.windowsArm64: Uint64(),
-  Abi.windowsIA32: Uint64(),
-  Abi.windowsX64: Uint64(),
-})
-class UnsignedLongLong extends AbiSpecificInteger {
-  const UnsignedLongLong();
-}
-
-/// The C `intptr_t` type.
-///
-/// The [IntPtr] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
-  Abi.androidArm: Int32(),
-  Abi.androidArm64: Int64(),
-  Abi.androidIA32: Int32(),
-  Abi.androidX64: Int64(),
-  Abi.fuchsiaArm64: Int64(),
-  Abi.fuchsiaX64: Int64(),
-  Abi.iosArm: Int32(),
-  Abi.iosArm64: Int64(),
-  Abi.iosX64: Int64(),
-  Abi.linuxArm: Int32(),
-  Abi.linuxArm64: Int64(),
-  Abi.linuxIA32: Int32(),
-  Abi.linuxX64: Int64(),
-  Abi.linuxRiscv32: Int32(),
-  Abi.linuxRiscv64: Int64(),
-  Abi.macosArm64: Int64(),
-  Abi.macosX64: Int64(),
-  Abi.windowsArm64: Int64(),
-  Abi.windowsIA32: Int32(),
-  Abi.windowsX64: Int64(),
-})
-class IntPtr extends AbiSpecificInteger {
-  const IntPtr();
-}
-
-/// The C `uintptr_t` type.
-///
-/// The [UintPtr] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
-  Abi.androidArm: Uint32(),
-  Abi.androidArm64: Uint64(),
-  Abi.androidIA32: Uint32(),
-  Abi.androidX64: Uint64(),
-  Abi.fuchsiaArm64: Uint64(),
-  Abi.fuchsiaX64: Uint64(),
-  Abi.iosArm: Uint32(),
-  Abi.iosArm64: Uint64(),
-  Abi.iosX64: Uint64(),
-  Abi.linuxArm: Uint32(),
-  Abi.linuxArm64: Uint64(),
-  Abi.linuxIA32: Uint32(),
-  Abi.linuxX64: Uint64(),
-  Abi.linuxRiscv32: Uint32(),
-  Abi.linuxRiscv64: Uint64(),
-  Abi.macosArm64: Uint64(),
-  Abi.macosX64: Uint64(),
-  Abi.windowsArm64: Uint64(),
-  Abi.windowsIA32: Uint32(),
-  Abi.windowsX64: Uint64(),
-})
-class UintPtr extends AbiSpecificInteger {
-  const UintPtr();
-}
-
-/// The C `size_t` type.
-///
-/// The [Size] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
-  Abi.androidArm: Uint32(),
-  Abi.androidArm64: Uint64(),
-  Abi.androidIA32: Uint32(),
-  Abi.androidX64: Uint64(),
-  Abi.fuchsiaArm64: Uint64(),
-  Abi.fuchsiaX64: Uint64(),
-  Abi.iosArm: Uint32(),
-  Abi.iosArm64: Uint64(),
-  Abi.iosX64: Uint64(),
-  Abi.linuxArm: Uint32(),
-  Abi.linuxArm64: Uint64(),
-  Abi.linuxIA32: Uint32(),
-  Abi.linuxX64: Uint64(),
-  Abi.linuxRiscv32: Uint32(),
-  Abi.linuxRiscv64: Uint64(),
-  Abi.macosArm64: Uint64(),
-  Abi.macosX64: Uint64(),
-  Abi.windowsArm64: Uint64(),
-  Abi.windowsIA32: Uint32(),
-  Abi.windowsX64: Uint64(),
-})
-class Size extends AbiSpecificInteger {
-  const Size();
-}
-
-/// The C `wchar_t` type.
-///
-/// The signedness of `wchar_t` is undefined in C. Here, it is exposed as the
-/// defaults on the tested [Abi]s.
-///
-/// The [WChar] type is a native type, and should not be constructed in
-/// Dart code.
-/// It occurs only in native type signatures and as annotation on [Struct] and
-/// [Union] fields.
-@AbiSpecificIntegerMapping({
-  Abi.androidArm: Uint32(),
-  Abi.androidArm64: Uint32(),
-  Abi.androidIA32: Uint32(),
-  Abi.androidX64: Uint32(),
-  Abi.fuchsiaArm64: Uint32(),
-  Abi.fuchsiaX64: Int32(),
-  Abi.iosArm: Int32(),
-  Abi.iosArm64: Int32(),
-  Abi.iosX64: Int32(),
-  Abi.linuxArm: Uint32(),
-  Abi.linuxArm64: Uint32(),
-  Abi.linuxIA32: Int32(),
-  Abi.linuxX64: Int32(),
-  Abi.linuxRiscv32: Uint32(),
-  Abi.linuxRiscv64: Uint32(),
-  Abi.macosArm64: Int32(),
-  Abi.macosX64: Int32(),
-  Abi.windowsArm64: Uint16(),
-  Abi.windowsIA32: Uint16(),
-  Abi.windowsX64: Uint16(),
-})
-class WChar extends AbiSpecificInteger {
-  const WChar();
-}
diff --git a/sdk/lib/ffi/ffi.dart b/sdk/lib/ffi/ffi.dart
index 9a7afe2..b1d53a6 100644
--- a/sdk/lib/ffi/ffi.dart
+++ b/sdk/lib/ffi/ffi.dart
@@ -20,7 +20,6 @@
 part 'native_type.dart';
 part 'allocation.dart';
 part 'annotations.dart';
-part 'c_type.dart';
 part 'dynamic_library.dart';
 part 'struct.dart';
 part 'union.dart';
diff --git a/sdk/lib/ffi/native_type.dart b/sdk/lib/ffi/native_type.dart
index 55a9f6d..dbbea7c 100644
--- a/sdk/lib/ffi/native_type.dart
+++ b/sdk/lib/ffi/native_type.dart
@@ -98,6 +98,36 @@
   const Uint64();
 }
 
+/// Represents a native pointer-sized integer in C.
+///
+/// [IntPtr] is not constructible in the Dart code and serves purely as marker
+/// in type signatures.
+@AbiSpecificIntegerMapping({
+  Abi.androidArm: Int32(),
+  Abi.androidArm64: Int64(),
+  Abi.androidIA32: Int32(),
+  Abi.androidX64: Int64(),
+  Abi.fuchsiaArm64: Int64(),
+  Abi.fuchsiaX64: Int64(),
+  Abi.iosArm: Int32(),
+  Abi.iosArm64: Int64(),
+  Abi.iosX64: Int64(),
+  Abi.linuxArm: Int32(),
+  Abi.linuxArm64: Int64(),
+  Abi.linuxIA32: Int32(),
+  Abi.linuxX64: Int64(),
+  Abi.linuxRiscv32: Int32(),
+  Abi.linuxRiscv64: Int64(),
+  Abi.macosArm64: Int64(),
+  Abi.macosX64: Int64(),
+  Abi.windowsArm64: Int64(),
+  Abi.windowsIA32: Int32(),
+  Abi.windowsX64: Int64(),
+})
+class IntPtr extends AbiSpecificInteger {
+  const IntPtr();
+}
+
 /// Represents a native 32 bit float in C.
 ///
 /// [Float] is not constructible in the Dart code and serves purely as marker
diff --git a/tests/ffi/abi_specific_int_test.dart b/tests/ffi/abi_specific_int_test.dart
index cea45b1..266655c 100644
--- a/tests/ffi/abi_specific_int_test.dart
+++ b/tests/ffi/abi_specific_int_test.dart
@@ -8,6 +8,8 @@
 import 'package:expect/expect.dart';
 import 'package:ffi/ffi.dart';
 
+import 'abi_specific_ints.dart';
+
 void main() {
   testSizeOf();
   testStoreLoad();
diff --git a/tests/ffi/abi_specific_ints.dart b/tests/ffi/abi_specific_ints.dart
new file mode 100644
index 0000000..c0cd3f0
--- /dev/null
+++ b/tests/ffi/abi_specific_ints.dart
@@ -0,0 +1,145 @@
+// 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 'dart:ffi';
+
+// TODO(dacoharkes): These should move to `package:ffi`.
+
+// `int` in C.
+typedef Int = Int32;
+
+// `unsigned int` in C.
+typedef UnsignedInt = Uint32;
+
+// `size_t` in C.
+typedef Size = UintPtr;
+
+// `ssize_t` in C.
+typedef SSize = IntPtr;
+
+// `off_t` in C.
+typedef Off = Long;
+
+/// Represents a native unsigned pointer-sized integer in C.
+///
+/// [UintPtr] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+  Abi.androidArm: Uint32(),
+  Abi.androidArm64: Uint64(),
+  Abi.androidIA32: Uint32(),
+  Abi.androidX64: Uint64(),
+  Abi.fuchsiaArm64: Uint64(),
+  Abi.fuchsiaX64: Uint64(),
+  Abi.iosArm: Uint32(),
+  Abi.iosArm64: Uint64(),
+  Abi.iosX64: Uint64(),
+  Abi.linuxArm: Uint32(),
+  Abi.linuxArm64: Uint64(),
+  Abi.linuxIA32: Uint32(),
+  Abi.linuxX64: Uint64(),
+  Abi.linuxRiscv32: Uint32(),
+  Abi.linuxRiscv64: Uint64(),
+  Abi.macosArm64: Uint64(),
+  Abi.macosX64: Uint64(),
+  Abi.windowsArm64: Uint64(),
+  Abi.windowsIA32: Uint32(),
+  Abi.windowsX64: Uint64(),
+})
+class UintPtr extends AbiSpecificInteger {
+  const UintPtr();
+}
+
+/// `long` in C.
+///
+/// [Long] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+  Abi.androidArm: Int32(),
+  Abi.androidArm64: Int64(),
+  Abi.androidIA32: Int32(),
+  Abi.androidX64: Int64(),
+  Abi.fuchsiaArm64: Int64(),
+  Abi.fuchsiaX64: Int64(),
+  Abi.iosArm: Int32(),
+  Abi.iosArm64: Int64(),
+  Abi.iosX64: Int64(),
+  Abi.linuxArm: Int32(),
+  Abi.linuxArm64: Int64(),
+  Abi.linuxIA32: Int32(),
+  Abi.linuxX64: Int64(),
+  Abi.linuxRiscv32: Int32(),
+  Abi.linuxRiscv64: Int64(),
+  Abi.macosArm64: Int64(),
+  Abi.macosX64: Int64(),
+  Abi.windowsArm64: Int32(),
+  Abi.windowsIA32: Int32(),
+  Abi.windowsX64: Int32(),
+})
+class Long extends AbiSpecificInteger {
+  const Long();
+}
+
+/// `unsigned long` in C.
+///
+/// [UnsignedLong] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+  Abi.androidArm: Uint32(),
+  Abi.androidArm64: Uint64(),
+  Abi.androidIA32: Uint32(),
+  Abi.androidX64: Uint64(),
+  Abi.fuchsiaArm64: Uint64(),
+  Abi.fuchsiaX64: Uint64(),
+  Abi.iosArm: Uint32(),
+  Abi.iosArm64: Uint64(),
+  Abi.iosX64: Uint64(),
+  Abi.linuxArm: Uint32(),
+  Abi.linuxArm64: Uint64(),
+  Abi.linuxIA32: Uint32(),
+  Abi.linuxX64: Uint64(),
+  Abi.linuxRiscv32: Uint32(),
+  Abi.linuxRiscv64: Uint64(),
+  Abi.macosArm64: Uint64(),
+  Abi.macosX64: Uint64(),
+  Abi.windowsArm64: Uint32(),
+  Abi.windowsIA32: Uint32(),
+  Abi.windowsX64: Uint32(),
+})
+class UnsignedLong extends AbiSpecificInteger {
+  const UnsignedLong();
+}
+
+/// `wchar_t` in C.
+///
+/// The signedness of `wchar_t` is undefined in C. Here, it is exposed as an
+/// unsigned integer.
+///
+/// [WChar] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+  Abi.androidArm: Uint32(),
+  Abi.androidArm64: Uint32(),
+  Abi.androidIA32: Uint32(),
+  Abi.androidX64: Uint32(),
+  Abi.fuchsiaArm64: Uint32(),
+  Abi.fuchsiaX64: Uint32(),
+  Abi.iosArm: Uint32(),
+  Abi.iosArm64: Uint32(),
+  Abi.iosX64: Uint32(),
+  Abi.linuxArm: Uint32(),
+  Abi.linuxArm64: Uint32(),
+  Abi.linuxIA32: Uint32(),
+  Abi.linuxX64: Uint32(),
+  Abi.linuxRiscv32: Uint32(),
+  Abi.linuxRiscv64: Uint32(),
+  Abi.macosArm64: Uint32(),
+  Abi.macosX64: Uint32(),
+  Abi.windowsArm64: Uint16(),
+  Abi.windowsIA32: Uint16(),
+  Abi.windowsX64: Uint16(),
+})
+class WChar extends AbiSpecificInteger {
+  const WChar();
+}
diff --git a/tests/ffi/c_types_test.dart b/tests/ffi/c_types_test.dart
index 3c2e815..d423c2c 100644
--- a/tests/ffi/c_types_test.dart
+++ b/tests/ffi/c_types_test.dart
@@ -7,11 +7,11 @@
 // SharedObjects=ffi_test_functions
 
 import 'dart:ffi';
+
+import "package:expect/expect.dart";
 import 'dart:io' show Platform;
 
-import 'package:expect/expect.dart';
-import 'package:ffi/ffi.dart';
-
+import 'abi_specific_ints.dart';
 import 'ffi_test_helpers.dart';
 
 void main() {
@@ -20,162 +20,62 @@
   testIntAssumptions();
   testSizeTAssumptions();
   testLongAssumptions();
+  testOffTAssumptions();
   testWCharTAssumptions();
 }
 
 class CType {
   final int ffiSize;
-  final int Function(Pointer)? ffiLoad;
   final String modifier;
   final String type;
-  final String type2;
 
-  CType(this.ffiSize, this.type,
-      {this.type2 = '', this.modifier = '', this.ffiLoad});
+  CType(this.ffiSize, this.type, [this.modifier = ""]);
 
-  String get cRepresentation => '$modifier $type $type2'.trim();
+  String get cRepresentation => "$modifier $type".trim();
 
-  String get _getSizeName => 'FfiSizeOf_$modifier\_$type\_$type2';
-
-  String get _getSignName => 'FfiSignOf_$modifier\_$type\_$type2';
+  String get _getSizeName => "FfiSizeOf_$modifier\_$type";
 
   int Function() get sizeFunction => ffiTestFunctions
       .lookupFunction<Uint64 Function(), int Function()>(_getSizeName);
 
-  int Function() get signFunction => ffiTestFunctions
-      .lookupFunction<Uint64 Function(), int Function()>(_getSignName);
-
   int get size => sizeFunction();
 
-  bool get isSigned => signFunction() != 0;
-
-  bool? get ffiIsSigned {
-    final ffiLoad_ = ffiLoad;
-    if (ffiLoad_ == null) {
-      return null;
-    }
-    assert(size < 8);
-    return using((Arena arena) {
-      final p = arena<Int64>()..value = -1;
-      return ffiLoad_(p) < 0;
-    });
-  }
-
   String toString() => cRepresentation;
 }
 
-final char = CType(
-  sizeOf<Char>(),
-  'char',
-  ffiLoad: (Pointer p) => p.cast<Char>().value,
-);
-final uchar = CType(
-  sizeOf<UnsignedChar>(),
-  'char',
-  modifier: 'unsigned',
-  ffiLoad: (Pointer p) => p.cast<UnsignedChar>().value,
-);
-final schar = CType(
-  sizeOf<SignedChar>(),
-  'char',
-  modifier: 'signed',
-  ffiLoad: (Pointer p) => p.cast<SignedChar>().value,
-);
-final short = CType(
-  sizeOf<Short>(),
-  'short',
-  ffiLoad: (Pointer p) => p.cast<Short>().value,
-);
-final ushort = CType(
-  sizeOf<UnsignedShort>(),
-  'short',
-  modifier: 'unsigned',
-  ffiLoad: (Pointer p) => p.cast<UnsignedShort>().value,
-);
-final int_ = CType(
-  sizeOf<Int>(),
-  'int',
-  ffiLoad: (Pointer p) => p.cast<Int>().value,
-);
-final uint = CType(
-  sizeOf<UnsignedInt>(),
-  'int',
-  modifier: 'unsigned',
-  ffiLoad: (Pointer p) => p.cast<UnsignedInt>().value,
-);
-final long = CType(
-  sizeOf<Long>(),
-  'long',
-);
-final ulong = CType(
-  sizeOf<UnsignedLong>(),
-  'long',
-  modifier: 'unsigned',
-);
-final longlong = CType(
-  sizeOf<LongLong>(),
-  'long',
-  type2: 'long',
-);
-final ulonglong = CType(
-  sizeOf<UnsignedLongLong>(),
-  'long',
-  type2: 'long',
-  modifier: 'unsigned',
-);
-final intptr_t = CType(
-  sizeOf<IntPtr>(),
-  'intptr_t',
-);
-final uintptr_t = CType(
-  sizeOf<UintPtr>(),
-  'uintptr_t',
-);
-final size_t = CType(
-  sizeOf<Size>(),
-  'size_t',
-);
-final wchar_t = CType(
-  sizeOf<WChar>(),
-  'wchar_t',
-  ffiLoad: (Pointer p) => p.cast<WChar>().value,
-);
+final intptr_t = CType(sizeOf<IntPtr>(), "intptr_t");
+final uintptr_t = CType(sizeOf<UintPtr>(), "uintptr_t");
+final int_ = CType(sizeOf<Int>(), "int");
+final uint = CType(sizeOf<UnsignedInt>(), "int", "unsigned");
+final long = CType(sizeOf<Long>(), "long");
+final ulong = CType(sizeOf<UnsignedLong>(), "long", "unsigned");
+final wchar_t = CType(sizeOf<WChar>(), "wchar_t");
+final size_t = CType(sizeOf<Size>(), "size_t");
+final ssize_t = CType(sizeOf<SSize>(), "ssize_t");
+final off_t = CType(sizeOf<Off>(), "off_t");
 
 final cTypes = [
-  char,
-  uchar,
-  schar,
-  short,
-  ushort,
+  intptr_t,
+  uintptr_t,
   int_,
   uint,
   long,
   ulong,
-  longlong,
-  ulonglong,
-  intptr_t,
-  uintptr_t,
-  size_t,
   wchar_t,
+  size_t,
+  ssize_t,
+  off_t
 ];
 
 void printSizes() {
   cTypes.forEach((element) {
-    final cName = element.cRepresentation.padRight(20);
-    final size = element.size;
-    final signed = element.isSigned ? 'signed' : 'unsigned';
-    print('$cName: $size $signed');
+    print("${element.cRepresentation.padRight(20)}: ${element.size}");
   });
 }
 
 void testSizes() {
   cTypes.forEach((element) {
-    print(element);
     Expect.equals(element.size, element.ffiSize);
-    final ffiIsSigned = element.ffiIsSigned;
-    if (ffiIsSigned != null) {
-      Expect.equals(element.isSigned, ffiIsSigned);
-    }
   });
 }
 
@@ -186,6 +86,7 @@
 
 void testSizeTAssumptions() {
   Expect.equals(intptr_t.size, size_t.size);
+  Expect.equals(intptr_t.size, ssize_t.size);
 }
 
 void testLongAssumptions() {
@@ -198,9 +99,13 @@
   }
 }
 
+void testOffTAssumptions() {
+  Expect.equals(long.size, off_t.size);
+}
+
 void testWCharTAssumptions() {
-  final bool isSigned = wchar_t.isSigned;
-  print('wchar_t isSigned $isSigned');
+  final bool isSigned = wCharMinValue() != 0;
+  print("wchar_t isSigned $isSigned");
   if (Platform.isWindows) {
     Expect.equals(2, wchar_t.size);
     if (isSigned) {
diff --git a/tests/ffi/function_callbacks_structs_by_value_generated_test.dart b/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
index 2fbccd1..2276d2f 100644
--- a/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
+++ b/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
@@ -16,6 +16,9 @@
 import "package:expect/expect.dart";
 import "package:ffi/ffi.dart";
 
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
+
 import 'callback_tests_utils.dart';
 
 import 'dylib_utils.dart';
diff --git a/tests/ffi/function_structs_by_value_generated_compounds.dart b/tests/ffi/function_structs_by_value_generated_compounds.dart
index 666ef20..439e9a34 100644
--- a/tests/ffi/function_structs_by_value_generated_compounds.dart
+++ b/tests/ffi/function_structs_by_value_generated_compounds.dart
@@ -7,6 +7,9 @@
 
 import 'dart:ffi';
 
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
+
 class Struct1ByteBool extends Struct {
   @Bool()
   external bool a0;
diff --git a/tests/ffi/function_structs_by_value_generated_leaf_test.dart b/tests/ffi/function_structs_by_value_generated_leaf_test.dart
index 7704417..283faad 100644
--- a/tests/ffi/function_structs_by_value_generated_leaf_test.dart
+++ b/tests/ffi/function_structs_by_value_generated_leaf_test.dart
@@ -16,6 +16,9 @@
 import "package:expect/expect.dart";
 import "package:ffi/ffi.dart";
 
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
+
 import 'dylib_utils.dart';
 
 // Reuse the compound classes.
diff --git a/tests/ffi/function_structs_by_value_generated_test.dart b/tests/ffi/function_structs_by_value_generated_test.dart
index 897472c..1f4c5d3 100644
--- a/tests/ffi/function_structs_by_value_generated_test.dart
+++ b/tests/ffi/function_structs_by_value_generated_test.dart
@@ -16,6 +16,9 @@
 import "package:expect/expect.dart";
 import "package:ffi/ffi.dart";
 
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
+
 import 'dylib_utils.dart';
 
 // Reuse the compound classes.
diff --git a/tests/ffi/generator/structs_by_value_tests_generator.dart b/tests/ffi/generator/structs_by_value_tests_generator.dart
index 3a18095..4c260b9 100644
--- a/tests/ffi/generator/structs_by_value_tests_generator.dart
+++ b/tests/ffi/generator/structs_by_value_tests_generator.dart
@@ -922,6 +922,8 @@
 
 import 'dart:ffi';
 
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
 """;
 }
 
@@ -965,6 +967,8 @@
 import "package:expect/expect.dart";
 import "package:ffi/ffi.dart";
 
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
 
 import 'dylib_utils.dart';
 
@@ -1025,6 +1029,8 @@
 import "package:expect/expect.dart";
 import "package:ffi/ffi.dart";
 
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
 
 import 'callback_tests_utils.dart';
 
diff --git a/tests/ffi_2/abi_specific_int_test.dart b/tests/ffi_2/abi_specific_int_test.dart
index 57daa3f..152c159 100644
--- a/tests/ffi_2/abi_specific_int_test.dart
+++ b/tests/ffi_2/abi_specific_int_test.dart
@@ -10,6 +10,8 @@
 import 'package:expect/expect.dart';
 import 'package:ffi/ffi.dart';
 
+import 'abi_specific_ints.dart';
+
 void main() {
   testSizeOf();
   testStoreLoad();
diff --git a/tests/ffi_2/abi_specific_ints.dart b/tests/ffi_2/abi_specific_ints.dart
new file mode 100644
index 0000000..c1d8302
--- /dev/null
+++ b/tests/ffi_2/abi_specific_ints.dart
@@ -0,0 +1,132 @@
+// 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.
+
+// @dart = 2.9
+
+import 'dart:ffi';
+
+// TODO(dacoharkes): These should move to `package:ffi`.
+
+/// Represents a native unsigned pointer-sized integer in C.
+///
+/// [UintPtr] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+  Abi.androidArm: Uint32(),
+  Abi.androidArm64: Uint64(),
+  Abi.androidIA32: Uint32(),
+  Abi.androidX64: Uint64(),
+  Abi.fuchsiaArm64: Uint64(),
+  Abi.fuchsiaX64: Uint64(),
+  Abi.iosArm: Uint32(),
+  Abi.iosArm64: Uint64(),
+  Abi.iosX64: Uint64(),
+  Abi.linuxArm: Uint32(),
+  Abi.linuxArm64: Uint64(),
+  Abi.linuxIA32: Uint32(),
+  Abi.linuxX64: Uint64(),
+  Abi.linuxRiscv32: Uint32(),
+  Abi.linuxRiscv64: Uint64(),
+  Abi.macosArm64: Uint64(),
+  Abi.macosX64: Uint64(),
+  Abi.windowsArm64: Uint64(),
+  Abi.windowsIA32: Uint32(),
+  Abi.windowsX64: Uint64(),
+})
+class UintPtr extends AbiSpecificInteger {
+  const UintPtr();
+}
+
+/// `long` in C.
+///
+/// [Long] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+  Abi.androidArm: Int32(),
+  Abi.androidArm64: Int64(),
+  Abi.androidIA32: Int32(),
+  Abi.androidX64: Int64(),
+  Abi.fuchsiaArm64: Int64(),
+  Abi.fuchsiaX64: Int64(),
+  Abi.iosArm: Int32(),
+  Abi.iosArm64: Int64(),
+  Abi.iosX64: Int64(),
+  Abi.linuxArm: Int32(),
+  Abi.linuxArm64: Int64(),
+  Abi.linuxIA32: Int32(),
+  Abi.linuxX64: Int64(),
+  Abi.linuxRiscv32: Int32(),
+  Abi.linuxRiscv64: Int64(),
+  Abi.macosArm64: Int64(),
+  Abi.macosX64: Int64(),
+  Abi.windowsArm64: Int32(),
+  Abi.windowsIA32: Int32(),
+  Abi.windowsX64: Int32(),
+})
+class Long extends AbiSpecificInteger {
+  const Long();
+}
+
+/// `unsigned long` in C.
+///
+/// [UnsignedLong] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+  Abi.androidArm: Uint32(),
+  Abi.androidArm64: Uint64(),
+  Abi.androidIA32: Uint32(),
+  Abi.androidX64: Uint64(),
+  Abi.fuchsiaArm64: Uint64(),
+  Abi.fuchsiaX64: Uint64(),
+  Abi.iosArm: Uint32(),
+  Abi.iosArm64: Uint64(),
+  Abi.iosX64: Uint64(),
+  Abi.linuxArm: Uint32(),
+  Abi.linuxArm64: Uint64(),
+  Abi.linuxIA32: Uint32(),
+  Abi.linuxX64: Uint64(),
+  Abi.linuxRiscv32: Uint32(),
+  Abi.linuxRiscv64: Uint64(),
+  Abi.macosArm64: Uint64(),
+  Abi.macosX64: Uint64(),
+  Abi.windowsArm64: Uint32(),
+  Abi.windowsIA32: Uint32(),
+  Abi.windowsX64: Uint32(),
+})
+class UnsignedLong extends AbiSpecificInteger {
+  const UnsignedLong();
+}
+
+/// `wchar_t` in C.
+///
+/// The signedness of `wchar_t` is undefined in C. Here, it is exposed as an
+/// unsigned integer.
+///
+/// [WChar] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+  Abi.androidArm: Uint32(),
+  Abi.androidArm64: Uint32(),
+  Abi.androidIA32: Uint32(),
+  Abi.androidX64: Uint32(),
+  Abi.fuchsiaArm64: Uint32(),
+  Abi.fuchsiaX64: Uint32(),
+  Abi.iosArm: Uint32(),
+  Abi.iosArm64: Uint32(),
+  Abi.iosX64: Uint32(),
+  Abi.linuxArm: Uint32(),
+  Abi.linuxArm64: Uint32(),
+  Abi.linuxIA32: Uint32(),
+  Abi.linuxX64: Uint32(),
+  Abi.linuxRiscv32: Uint32(),
+  Abi.linuxRiscv64: Uint32(),
+  Abi.macosArm64: Uint32(),
+  Abi.macosX64: Uint32(),
+  Abi.windowsArm64: Uint16(),
+  Abi.windowsIA32: Uint16(),
+  Abi.windowsX64: Uint16(),
+})
+class WChar extends AbiSpecificInteger {
+  const WChar();
+}
diff --git a/tests/ffi_2/c_types_test.dart b/tests/ffi_2/c_types_test.dart
index 7a651ce..fa762bd 100644
--- a/tests/ffi_2/c_types_test.dart
+++ b/tests/ffi_2/c_types_test.dart
@@ -9,187 +9,65 @@
 // @dart = 2.9
 
 import 'dart:ffi';
+
+import "package:expect/expect.dart";
 import 'dart:io' show Platform;
 
-import 'package:expect/expect.dart';
-import 'package:ffi/ffi.dart';
-
+import 'abi_specific_ints.dart';
 import 'ffi_test_helpers.dart';
 
 void main() {
   printSizes();
   testSizes();
-  testIntAssumptions();
-  testSizeTAssumptions();
   testLongAssumptions();
   testWCharTAssumptions();
 }
 
 class CType {
   final int ffiSize;
-  final int Function(Pointer) ffiLoad;
   final String modifier;
   final String type;
-  final String type2;
 
-  CType(this.ffiSize, this.type,
-      {this.type2 = '', this.modifier = '', this.ffiLoad});
+  CType(this.ffiSize, this.type, [this.modifier = ""]);
 
-  String get cRepresentation => '$modifier $type $type2'.trim();
+  String get cRepresentation => "$modifier $type".trim();
 
-  String get _getSizeName => 'FfiSizeOf_$modifier\_$type\_$type2';
-
-  String get _getSignName => 'FfiSignOf_$modifier\_$type\_$type2';
+  String get _getSizeName => "FfiSizeOf_$modifier\_$type";
 
   int Function() get sizeFunction => ffiTestFunctions
       .lookupFunction<Uint64 Function(), int Function()>(_getSizeName);
 
-  int Function() get signFunction => ffiTestFunctions
-      .lookupFunction<Uint64 Function(), int Function()>(_getSignName);
-
   int get size => sizeFunction();
 
-  bool get isSigned => signFunction() != 0;
-
-  bool get ffiIsSigned {
-    final ffiLoad_ = ffiLoad;
-    if (ffiLoad_ == null) {
-      return null;
-    }
-    assert(size < 8);
-    return using((Arena arena) {
-      final p = arena<Int64>()..value = -1;
-      return ffiLoad_(p) < 0;
-    });
-  }
-
   String toString() => cRepresentation;
 }
 
-final char = CType(
-  sizeOf<Char>(),
-  'char',
-  ffiLoad: (Pointer p) => p.cast<Char>().value,
-);
-final uchar = CType(
-  sizeOf<UnsignedChar>(),
-  'char',
-  modifier: 'unsigned',
-  ffiLoad: (Pointer p) => p.cast<UnsignedChar>().value,
-);
-final schar = CType(
-  sizeOf<SignedChar>(),
-  'char',
-  modifier: 'signed',
-  ffiLoad: (Pointer p) => p.cast<SignedChar>().value,
-);
-final short = CType(
-  sizeOf<Short>(),
-  'short',
-  ffiLoad: (Pointer p) => p.cast<Short>().value,
-);
-final ushort = CType(
-  sizeOf<UnsignedShort>(),
-  'short',
-  modifier: 'unsigned',
-  ffiLoad: (Pointer p) => p.cast<UnsignedShort>().value,
-);
-final int_ = CType(
-  sizeOf<Int>(),
-  'int',
-  ffiLoad: (Pointer p) => p.cast<Int>().value,
-);
-final uint = CType(
-  sizeOf<UnsignedInt>(),
-  'int',
-  modifier: 'unsigned',
-  ffiLoad: (Pointer p) => p.cast<UnsignedInt>().value,
-);
-final long = CType(
-  sizeOf<Long>(),
-  'long',
-);
-final ulong = CType(
-  sizeOf<UnsignedLong>(),
-  'long',
-  modifier: 'unsigned',
-);
-final longlong = CType(
-  sizeOf<LongLong>(),
-  'long',
-  type2: 'long',
-);
-final ulonglong = CType(
-  sizeOf<UnsignedLongLong>(),
-  'long',
-  type2: 'long',
-  modifier: 'unsigned',
-);
-final intptr_t = CType(
-  sizeOf<IntPtr>(),
-  'intptr_t',
-);
-final uintptr_t = CType(
-  sizeOf<UintPtr>(),
-  'uintptr_t',
-);
-final size_t = CType(
-  sizeOf<Size>(),
-  'size_t',
-);
-final wchar_t = CType(
-  sizeOf<WChar>(),
-  'wchar_t',
-  ffiLoad: (Pointer p) => p.cast<WChar>().value,
-);
+final intptr_t = CType(sizeOf<IntPtr>(), "intptr_t");
+final uintptr_t = CType(sizeOf<UintPtr>(), "uintptr_t");
+final long = CType(sizeOf<Long>(), "long");
+final ulong = CType(sizeOf<UnsignedLong>(), "long", "unsigned");
+final wchar_t = CType(sizeOf<WChar>(), "wchar_t");
 
 final cTypes = [
-  char,
-  uchar,
-  schar,
-  short,
-  ushort,
-  int_,
-  uint,
-  long,
-  ulong,
-  longlong,
-  ulonglong,
   intptr_t,
   uintptr_t,
-  size_t,
+  long,
+  ulong,
   wchar_t,
 ];
 
 void printSizes() {
   cTypes.forEach((element) {
-    final cName = element.cRepresentation.padRight(20);
-    final size = element.size;
-    final signed = element.isSigned ? 'signed' : 'unsigned';
-    print('$cName: $size $signed');
+    print("${element.cRepresentation.padRight(20)}: ${element.size}");
   });
 }
 
 void testSizes() {
   cTypes.forEach((element) {
-    print(element);
     Expect.equals(element.size, element.ffiSize);
-    final ffiIsSigned = element.ffiIsSigned;
-    if (ffiIsSigned != null) {
-      Expect.equals(element.isSigned, ffiIsSigned);
-    }
   });
 }
 
-void testIntAssumptions() {
-  Expect.equals(4, int_.size);
-  Expect.equals(4, uint.size);
-}
-
-void testSizeTAssumptions() {
-  Expect.equals(intptr_t.size, size_t.size);
-}
-
 void testLongAssumptions() {
   if (Platform.isWindows) {
     Expect.equals(4, long.size);
@@ -201,8 +79,8 @@
 }
 
 void testWCharTAssumptions() {
-  final bool isSigned = wchar_t.isSigned;
-  print('wchar_t isSigned $isSigned');
+  final bool isSigned = wCharMinValue() != 0;
+  print("wchar_t isSigned $isSigned");
   if (Platform.isWindows) {
     Expect.equals(2, wchar_t.size);
     if (isSigned) {
diff --git a/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart b/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
index b890cbc..f4100fb 100644
--- a/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
+++ b/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
@@ -18,6 +18,9 @@
 import "package:expect/expect.dart";
 import "package:ffi/ffi.dart";
 
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
+
 import 'callback_tests_utils.dart';
 
 import 'dylib_utils.dart';
diff --git a/tests/ffi_2/function_structs_by_value_generated_compounds.dart b/tests/ffi_2/function_structs_by_value_generated_compounds.dart
index cd3fdf1..6908177 100644
--- a/tests/ffi_2/function_structs_by_value_generated_compounds.dart
+++ b/tests/ffi_2/function_structs_by_value_generated_compounds.dart
@@ -9,6 +9,9 @@
 
 import 'dart:ffi';
 
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
+
 class Struct1ByteBool extends Struct {
   @Bool()
   bool a0;
diff --git a/tests/ffi_2/function_structs_by_value_generated_leaf_test.dart b/tests/ffi_2/function_structs_by_value_generated_leaf_test.dart
index 8c01056..7c64296 100644
--- a/tests/ffi_2/function_structs_by_value_generated_leaf_test.dart
+++ b/tests/ffi_2/function_structs_by_value_generated_leaf_test.dart
@@ -18,6 +18,9 @@
 import "package:expect/expect.dart";
 import "package:ffi/ffi.dart";
 
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
+
 import 'dylib_utils.dart';
 
 // Reuse the compound classes.
diff --git a/tests/ffi_2/function_structs_by_value_generated_test.dart b/tests/ffi_2/function_structs_by_value_generated_test.dart
index 6329287..ef24ad2 100644
--- a/tests/ffi_2/function_structs_by_value_generated_test.dart
+++ b/tests/ffi_2/function_structs_by_value_generated_test.dart
@@ -18,6 +18,9 @@
 import "package:expect/expect.dart";
 import "package:ffi/ffi.dart";
 
+// Reuse the AbiSpecificInts.
+import 'abi_specific_ints.dart';
+
 import 'dylib_utils.dart';
 
 // Reuse the compound classes.
diff --git a/tools/VERSION b/tools/VERSION
index 58a37e5..9d1057b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 42
+PRERELEASE 43
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh
index 3d7f966..1b96929 100755
--- a/tools/bots/try_benchmarks.sh
+++ b/tools/bots/try_benchmarks.sh
@@ -328,19 +328,19 @@
     DART_CONFIGURATION=ReleaseX64 pkg/vm/tool/precompiler2 --sound-null-safety --packages=.packages hello.dart blob.bin
     DART_CONFIGURATION=ReleaseX64 pkg/vm/tool/dart_precompiled_runtime2 --profile-period=10000 blob.bin
     out/ReleaseX64/dart --profile-period=10000 --packages=.packages --optimization-counter-threshold=-1 hello.dart
-    out/ReleaseX64/dart-sdk/bin/dart2js --packages=.packages --out=out.js -m hello.dart
+    out/ReleaseX64/dart-sdk/bin/dart compile js --packages=.packages --out=out.js -m hello.dart
     third_party/d8/linux/x64/d8 --stack_size=1024 sdk/lib/_internal/js_runtime/lib/preambles/d8.js out.js
-    out/ReleaseX64/dart-sdk/bin/dart2js --sound-null-safety --packages=.packages --out=out.js -m hello.dart
+    out/ReleaseX64/dart-sdk/bin/dart compile js --sound-null-safety --packages=.packages --out=out.js -m hello.dart
     third_party/d8/linux/x64/d8 --stack_size=1024 sdk/lib/_internal/js_runtime/lib/preambles/d8.js out.js
-    out/ReleaseX64/dart-sdk/bin/dart2js --packages=.packages --out=out.js -m hello.dart
+    out/ReleaseX64/dart-sdk/bin/dart compile js --packages=.packages --out=out.js -m hello.dart
     LD_LIBRARY_PATH=third_party/firefox_jsshell/ third_party/firefox_jsshell/js -f sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js -f out.js
-    out/ReleaseX64/dart-sdk/bin/dart2js --sound-null-safety --packages=.packages --out=out.js -m hello.dart
+    out/ReleaseX64/dart-sdk/bin/dart compile js --sound-null-safety --packages=.packages --out=out.js -m hello.dart
     LD_LIBRARY_PATH=third_party/firefox_jsshell/ third_party/firefox_jsshell/js -f sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js -f out.js
-    out/ReleaseX64/dart-sdk/bin/dart2js --benchmarking-production --packages=.packages --out=out.js -m hello.dart
+    out/ReleaseX64/dart-sdk/bin/dart compile js --benchmarking-production --packages=.packages --out=out.js -m hello.dart
     third_party/d8/linux/x64/d8 --stack_size=1024 sdk/lib/_internal/js_runtime/lib/preambles/d8.js out.js
-    out/ReleaseX64/dart-sdk/bin/dart2js --sound-null-safety --benchmarking-production --packages=.packages --out=out.js -m hello.dart
+    out/ReleaseX64/dart-sdk/bin/dart compile js --sound-null-safety --benchmarking-production --packages=.packages --out=out.js -m hello.dart
     third_party/d8/linux/x64/d8 --stack_size=1024 sdk/lib/_internal/js_runtime/lib/preambles/d8.js out.js
-    out/ReleaseX64/dart-sdk/bin/dart2js --benchmarking-x --packages=.packages --out=out.js -m hello.dart
+    out/ReleaseX64/dart-sdk/bin/dart compile js --benchmarking-x --packages=.packages --out=out.js -m hello.dart
     third_party/d8/linux/x64/d8 --stack_size=1024 sdk/lib/_internal/js_runtime/lib/preambles/d8.js out.js
     out/ReleaseX64/dart-sdk/bin/dart pkg/dev_compiler/tool/ddb -r d8 -b third_party/d8/linux/x64/d8 hello.dart
     out/ReleaseX64/dart-sdk/bin/dart pkg/dev_compiler/tool/ddb -r d8 -b third_party/d8/linux/x64/d8 --mode=compile --compile-vm-options=--print-metrics --packages=.packages --out out.js hello.dart