Add library introspection apis for macros.

Allows you to ask for the types in a library in the declarations phase, and all
the top level declarations in the definitions phase.

Bug: https://github.com/dart-lang/language/issues/2839
Change-Id: If0f8fb777fd8a006d686d457cf5d5ca11fcca9ee
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311900
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Jake Macdonald <jakemac@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
index ddf1c96..665ffe9 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
@@ -51,6 +51,8 @@
 /// The API used to introspect on any [TypeDeclaration] which also has the
 /// marker interface [IntrospectableType].
 ///
+/// Can also be used to ask for all the types declared in a [Library].
+///
 /// Available in the declaration and definition phases.
 abstract interface class TypeIntrospector {
   /// The values available for [enuum].
@@ -78,6 +80,15 @@
   /// on [type].
   Future<List<ConstructorDeclaration>> constructorsOf(
       covariant IntrospectableType type);
+
+  /// [TypeDeclaration]s for all the types declared in [library].
+  ///
+  /// In the declarations phase these will not be [IntrospectableType]s, since
+  /// types are still incomplete at that point.
+  ///
+  /// In the definitions phase, these will be [IntrospectableType]s where
+  /// appropriate (but, for instance, type aliases will not be).
+  Future<List<TypeDeclaration>> typesOf(covariant Library library);
 }
 
 /// The interface used by [Macro]s to resolve any [Identifier]s pointing to
@@ -92,7 +103,7 @@
   ///
   /// In the declaration phase, this will return [IntrospectableType] instances
   /// only for those types that are introspectable. Specifically, types are only
-  /// introspectable of the macro is running on a class declaration, and the
+  /// introspectable if the macro is running on a class declaration, and the
   /// type appears in the type hierarchy of that class.
   ///
   /// In the definition phase, this will return [IntrospectableType] instances
@@ -143,6 +154,17 @@
   Future<TypeAnnotation> inferType(covariant OmittedTypeAnnotation omittedType);
 }
 
+/// The interface used by [Macro]s to get the list of all declarations in a
+/// [Library].
+///
+/// Only available in the definition phase of macro expansion.
+abstract interface class LibraryDeclarationsResolver {
+  /// Returns a list of all the [Declaration]s in the given [library].
+  ///
+  /// Where applicable, these will be introspectable declarations.
+  Future<List<Declaration>> topLevelDeclarationsOf(covariant Library library);
+}
+
 /// 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.
@@ -153,7 +175,8 @@
         TypeIntrospector,
         TypeDeclarationResolver,
         TypeInferrer,
-        TypeResolver {}
+        TypeResolver,
+        LibraryDeclarationsResolver {}
 
 /// The APIs used by [Macro]s that run on type declarations, to fill in the
 /// definitions of any declarations within that class.
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
index cfb5ff4..5190b77 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
@@ -329,10 +329,15 @@
         sendRequest,
         remoteInstance: request.typeInferrer,
         serializationZoneId: request.serializationZoneId);
+    var libraryDeclarationsResolver = ClientLibraryDeclarationsResolver(
+        sendRequest,
+        remoteInstance: request.libraryDeclarationsResolver,
+        serializationZoneId: request.serializationZoneId);
 
     var result = await executeDefinitionMacro(
         instance, request.declaration, identifierResolver, typeIntrospector,
-        typeResolver, typeDeclarationResolver, typeInferrer);
+        typeResolver, typeDeclarationResolver, typeInferrer,
+        libraryDeclarationsResolver);
     return new SerializableResponse(
         responseType: MessageType.macroExecutionResult,
         response: result,
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor.dart
index 746b96b..9396e3f 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor.dart
@@ -59,7 +59,8 @@
       TypeDeclarationResolver typeDeclarationResolver,
       TypeResolver typeResolver,
       TypeIntrospector typeIntrospector,
-      TypeInferrer typeInferrer);
+      TypeInferrer typeInferrer,
+      LibraryDeclarationsResolver libraryDeclarationsResolver);
 
   /// Combines multiple [MacroExecutionResult]s into a single library
   /// augmentation file, and returns a [String] representing that file.
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/builder_impls.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/builder_impls.dart
index 96e6ba6..5c74712 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor/builder_impls.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/builder_impls.dart
@@ -96,6 +96,10 @@
   @override
   Future<StaticType> resolve(TypeAnnotationCode code) =>
       typeResolver.resolve(code);
+
+  @override
+  Future<List<TypeDeclaration>> typesOf(Library library) =>
+      typeIntrospector.typesOf(library);
 }
 
 class DeclarationBuilderImpl extends DeclarationBuilderBase
@@ -152,15 +156,18 @@
 
 /// Base class for all [DefinitionBuilder]s.
 class DefinitionBuilderBase extends DeclarationBuilderBase
