Version 2.17.0-31.0.dev

Merge commit '26d9cb5146e7553ab7cc6d696e425793506b511f' into 'dev'
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 9a507f4..2bfd7e8 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
@@ -44,28 +44,29 @@
   ///
   /// 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);
+  Future<List<FieldDeclaration>> fieldsOf(covariant 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);
+  Future<List<MethodDeclaration>> methodsOf(covariant 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);
+  Future<List<ConstructorDeclaration>> constructorsOf(
+      covariant ClassDeclaration clazz);
 
   /// The class that is directly extended via an `extends` clause.
-  Future<ClassDeclaration?> superclassOf(ClassDeclaration clazz);
+  Future<ClassDeclaration?> superclassOf(covariant ClassDeclaration clazz);
 
   /// All of the classes that are mixed in with `with` clauses.
-  Future<List<ClassDeclaration>> mixinsOf(ClassDeclaration clazz);
+  Future<List<ClassDeclaration>> mixinsOf(covariant ClassDeclaration clazz);
 
   /// All of the classes that are implemented with an `implements` clause.
-  Future<List<ClassDeclaration>> interfacesOf(ClassDeclaration clazz);
+  Future<List<ClassDeclaration>> interfacesOf(covariant ClassDeclaration clazz);
 }
 
 /// The api used by [Macro]s to contribute new (non-type)
@@ -97,7 +98,7 @@
 /// Only available in the definition phase of macro expansion.
 abstract class TypeDeclarationResolver {
   /// Resolves a [NamedStaticType] to its [TypeDeclaration].
-  Future<TypeDeclaration> declarationOf(NamedStaticType annotation);
+  Future<TypeDeclaration> declarationOf(covariant NamedStaticType annotation);
 }
 
 /// The base class for builders in the definition phase. These can convert
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 c0f8a9f..10ccafa 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart
@@ -57,9 +57,7 @@
 
 /// A subtype of [StaticType] representing types that can be resolved by name
 /// to a concrete declaration.
-abstract class NamedStaticType implements StaticType {
-  String get name;
-}
+abstract class NamedStaticType implements StaticType {}
 
 /// The base class for all declarations.
 abstract class Declaration {
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
index 158363f..514fcd9 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
@@ -155,9 +155,39 @@
           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(
-          ('Only FunctionDefinitionMacros are supported currently'));
+          'Unsupported macro type, only Method and Function Definition '
+          'Macros are supported currently');
     }
   } catch (e, s) {
     return new SerializableResponse(
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 820c899..f16daf9 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
@@ -14,6 +14,7 @@
 import 'introspection_impls.dart';
 import 'remote_instance.dart';
 import 'serialization.dart';
+import 'serialization_extensions.dart';
 
 /// Base class all requests extend, provides a unique id for each request.
 abstract class Request implements Serializable {
@@ -45,12 +46,14 @@
   final Object? error;
   final String? stackTrace;
   final int requestId;
+  final MessageType responseType;
 
   Response({
     this.response,
     this.error,
     this.stackTrace,
     required this.requestId,
+    required this.responseType,
   })  : assert(response != null || error != null),
         assert(response == null || error == null);
 }
@@ -71,8 +74,7 @@
     this.response,
     required this.responseType,
     required this.serializationZoneId,
-  })  : assert(response != null || error != null),
-        assert(response == null || error == null);
+  });
 
   /// You must first parse the [serializationZoneId] yourself, and then
   /// call this function in that zone, and pass the ID.
@@ -100,11 +102,21 @@
         response = new MacroExecutionResultImpl.deserialize(deserializer);
         break;
       case MessageType.staticType:
+      case MessageType.namedStaticType:
         response = RemoteInstance.deserialize(deserializer);
         break;
       case MessageType.boolean:
         response = new BooleanValue.deserialize(deserializer);
         break;
+      case MessageType.declarationList:
+        response = new DeclarationList.deserialize(deserializer);
+        break;
+      case MessageType.remoteInstance:
+        deserializer.moveNext();
+        if (!deserializer.checkNull()) {
+          response = deserializer.expectRemoteInstance();
+        }
+        break;
       default:
         throw new StateError('Unexpected response type $responseType');
     }
@@ -123,11 +135,13 @@
       ..addNum(serializationZoneId)
       ..addNum(MessageType.response.index)
       ..addNum(responseType.index);
-    if (response != null) {
-      response!.serialize(serializer);
-    } else if (error != null) {
-      serializer.addString(error!.toString());
-      serializer.addNullableString(stackTrace);
+    switch (responseType) {
+      case MessageType.error:
+        serializer.addString(error!.toString());
+        serializer.addNullableString(stackTrace);
+        break;
+      default:
+        response.serializeNullable(serializer);
     }
     serializer.addNum(requestId);
   }
@@ -145,6 +159,33 @@
   void serialize(Serializer serializer) => serializer..addBool(value);
 }
 
