implement the remaining definition phase macros, as well as all declaration phase macros

Change-Id: I8ad1625d102cfbdafed020a7a1b88220e4e6a6bc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/229000
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Auto-Submit: Jake Macdonald <jakemac@google.com>
Commit-Queue: Jake Macdonald <jakemac@google.com>
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)}';
 }