-    implements TypeInferrer {
+    implements TypeInferrer, LibraryDeclarationsResolver {
   final TypeInferrer typeInferrer;
 
+  final LibraryDeclarationsResolver libraryDeclarationsResolver;
+
   DefinitionBuilderBase(
     super.identifierResolver,
     super.typeIntrospector,
     super.typeDeclarationResolver,
     super.typeResolver,
-    this.typeInferrer, {
+    this.typeInferrer,
+    this.libraryDeclarationsResolver, {
     super.parentTypeAugmentations,
     super.parentEnumValueAugmentations,
     super.parentLibraryAugmentations,
@@ -169,6 +176,10 @@
   @override
   Future<TypeAnnotation> inferType(OmittedTypeAnnotationImpl omittedType) =>
       typeInferrer.inferType(omittedType);
+
+  @override
+  Future<List<Declaration>> topLevelDeclarationsOf(Library library) =>
+      libraryDeclarationsResolver.topLevelDeclarationsOf(library);
 }
 
 class TypeDefinitionBuilderImpl extends DefinitionBuilderBase
@@ -182,7 +193,8 @@
     super.typeIntrospector,
     super.typeDeclarationResolver,
     super.typeResolver,
-    super.typeInferrer, {
+    super.typeInferrer,
+    super.libraryDeclarationsResolver, {
     super.parentTypeAugmentations,
     super.parentEnumValueAugmentations,
     super.parentLibraryAugmentations,
@@ -195,8 +207,14 @@
                 .constructorsOf(declaration))
             .firstWhere((constructor) => constructor.identifier == identifier)
         as ConstructorDeclarationImpl;
-    return new ConstructorDefinitionBuilderImpl(constructor, identifierResolver,
-        typeIntrospector, typeDeclarationResolver, typeResolver, typeInferrer,
+    return new ConstructorDefinitionBuilderImpl(
+        constructor,
+        identifierResolver,
+        typeIntrospector,
+        typeDeclarationResolver,
+        typeResolver,
+        typeInferrer,
+        libraryDeclarationsResolver,
         parentTypeAugmentations: _typeAugmentations,
         parentLibraryAugmentations: _libraryAugmentations);
   }
@@ -205,8 +223,14 @@
   Future<VariableDefinitionBuilder> buildField(Identifier identifier) async {
     FieldDeclaration field = (await typeIntrospector.fieldsOf(declaration))
         .firstWhere((field) => field.identifier == identifier);
-    return new VariableDefinitionBuilderImpl(field, identifierResolver,
-        typeIntrospector, typeDeclarationResolver, typeResolver, typeInferrer,
+    return new VariableDefinitionBuilderImpl(
+        field,
+        identifierResolver,
+        typeIntrospector,
+        typeDeclarationResolver,
+        typeResolver,
+        typeInferrer,
+        libraryDeclarationsResolver,
         parentTypeAugmentations: _typeAugmentations,
         parentLibraryAugmentations: _libraryAugmentations);
   }
@@ -217,8 +241,14 @@
         (await typeIntrospector.methodsOf(declaration))
                 .firstWhere((method) => method.identifier == identifier)
             as MethodDeclarationImpl;
-    return new FunctionDefinitionBuilderImpl(method, identifierResolver,
-        typeIntrospector, typeDeclarationResolver, typeResolver, typeInferrer,
+    return new FunctionDefinitionBuilderImpl(
+        method,
+        identifierResolver,
+        typeIntrospector,
+        typeDeclarationResolver,
+        typeResolver,
+        typeInferrer,
+        libraryDeclarationsResolver,
         parentTypeAugmentations: _typeAugmentations,
         parentLibraryAugmentations: _libraryAugmentations);
   }
@@ -236,7 +266,8 @@
     super.typeIntrospector,
     super.typeDeclarationResolver,
     super.typeResolver,
-    super.typeInferrer, {
+    super.typeInferrer,
+    super.libraryDeclarationsResolver, {
     super.parentTypeAugmentations,
     super.parentEnumValueAugmentations,
     super.parentLibraryAugmentations,
@@ -249,8 +280,14 @@
         (await typeIntrospector.valuesOf(declaration))
                 .firstWhere((entry) => entry.identifier == identifier)
             as EnumValueDeclarationImpl;
-    return new EnumValueDefinitionBuilderImpl(entry, identifierResolver,
-        typeIntrospector, typeDeclarationResolver, typeResolver, typeInferrer,
+    return new EnumValueDefinitionBuilderImpl(
+        entry,
+        identifierResolver,
+        typeIntrospector,
+        typeDeclarationResolver,
+        typeResolver,
+        typeInferrer,
+        libraryDeclarationsResolver,
         parentTypeAugmentations: _typeAugmentations,
         parentEnumValueAugmentations: _enumValueAugmentations,
         parentLibraryAugmentations: _libraryAugmentations);
@@ -267,7 +304,8 @@
     super.typeIntrospector,
     super.typeDeclarationResolver,
     super.typeResolver,
-    super.typeInferrer, {
+    super.typeInferrer,
+    super.libraryDeclarationsResolver, {
     super.parentTypeAugmentations,
     super.parentEnumValueAugmentations,
     super.parentLibraryAugmentations,
@@ -292,7 +330,8 @@
     super.typeIntrospector,
     super.typeDeclarationResolver,
     super.typeResolver,
-    super.typeInferrer, {
+    super.typeInferrer,
+    super.libraryDeclarationsResolver, {
     super.parentTypeAugmentations,
     super.parentEnumValueAugmentations,
     super.parentLibraryAugmentations,
@@ -323,7 +362,8 @@
     super.typeIntrospector,
     super.typeDeclarationResolver,
     super.typeResolver,
-    super.typeInferrer, {
+    super.typeInferrer,
+    super.libraryDeclarationsResolver, {
     super.parentTypeAugmentations,
     super.parentEnumValueAugmentations,
     super.parentLibraryAugmentations,
@@ -355,7 +395,8 @@
     super.typeIntrospector,
     super.typeDeclarationResolver,
     super.typeResolver,
-    super.typeInferrer, {
+    super.typeInferrer,
+    super.libraryDeclarationsResolver, {
     super.parentTypeAugmentations,
     super.parentEnumValueAugmentations,
     super.parentLibraryAugmentations,
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/execute_macro.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/execute_macro.dart
index c46e35a..70bb7c4 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor/execute_macro.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/execute_macro.dart
@@ -174,7 +174,8 @@
     TypeIntrospector typeIntrospector,
     TypeResolver typeResolver,
     TypeDeclarationResolver typeDeclarationResolver,
-    TypeInferrer typeInferrer) async {
+    TypeInferrer typeInferrer,
+    LibraryDeclarationsResolver libraryDeclarationsResolver) async {
   if (declaration is FunctionDeclaration) {
     if (macro is ConstructorDefinitionMacro &&
         declaration is ConstructorDeclaration) {
@@ -185,7 +186,8 @@
               typeIntrospector,
               typeDeclarationResolver,
               typeResolver,
-              typeInferrer);
+              typeInferrer,
+              libraryDeclarationsResolver);
       await macro.buildDefinitionForConstructor(declaration, builder);
       return builder.result;
     } else {
@@ -195,7 +197,8 @@
           typeIntrospector,
           typeDeclarationResolver,
           typeResolver,
-          typeInferrer);
+          typeInferrer,
+          libraryDeclarationsResolver);
       if (macro is MethodDefinitionMacro && declaration is MethodDeclaration) {
         await macro.buildDefinitionForMethod(
             declaration as MethodDeclarationImpl, builder);
@@ -212,7 +215,8 @@
         typeIntrospector,
         typeDeclarationResolver,
         typeResolver,
-        typeInferrer);
+        typeInferrer,
+        libraryDeclarationsResolver);
     if (macro is FieldDefinitionMacro && declaration is FieldDeclaration) {
       await macro.buildDefinitionForField(declaration, builder);
       return builder.result;
@@ -232,7 +236,8 @@
         typeIntrospector,
         typeDeclarationResolver,
         typeResolver,
-        typeInferrer);
+        typeInferrer,
+        libraryDeclarationsResolver);
     await macro.buildDefinitionForClass(declaration, builder);
     return builder.result;
   } else if (macro is EnumDefinitionMacro && declaration is EnumDeclaration) {
@@ -247,7 +252,8 @@
         typeIntrospector,
         typeDeclarationResolver,
         typeResolver,
-        typeInferrer);
+        typeInferrer,
+        libraryDeclarationsResolver);
     await macro.buildDefinitionForEnum(declaration, builder);
     return builder.result;
   } else if (macro is EnumValueDefinitionMacro &&
@@ -258,7 +264,8 @@
         typeIntrospector,
         typeDeclarationResolver,
         typeResolver,
-        typeInferrer);
+        typeInferrer,
+        libraryDeclarationsResolver);
     await macro.buildDefinitionForEnumValue(declaration, builder);
     return builder.result;
   } else if (macro is MixinDefinitionMacro && declaration is MixinDeclaration) {
@@ -273,7 +280,8 @@
         typeIntrospector,
         typeDeclarationResolver,
         typeResolver,
-        typeInferrer);
+        typeInferrer,
+        libraryDeclarationsResolver);
     await macro.buildDefinitionForMixin(declaration, builder);
     return builder.result;
   }
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/executor_base.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/executor_base.dart
index 65c6b48..85d5694 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor/executor_base.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/executor_base.dart
@@ -188,8 +188,8 @@
               sendResult(serializer);
               break;
             case MessageType.constructorsOfRequest:
-              InterfaceIntrospectionRequest request =
-                  new InterfaceIntrospectionRequest.deserialize(
+              TypeIntrospectorRequest request =
+                  new TypeIntrospectorRequest.deserialize(
                       deserializer, messageType, zoneId);
               TypeIntrospector typeIntrospector =
                   request.typeIntrospector.instance as TypeIntrospector;
@@ -197,7 +197,8 @@
                   requestId: request.id,
                   responseType: MessageType.declarationList,
                   response: new DeclarationList((await typeIntrospector
-                          .constructorsOf(request.type))
+                          .constructorsOf(
+                              request.declaration as IntrospectableType))
                       // TODO: Consider refactoring to avoid the need for this.
                       .cast<ConstructorDeclarationImpl>()),
                   serializationZoneId: zoneId);
@@ -205,9 +206,29 @@
               response.serialize(serializer);
               sendResult(serializer);
               break;
+            case MessageType.topLevelDeclarationsOfRequest:
+              DeclarationsOfRequest request =
+                  new DeclarationsOfRequest.deserialize(deserializer, zoneId);
+              LibraryDeclarationsResolver libraryDeclarationsResolver = request
+                  .libraryDeclarationsResolver
+                  .instance as LibraryDeclarationsResolver;
+              SerializableResponse response = new SerializableResponse(
+                  requestId: request.id,
+                  responseType: MessageType.declarationList,
+                  response: new DeclarationList(// force newline
+                      (await libraryDeclarationsResolver
+                              .topLevelDeclarationsOf(request.library))
+                          // TODO: Consider refactoring to avoid the need for
+                          // this.
+                          .cast<DeclarationImpl>()),
+                  serializationZoneId: zoneId);
+              Serializer serializer = serializerFactory();
+              response.serialize(serializer);
+              sendResult(serializer);
+              break;
             case MessageType.fieldsOfRequest:
-              InterfaceIntrospectionRequest request =
-                  new InterfaceIntrospectionRequest.deserialize(
+              TypeIntrospectorRequest request =
+                  new TypeIntrospectorRequest.deserialize(
                       deserializer, messageType, zoneId);
               TypeIntrospector typeIntrospector =
                   request.typeIntrospector.instance as TypeIntrospector;
@@ -215,7 +236,7 @@
                   requestId: request.id,
                   responseType: MessageType.declarationList,
                   response: new DeclarationList((await typeIntrospector
-                          .fieldsOf(request.type))
+                          .fieldsOf(request.declaration as IntrospectableType))
                       // TODO: Consider refactoring to avoid the need for this.
                       .cast<FieldDeclarationImpl>()),
                   serializationZoneId: zoneId);
@@ -224,8 +245,8 @@
               sendResult(serializer);
               break;
             case MessageType.methodsOfRequest:
-              InterfaceIntrospectionRequest request =
-                  new InterfaceIntrospectionRequest.deserialize(
+              TypeIntrospectorRequest request =
+                  new TypeIntrospectorRequest.deserialize(
                       deserializer, messageType, zoneId);
               TypeIntrospector typeIntrospector =
                   request.typeIntrospector.instance as TypeIntrospector;
@@ -233,7 +254,7 @@
                   requestId: request.id,
                   responseType: MessageType.declarationList,
                   response: new DeclarationList((await typeIntrospector
-                          .methodsOf(request.type))
+                          .methodsOf(request.declaration as IntrospectableType))
                       // TODO: Consider refactoring to avoid the need for this.
                       .cast<MethodDeclarationImpl>()),
                   serializationZoneId: zoneId);
@@ -241,9 +262,9 @@
               response.serialize(serializer);
               sendResult(serializer);
               break;
-            case MessageType.valuesOfRequest:
-              InterfaceIntrospectionRequest request =
-                  new InterfaceIntrospectionRequest.deserialize(
+            case MessageType.typesOfRequest:
+              TypeIntrospectorRequest request =
+                  new TypeIntrospectorRequest.deserialize(
                       deserializer, messageType, zoneId);
               TypeIntrospector typeIntrospector =
                   request.typeIntrospector.instance as TypeIntrospector;
@@ -251,7 +272,25 @@
                   requestId: request.id,
                   responseType: MessageType.declarationList,
                   response: new DeclarationList((await typeIntrospector
-                          .valuesOf(request.type as IntrospectableEnum))
+                          .typesOf(request.declaration as Library))
+                      // TODO: Consider refactoring to avoid the need for this.
+                      .cast<TypeDeclarationImpl>()),
+                  serializationZoneId: zoneId);
+              Serializer serializer = serializerFactory();
+              response.serialize(serializer);
+              sendResult(serializer);
+              break;
+            case MessageType.valuesOfRequest:
+              TypeIntrospectorRequest request =
+                  new TypeIntrospectorRequest.deserialize(
+                      deserializer, messageType, zoneId);
+              TypeIntrospector typeIntrospector =
+                  request.typeIntrospector.instance as TypeIntrospector;
+              SerializableResponse response = new SerializableResponse(
+                  requestId: request.id,
+                  responseType: MessageType.declarationList,
+                  response: new DeclarationList((await typeIntrospector
+                          .valuesOf(request.declaration as IntrospectableEnum))
                       // TODO: Consider refactoring to avoid the need for this.
                       .cast<EnumValueDeclarationImpl>()),
                   serializationZoneId: zoneId);
@@ -314,7 +353,8 @@
           TypeDeclarationResolver typeDeclarationResolver,
           TypeResolver typeResolver,
           TypeIntrospector typeIntrospector,
-          TypeInferrer typeInferrer) =>
+          TypeInferrer typeInferrer,
+          LibraryDeclarationsResolver libraryDeclarationsResolver) =>
       _sendRequest((zoneId) => new ExecuteDefinitionsPhaseRequest(
           macro,
           declaration,
@@ -338,6 +378,10 @@
               instance: typeInferrer,
               id: RemoteInstance.uniqueId,
               kind: RemoteInstanceKind.typeInferrer),
+          new RemoteInstanceImpl(
+              instance: libraryDeclarationsResolver,
+              id: RemoteInstance.uniqueId,
+              kind: RemoteInstanceKind.libraryDeclarationsResolver),
           serializationZoneId: zoneId));
 
   @override
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/introspection_impls.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/introspection_impls.dart
index b1e6f68..4b57086 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor/introspection_impls.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/introspection_impls.dart
@@ -618,8 +618,11 @@
   }
 }
 