+/// A serialized list of [Declaration]s.
+class DeclarationList<T extends DeclarationImpl> implements Serializable {
+  final List<T> declarations;
+
+  DeclarationList(this.declarations);
+
+  DeclarationList.deserialize(Deserializer deserializer)
+      : declarations = [
+          for (bool hasNext = (deserializer
+                    ..moveNext()
+                    ..expectList())
+                  .moveNext();
+              hasNext;
+              hasNext = deserializer.moveNext())
+            deserializer.expectRemoteInstance(),
+        ];
+
+  @override
+  void serialize(Serializer serializer) {
+    serializer.startList();
+    for (DeclarationImpl declaration in declarations) {
+      declaration.serialize(serializer);
+    }
+    serializer.endList();
+  }
+}
+
 /// A request to load a macro in this isolate.
 class LoadMacroRequest extends Request {
   final Uri library;
@@ -286,8 +327,8 @@
 
 /// A request to check if a type is exactly another type.
 class IsSubtypeOfRequest extends Request {
-  final ClientStaticTypeImpl leftType;
-  final ClientStaticTypeImpl rightType;
+  final RemoteInstanceImpl leftType;
+  final RemoteInstanceImpl rightType;
 
   IsSubtypeOfRequest(this.leftType, this.rightType,
       {required int serializationZoneId})
@@ -303,8 +344,63 @@
 
   void serialize(Serializer serializer) {
     serializer.addNum(MessageType.isSubtypeOfRequest.index);
-    leftType.remoteInstance.serialize(serializer);
-    rightType.remoteInstance.serialize(serializer);
+    leftType.serialize(serializer);
+    rightType.serialize(serializer);
+    super.serialize(serializer);
+  }
+}
+
+/// A general request class for all requests coming from methods on the
+/// [ClassIntrospector] interface.
+class ClassIntrospectionRequest extends Request {
+  final ClassDeclarationImpl classDeclaration;
+  final RemoteInstanceImpl classIntrospector;
+  final MessageType requestKind;
+
+  ClassIntrospectionRequest(
+      this.classDeclaration, this.classIntrospector, this.requestKind,
+      {required int serializationZoneId})
+      : super(serializationZoneId: serializationZoneId);
+
+  /// When deserializing we have already consumed the message type, so we don't
+  /// consume it again and it should instead be passed in here.
+  ClassIntrospectionRequest.deserialize(
+      Deserializer deserializer, this.requestKind, int serializationZoneId)
+      : classDeclaration = RemoteInstance.deserialize(deserializer),
+        classIntrospector = RemoteInstance.deserialize(deserializer),
+        super.deserialize(deserializer, serializationZoneId);
+
+  @override
+  void serialize(Serializer serializer) {
+    serializer.addNum(requestKind.index);
+    classDeclaration.serialize(serializer);
+    classIntrospector.serialize(serializer);
+    super.serialize(serializer);
+  }
+}
+
+/// A request to get a [TypeDeclaration] for a [StaticType].
+class DeclarationOfRequest extends Request {
+  final RemoteInstanceImpl type;
+  final RemoteInstanceImpl typeDeclarationResolver;
+
+  DeclarationOfRequest(this.type, this.typeDeclarationResolver,
+      {required int serializationZoneId})
+      : super(serializationZoneId: serializationZoneId);
+
+  /// When deserializing we have already consumed the message type, so we don't
+  /// consume it again.
+  DeclarationOfRequest.deserialize(
+      Deserializer deserializer, int serializationZoneId)
+      : type = RemoteInstance.deserialize(deserializer),
+        typeDeclarationResolver = RemoteInstance.deserialize(deserializer),
+        super.deserialize(deserializer, serializationZoneId);
+
+  @override
+  void serialize(Serializer serializer) {
+    serializer.addNum(MessageType.declarationOfRequest.index);
+    type.serialize(serializer);
+    typeDeclarationResolver.serialize(serializer);
     super.serialize(serializer);
   }
 }
@@ -333,8 +429,20 @@
         serializationZoneId: serializationZoneId);
     RemoteInstanceImpl remoteType =
         _handleResponse(await _sendRequest(request));
-    return new ClientStaticTypeImpl(_sendRequest,
-        remoteInstance: remoteType, serializationZoneId: serializationZoneId);
+    switch (remoteType.kind) {
+      case RemoteInstanceKind.namedStaticType:
+        return new ClientNamedStaticTypeImpl(_sendRequest,
+            remoteInstance: remoteType,
+            serializationZoneId: serializationZoneId);
+      case RemoteInstanceKind.staticType:
+        return new ClientStaticTypeImpl(_sendRequest,
+            remoteInstance: remoteType,
+            serializationZoneId: serializationZoneId);
+      default:
+        throw new StateError(
+            'Expected either a StaticType or NamedStaticType but got '
+            '${remoteType.kind}');
+    }
   }
 }
 
@@ -361,13 +469,27 @@
 
   @override
   Future<bool> isSubtypeOf(ClientStaticTypeImpl other) async {
-    IsSubtypeOfRequest request = new IsSubtypeOfRequest(this, other,
+    IsSubtypeOfRequest request = new IsSubtypeOfRequest(
+        remoteInstance, other.remoteInstance,
         serializationZoneId: serializationZoneId);
     return _handleResponse<BooleanValue>(await sendRequest(request)).value;
   }
 }
 
-/// TODO: Implement this
+/// Named variant of the [ClientStaticTypeImpl].
+class ClientNamedStaticTypeImpl extends ClientStaticTypeImpl
+    implements NamedStaticType {
+  ClientNamedStaticTypeImpl(
+      Future<Response> Function(Request request) sendRequest,
+      {required RemoteInstanceImpl remoteInstance,
+      required int serializationZoneId})
+      : super(sendRequest,
+            remoteInstance: remoteInstance,
+            serializationZoneId: serializationZoneId);
+}
+
+/// Client side implementation of the [ClientClassIntrospector], converts all
+/// invocations into remote RPC calls.
 class ClientClassIntrospector implements ClassIntrospector {
   /// The actual remote instance of this class introspector.
   final RemoteInstanceImpl remoteInstance;
@@ -383,43 +505,73 @@
       {required this.remoteInstance, required this.serializationZoneId});
 
   @override
