Move macro apis to _fe_analyzer_shared from the language repo.

I could do a separate package if you think that would be better, but putting it here I think makes things simpler.

Change-Id: I4e62bc18dcd9d3bb84a7aceb8f4e2821c84d1361
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/224280
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api.dart
new file mode 100644
index 0000000..5d5c262
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api.dart
@@ -0,0 +1,10 @@
+// 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';
+
+part 'api/builders.dart';
+part 'api/code.dart';
+part 'api/introspection.dart';
+part 'api/macros.dart';
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
new file mode 100644
index 0000000..74bf73c
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
@@ -0,0 +1,159 @@
+// 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.
+
+part of '../api.dart';
+
+/// The base interface used to add declarations to the program as well
+/// as augment existing ones.
+abstract class Builder {}
+
+/// The api used by [Macro]s to contribute new type declarations to the
+/// current library, and get [TypeAnnotation]s from runtime [Type] objects.
+abstract class TypeBuilder implements Builder {
+  /// Adds a new type declaration to the surrounding library.
+  void declareType(DeclarationCode typeDeclaration);
+}
+
+/// The interface to resolve a [TypeAnnotation] to a [StaticType].
+///
+/// The [StaticType]s can be compared against other [StaticType]s to see how
+/// they relate to each other.
+///
+/// This api is only available to the declaration and definition phases of
+/// macro expansion.
+abstract class TypeResolver {
+  /// Resolves [typeAnnotation] to a [StaticType].
+  ///
+  /// Throws an error if the type annotation cannot be resolved. This should
+  /// only happen in the case of incomplete or invalid programs, but macros
+  /// may be asked to run in this state during the development cycle. It is
+  /// helpful for users if macros provide a best effort implementation in that
+  /// case or handle the error in a useful way.
+  Future<StaticType> resolve(TypeAnnotation typeAnnotation);
+}
+
+/// The api used to introspect on a [ClassDeclaration].
+///
+/// Available in the declaration and definition phases, but limited in the
+/// declaration phase to immediately annotated [ClassDeclaration]s. This is
+/// done by limiting the access to the [TypeDeclarationResolver] to the
+/// definition phase.
+abstract class ClassIntrospector {
+  /// The fields available for [clazz].
+  ///
+  /// This may be incomplete if in the declaration phase and additional macros
+  /// are going to run on this class.
+  Future<List<FieldDeclaration>> fieldsOf(ClassDeclaration clazz);
+
+  /// The methods available so far for the current class.
+  ///
+  /// This may be incomplete if additional declaration macros are running on
+  /// this class.
+  Future<List<MethodDeclaration>> methodsOf(ClassDeclaration clazz);
+
+  /// The constructors available so far for the current class.
+  ///
+  /// This may be incomplete if additional declaration macros are running on
+  /// this class.
+  Future<List<ConstructorDeclaration>> constructorsOf(ClassDeclaration clazz);
+
+  /// The class that is directly extended via an `extends` clause.
+  Future<ClassDeclaration?> superclassOf(ClassDeclaration clazz);
+
+  /// All of the classes that are mixed in with `with` clauses.
+  Future<List<ClassDeclaration>> mixinsOf(ClassDeclaration clazz);
+
+  /// All of the classes that are implemented with an `implements` clause.
+  Future<List<ClassDeclaration>> interfacesOf(ClassDeclaration clazz);
+}
+
+/// The api used by [Macro]s to contribute new (non-type)
+/// declarations to the current library.
+///
+/// Can also be used to do subtype checks on types.
+abstract class DeclarationBuilder
+    implements Builder, TypeResolver, ClassIntrospector {
+  /// Adds a new regular declaration to the surrounding library.
+  ///
+  /// Note that type declarations are not supported.
+  void declareInLibrary(DeclarationCode declaration);
+}
+
+/// The api used by [Macro]s to contribute new members to a class.
+abstract class ClassMemberDeclarationBuilder implements DeclarationBuilder {
+  /// Adds a new declaration to the surrounding class.
+  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.
+///
+/// Only available in the definition phase of macro expansion.
+abstract class TypeDeclarationResolver {
+  /// Resolves a [NamedStaticType] to its [TypeDeclaration].
+  Future<TypeDeclaration> declarationOf(NamedStaticType annotation);
+}
+
+/// The base class for builders in the definition phase. These can convert
+/// any [TypeAnnotation] into its corresponding [TypeDeclaration], and also
+/// reflect more deeply on those.
+abstract class DefinitionBuilder
+    implements
+        Builder,
+        TypeResolver,
+        ClassIntrospector,
+        TypeDeclarationResolver {}
+
+/// The apis used by [Macro]s that run on classes, to fill in the definitions
+/// of any external declarations within that class.
+abstract class ClassDefinitionBuilder implements DefinitionBuilder {
+  /// Retrieve a [VariableDefinitionBuilder] for a field by [name].
+  ///
+  /// Throws an [ArgumentError] if there is no field by that name.
+  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);
+
+  /// Retrieve a [ConstructorDefinitionBuilder] for a constructor by [name].
+  ///
+  /// Throws an [ArgumentError] if there is no constructor by that name.
+  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].
+  ///
+  /// TODO: Link the library augmentations proposal to describe the semantics.
+  void augment({FunctionBodyCode? body, List<Code>? initializers});
+}
+
+/// The apis used by [Macro]s to augment functions or methods.
+abstract class FunctionDefinitionBuilder implements DefinitionBuilder {
+  /// Augments the function.
+  ///
+  /// TODO: Link the library augmentations proposal to describe the semantics.
+  void augment(FunctionBodyCode body);
+}
+
+/// The api used by [Macro]s to augment a top level variable or instance field.
+abstract class VariableDefinitionBuilder implements DefinitionBuilder {
+  /// Augments the field.
+  ///
+  /// TODO: Link the library augmentations proposal to describe the semantics.
+  void augment({
+    DeclarationCode? getter,
+    DeclarationCode? setter,
+    ExpressionCode? initializer,
+  });
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/code.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/code.dart
new file mode 100644
index 0000000..89f169f
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/code.dart
@@ -0,0 +1,104 @@
+// 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.
+
+part of '../api.dart';
+
+/// The base class representing an arbitrary chunk of Dart code, which may or
+/// may not be syntactically or semantically valid yet.
+class Code {
+  /// All the chunks of [Code] or raw [String]s that comprise this [Code]
+  /// object.
+  final List<Object> parts;
+
+  Code.fromString(String code) : parts = [code];
+
+  Code.fromParts(this.parts);
+}
+
+/// A piece of code representing a syntactically valid declaration.
+class DeclarationCode extends Code {
+  DeclarationCode.fromString(String code) : super.fromString(code);
+
+  DeclarationCode.fromParts(List<Object> parts) : super.fromParts(parts);
+}
+
+/// A piece of code representing a syntactically valid element.
+///
+/// Should not include any trailing commas,
+class ElementCode extends Code {
+  ElementCode.fromString(String code) : super.fromString(code);
+
+  ElementCode.fromParts(List<Object> parts) : super.fromParts(parts);
+}
+
+/// A piece of code representing a syntactically valid expression.
+class ExpressionCode extends Code {
+  ExpressionCode.fromString(String code) : super.fromString(code);
+
+  ExpressionCode.fromParts(List<Object> parts) : super.fromParts(parts);
+}
+
+/// A piece of code representing a syntactically valid function body.
+///
+/// This includes any and all code after the parameter list of a function,
+/// including modifiers like `async`.
+///
+/// Both arrow and block function bodies are allowed.
+class FunctionBodyCode extends Code {
+  FunctionBodyCode.fromString(String code) : super.fromString(code);
+
+  FunctionBodyCode.fromParts(List<Object> parts) : super.fromParts(parts);
+}
+
+/// A piece of code representing a syntactically valid identifier.
+class IdentifierCode extends Code {
+  IdentifierCode.fromString(String code) : super.fromString(code);
+
+  IdentifierCode.fromParts(List<Object> parts) : super.fromParts(parts);
+}
+
+/// A piece of code identifying a named argument.
+///
+/// This should not include any trailing commas.
+class NamedArgumentCode extends Code {
+  NamedArgumentCode.fromString(String code) : super.fromString(code);
+
+  NamedArgumentCode.fromParts(List<Object> parts) : super.fromParts(parts);
+}
+
+/// A piece of code identifying a syntactically valid function parameter.
+///
+/// This should not include any trailing commas, but may include modifiers
+/// such as `required`, and default values.
+///
+/// There is no distinction here made between named and positional parameters,
+/// nor between optional or required parameters. It is the job of the user to
+/// construct and combine these together in a way that creates valid parameter
+/// lists.
+class ParameterCode extends Code {
+  ParameterCode.fromString(String code) : super.fromString(code);
+
+  ParameterCode.fromParts(List<Object> parts) : super.fromParts(parts);
+}
+
+/// A piece of code representing a syntactically valid statement.
+///
+/// Should always end with a semicolon.
+class StatementCode extends Code {
+  StatementCode.fromString(String code) : super.fromString(code);
+
+  StatementCode.fromParts(List<Object> parts) : super.fromParts(parts);
+}
+
+extension Join<T extends Code> on List<T> {
+  /// Joins all the items in [this] with [separator], and returns
+  /// a new list.
+  List<Code> joinAsCode(String separator) => [
+        for (int i = 0; i < length - 1; i++) ...[
+          this[i],
+          new Code.fromString(separator),
+        ],
+        last,
+      ];
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart
new file mode 100644
index 0000000..e892296
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart
@@ -0,0 +1,192 @@
+// 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.
+
+part of '../api.dart';
+
+/// The base class for an unresolved reference to a type.
+///
+/// See the subtypes [FunctionTypeAnnotation] and [NamedTypeAnnotation].
+abstract class TypeAnnotation {
+  /// Whether or not the type annotation is explicitly nullable (contains a
+  /// trailing `?`)
+  bool get isNullable;
+
+  /// A [Code] object representation of this type annotation.
+  Code get code;
+}
+
+/// The base class for function type declarations.
+abstract class FunctionTypeAnnotation implements TypeAnnotation {
+  /// The return type of this function.
+  TypeAnnotation get returnType;
+
+  /// The positional parameters for this function.
+  Iterable<ParameterDeclaration> get positionalParameters;
+
+  /// The named parameters for this function.
+  Iterable<ParameterDeclaration> get namedParameters;
+
+  /// The type parameters for this function.
+  Iterable<TypeParameterDeclaration> get typeParameters;
+}
+
+/// An unresolved reference to a type.
+///
+/// These can be resolved to a [TypeDeclaration] using the `builder` classes
+/// depending on the phase a macro is running in.
+abstract class NamedTypeAnnotation implements TypeAnnotation {
+  /// The name of the type as it exists in the type annotation.
+  String get name;
+
+  /// The type arguments, if applicable.
+  Iterable<TypeAnnotation> get typeArguments;
+}
+
+/// The interface representing a resolved type.
+///
+/// Resolved types understand exactly what type they represent, and can be
+/// compared to other static types.
+abstract class StaticType {
+  /// Returns true if this is a subtype of [other].
+  Future<bool> isSubtypeOf(StaticType other);
+
+  /// Returns true if this is an identical type to [other].
+  Future<bool> isExactly(StaticType other);
+}
+
+/// A subtype of [StaticType] representing types that can be resolved by name
+/// to a concrete declaration.
+abstract class NamedStaticType implements StaticType {
+  String get name;
+}
+
+/// The base class for all declarations.
+abstract class Declaration {
+  /// The name of this declaration.
+  String get name;
+}
+
+/// A declaration that defines a new type in the program.
+abstract class TypeDeclaration implements Declaration {
+  /// The type parameters defined for this type declaration.
+  Iterable<TypeParameterDeclaration> get typeParameters;
+
+  /// Create a static type representing this type with [typeArguments].
+  ///
+  /// If [isNullable] is `true`, then this type will behave as if it has a
+  /// trailing `?`.
+  ///
+  /// Throws an exception if the type could not be instantiated, typically due
+  /// to one of the type arguments not matching the bounds of the corresponding
+  /// type parameter.
+  Future<StaticType> instantiate(
+      {required List<StaticType> typeArguments, required bool isNullable});
+}
+
+/// Class (and enum) introspection information.
+///
+/// Information about fields, methods, and constructors must be retrieved from
+/// the `builder` objects.
+abstract class ClassDeclaration implements TypeDeclaration {
+  /// Whether this class has an `abstract` modifier.
+  bool get isAbstract;
+
+  /// Whether this class has an `external` modifier.
+  bool get isExternal;
+
+  /// The `extends` type annotation, if present.
+  TypeAnnotation? get superclass;
+
+  /// All the `implements` type annotations.
+  Iterable<TypeAnnotation> get interfaces;
+
+  /// All the `with` type annotations.
+  Iterable<TypeAnnotation> get mixins;
+
+  /// All the type arguments, if applicable.
+  Iterable<TypeParameterDeclaration> get typeParameters;
+}
+
+/// Function introspection information.
+abstract class FunctionDeclaration implements Declaration {
+  /// Whether this function has an `abstract` modifier.
+  bool get isAbstract;
+
+  /// Whether this function has an `external` modifier.
+  bool get isExternal;
+
+  /// Whether this function is actually a getter.
+  bool get isGetter;
+
+  /// Whether this function is actually a setter.
+  bool get isSetter;
+
+  /// The return type of this function.
+  TypeAnnotation get returnType;
+
+  /// The positional parameters for this function.
+  Iterable<ParameterDeclaration> get positionalParameters;
+
+  /// The named parameters for this function.
+  Iterable<ParameterDeclaration> get namedParameters;
+
+  /// The type parameters for this function.
+  Iterable<TypeParameterDeclaration> get typeParameters;
+}
+
+/// Method introspection information.
+abstract class MethodDeclaration implements FunctionDeclaration {
+  /// The class that defines this method.
+  TypeAnnotation get definingClass;
+}
+
+/// Constructor introspection information.
+abstract class ConstructorDeclaration implements MethodDeclaration {
+  /// Whether or not this is a factory constructor.
+  bool get isFactory;
+}
+
+/// 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.
+  bool get isExternal;
+
+  /// The type of this field.
+  TypeAnnotation get type;
+
+  /// A [Code] object representing the initializer for this field, if present.
+  Code? get initializer;
+}
+
+/// Field introspection information ..
+abstract class FieldDeclaration implements VariableDeclaration {
+  /// The class that defines this method.
+  TypeAnnotation get definingClass;
+}
+
+/// Parameter introspection information.
+abstract class ParameterDeclaration implements Declaration {
+  /// The type of this parameter.
+  TypeAnnotation get type;
+
+  /// Whether or not this is a named parameter.
+  bool get isNamed;
+
+  /// Whether or not this parameter is either a non-optional positional
+  /// parameter or an optional parameter with the `required` keyword.
+  bool get isRequired;
+
+  /// A [Code] object representing the default value for this parameter, if
+  /// present. Can be used to copy default values to other parameters.
+  Code? get defaultValue;
+}
+
+/// Type parameter introspection information.
+abstract class TypeParameterDeclaration implements Declaration {
+  /// The bounds for this type parameter, if it has any.
+  TypeAnnotation? get bounds;
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/macros.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/macros.dart
new file mode 100644
index 0000000..7685589a
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/macros.dart
@@ -0,0 +1,139 @@
+// 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.
+
+part of '../api.dart';
+
+/// The marker interface for all types of macros.
+abstract class Macro {}
+
+/// The interface for [Macro]s that can be applied to any top level function,
+/// instance method, or static method, and wants to contribute new type
+/// declarations to the program.
+abstract class FunctionTypesMacro implements Macro {
+  FutureOr<void> buildTypesForFunction(
+      FunctionDeclaration function, TypeBuilder builder);
+}
+
+/// The interface for [Macro]s that can be applied to any top level function,
+/// instance method, or static method, and wants to contribute new non-type
+/// declarations to the program.
+abstract class FunctionDeclarationsMacro implements Macro {
+  FutureOr<void> buildDeclarationsForFunction(
+      FunctionDeclaration function, DeclarationBuilder builder);
+}
+
+/// The interface for [Macro]s that can be applied to any top level function,
+/// instance method, or static method, and wants to augment the function
+/// definition.
+abstract class FunctionDefinitionMacro implements Macro {
+  FutureOr<void> buildDefinitionForFunction(
+      FunctionDeclaration function, FunctionDefinitionBuilder builder);
+}
+
+/// The interface for [Macro]s that can be applied to any top level variable or
+/// instance field, and wants to contribute new type declarations to the
+/// program.
+abstract class VariableTypesMacro implements Macro {
+  FutureOr<void> buildTypesForVariable(
+      VariableDeclaration variable, TypeBuilder builder);
+}
+
+/// The interface for [Macro]s that can be applied to any top level variable or
+/// instance field and wants to contribute new non-type declarations to the
+/// program.
+abstract class VariableDeclarationsMacro implements Macro {
+  FutureOr<void> buildDeclarationsForVariable(
+      VariableDeclaration variable, DeclarationBuilder builder);
+}
+
+/// 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(
+      VariableDeclaration variable, VariableDefinitionBuilder builder);
+}
+
+/// The interface for [Macro]s that can be applied to any class, and wants to
+/// contribute new type declarations to the program.
+abstract class ClassTypesMacro implements Macro {
+  FutureOr<void> buildTypesForClass(
+      ClassDeclaration clazz, TypeBuilder builder);
+}
+
+/// The interface for [Macro]s that can be applied to any class, and wants to
+/// contribute new non-type declarations to the program.
+abstract class ClassDeclarationsMacro implements Macro {
+  FutureOr<void> buildDeclarationsForClass(
+      ClassDeclaration clazz, ClassDeclarationBuilder builder);
+}
+
+/// The interface for [Macro]s that can be applied to any class, and wants to
+/// augment the definitions of members on the class.
+abstract class ClassDefinitionMacro implements Macro {
+  FutureOr<void> buildDefinitionForClass(
+      ClassDeclaration clazz, ClassDefinitionBuilder builder);
+}
+
+/// The interface for [Macro]s that can be applied to any field, and wants to
+/// contribute new type declarations to the program.
+abstract class FieldTypesMacro implements Macro {
+  FutureOr<void> buildTypesForField(
+      FieldDeclaration field, TypeBuilder builder);
+}
+
+/// 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(
+      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 {
+  FutureOr<void> buildDefinitionForField(
+      FieldDeclaration field, VariableDefinitionBuilder builder);
+}
+
+/// The interface for [Macro]s that can be applied to any method, and wants to
+/// contribute new type declarations to the program.
+abstract class MethodTypesMacro implements Macro {
+  FutureOr<void> buildTypesForMethod(
+      MethodDeclaration method, TypeBuilder builder);
+}
+
+/// 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 {
+  FutureOr<void> buildDeclarationsForMethod(
+      MethodDeclaration method, ClassMemberDeclarationBuilder builder);
+}
+
+/// The interface for [Macro]s that can be applied to any method, and wants to
+/// augment the function definition.
+abstract class MethodDefinitionMacro implements Macro {
+  FutureOr<void> buildDefinitionForMethod(
+      MethodDeclaration method, FunctionDefinitionBuilder builder);
+}
+
+/// The interface for [Macro]s that can be applied to any constructor, and wants
+/// to contribute new type declarations to the program.
+abstract class ConstructorTypesMacro implements Macro {
+  FutureOr<void> buildTypesForConstructor(
+      ConstructorDeclaration method, 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 {
+  FutureOr<void> buildDeclarationsForConstructor(
+      ConstructorDeclaration method, 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);
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor.dart
new file mode 100644
index 0000000..0d4e878
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor.dart
@@ -0,0 +1,115 @@
+// 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 'api.dart';
+
+/// The interface used by Dart language implementations, in order to load
+/// and execute macros, as well as produce library augmentations from those
+/// macro applications.
+///
+/// This class more clearly defines the role of a Dart language implementation
+/// during macro discovery and expansion, and unifies how augmentation libraries
+/// are produced.
+abstract class MacroExecutor {
+  /// Invoked when an implementation discovers a new macro definition in a
+  /// [library] with [name], and prepares this executor to run the macro.
+  ///
+  /// May be invoked more than once for the same macro, which will cause the
+  /// macro to be re-loaded. Previous [MacroClassIdentifier]s and
+  /// [MacroInstanceIdentifier]s given for this macro will be invalid after
+  /// that point and should be discarded.
+  ///
+  /// Throws an exception if the macro fails to load.
+  Future<MacroClassIdentifier> loadMacro(Uri library, String name);
+
+  /// Creates an instance of [macroClass] in the executor, and returns an
+  /// identifier for that instance.
+  ///
+  /// Throws an exception if an instance is not created.
+  Future<MacroInstanceIdentifier> instantiateMacro(
+      MacroClassIdentifier macroClass, String constructor, Arguments arguments);
+
+  /// Runs the type phase for [macro] on a given [declaration].
+  ///
+  /// Throws an exception if there is an error executing the macro.
+  Future<MacroExecutionResult> executeTypesPhase(
+      MacroInstanceIdentifier macro, Declaration declaration);
+
+  /// Runs the declarations phase for [macro] on a given [declaration].
+  ///
+  /// Throws an exception if there is an error executing the macro.
+  Future<MacroExecutionResult> executeDeclarationsPhase(
+      MacroInstanceIdentifier macro,
+      Declaration declaration,
+      TypeResolver typeResolver,
+      ClassIntrospector classIntrospector);
+
+  /// Runs the definitions phase for [macro] on a given [declaration].
+  ///
+  /// Throws an exception if there is an error executing the macro.
+  Future<MacroExecutionResult> executeDefinitionsPhase(
+      MacroInstanceIdentifier macro,
+      Declaration declaration,
+      TypeResolver typeResolver,
+      ClassIntrospector classIntrospector,
+      TypeDeclarationResolver typeDeclarationResolver);
+
+  /// Combines multiple [MacroExecutionResult]s into a single library
+  /// augmentation file, and returns a [String] representing that file.
+  Future<String> buildAugmentationLibrary(
+      Iterable<MacroExecutionResult> macroResults);
+
+  /// Tell the executor to shut down and clean up any resources it may have
+  /// allocated.
+  void close();
+}
+
+/// The arguments passed to a macro constructor.
+///
+/// All argument instances must be of type [Code] or a built-in value type that
+/// is serializable (num, bool, String, null, etc).
+class Arguments {
+  final List<Object?> positional;
+
+  final Map<String, Object?> named;
+
+  Arguments(this.positional, this.named);
+}
+
+/// An opaque identifier for a macro class, retrieved by
+/// [MacroExecutor.loadMacro].
+///
+/// Used to execute or reload this macro in the future.
+abstract class MacroClassIdentifier {}
+
+/// An opaque identifier for an instance of a macro class, retrieved by
+/// [MacroExecutor.instantiateMacro].
+///
+/// Used to execute or reload this macro in the future.
+abstract class MacroInstanceIdentifier {}
+
+/// A summary of the results of running a macro in a given phase.
+///
+/// All modifications are expressed in terms of library augmentation
+/// declarations.
+abstract class MacroExecutionResult {
+  /// Any library imports that should be added to support the code used in
+  /// the augmentations.
+  Iterable<DeclarationCode> get imports;
+
+  /// Any augmentations that should be applied as a result of executing a macro.
+  Iterable<DeclarationCode> get augmentations;
+}
+
+/// Each of the different macro execution phases.
+enum Phase {
+  /// Only new types are added in this phase.
+  types,
+
+  /// New non-type declarations are added in this phase.
+  declarations,
+
+  /// This phase allows augmenting existing declarations.
+  definitions,
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart
new file mode 100644
index 0000000..d6476af
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart
@@ -0,0 +1,137 @@
+// 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 'dart:isolate';
+import 'dart:mirrors';
+
+import 'isolate_mirrors_impl.dart';
+import 'protocol.dart';
+import '../executor.dart';
+import '../api.dart';
+
+/// A [MacroExecutor] implementation which relies on [IsolateMirror.loadUri]
+/// in order to load macros libraries.
+///
+/// All actual work happens in a separate [Isolate], and this class serves as
+/// a bridge between that isolate and the language frontends.
+class IsolateMirrorMacroExecutor implements MacroExecutor {
+  /// The actual isolate doing macro loading and execution.
+  final Isolate _macroIsolate;
+
+  /// The channel used to send requests to the [_macroIsolate].
+  final SendPort _sendPort;
+
+  /// The stream of responses from the [_macroIsolate].
+  final Stream<GenericResponse> _responseStream;
+
+  /// A map of response completers by request id.
+  final _responseCompleters = <int, Completer<GenericResponse>>{};
+
+  /// A function that should be invoked when shutting down this executor
+  /// to perform any necessary cleanup.
+  final void Function() _onClose;
+
+  IsolateMirrorMacroExecutor._(
+      this._macroIsolate, this._sendPort, this._responseStream, this._onClose) {
+    _responseStream.listen((event) {
+      Completer<GenericResponse>? completer =
+          _responseCompleters.remove(event.requestId);
+      if (completer == null) {
+        throw new StateError(
+            'Got a response for an unrecognized request id ${event.requestId}');
+      }
+      completer.complete(event);
+    });
+  }
+
+  /// Initialize an [IsolateMirrorMacroExecutor] and return it once ready.
+  ///
+  /// Spawns the macro isolate and sets up a communication channel.
+  static Future<MacroExecutor> start() async {
+    ReceivePort receivePort = new ReceivePort();
+    Completer<SendPort> sendPortCompleter = new Completer<SendPort>();
+    StreamController<GenericResponse> responseStreamController =
+        new StreamController<GenericResponse>(sync: true);
+    receivePort.listen((message) {
+      if (!sendPortCompleter.isCompleted) {
+        sendPortCompleter.complete(message as SendPort);
+      } else {
+        responseStreamController.add(message as GenericResponse);
+      }
+    }).onDone(responseStreamController.close);
+    Isolate macroIsolate = await Isolate.spawn(spawn, receivePort.sendPort);
+
+    return new IsolateMirrorMacroExecutor._(
+        macroIsolate,
+        await sendPortCompleter.future,
+        responseStreamController.stream,
+        receivePort.close);
+  }
+
+  @override
+  Future<String> buildAugmentationLibrary(
+      Iterable<MacroExecutionResult> macroResults) {
+    // TODO: implement buildAugmentationLibrary
+    throw new UnimplementedError();
+  }
+
+  @override
+  void close() {
+    _onClose();
+    _macroIsolate.kill();
+  }
+
+  @override
+  Future<MacroExecutionResult> executeDeclarationsPhase(
+      MacroInstanceIdentifier macro,
+      Declaration declaration,
+      TypeResolver typeResolver,
+      ClassIntrospector classIntrospector) {
+    // TODO: implement executeDeclarationsPhase
+    throw new UnimplementedError();
+  }
+
+  @override
+  Future<MacroExecutionResult> executeDefinitionsPhase(
+          MacroInstanceIdentifier macro,
+          Declaration declaration,
+          TypeResolver typeResolver,
+          ClassIntrospector classIntrospector,
+          TypeDeclarationResolver typeDeclarationResolver) =>
+      _sendRequest(new ExecuteDefinitionsPhaseRequest(macro, declaration,
+          typeResolver, classIntrospector, typeDeclarationResolver));
+
+  @override
+  Future<MacroExecutionResult> executeTypesPhase(
+      MacroInstanceIdentifier macro, Declaration declaration) {
+    // TODO: implement executeTypesPhase
+    throw new UnimplementedError();
+  }
+
+  @override
+  Future<MacroInstanceIdentifier> instantiateMacro(
+          MacroClassIdentifier macroClass,
+          String constructor,
+          Arguments arguments) =>
+      _sendRequest(
+          new InstantiateMacroRequest(macroClass, constructor, arguments));
+
+  @override
+  Future<MacroClassIdentifier> loadMacro(Uri library, String name) =>
+      _sendRequest(new LoadMacroRequest(library, name));
+
+  /// Sends a request and returns the response, casting it to the expected
+  /// type.
+  Future<T> _sendRequest<T>(Request request) async {
+    _sendPort.send(request);
+    Completer<GenericResponse<T>> completer =
+        new Completer<GenericResponse<T>>();
+    _responseCompleters[request.id] = completer;
+    GenericResponse<T> response = await completer.future;
+    T? result = response.response;
+    if (result != null) return result;
+    throw response.error!;
+  }
+}
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
new file mode 100644
index 0000000..3cf24a5
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart
@@ -0,0 +1,255 @@
+// 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 'dart:isolate';
+import 'dart:mirrors';
+
+import 'protocol.dart';
+import '../executor.dart';
+import '../api.dart';
+
+/// Spawns a new isolate for loading and executing macros.
+void spawn(SendPort sendPort) {
+  ReceivePort receivePort = new ReceivePort();
+  sendPort.send(receivePort.sendPort);
+  receivePort.listen((message) async {
+    if (message is LoadMacroRequest) {
+      GenericResponse<MacroClassIdentifier> response =
+          await _loadMacro(message);
+      sendPort.send(response);
+    } else if (message is InstantiateMacroRequest) {
+      GenericResponse<MacroInstanceIdentifier> response =
+          await _instantiateMacro(message);
+      sendPort.send(response);
+    } else if (message is ExecuteDefinitionsPhaseRequest) {
+      GenericResponse<MacroExecutionResult> response =
+          await _executeDefinitionsPhase(message);
+      sendPort.send(response);
+    } else {
+      throw new StateError('Unrecognized event type $message');
+    }
+  });
+}
+
+/// Maps macro identifiers to class mirrors.
+final _macroClasses = <_MacroClassIdentifier, ClassMirror>{};
+
+/// Handles [LoadMacroRequest]s.
+Future<GenericResponse<MacroClassIdentifier>> _loadMacro(
+    LoadMacroRequest request) async {
+  try {
+    _MacroClassIdentifier identifier =
+        new _MacroClassIdentifier(request.library, request.name);
+    if (_macroClasses.containsKey(identifier)) {
+      throw new UnsupportedError(
+          'Reloading macros is not supported by this implementation');
+    }
+    LibraryMirror libMirror =
+        await currentMirrorSystem().isolate.loadUri(request.library);
+    ClassMirror macroClass =
+        libMirror.declarations[new Symbol(request.name)] as ClassMirror;
+    _macroClasses[identifier] = macroClass;
+    return new GenericResponse(response: identifier, requestId: request.id);
+  } catch (e) {
+    return new GenericResponse(error: e, requestId: request.id);
+  }
+}
+
+/// Maps macro instance identifiers to instances.
+final _macroInstances = <_MacroInstanceIdentifier, Macro>{};
+
+/// Handles [InstantiateMacroRequest]s.
+Future<GenericResponse<MacroInstanceIdentifier>> _instantiateMacro(
+    InstantiateMacroRequest request) async {
+  try {
+    ClassMirror? clazz = _macroClasses[request.macroClass];
+    if (clazz == null) {
+      throw new ArgumentError('Unrecognized macro class ${request.macroClass}');
+    }
+    Macro instance = clazz.newInstance(
+        new Symbol(request.constructorName), request.arguments.positional, {
+      for (MapEntry<String, Object?> entry in request.arguments.named.entries)
+        new Symbol(entry.key): entry.value,
+    }).reflectee as Macro;
+    _MacroInstanceIdentifier identifier = new _MacroInstanceIdentifier();
+    _macroInstances[identifier] = instance;
+    return new GenericResponse<MacroInstanceIdentifier>(
+        response: identifier, requestId: request.id);
+  } catch (e) {
+    return new GenericResponse(error: e, requestId: request.id);
+  }
+}
+
+Future<GenericResponse<MacroExecutionResult>> _executeDefinitionsPhase(
+    ExecuteDefinitionsPhaseRequest request) async {
+  try {
+    Macro? instance = _macroInstances[request.macro];
+    if (instance == null) {
+      throw new StateError('Unrecognized macro instance ${request.macro}\n'
+          'Known instances: $_macroInstances)');
+    }
+    Declaration declaration = request.declaration;
+    if (instance is FunctionDefinitionMacro &&
+        declaration is FunctionDeclaration) {
+      _FunctionDefinitionBuilder builder = new _FunctionDefinitionBuilder(
+          declaration,
+          request.typeResolver,
+          request.typeDeclarationResolver,
+          request.classIntrospector);
+      await instance.buildDefinitionForFunction(declaration, builder);
+      return new GenericResponse(
+          response: builder.result, requestId: request.id);
+    } else {
+      throw new UnsupportedError(
+          ('Only FunctionDefinitionMacros are supported currently'));
+    }
+  } catch (e) {
+    return new GenericResponse(error: e, requestId: request.id);
+  }
+}
+
+/// Our implementation of [MacroClassIdentifier].
+class _MacroClassIdentifier implements MacroClassIdentifier {
+  final String id;
+
+  _MacroClassIdentifier(Uri library, String name) : id = '$library#$name';
+
+  operator ==(other) => other is _MacroClassIdentifier && id == other.id;
+
+  int get hashCode => id.hashCode;
+}
+
+/// Our implementation of [MacroInstanceIdentifier].
+class _MacroInstanceIdentifier implements MacroInstanceIdentifier {
+  static int _next = 0;
+
+  final int id;
+
+  _MacroInstanceIdentifier() : id = _next++;
+
+  operator ==(other) => other is _MacroInstanceIdentifier && id == other.id;
+
+  int get hashCode => id;
+}
+
+/// Our implementation of [MacroExecutionResult].
+class _MacroExecutionResult implements MacroExecutionResult {
+  @override
+  final List<DeclarationCode> augmentations = <DeclarationCode>[];
+
+  @override
+  final List<DeclarationCode> imports = <DeclarationCode>[];
+}
+
+/// Custom implementation of [FunctionDefinitionBuilder].
+class _FunctionDefinitionBuilder implements FunctionDefinitionBuilder {
+  final TypeResolver typeResolver;
+  final TypeDeclarationResolver typeDeclarationResolver;
+  final ClassIntrospector classIntrospector;
+
+  /// The declaration this is a builder for.
+  final FunctionDeclaration declaration;
+
+  /// The final result, will be built up over `augment` calls.
+  final _MacroExecutionResult result = new _MacroExecutionResult();
+
+  _FunctionDefinitionBuilder(this.declaration, this.typeResolver,
+      this.typeDeclarationResolver, this.classIntrospector);
+
+  @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/isolate_mirrors_executor/protocol.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/protocol.dart
new file mode 100644
index 0000000..96a2724
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/protocol.dart
@@ -0,0 +1,61 @@
+// 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.
+
+/// Defines the objects used for communication between the macro executor and
+/// the isolate doing the work of macro loading and execution.
+library protocol;
+
+import '../executor.dart';
+import '../api.dart';
+
+/// Base class all requests extend, provides a unique id for each request.
+class Request {
+  final int id;
+
+  Request() : id = _next++;
+
+  static int _next = 0;
+}
+
+/// A generic response object that is either an instance of [T] or an error.
+class GenericResponse<T> {
+  final T? response;
+  final Object? error;
+  final int requestId;
+
+  GenericResponse({this.response, this.error, required this.requestId})
+      : assert(response != null || error != null),
+        assert(response == null || error == null);
+}
+
+/// A request to load a macro in this isolate.
+class LoadMacroRequest extends Request {
+  final Uri library;
+  final String name;
+
+  LoadMacroRequest(this.library, this.name);
+}
+
+/// A request to instantiate a macro instance.
+class InstantiateMacroRequest extends Request {
+  final MacroClassIdentifier macroClass;
+  final String constructorName;
+  final Arguments arguments;
+
+  InstantiateMacroRequest(
+      this.macroClass, this.constructorName, this.arguments);
+}
+
+/// A request to execute a macro on a particular declaration in the definition
+/// phase.
+class ExecuteDefinitionsPhaseRequest extends Request {
+  final MacroInstanceIdentifier macro;
+  final Declaration declaration;
+  final TypeResolver typeResolver;
+  final ClassIntrospector classIntrospector;
+  final TypeDeclarationResolver typeDeclarationResolver;
+
+  ExecuteDefinitionsPhaseRequest(this.macro, this.declaration,
+      this.typeResolver, this.classIntrospector, this.typeDeclarationResolver);
+}
diff --git a/pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/isolate_mirror_executor_test.dart b/pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/isolate_mirror_executor_test.dart
new file mode 100644
index 0000000..48ca97b
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/isolate_mirror_executor_test.dart
@@ -0,0 +1,147 @@
+// 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:io';
+
+import 'package:_fe_analyzer_shared/src/macros/api.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor.dart';
+import 'package:_fe_analyzer_shared/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart';
+
+import 'package:test/fake.dart';
+import 'package:test/test.dart';
+
+void main() {
+  late MacroExecutor executor;
+
+  setUp(() async {
+    executor = await IsolateMirrorMacroExecutor.start();
+  });
+
+  tearDown(() {
+    executor.close();
+  });
+
+  test('can load macros and create instances', () async {
+    var clazzId = await executor.loadMacro(
+        // Tests run from the root of the repo.
+        File('pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/simple_macro.dart')
+            .absolute
+            .uri,
+        'SimpleMacro');
+    expect(clazzId, isNotNull, reason: 'Can load a macro.');
+
+    var instanceId =
+        await executor.instantiateMacro(clazzId, '', Arguments([], {}));
+    expect(instanceId, isNotNull,
+        reason: 'Can create an instance with no arguments.');
+
+    instanceId =
+        await executor.instantiateMacro(clazzId, '', Arguments([1, 2], {}));
+    expect(instanceId, isNotNull,
+        reason: 'Can create an instance with positional arguments.');
+
+    instanceId = await executor.instantiateMacro(
+        clazzId, 'named', Arguments([], {'x': 1, 'y': 2}));
+    expect(instanceId, isNotNull,
+        reason: 'Can create an instance with named arguments.');
+
+    var definitionResult = await executor.executeDefinitionsPhase(
+        instanceId,
+        _FunctionDeclaration(
+          isAbstract: false,
+          isExternal: false,
+          isGetter: false,
+          isSetter: false,
+          name: 'foo',
+          namedParameters: [],
+          positionalParameters: [],
+          returnType:
+              _TypeAnnotation(Code.fromString('String'), isNullable: false),
+          typeParameters: [],
+        ),
+        _FakeTypeResolver(),
+        _FakeClassIntrospector(),
+        _FakeTypeDeclarationResolver());
+    expect(definitionResult.augmentations, hasLength(1));
+    expect(definitionResult.augmentations.first.debugString().toString(),
+        equalsIgnoringWhitespace('''
+            augment String foo() {
+              print('x: 1, y: 2');
+              return augment super();
+            }'''));
+  });
+}
+
+class _FakeClassIntrospector with Fake implements ClassIntrospector {}
+
+class _FakeTypeResolver with Fake implements TypeResolver {}
+
+class _FakeTypeDeclarationResolver
+    with Fake
+    implements TypeDeclarationResolver {}
+
+class _FunctionDeclaration implements FunctionDeclaration {
+  @override
+  final bool isAbstract;
+
+  @override
+  final bool isExternal;
+
+  @override
+  final bool isGetter;
+
+  @override
+  final bool isSetter;
+
+  @override
+  final String name;
+
+  @override
+  final Iterable<ParameterDeclaration> namedParameters;
+
+  @override
+  final Iterable<ParameterDeclaration> positionalParameters;
+
+  @override
+  final TypeAnnotation returnType;
+
+  @override
+  final Iterable<TypeParameterDeclaration> typeParameters;
+
+  _FunctionDeclaration({
+    required this.isAbstract,
+    required this.isExternal,
+    required this.isGetter,
+    required this.isSetter,
+    required this.name,
+    required this.namedParameters,
+    required this.positionalParameters,
+    required this.returnType,
+    required this.typeParameters,
+  });
+}
+
+class _TypeAnnotation implements TypeAnnotation {
+  @override
+  final Code code;
+
+  @override
+  final bool isNullable;
+
+  _TypeAnnotation(this.code, {required this.isNullable});
+}
+
+extension _ on Code {
+  StringBuffer debugString([StringBuffer? buffer]) {
+    buffer ??= StringBuffer();
+    for (var part in parts) {
+      if (part is Code) {
+        part.debugString(buffer);
+      } else {
+        buffer.write(part.toString());
+      }
+    }
+    return buffer;
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/simple_macro.dart b/pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/simple_macro.dart
new file mode 100644
index 0000000..b95da0b
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/simple_macro.dart
@@ -0,0 +1,33 @@
+// 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 '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 FunctionDefinitionMacro {
+  final int? x;
+  final int? y;
+
+  SimpleMacro([this.x, this.y]);
+
+  SimpleMacro.named({this.x, this.y});
+
+  @override
+  FutureOr<void> buildDefinitionForFunction(
+      FunctionDeclaration method, FunctionDefinitionBuilder builder) {
+    if (method.namedParameters
+        .followedBy(method.positionalParameters)
+        .isNotEmpty) {
+      throw ArgumentError(
+          'This macro can only be run on functions with no arguments!');
+    }
+    builder.augment(FunctionBodyCode.fromString('''{
+      print('x: $x, y: $y');
+      return augment super();
+    }'''));
+  }
+}
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index a132ce2..81e6368 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -47,6 +47,7 @@
 anyone
 ap
 api
+apis
 app
 apparently
 applicable
@@ -73,6 +74,11 @@
 atom
 atoms
 attributes
+augment
+augmentation
+augmentations
+augmenting
+augments
 auto
 automagically
 auxiliary
@@ -140,6 +146,7 @@
 breadcrumbs
 brevity
 brianwilkerson
+bridge
 bs
 bsd
 bslash
@@ -225,15 +232,18 @@
 combinator
 combine2
 combiner
+communication
 compared
 compares
 compilations
+completers
 completes
 complicating
 component's
 comprehensive
 compressed
 compression
+comprise
 concat
 concatenate
 concerned
@@ -252,6 +262,7 @@
 containers
 continuations
 contra
+contribute
 convention
 coordinated
 coordinating
@@ -310,6 +321,7 @@
 deeply
 def
 defaulting
+definitions
 degrades
 degree
 del
@@ -353,6 +365,7 @@
 disallow
 disambiguating
 disambiguator
+discovers
 disjoint
 dispatched
 distribute
@@ -420,6 +433,7 @@
 estimate
 eval
 execute
+executor
 exhausted
 existence
 existentially
@@ -643,10 +657,14 @@
 interval
 intervals
 intl
+introspect
+introspection
+introspector
 ints
 invariants
 io
 is64
+isolate
 isolated
 issuecomment
 issuing
@@ -661,6 +679,7 @@
 java
 jenkins
 jensj
+job
 johnniwinther
 js
 json
@@ -672,6 +691,7 @@
 kallentu
 kernel's
 kernel2kernel
+kill
 klass
 kmillikin
 kotlin
@@ -707,6 +727,7 @@
 libs
 lifted
 lifter
+limiting
 linearized
 linebreak
 linter
@@ -948,6 +969,7 @@
 preexisting
 premark
 preorder
+prepares
 preprocess
 presented
 presubmit
@@ -966,10 +988,12 @@
 promo
 proof
 prop
+proposal
 propose
 proposed
 proto
 protobuf
+protocol
 ps
 pulled
 pure
@@ -1048,6 +1072,7 @@
 reexports
 ref
 reflect
+reflectee
 reflective
 reg
 regis
@@ -1063,6 +1088,8 @@
 relaxes
 released
 relink
+reload
+reloading
 remapped
 remedy
 removal
@@ -1079,11 +1106,14 @@
 repo
 repositories
 repurposed
+requests
 requirement
 res
 residue
 resource
 respond
+response
+responses
 restoring
 restriction
 resumed
@@ -1131,11 +1161,13 @@
 separators
 sequencing
 sequential
+serializable
 serializables
 serializer
 serializers
 serve
 server
+serves
 service
 session
 setable
@@ -1154,6 +1186,8 @@
 shr
 shrinking
 shru
+shut
+shutting
 si
 sibling
 siblings
@@ -1186,6 +1220,8 @@
 sourcemap
 spaced
 sparse
+spawn
+spawns
 spec
 spec'ed
 specialization
@@ -1384,6 +1420,7 @@
 unifiable
 unification
 unifier
+unifies
 unify
 uninstantiable
 uninstantiated
@@ -1456,6 +1493,7 @@
 w
 waiting
 wanting
+wants
 waste
 wasted
 watch