+abstract interface class TypeDeclarationImpl
+    implements DeclarationImpl, TypeDeclaration {}
+
 abstract class ParameterizedTypeDeclarationImpl extends DeclarationImpl
-    implements ParameterizedTypeDeclaration {
+    implements ParameterizedTypeDeclaration, TypeDeclarationImpl {
   @override
   final List<TypeParameterDeclarationImpl> typeParameters;
 
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/multi_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/multi_executor.dart
index b8eb740..c6db7d2 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor/multi_executor.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/multi_executor.dart
@@ -119,7 +119,8 @@
           TypeDeclarationResolver typeDeclarationResolver,
           TypeResolver typeResolver,
           TypeIntrospector typeIntrospector,
-          TypeInferrer typeInferrer) =>
+          TypeInferrer typeInferrer,
+          LibraryDeclarationsResolver libraryDeclarationsResolver) =>
       _instanceExecutors[macro]!._withInstance((executor) =>
           executor.executeDefinitionsPhase(
               macro,
@@ -128,7 +129,8 @@
               typeDeclarationResolver,
               typeResolver,
               typeIntrospector,
-              typeInferrer));
+              typeInferrer,
+              libraryDeclarationsResolver));
 
   @override
   Future<MacroExecutionResult> executeTypesPhase(MacroInstanceIdentifier macro,
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/protocol.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/protocol.dart
index 8e47678..22d6942 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor/protocol.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/protocol.dart
@@ -344,6 +344,7 @@
   final RemoteInstanceImpl typeIntrospector;
   final RemoteInstanceImpl typeDeclarationResolver;
   final RemoteInstanceImpl typeInferrer;
+  final RemoteInstanceImpl libraryDeclarationsResolver;
 
   ExecuteDefinitionsPhaseRequest(
       this.macro,
@@ -353,6 +354,7 @@
       this.typeIntrospector,
       this.typeDeclarationResolver,
       this.typeInferrer,
+      this.libraryDeclarationsResolver,
       {required super.serializationZoneId});
 
   /// When deserializing we have already consumed the message type, so we don't
@@ -366,6 +368,7 @@
         typeIntrospector = RemoteInstance.deserialize(deserializer),
         typeDeclarationResolver = RemoteInstance.deserialize(deserializer),
         typeInferrer = RemoteInstance.deserialize(deserializer),
+        libraryDeclarationsResolver = RemoteInstance.deserialize(deserializer),
         super.deserialize();
 
   @override
@@ -378,6 +381,7 @@
     typeIntrospector.serialize(serializer);
     typeDeclarationResolver.serialize(serializer);
     typeInferrer.serialize(serializer);
+    libraryDeclarationsResolver.serialize(serializer);
 
     super.serialize(serializer);
   }