-  Future<List<ConstructorDeclaration>> constructorsOf(ClassDeclaration clazz) {
-    // TODO: implement constructorsOf
-    throw new UnimplementedError();
+  Future<List<ConstructorDeclaration>> constructorsOf(
+      ClassDeclarationImpl clazz) async {
+    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
+        clazz, remoteInstance, MessageType.constructorsOfRequest,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<DeclarationList>(await sendRequest(request))
+        .declarations
+        // TODO: Refactor so we can remove this cast
+        .cast();
   }
 
   @override
-  Future<List<FieldDeclaration>> fieldsOf(ClassDeclaration clazz) {
-    // TODO: implement fieldsOf
-    throw new UnimplementedError();
+  Future<List<FieldDeclaration>> fieldsOf(ClassDeclarationImpl clazz) async {
+    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
+        clazz, remoteInstance, MessageType.fieldsOfRequest,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<DeclarationList>(await sendRequest(request))
+        .declarations
+        // TODO: Refactor so we can remove this cast
+        .cast();
   }
 
   @override
-  Future<List<ClassDeclaration>> interfacesOf(ClassDeclaration clazz) {
-    // TODO: implement interfacesOf
-    throw new UnimplementedError();
+  Future<List<ClassDeclaration>> interfacesOf(
+      ClassDeclarationImpl clazz) async {
+    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
+        clazz, remoteInstance, MessageType.interfacesOfRequest,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<DeclarationList>(await sendRequest(request))
+        .declarations
+        // TODO: Refactor so we can remove this cast
+        .cast();
   }
 
   @override
-  Future<List<MethodDeclaration>> methodsOf(ClassDeclaration clazz) {
-    // TODO: implement methodsOf
-    throw new UnimplementedError();
+  Future<List<MethodDeclaration>> methodsOf(ClassDeclarationImpl clazz) async {
+    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
+        clazz, remoteInstance, MessageType.methodsOfRequest,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<DeclarationList>(await sendRequest(request))
+        .declarations
+        // TODO: Refactor so we can remove this cast
+        .cast();
   }
 
   @override
-  Future<List<ClassDeclaration>> mixinsOf(ClassDeclaration clazz) {
-    // TODO: implement mixinsOf
-    throw new UnimplementedError();
+  Future<List<ClassDeclaration>> mixinsOf(ClassDeclarationImpl clazz) async {
+    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
+        clazz, remoteInstance, MessageType.mixinsOfRequest,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<DeclarationList>(await sendRequest(request))
+        .declarations
+        // TODO: Refactor so we can remove this cast
+        .cast();
   }
 
   @override
-  Future<ClassDeclaration?> superclassOf(ClassDeclaration clazz) {
-    // TODO: implement superclassOf
-    throw new UnimplementedError();
+  Future<ClassDeclaration?> superclassOf(ClassDeclarationImpl clazz) async {
+    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
+        clazz, remoteInstance, MessageType.superclassOfRequest,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<ClassDeclaration?>(await sendRequest(request));
   }
 }
 
-/// TODO: Implement this
+/// Client side implementation of a [TypeDeclarationResolver], converts all
+/// invocations into remote procedure calls.
 class ClientTypeDeclarationResolver implements TypeDeclarationResolver {
   /// The actual remote instance of this type resolver.
   final RemoteInstanceImpl remoteInstance;
@@ -435,9 +587,11 @@
       {required this.remoteInstance, required this.serializationZoneId});
 
   @override
-  Future<TypeDeclaration> declarationOf(NamedStaticType annotation) {
-    // TODO: implement declarationOf
-    throw new UnimplementedError();
+  Future<TypeDeclaration> declarationOf(ClientNamedStaticTypeImpl type) async {
+    DeclarationOfRequest request = new DeclarationOfRequest(
+        type.remoteInstance, remoteInstance,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<TypeDeclaration>(await sendRequest(request));
   }
 }
 
@@ -456,24 +610,34 @@
 /// Either returns the actual response from [response], casted to [T], or throws
 /// a [RemoteException] with the given error and stack trace.
 T _handleResponse<T>(Response response) {
-  if (response.response != null) {
-    return response.response as T;
+  if (response.responseType == MessageType.error) {
+    throw new RemoteException(response.error!.toString(), response.stackTrace);
   }
-  throw new RemoteException(response.error!.toString(), response.stackTrace);
+  return response.response as T;
 }
 
 enum MessageType {
   boolean,
+  constructorsOfRequest,
+  declarationOfRequest,
+  declarationList,
+  fieldsOfRequest,
+  interfacesOfRequest,
+  methodsOfRequest,
+  mixinsOfRequest,
+  superclassOfRequest,
   error,
   executeDefinitionsPhaseRequest,
   instantiateMacroRequest,
   isExactlyTypeRequest,
   isSubtypeOfRequest,
   loadMacroRequest,
+  remoteInstance,
   resolveTypeRequest,
   macroClassIdentifier,
   macroInstanceIdentifier,
   macroExecutionResult,
+  namedStaticType,
   response,
   staticType,
 }
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/remote_instance.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/remote_instance.dart
index 59c26fd..411f2aa 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/remote_instance.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/remote_instance.dart
@@ -79,24 +79,31 @@
   final Object? instance;
 
   @override
-  RemoteInstanceKind get kind => RemoteInstanceKind.instance;
+  final RemoteInstanceKind kind;
 
-  RemoteInstanceImpl({required int id, this.instance}) : super(id);
+  RemoteInstanceImpl({
+    required int id,
+    this.instance,
+    required this.kind,
+  }) : super(id);
 }
 
 // The kinds of instances.
 enum RemoteInstanceKind {
   classDeclaration,
+  classIntrospector,
   constructorDeclaration,
   fieldDeclaration,
   functionDeclaration,
   functionTypeAnnotation,
+  namedStaticType,
   methodDeclaration,
   namedTypeAnnotation,
   parameterDeclaration,
+  staticType,
   typeAliasDeclaration,
   typeParameterDeclaration,
+  typeResolver,
+  typeDeclarationResolver,
   variableDeclaration,
-  // A generic instance that is just a pointer to some server side instance.
-  instance,
 }
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 e341b91..b7df0be 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
@@ -12,6 +12,13 @@
         moveNext();
         RemoteInstanceKind kind = RemoteInstanceKind.values[expectNum()];
         switch (kind) {
+          case RemoteInstanceKind.classIntrospector:
+          case RemoteInstanceKind.namedStaticType:
+          case RemoteInstanceKind.staticType:
+          case RemoteInstanceKind.typeDeclarationResolver:
+          case RemoteInstanceKind.typeResolver:
+            // These are simple wrappers, just pass in the kind
+            return new RemoteInstanceImpl(id: id, kind: kind) as T;
           case RemoteInstanceKind.classDeclaration:
             moveNext();
             return _expectClassDeclaration(id) as T;
@@ -27,8 +34,6 @@
           case RemoteInstanceKind.functionTypeAnnotation:
             moveNext();
             return _expectFunctionTypeAnnotation(id) as T;
-          case RemoteInstanceKind.instance:
-            return new RemoteInstanceImpl(id: id) as T;
           case RemoteInstanceKind.methodDeclaration:
             moveNext();
             return _expectMethodDeclaration(id) as T;
@@ -170,7 +175,8 @@
         isAbstract: (this..moveNext()).expectBool(),
         isExternal: (this..moveNext()).expectBool(),
         mixins: (this..moveNext())._expectRemoteInstanceList(),
-        superclass: RemoteInstance.deserialize(this),
+        superclass:
+            (this..moveNext()).checkNull() ? null : expectRemoteInstance(),
       );
 
   TypeAliasDeclaration _expectTypeAliasDeclaration(int id) =>
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
index f5a7287..797ffb8 100644
--- 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
@@ -111,11 +111,17 @@
           macro,
           declaration,
           new RemoteInstanceImpl(
-              instance: typeResolver, id: RemoteInstance.uniqueId),
+              instance: typeResolver,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.typeResolver),
           new RemoteInstanceImpl(
-              instance: classIntrospector, id: RemoteInstance.uniqueId),
+              instance: classIntrospector,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.classIntrospector),
           new RemoteInstanceImpl(
-              instance: typeDeclarationResolver, id: RemoteInstance.uniqueId),
+              instance: typeDeclarationResolver,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.typeDeclarationResolver),
           // Serialization zones are not necessary in this executor.
           serializationZoneId: -1));
 
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 4673d17..91b1125 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
@@ -47,9 +47,13 @@
     ClassMirror macroClass =
         libMirror.declarations[new Symbol(request.name)] as ClassMirror;
     _macroClasses[identifier] = macroClass;
-    return new Response(response: identifier, requestId: request.id);
+    return new Response(
+        response: identifier,
+        requestId: request.id,
+        responseType: MessageType.macroClassIdentifier);
   } catch (e) {
-    return new Response(error: e, requestId: request.id);
+    return new Response(
+        error: e, requestId: request.id, responseType: MessageType.error);
   }
 }
 