@@ -504,27 +508,27 @@
 
 /// A general request class for all requests coming from methods on the
 /// [TypeIntrospector] interface.
-class InterfaceIntrospectionRequest extends Request {
-  final IntrospectableType type;
+class TypeIntrospectorRequest extends Request {
+  final Object declaration;
   final RemoteInstanceImpl typeIntrospector;
   final MessageType requestKind;
 
-  InterfaceIntrospectionRequest(
-      this.type, this.typeIntrospector, this.requestKind,
+  TypeIntrospectorRequest(
+      this.declaration, this.typeIntrospector, this.requestKind,
       {required super.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.
-  InterfaceIntrospectionRequest.deserialize(
+  TypeIntrospectorRequest.deserialize(
       Deserializer deserializer, this.requestKind, int serializationZoneId)
-      : type = RemoteInstance.deserialize(deserializer),
+      : declaration = RemoteInstance.deserialize(deserializer),
         typeIntrospector = RemoteInstance.deserialize(deserializer),
         super.deserialize(deserializer, serializationZoneId);
 
   @override
   void serialize(Serializer serializer) {
     serializer.addInt(requestKind.index);
-    (type as Serializable).serialize(serializer);
+    (declaration as Serializable).serialize(serializer);
     typeIntrospector.serialize(serializer);
     super.serialize(serializer);
   }
@@ -580,6 +584,31 @@
   }
 }
 
+/// A request to get all the top level [Declaration]s in a [Library].
+class DeclarationsOfRequest extends Request {
+  final LibraryImpl library;
+  final RemoteInstanceImpl libraryDeclarationsResolver;
+
+  DeclarationsOfRequest(this.library, this.libraryDeclarationsResolver,
+      {required super.serializationZoneId});
+
+  /// When deserializing we have already consumed the message type, so we don't
+  /// consume it again.
+  DeclarationsOfRequest.deserialize(
+      super.deserializer, super.serializationZoneId)
+      : library = RemoteInstance.deserialize(deserializer),
+        libraryDeclarationsResolver = RemoteInstance.deserialize(deserializer),
+        super.deserialize();
+
+  @override
+  void serialize(Serializer serializer) {
+    serializer.addInt(MessageType.topLevelDeclarationsOfRequest.index);
+    library.serialize(serializer);
+    libraryDeclarationsResolver.serialize(serializer);
+    super.serialize(serializer);
+  }
+}
+
 /// Client side implementation of an [IdentifierResolver], which creates a
 /// [ResolveIdentifierRequest] and passes it to a given [_sendRequest] function
 /// which can return the [Response].
@@ -700,7 +729,7 @@
   @override
   Future<List<ConstructorDeclaration>> constructorsOf(
       IntrospectableType type) async {
-    InterfaceIntrospectionRequest request = new InterfaceIntrospectionRequest(
+    TypeIntrospectorRequest request = new TypeIntrospectorRequest(
         type, remoteInstance, MessageType.constructorsOfRequest,
         serializationZoneId: serializationZoneId);
     return _handleResponse<DeclarationList>(await sendRequest(request))
@@ -712,7 +741,7 @@
   @override
   Future<List<EnumValueDeclaration>> valuesOf(
       IntrospectableEnum enumType) async {
-    InterfaceIntrospectionRequest request = new InterfaceIntrospectionRequest(
+    TypeIntrospectorRequest request = new TypeIntrospectorRequest(
         enumType, remoteInstance, MessageType.valuesOfRequest,
         serializationZoneId: serializationZoneId);
     return _handleResponse<DeclarationList>(await sendRequest(request))
@@ -723,7 +752,7 @@
 
   @override
   Future<List<FieldDeclaration>> fieldsOf(IntrospectableType type) async {
-    InterfaceIntrospectionRequest request = new InterfaceIntrospectionRequest(
+    TypeIntrospectorRequest request = new TypeIntrospectorRequest(
         type, remoteInstance, MessageType.fieldsOfRequest,
         serializationZoneId: serializationZoneId);
     return _handleResponse<DeclarationList>(await sendRequest(request))
@@ -734,7 +763,7 @@
 
   @override
   Future<List<MethodDeclaration>> methodsOf(IntrospectableType type) async {
-    InterfaceIntrospectionRequest request = new InterfaceIntrospectionRequest(
+    TypeIntrospectorRequest request = new TypeIntrospectorRequest(
         type, remoteInstance, MessageType.methodsOfRequest,
         serializationZoneId: serializationZoneId);
     return _handleResponse<DeclarationList>(await sendRequest(request))
@@ -742,6 +771,17 @@
         // TODO: Refactor so we can remove this cast
         .cast();
   }
+
+  @override
+  Future<List<TypeDeclaration>> typesOf(Library library) async {
+    TypeIntrospectorRequest request = new TypeIntrospectorRequest(
+        library, remoteInstance, MessageType.typesOfRequest,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<DeclarationList>(await sendRequest(request))
+        .declarations
+        // TODO: Refactor so we can remove this cast.
+        .cast();
+  }
 }
 
 /// Client side implementation of a [TypeDeclarationResolver], converts all
@@ -794,6 +834,32 @@
   }
 }
 
+/// Client side implementation of a [LibraryDeclarationsResolver], converts all
+/// invocations into remote procedure calls.
+class ClientLibraryDeclarationsResolver implements LibraryDeclarationsResolver {
+  /// The actual remote instance of this library declarations resolver.
+  final RemoteInstanceImpl remoteInstance;
+
+  /// The ID of the zone in which to find the original type resolver.
+  final int serializationZoneId;
+
+  /// A function that can send a request and return a response using an
+  /// arbitrary communication channel.
+  final Future<Response> Function(Request request) sendRequest;
+
+  ClientLibraryDeclarationsResolver(this.sendRequest,
+      {required this.remoteInstance, required this.serializationZoneId});
+
+  @override
+  Future<List<Declaration>> topLevelDeclarationsOf(LibraryImpl library) async {
+    DeclarationsOfRequest request = new DeclarationsOfRequest(
+        library, remoteInstance,
+        serializationZoneId: serializationZoneId);
+    return _handleResponse<DeclarationList>(await sendRequest(request))
+        .declarations;
+  }
+}
+
 /// An exception that occurred remotely, the exception object and stack trace
 /// are serialized as [String]s and both included in the [toString] output.
 class RemoteException implements Exception {
@@ -846,4 +912,6 @@
   namedStaticType,
   response,
   staticType,
+  topLevelDeclarationsOfRequest,
+  typesOfRequest,
 }
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/remote_instance.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/remote_instance.dart
index 8f70b1b..fb2e565 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor/remote_instance.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/remote_instance.dart
@@ -113,6 +113,7 @@
   introspectableEnumDeclaration,
   introspectableMixinDeclaration,
   library,
+  libraryDeclarationsResolver,
   methodDeclaration,
   mixinDeclaration,
   namedStaticType,
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/serialization_extensions.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/serialization_extensions.dart
index 0815f9f..c9e5347 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor/serialization_extensions.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/serialization_extensions.dart
@@ -19,6 +19,7 @@
     final RemoteInstance instance = switch (kind) {
       RemoteInstanceKind.typeIntrospector ||
       RemoteInstanceKind.identifierResolver ||
+      RemoteInstanceKind.libraryDeclarationsResolver ||
       RemoteInstanceKind.namedStaticType ||
       RemoteInstanceKind.staticType ||
       RemoteInstanceKind.typeDeclarationResolver ||
diff --git a/pkg/_fe_analyzer_shared/test/macros/executor/executor_test.dart b/pkg/_fe_analyzer_shared/test/macros/executor/executor_test.dart
index 39652d4..0e4b455 100644
--- a/pkg/_fe_analyzer_shared/test/macros/executor/executor_test.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/executor/executor_test.dart
@@ -398,7 +398,18 @@
                     equalsIgnoringWhitespace('''
                 static const List<String> fieldNames = ['myField',];
               '''));
-                expect(result.libraryAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations
+                        .map((code) => code.debugString().toString())
+                        .toList(),
+                    [
+                      equalsIgnoringWhitespace(
+                          "const library = 'package:foo/bar.dart';"),
+                      equalsIgnoringWhitespace(
+                          "const languageVersion = '3.0';"),
+                      equalsIgnoringWhitespace("const definedTypes = "
+                          "['MyClass','MyEnum','MyMixin',];"),
+                    ]);
               });
 
               test('on enums', () async {
@@ -472,7 +483,8 @@
                     Fixtures.testTypeDeclarationResolver,
                     Fixtures.testTypeResolver,
                     Fixtures.testTypeIntrospector,
-                    Fixtures.testTypeInferrer);
+                    Fixtures.testTypeInferrer,
+                    Fixtures.testLibraryDeclarationsResolver);
                 expect(result.enumValueAugmentations, isEmpty);
                 expect(result.typeAugmentations, isEmpty);
                 expect(
@@ -496,7 +508,8 @@
                     Fixtures.testTypeDeclarationResolver,
                     Fixtures.testTypeResolver,
                     Fixtures.testTypeIntrospector,
-                    Fixtures.testTypeInferrer);
+                    Fixtures.testTypeInferrer,
+                    Fixtures.testLibraryDeclarationsResolver);
                 expect(definitionResult.enumValueAugmentations, isEmpty);
                 expect(definitionResult.typeAugmentations, hasLength(1));
                 var augmentationStrings = definitionResult
@@ -516,7 +529,8 @@
                     Fixtures.testTypeDeclarationResolver,
                     Fixtures.testTypeResolver,
                     Fixtures.testTypeIntrospector,
-                    Fixtures.testTypeInferrer);
+                    Fixtures.testTypeInferrer,
+                    Fixtures.testLibraryDeclarationsResolver);
                 expect(definitionResult.enumValueAugmentations, isEmpty);
                 expect(definitionResult.typeAugmentations, hasLength(1));
                 expect(
@@ -537,7 +551,8 @@
                     Fixtures.testTypeDeclarationResolver,
                     Fixtures.testTypeResolver,
                     Fixtures.testTypeIntrospector,
-                    Fixtures.testTypeInferrer);
+                    Fixtures.testTypeInferrer,
+                    Fixtures.testLibraryDeclarationsResolver);
                 expect(result.enumValueAugmentations, isEmpty);
                 expect(result.typeAugmentations, isEmpty);
                 expect(
@@ -561,7 +576,8 @@
                     Fixtures.testTypeDeclarationResolver,
                     Fixtures.testTypeResolver,
                     Fixtures.testTypeIntrospector,
-                    Fixtures.testTypeInferrer);
+                    Fixtures.testTypeInferrer,
+                    Fixtures.testLibraryDeclarationsResolver);
                 expect(result.enumValueAugmentations, isEmpty);
                 expect(result.typeAugmentations, isEmpty);
                 expect(
@@ -586,7 +602,8 @@
                     Fixtures.testTypeDeclarationResolver,
                     Fixtures.testTypeResolver,
                     Fixtures.testTypeIntrospector,
-                    Fixtures.testTypeInferrer);
+                    Fixtures.testTypeInferrer,
+                    Fixtures.testLibraryDeclarationsResolver);
                 expect(result.enumValueAugmentations, isEmpty);
                 expect(result.typeAugmentations, isEmpty);
                 expect(
@@ -609,6 +626,27 @@
                 augment final /*inferred*/String _myVariable = 'new initial value' + augment super;
                 '''),
                     ]));
+
+                result = await executor.executeDefinitionsPhase(
+                    instanceId,
+                    Fixtures.allDeclarationsVariable,
+                    FakeIdentifierResolver(),
+                    Fixtures.testTypeDeclarationResolver,
+                    Fixtures.testTypeResolver,
+                    Fixtures.testTypeIntrospector,
+                    Fixtures.testTypeInferrer,
+                    Fixtures.testLibraryDeclarationsResolver);
+                expect(result.enumValueAugmentations, isEmpty);
+                expect(result.typeAugmentations, isEmpty);
+                expect(
+                    result.libraryAugmentations
+                        .map((a) => a.debugString().toString()),
+                    unorderedEquals([
+                      equalsIgnoringWhitespace(
+                          "augment final List<String> allLibraryDeclarations = "
+                          "['MyClass','MyEnum','MyMixin','myFunction',"
+                          "'_myVariable',];"),
+                    ]));
               });
 
               test('on fields', () async {
@@ -619,7 +657,8 @@
                     Fixtures.testTypeDeclarationResolver,
                     Fixtures.testTypeResolver,
                     Fixtures.testTypeIntrospector,
-                    Fixtures.testTypeInferrer);
+                    Fixtures.testTypeInferrer,
+                    Fixtures.testLibraryDeclarationsResolver);
                 expect(definitionResult.enumValueAugmentations, isEmpty);
                 expect(definitionResult.typeAugmentations, hasLength(1));
                 expect(
@@ -638,7 +677,8 @@
                     Fixtures.testTypeDeclarationResolver,
                     Fixtures.testTypeResolver,
                     Fixtures.testTypeIntrospector,
-                    Fixtures.testTypeInferrer);
+                    Fixtures.testTypeInferrer,
+                    Fixtures.testLibraryDeclarationsResolver);
                 expect(definitionResult.enumValueAugmentations, isEmpty);
                 expect(definitionResult.typeAugmentations, hasLength(1));
                 var augmentationStrings = definitionResult
@@ -662,7 +702,8 @@
                     Fixtures.testTypeDeclarationResolver,
                     Fixtures.testTypeResolver,
                     Fixtures.testTypeIntrospector,
-                    Fixtures.testTypeInferrer);
+                    Fixtures.testTypeInferrer,
+                    Fixtures.testLibraryDeclarationsResolver);
                 expect(definitionResult.enumValueAugmentations, hasLength(1));
                 var entryAugmentationStrings = definitionResult
                     .enumValueAugmentations[Fixtures.myEnum.identifier]!
@@ -701,7 +742,8 @@
                     Fixtures.testTypeDeclarationResolver,
                     Fixtures.testTypeResolver,
                     Fixtures.testTypeIntrospector,
-                    Fixtures.testTypeInferrer);
+                    Fixtures.testTypeInferrer,
+                    Fixtures.testLibraryDeclarationsResolver);
                 expect(definitionResult.enumValueAugmentations, hasLength(1));
                 var augmentationStrings = definitionResult
                     .enumValueAugmentations[Fixtures.myEnum.identifier]!
@@ -720,7 +762,8 @@
                     Fixtures.testTypeDeclarationResolver,
                     Fixtures.testTypeResolver,
                     Fixtures.testTypeIntrospector,
-                    Fixtures.testTypeInferrer);
+                    Fixtures.testTypeInferrer,
+                    Fixtures.testLibraryDeclarationsResolver);
                 expect(definitionResult.enumValueAugmentations, isEmpty);
                 expect(definitionResult.typeAugmentations, hasLength(1));
                 var augmentationStrings = definitionResult
diff --git a/pkg/_fe_analyzer_shared/test/macros/executor/simple_macro.dart b/pkg/_fe_analyzer_shared/test/macros/executor/simple_macro.dart
index d90c8fc..e58960e 100644
--- a/pkg/_fe_analyzer_shared/test/macros/executor/simple_macro.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/executor/simple_macro.dart
@@ -75,6 +75,21 @@
       for (var field in fields) "'${field.identifier.name}',",
       '];',
     ]));
+
+    // TODO: Do this in `buildDeclarationsForLibrary` once that exists.
+    var languageVersion = clazz.library.languageVersion;
+    builder.declareInLibrary(
+        DeclarationCode.fromString("const library = '${clazz.library.uri}';"));
+    builder.declareInLibrary(DeclarationCode.fromString(
+      'const languageVersion = '
+      "'${languageVersion.major}.${languageVersion.minor}';",
+    ));
+    var libraryTypes = await builder.typesOf(clazz.library);
+    builder.declareInLibrary(DeclarationCode.fromParts([
+      'const definedTypes = [',
+      for (var type in libraryTypes) "'${type.identifier.name}',",
+      '];',
+    ]));
   }
 
   @override
@@ -403,31 +418,43 @@
   @override
   Future<void> buildDefinitionForVariable(
       VariableDeclaration variable, VariableDefinitionBuilder builder) async {
-    var definingClass =
-        variable is FieldDeclaration ? variable.definingType.name : '';
-    builder.augment(
-      getter: DeclarationCode.fromParts([
-        variable.type.code,
-        ' get ',
-        variable.identifier.name,
-        ''' {
+    if (variable.identifier.name == 'allLibraryDeclarations') {
+      var allDeclarations =
+          await builder.topLevelDeclarationsOf(variable.library);
+      builder.augment(
+          initializer: ExpressionCode.fromParts([
+        '[',
+        for (var declaration in allDeclarations)
+          "'${declaration.identifier.name}',",
+        ']',
+      ]));
+    } else {
+      var definingClass =
+          variable is FieldDeclaration ? variable.definingType.name : '';
+      builder.augment(
+        getter: DeclarationCode.fromParts([
+          variable.type.code,
+          ' get ',
+          variable.identifier.name,
+          ''' {
           print('parentClass: $definingClass');
           print('isExternal: ${variable.isExternal}');
           print('isFinal: ${variable.isFinal}');
           print('isLate: ${variable.isLate}');
           return augment super;
         }''',
-      ]),
-      setter: DeclarationCode.fromParts([
-        'set ',
-        variable.identifier.name,
-        '(',
-        variable.type.code,
-        ' value) { augment super = value; }'
-      ]),
-      initializer:
-          ExpressionCode.fromString("'new initial value' + augment super"),
-    );
+        ]),
+        setter: DeclarationCode.fromParts([
+          'set ',
+          variable.identifier.name,
+          '(',
+          variable.type.code,
+          ' value) { augment super = value; }'
+        ]),
+        initializer:
+            ExpressionCode.fromString("'new initial value' + augment super"),
+      );
+    }
   }
 
   @override
diff --git a/pkg/_fe_analyzer_shared/test/macros/util.dart b/pkg/_fe_analyzer_shared/test/macros/util.dart
index 2781403..2ffacce 100644
--- a/pkg/_fe_analyzer_shared/test/macros/util.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/util.dart
@@ -19,12 +19,14 @@
   final Map<IntrospectableEnum, List<EnumValueDeclaration>> enumValues;
   final Map<IntrospectableType, List<FieldDeclaration>> fields;
   final Map<IntrospectableType, List<MethodDeclaration>> methods;
+  final Map<Library, List<TypeDeclaration>> libraryTypes;
 
   TestTypeIntrospector({
     required this.constructors,
     required this.enumValues,
     required this.fields,
     required this.methods,
+    required this.libraryTypes,
   });
 
   @override
@@ -46,6 +48,10 @@
   Future<List<MethodDeclaration>> methodsOf(
           covariant IntrospectableType clazz) async =>
       methods[clazz]!;
+
+  @override
+  Future<List<TypeDeclaration>> typesOf(covariant Library library) async =>
+      libraryTypes[library]!;
 }
 
 class FakeIdentifierResolver implements IdentifierResolver {
@@ -138,6 +144,17 @@
             kind: kind, name: name, staticScope: staticScope, uri: uri);
 }
 