@@ -70,9 +74,13 @@
     }).reflectee as Macro;
     MacroInstanceIdentifierImpl identifier = new MacroInstanceIdentifierImpl();
     _macroInstances[identifier] = instance;
-    return new Response(response: identifier, requestId: request.id);
+    return new Response(
+        response: identifier,
+        requestId: request.id,
+        responseType: MessageType.macroInstanceIdentifier);
   } catch (e) {
-    return new Response(error: e, requestId: request.id);
+    return new Response(
+        error: e, requestId: request.id, responseType: MessageType.error);
   }
 }
 
@@ -93,12 +101,29 @@
           request.typeDeclarationResolver.instance as TypeDeclarationResolver,
           request.classIntrospector.instance as ClassIntrospector);
       await instance.buildDefinitionForFunction(declaration, builder);
-      return new Response(response: builder.result, requestId: request.id);
+      return new Response(
+          response: builder.result,
+          requestId: request.id,
+          responseType: MessageType.macroExecutionResult);
+    } else if (instance is MethodDefinitionMacro &&
+        declaration is MethodDeclarationImpl) {
+      FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
+          declaration,
+          request.typeResolver.instance as TypeResolver,
+          request.typeDeclarationResolver.instance as TypeDeclarationResolver,
+          request.classIntrospector.instance as ClassIntrospector);
+      await instance.buildDefinitionForMethod(declaration, builder);
+      return new SerializableResponse(
+          responseType: MessageType.macroExecutionResult,
+          response: builder.result,
+          requestId: request.id,
+          serializationZoneId: request.serializationZoneId);
     } else {
       throw new UnsupportedError(
-          ('Only FunctionDefinitionMacros are supported currently'));
+          'Only Method and Function Definition Macros are supported currently');
     }
   } catch (e) {
-    return new Response(error: e, requestId: request.id);
+    return new Response(
+        error: e, requestId: request.id, responseType: MessageType.error);
   }
 }
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 b2b3b49..849c662 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
@@ -159,14 +159,20 @@
             case MessageType.resolveTypeRequest:
               ResolveTypeRequest request =
                   new ResolveTypeRequest.deserialize(deserializer, zoneId);
+              StaticType instance =
+                  await (request.typeResolver.instance as TypeResolver)
+                      .resolve(request.typeAnnotation);
               SerializableResponse response = new SerializableResponse(
                   response: new RemoteInstanceImpl(
                       id: RemoteInstance.uniqueId,
-                      instance:
-                          await (request.typeResolver.instance as TypeResolver)
-                              .resolve(request.typeAnnotation)),
+                      instance: instance,
+                      kind: instance is NamedStaticType
+                          ? RemoteInstanceKind.namedStaticType
+                          : RemoteInstanceKind.staticType),
                   requestId: request.id,
-                  responseType: MessageType.staticType,
+                  responseType: instance is NamedStaticType
+                      ? MessageType.namedStaticType
+                      : MessageType.staticType,
                   serializationZoneId: zoneId);
               JsonSerializer serializer = new JsonSerializer();
               response.serialize(serializer);
@@ -188,8 +194,8 @@
               sendPort.send(serializer.result);
               break;
             case MessageType.isSubtypeOfRequest:
-              IsExactlyTypeRequest request =
-                  new IsExactlyTypeRequest.deserialize(deserializer, zoneId);
+              IsSubtypeOfRequest request =
+                  new IsSubtypeOfRequest.deserialize(deserializer, zoneId);
               StaticType leftType = request.leftType.instance as StaticType;
               StaticType rightType = request.leftType.instance as StaticType;
               SerializableResponse response = new SerializableResponse(
@@ -202,6 +208,131 @@
               response.serialize(serializer);
               sendPort.send(serializer.result);
               break;
+            case MessageType.declarationOfRequest:
+              DeclarationOfRequest request =
+                  new DeclarationOfRequest.deserialize(deserializer, zoneId);
+              NamedStaticType type = request.type.instance as NamedStaticType;
+              TypeDeclarationResolver resolver = request
+                  .typeDeclarationResolver.instance as TypeDeclarationResolver;
+              SerializableResponse response = new SerializableResponse(
+                  requestId: request.id,
+                  responseType: MessageType.remoteInstance,
+                  response: (await resolver.declarationOf(type)
+                      // TODO: Consider refactoring to avoid the need for this.
+                      as TypeDeclarationImpl),
+                  serializationZoneId: zoneId);
+              JsonSerializer serializer = new JsonSerializer();
+              response.serialize(serializer);
+              sendPort.send(serializer.result);
+              break;
+            case MessageType.constructorsOfRequest:
+              ClassIntrospectionRequest request =
+                  new ClassIntrospectionRequest.deserialize(
+                      deserializer, messageType, zoneId);
+              ClassIntrospector classIntrospector =
+                  request.classIntrospector.instance as ClassIntrospector;
+              SerializableResponse response = new SerializableResponse(
+                  requestId: request.id,
+                  responseType: MessageType.declarationList,
+                  response: new DeclarationList((await classIntrospector
+                          .constructorsOf(request.classDeclaration))
+                      // TODO: Consider refactoring to avoid the need for this.
+                      .cast<ConstructorDeclarationImpl>()),
+                  serializationZoneId: zoneId);
+              JsonSerializer serializer = new JsonSerializer();
+              response.serialize(serializer);
+              sendPort.send(serializer.result);
+              break;
+            case MessageType.fieldsOfRequest:
+              ClassIntrospectionRequest request =
+                  new ClassIntrospectionRequest.deserialize(
+                      deserializer, messageType, zoneId);
+              ClassIntrospector classIntrospector =
+                  request.classIntrospector.instance as ClassIntrospector;
+              SerializableResponse response = new SerializableResponse(
+                  requestId: request.id,
+                  responseType: MessageType.declarationList,
+                  response: new DeclarationList((await classIntrospector
+                          .fieldsOf(request.classDeclaration))
+                      // TODO: Consider refactoring to avoid the need for this.
+                      .cast<FieldDeclarationImpl>()),
+                  serializationZoneId: zoneId);
+              JsonSerializer serializer = new JsonSerializer();
+              response.serialize(serializer);
+              sendPort.send(serializer.result);
+              break;
+            case MessageType.interfacesOfRequest:
+              ClassIntrospectionRequest request =
+                  new ClassIntrospectionRequest.deserialize(
+                      deserializer, messageType, zoneId);
+              ClassIntrospector classIntrospector =
+                  request.classIntrospector.instance as ClassIntrospector;
+              SerializableResponse response = new SerializableResponse(
+                  requestId: request.id,
+                  responseType: MessageType.declarationList,
+                  response: new DeclarationList((await classIntrospector
+                          .interfacesOf(request.classDeclaration))
+                      // TODO: Consider refactoring to avoid the need for this.
+                      .cast<ClassDeclarationImpl>()),
+                  serializationZoneId: zoneId);
+              JsonSerializer serializer = new JsonSerializer();
+              response.serialize(serializer);
+              sendPort.send(serializer.result);
+              break;
+            case MessageType.methodsOfRequest:
+              ClassIntrospectionRequest request =
+                  new ClassIntrospectionRequest.deserialize(
+                      deserializer, messageType, zoneId);
+              ClassIntrospector classIntrospector =
+                  request.classIntrospector.instance as ClassIntrospector;
+              SerializableResponse response = new SerializableResponse(
+                  requestId: request.id,
+                  responseType: MessageType.declarationList,
+                  response: new DeclarationList((await classIntrospector
+                          .methodsOf(request.classDeclaration))
+                      // TODO: Consider refactoring to avoid the need for this.
+                      .cast<MethodDeclarationImpl>()),
+                  serializationZoneId: zoneId);
+              JsonSerializer serializer = new JsonSerializer();
+              response.serialize(serializer);
+              sendPort.send(serializer.result);
+              break;
+            case MessageType.mixinsOfRequest:
+              ClassIntrospectionRequest request =
+                  new ClassIntrospectionRequest.deserialize(
+                      deserializer, messageType, zoneId);
+              ClassIntrospector classIntrospector =
+                  request.classIntrospector.instance as ClassIntrospector;
+              SerializableResponse response = new SerializableResponse(
+                  requestId: request.id,
+                  responseType: MessageType.declarationList,
+                  response: new DeclarationList((await classIntrospector
+                          .mixinsOf(request.classDeclaration))
+                      // TODO: Consider refactoring to avoid the need for this.
+                      .cast<ClassDeclarationImpl>()),
+                  serializationZoneId: zoneId);
+              JsonSerializer serializer = new JsonSerializer();
+              response.serialize(serializer);
+              sendPort.send(serializer.result);
+              break;
+            case MessageType.superclassOfRequest:
+              ClassIntrospectionRequest request =
+                  new ClassIntrospectionRequest.deserialize(
+                      deserializer, messageType, zoneId);
+              ClassIntrospector classIntrospector =
+                  request.classIntrospector.instance as ClassIntrospector;
+              SerializableResponse response = new SerializableResponse(
+                  requestId: request.id,
+                  responseType: MessageType.remoteInstance,
+                  response: (await classIntrospector
+                          .superclassOf(request.classDeclaration))
+                      // TODO: Consider refactoring to avoid the need for this.
+                      as ClassDeclarationImpl?,
+                  serializationZoneId: zoneId);
+              JsonSerializer serializer = new JsonSerializer();
+              response.serialize(serializer);
+              sendPort.send(serializer.result);
+              break;
             default:
               throw new StateError('Unexpected message type $messageType');
           }