+class TestLibraryDeclarationsResolver implements LibraryDeclarationsResolver {
+  final Map<Library, List<Declaration>> libraryDeclarations;
+
+  TestLibraryDeclarationsResolver(this.libraryDeclarations);
+
+  @override
+  Future<List<Declaration>> topLevelDeclarationsOf(
+          covariant Library library) async =>
+      libraryDeclarations[library]!;
+}
+
 extension DebugCodeString on Code {
   StringBuffer debugString([StringBuffer? buffer]) {
     buffer ??= StringBuffer();
@@ -376,6 +393,20 @@
       returnType: voidType,
       typeParameters: []);
 
+  static final allDeclarationsVariable = VariableDeclarationImpl(
+      id: RemoteInstance.uniqueId,
+      identifier: IdentifierImpl(
+          id: RemoteInstance.uniqueId, name: 'allLibraryDeclarations'),
+      library: Fixtures.library,
+      isExternal: false,
+      isFinal: true,
+      isLate: false,
+      type: NamedTypeAnnotationImpl(
+          id: RemoteInstance.uniqueId,
+          isNullable: false,
+          identifier: IdentifierImpl(id: RemoteInstance.uniqueId, name: 'List'),
+          typeArguments: [stringType]));
+
   // Class and member declarations
   static final myInterfaceType = NamedTypeAnnotationImpl(
       id: RemoteInstance.uniqueId,
@@ -575,26 +606,27 @@
         TestNamedStaticType(stringType.identifier, 'dart:core', []),
     myClass.identifier: myClassStaticType,
   });