@@ -265,11 +396,17 @@
           macro,
           declaration,
           new RemoteInstanceImpl(
-              instance: typeResolver, id: RemoteInstance.uniqueId),
+              instance: typeResolver,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.typeResolver),
           new RemoteInstanceImpl(
-              instance: classIntrospector, id: RemoteInstance.uniqueId),
+              instance: classIntrospector,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.classIntrospector),
           new RemoteInstanceImpl(
-              instance: typeDeclarationResolver, id: RemoteInstance.uniqueId),
+              instance: typeDeclarationResolver,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.typeDeclarationResolver),
           serializationZoneId: zoneId));
 
   @override
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
index c1f7c1d..0614b4f 100644
--- 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
@@ -20,10 +20,11 @@
 
   setUpAll(() {
     // We support running from either the root of the SDK or the package root.
-    simpleMacroFile =
-        File('pkg/_fe_analyzer_shared/test/macros/simple_macro.dart');
+    simpleMacroFile = File(
+        'pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/simple_macro.dart');
     if (!simpleMacroFile.existsSync()) {
-      simpleMacroFile = File('test/macros/simple_macro.dart');
+      simpleMacroFile =
+          File('test/macros/isolate_mirror_executor/simple_macro.dart');
     }
   });
 
@@ -75,7 +76,7 @@
           typeParameters: [],
         ),
         TestTypeResolver(
-            {returnType: TestStaticType('dart:core', 'String', [])}),
+            {returnType: TestNamedStaticType('dart:core', 'String', [])}),
         FakeClassIntrospector(),
         FakeTypeDeclarationResolver());
     expect(definitionResult.augmentations, hasLength(1));
diff --git a/pkg/_fe_analyzer_shared/test/macros/simple_macro.dart b/pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/simple_macro.dart
similarity index 100%
rename from pkg/_fe_analyzer_shared/test/macros/simple_macro.dart
rename to pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/simple_macro.dart
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 1bdb14f..a7f5491 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
@@ -23,10 +23,10 @@
 
   setUpAll(() {
     // We support running from either the root of the SDK or the package root.
-    simpleMacroFile =
-        File('pkg/_fe_analyzer_shared/test/macros/simple_macro.dart');
+    simpleMacroFile = File(
+        'pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart');
     if (!simpleMacroFile.existsSync()) {
-      simpleMacroFile = File('test/macros/simple_macro.dart');
+      simpleMacroFile = File('test/macros/isolated_executor/simple_macro.dart');
     }
   });
 
@@ -78,15 +78,111 @@
     expect(instanceId, isNotNull,
         reason: 'Can create an instance with named arguments.');
 