-  static final testTypeIntrospector = TestTypeIntrospector(
-    constructors: {
-      myClass: [myConstructor],
-      myEnum: [myEnumConstructor],
-      myMixin: [],
-    },
-    enumValues: {
-      myEnum: myEnumValues,
-    },
-    fields: {
-      myClass: [myField],
-      myMixin: [],
-      myEnum: [],
-    },
-    methods: {
-      myClass: [myMethod],
-      myMixin: [myMixinMethod],
-      myEnum: [],
-    },
-  );
+  static final testTypeIntrospector = TestTypeIntrospector(constructors: {
+    myClass: [myConstructor],
+    myEnum: [myEnumConstructor],
+    myMixin: [],
+  }, enumValues: {
+    myEnum: myEnumValues,
+  }, fields: {
+    myClass: [myField],
+    myMixin: [],
+    myEnum: [],
+  }, methods: {
+    myClass: [myMethod],
+    myMixin: [myMixinMethod],
+    myEnum: [],
+  }, libraryTypes: {
+    Fixtures.library: [
+      myClass,
+      myEnum,
+      myMixin,
+    ],
+  });
   static final testTypeDeclarationResolver = TestTypeDeclarationResolver({
     myClass.identifier: myClass,
     myEnum.identifier: myEnum,
@@ -604,4 +636,15 @@
   });
 
   static final testTypeInferrer = TestTypeInferrer();