-    var returnType = NamedTypeAnnotationImpl(
+    var stringType = NamedTypeAnnotationImpl(
         id: RemoteInstance.uniqueId,
         name: 'String',
         isNullable: false,
         typeArguments: const []);
+
+    var myInterfaceType = NamedTypeAnnotationImpl(
+        id: RemoteInstance.uniqueId,
+        name: 'MyInterface',
+        isNullable: false,
+        typeArguments: const []);
+    var myMixinType = NamedTypeAnnotationImpl(
+        id: RemoteInstance.uniqueId,
+        name: 'MyMixin',
+        isNullable: false,
+        typeArguments: const []);
+    var mySuperclassType = NamedTypeAnnotationImpl(
+        id: RemoteInstance.uniqueId,
+        name: 'MySuperclass',
+        isNullable: false,
+        typeArguments: const []);
+    var myClassType = NamedTypeAnnotationImpl(
+        id: RemoteInstance.uniqueId,
+        name: 'MyClass',
+        isNullable: false,
+        typeArguments: const []);
+
+    var myClass = ClassDeclarationImpl(
+        id: RemoteInstance.uniqueId,
+        name: myClassType.name,
+        typeParameters: [],
+        interfaces: [myInterfaceType],
+        isAbstract: false,
+        isExternal: false,
+        mixins: [myMixinType],
+        superclass: mySuperclassType);
+    var myConstructor = ConstructorDeclarationImpl(
+        id: RemoteInstance.uniqueId,
+        name: 'myConstructor',
+        isAbstract: false,
+        isExternal: false,
+        isGetter: false,
+        isSetter: false,
+        namedParameters: [],
+        positionalParameters: [],
+        returnType: myClassType,
+        typeParameters: [],
+        definingClass: myClassType,
+        isFactory: false);
+    var myField = FieldDeclarationImpl(
+        id: RemoteInstance.uniqueId,
+        name: 'myField',
+        initializer: null,
+        isAbstract: false,
+        isExternal: false,
+        type: stringType,
+        definingClass: myClassType);
+    var myInterface = ClassDeclarationImpl(
+        id: RemoteInstance.uniqueId,
+        name: myInterfaceType.name,
+        typeParameters: [],
+        interfaces: [],
+        isAbstract: false,
+        isExternal: false,
+        mixins: [],
+        superclass: null);
+    var myMethod = MethodDeclarationImpl(
+        id: RemoteInstance.uniqueId,
+        name: 'myMethod',
+        isAbstract: false,
+        isExternal: false,
+        isGetter: false,
+        isSetter: false,
+        namedParameters: [],
+        positionalParameters: [],
+        returnType: stringType,
+        typeParameters: [],
+        definingClass: myClassType);
+    var myMixin = ClassDeclarationImpl(
+        id: RemoteInstance.uniqueId,
+        name: myMixinType.name,
+        typeParameters: [],
+        interfaces: [],
+        isAbstract: false,
+        isExternal: false,
+        mixins: [],
+        superclass: null);
+    var mySuperclass = ClassDeclarationImpl(
+        id: RemoteInstance.uniqueId,
+        name: mySuperclassType.name,
+        typeParameters: [],
+        interfaces: [],
+        isAbstract: false,
+        isExternal: false,
+        mixins: [],
+        superclass: null);
+
+    var myClassStaticType = TestNamedStaticType(
+        'package:my_package/my_package.dart', myClassType.name, []);
+
     var definitionResult = await executor.executeDefinitionsPhase(
         instanceId,
-        FunctionDeclarationImpl(
+        MethodDeclarationImpl(
           id: RemoteInstance.uniqueId,
+          definingClass: myClassType,
           isAbstract: false,
           isExternal: false,
           isGetter: false,
@@ -94,19 +190,49 @@
           name: 'foo',
           namedParameters: [],
           positionalParameters: [],
-          returnType: returnType,
+          returnType: stringType,
           typeParameters: [],
         ),
-        TestTypeResolver(
-            {returnType: TestStaticType('dart:core', 'String', [])}),
-        FakeClassIntrospector(),
-        FakeTypeDeclarationResolver());
+        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();
-            }'''));
+            }
+          }'''));
   });
 }
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
new file mode 100644
index 0000000..035d96f
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart
@@ -0,0 +1,77 @@
+// 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 MethodDefinitionMacro {
+  final int? x;
+  final int? y;
+
+  SimpleMacro([this.x, this.y]);
+
+  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!');
+    }
+
+    // Test the type resolver and static type interfaces
+    var staticReturnType = await builder.resolve(method.returnType);
+    if (!(await staticReturnType.isExactly(staticReturnType))) {
+      throw StateError('The return type should be exactly equal to itself!');
+    }
+    if (!(await staticReturnType.isSubtypeOf(staticReturnType))) {
+      throw StateError('The return type should be a subtype of itself!');
+    }
+    var classType =
+        await builder.resolve(method.definingClass) as NamedStaticType;
+    if (!(await staticReturnType.isExactly(classType))) {
+      throw StateError(
+          'The return type should not be exactly equal to the class type');
+    }
+    if (!(await staticReturnType.isSubtypeOf(classType))) {
+      throw StateError(
+          'The return type should be a subtype of the class type!');
+    }
+
+    // Test the type declaration resolver
+    var parentClass =
+        await builder.declarationOf(classType) as ClassDeclaration;
+
+    // Test the class introspector
+    var superClass = (await builder.superclassOf(parentClass))!;
+    var interfaces = (await builder.interfacesOf(parentClass));
+    var mixins = (await builder.mixinsOf(parentClass));
+    var fields = (await builder.fieldsOf(parentClass));
+    var methods = (await builder.methodsOf(parentClass));
+    var constructors = (await builder.constructorsOf(parentClass));
+
+    builder.augment(FunctionBodyCode.fromParts([
+      '''{
+      print('x: $x, y: $y');
+      print('parentClass: ${parentClass.name}');
+      print('superClass: ${superClass.name}');''',
+      for (var interface in interfaces)
+        "\n      print('interface: ${interface.name}');",
+      for (var mixin in mixins) "\n      print('mixin: ${mixin.name}');",
+      for (var field in fields) "\n      print('field: ${field.name}');",
+      for (var method in methods) "\n      print('method: ${method.name}');",
+      for (var constructor in constructors)
+        "\n      print('constructor: ${constructor.name}');",
+      '''
+\n      return augment super();
+    }''',
+    ]));
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/test/macros/util.dart b/pkg/_fe_analyzer_shared/test/macros/util.dart
index d92c884..ef73298 100644
--- a/pkg/_fe_analyzer_shared/test/macros/util.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/util.dart
@@ -5,13 +5,73 @@
 import 'dart:mirrors';
 
 import 'package:_fe_analyzer_shared/src/macros/api.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor_shared/introspection_impls.dart';
 
 import 'package:test/fake.dart';
 import 'package:test/test.dart';
 
-class FakeClassIntrospector with Fake implements ClassIntrospector {}
+class FakeClassIntrospector extends Fake implements ClassIntrospector {}
 
-class FakeTypeDeclarationResolver with Fake implements TypeDeclarationResolver {
+class TestClassIntrospector implements ClassIntrospector {
+  final Map<ClassDeclaration, List<ConstructorDeclaration>> constructors;
+  final Map<ClassDeclaration, List<FieldDeclaration>> fields;
+  final Map<ClassDeclaration, List<ClassDeclarationImpl>> interfaces;
+  final Map<ClassDeclaration, List<ClassDeclarationImpl>> mixins;
+  final Map<ClassDeclaration, List<MethodDeclaration>> methods;
+  final Map<ClassDeclaration, ClassDeclaration?> superclass;
+
+  TestClassIntrospector({
+    required this.constructors,
+    required this.fields,
+    required this.interfaces,
+    required this.mixins,
+    required this.methods,
+    required this.superclass,
+  });
+
+  @override
+  Future<List<ConstructorDeclaration>> constructorsOf(
+          covariant ClassDeclaration clazz) async =>
+      constructors[clazz]!;
+
+  @override
+  Future<List<FieldDeclaration>> fieldsOf(
+          covariant ClassDeclaration clazz) async =>
+      fields[clazz]!;
+
+  @override
+  Future<List<ClassDeclaration>> interfacesOf(
+          covariant ClassDeclaration clazz) async =>
+      interfaces[clazz]!;
+
+  @override
+  Future<List<MethodDeclaration>> methodsOf(
+          covariant ClassDeclaration clazz) async =>
+      methods[clazz]!;
+
+  @override
+  Future<List<ClassDeclaration>> mixinsOf(
+          covariant ClassDeclaration clazz) async =>
+      mixins[clazz]!;
+
+  @override
+  Future<ClassDeclaration?> superclassOf(
+          covariant ClassDeclaration clazz) async =>
+      superclass[clazz];
+}
+
+class FakeTypeDeclarationResolver extends Fake
+    implements TypeDeclarationResolver {}
+
+class TestTypeDeclarationResolver implements TypeDeclarationResolver {
+  final Map<NamedStaticType, TypeDeclaration> typeDeclarations;
+
+  TestTypeDeclarationResolver(this.typeDeclarations);
+
+  @override
+  Future<TypeDeclaration> declarationOf(
+          covariant NamedStaticType annotation) async =>
+      typeDeclarations[annotation]!;
 }
 
 class TestTypeResolver implements TypeResolver {
@@ -26,22 +86,22 @@
 }
 
 // Doesn't handle generics etc but thats ok for now
-class TestStaticType implements StaticType {
+class TestNamedStaticType implements NamedStaticType {
   final String library;
   final String name;
-  final List<TestStaticType> superTypes;
+  final List<TestNamedStaticType> superTypes;
 
-  TestStaticType(this.library, this.name, this.superTypes);
+  TestNamedStaticType(this.library, this.name, this.superTypes);
 
   @override
-  Future<bool> isExactly(TestStaticType other) async => _isExactly(other);
+  Future<bool> isExactly(TestNamedStaticType other) async => _isExactly(other);
 
   @override
-  Future<bool> isSubtypeOf(TestStaticType other) async =>
+  Future<bool> isSubtypeOf(TestNamedStaticType other) async =>
       _isExactly(other) ||
       superTypes.any((superType) => superType._isExactly(other));
 
-  bool _isExactly(TestStaticType other) =>
+  bool _isExactly(TestNamedStaticType other) =>
       identical(other, this) ||
       (library == other.library && name == other.name);
 }
@@ -71,8 +131,8 @@
 Matcher deepEqualsDeclaration(Declaration declaration) =>
     _DeepEqualityMatcher(declaration);
 
-/// Checks if two [TypeAnnotation]s are of the same type and all their fields are
-/// equal.
+/// Checks if two [TypeAnnotation]s are of the same type and all their fields
+/// are equal.
 Matcher deepEqualsTypeAnnotation(TypeAnnotation declaration) =>
     _DeepEqualityMatcher(declaration);
 
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index ca03543..b67f720 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -1089,6 +1089,7 @@
 redo
 reexports
 ref
+refactoring
 reflect
 reflectee
 reflective
@@ -1542,6 +1543,7 @@
 worthwhile
 worthy
 woven
+wrappers
 writeln
 wrongfully
 wrt
diff --git a/tools/VERSION b/tools/VERSION
index 03fbd69..b85d527 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 30
+PRERELEASE 31
 PRERELEASE_PATCH 0
\ No newline at end of file