+
+  static final testLibraryDeclarationsResolver =
+      TestLibraryDeclarationsResolver({
+    Fixtures.library: [
+      myClass,
+      myEnum,
+      myMixin,
+      myFunction,
+      myVariable,
+    ],
+  });
 }
diff --git a/pkg/analyzer/lib/src/summary2/macro_application.dart b/pkg/analyzer/lib/src/summary2/macro_application.dart
index 2c75ac9..5f8ce68 100644
--- a/pkg/analyzer/lib/src/summary2/macro_application.dart
+++ b/pkg/analyzer/lib/src/summary2/macro_application.dart
@@ -680,6 +680,12 @@
   }
 
   @override
+  Future<List<macro.TypeDeclaration>> typesOf(covariant macro.Library library) {
+    // TODO: implement typesOf
+    throw UnimplementedError();
+  }
+
+  @override
   Future<List<macro.EnumValueDeclaration>> valuesOf(
       covariant macro.IntrospectableEnum type) {
     // TODO: implement valuesOf
diff --git a/pkg/front_end/lib/src/fasta/kernel/macro/macro.dart b/pkg/front_end/lib/src/fasta/kernel/macro/macro.dart
index 8ca9058..c61aa00 100644
--- a/pkg/front_end/lib/src/fasta/kernel/macro/macro.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/macro/macro.dart
@@ -713,7 +713,8 @@
                 typeDeclarationResolver,
                 typeResolver,
                 typeIntrospector,
-                typeInferrer);
+                typeInferrer,
+                libraryDeclarationsResolver);
         if (result.isNotEmpty) {
           results.add(result);
         }
@@ -727,9 +728,11 @@
   }
 
   late macro.TypeInferrer typeInferrer;
+  late macro.LibraryDeclarationsResolver libraryDeclarationsResolver;
 
   Future<List<SourceLibraryBuilder>> applyDefinitionMacros() async {
     typeInferrer = new _TypeInferrer(this);
+    libraryDeclarationsResolver = new _LibraryDeclarationsResolver();
     List<SourceLibraryBuilder> augmentationLibraries = [];
     for (MapEntry<SourceLibraryBuilder, LibraryMacroApplicationData> entry
         in libraryData.entries) {
@@ -1332,6 +1335,12 @@
     }
     return new Future.value(result);
   }
+
+  @override
+  Future<List<macro.TypeDeclaration>> typesOf(covariant macro.Library library) {
+    // TODO: implement typesOf
+    throw new UnimplementedError();
+  }
 }
 
 class _TypeDeclarationResolver implements macro.TypeDeclarationResolver {
@@ -1360,6 +1369,16 @@
       new Future.value(_macroApplications._inferOmittedType(omittedType));
 }
 
+class _LibraryDeclarationsResolver
+    implements macro.LibraryDeclarationsResolver {
+  @override
+  Future<List<macro.Declaration>> topLevelDeclarationsOf(
+      macro.Library library) {
+    // TODO: implement topLevelDeclarationsOf
+    throw new UnimplementedError();
+  }
+}
+
 macro.DeclarationKind _declarationKind(macro.Declaration declaration) {
   if (declaration is macro.ConstructorDeclaration) {
     return macro.DeclarationKind.constructor;
diff --git a/pkg/front_end/test/macros/declaration/macro_declaration_test.dart b/pkg/front_end/test/macros/declaration/macro_declaration_test.dart
index 2146301..c5c7375 100644
--- a/pkg/front_end/test/macros/declaration/macro_declaration_test.dart
+++ b/pkg/front_end/test/macros/declaration/macro_declaration_test.dart
@@ -318,7 +318,8 @@
       TypeDeclarationResolver typeDeclarationResolver,
       TypeResolver typeResolver,
       TypeIntrospector typeIntrospector,
-      TypeInferrer typeInferrer) async {
+      TypeInferrer typeInferrer,
+      LibraryDeclarationsResolver libraryDeclarationsResolver) async {
     return new _MacroExecutionResult();
   }