Macro. Test state after macros, add macro generate file when loading bundle.

Change-Id: I8b88f607c18b0700f558b7f75c101a2a59b5409a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/327044
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index dbec019..aa3b650 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -88,7 +88,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 307;
+  static const int DATA_VERSION = 308;
 
   /// The number of exception contexts allowed to write. Once this field is
   /// zero, we stop writing any new exception contexts in this process.
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 6f9bb46..6ffc674 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -403,6 +403,8 @@
 
   FileKind? _kind;
 
+  bool isMacroAugmentation = false;
+
   /// Files that reference this file.
   final Set<FileState> referencingFiles = {};
 
@@ -508,6 +510,7 @@
     if (_fsState._macroFileContent case final macroFileContent?) {
       _fsState._macroFileContent = null;
       rawFileState = macroFileContent;
+      isMacroAugmentation = true;
     } else {
       rawFileState = _fsState.fileContentStrategy.get(path);
     }
@@ -1772,17 +1775,25 @@
     }).toFixedList();
   }
 
-  AugmentationImportWithFile? addOrUpdateMacro(String code) {
+  AugmentationImportWithFile? addOrUpdateMacro(
+    String code, {
+    required bool addLibraryAugmentDirective,
+  }) {
     final pathContext = file._fsState.pathContext;
     final libraryFileName = pathContext.basename(file.path);
     final macroFileName =
         pathContext.setExtension(libraryFileName, '.macro.dart');
 
-    final augmentationContent = '''
+    final String augmentationContent;
+    if (addLibraryAugmentDirective) {
+      augmentationContent = '''
 library augment '$libraryFileName';
 
 $code
 ''';
+    } else {
+      augmentationContent = code;
+    }
 
     final contentBytes = utf8.encoder.convert(augmentationContent);
     final hashBytes = md5.convert(contentBytes).bytes;
@@ -1887,6 +1898,7 @@
       _augmentationImports = augmentationImports.withoutLast.toFixedList();
       // Discard the file.
       final macroFile = macroImport.importedFile;
+      macroFile.kind.dispose();
       file._fsState._pathToFile.remove(macroFile.path);
       file._fsState._uriToFile.remove(macroFile.uri);
     }
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index 245153b..545cff7 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -206,14 +206,14 @@
         // TODO(scheglov) Take / clear parsed units in files.
         bytesGet += linkedBytes.length;
         librariesLoaded += cycle.libraries.length;
-        elementFactory.addBundle(
-          BundleReader(
-            elementFactory: elementFactory,
-            unitsInformativeBytes: unitsInformativeBytes,
-            resolutionBytes: linkedBytes,
-            infoDeclarationStore: infoDeclarationStore,
-          ),
+        final bundleReader = BundleReader(
+          elementFactory: elementFactory,
+          unitsInformativeBytes: unitsInformativeBytes,
+          resolutionBytes: linkedBytes,
+          infoDeclarationStore: infoDeclarationStore,
         );
+        elementFactory.addBundle(bundleReader);
+        _addMacroAugmentations(cycle, bundleReader);
       }
 
       final macroKernelBuilder = this.macroKernelBuilder;
@@ -299,6 +299,23 @@
     return keySet;
   }
 
+  /// Create files with macro generated augmentation libraries.
+  void _addMacroAugmentations(LibraryCycle cycle, BundleReader bundleReader) {
+    for (final libraryReader in bundleReader.libraryMap.values) {
+      final macroGeneratedCode = libraryReader.macroGeneratedCode;
+      if (macroGeneratedCode != null) {
+        for (final libraryKind in cycle.libraries) {
+          if (libraryKind.file.uri == libraryReader.uri) {
+            libraryKind.addOrUpdateMacro(
+              macroGeneratedCode,
+              addLibraryAugmentDirective: false,
+            );
+          }
+        }
+      }
+    }
+  }
+
   /// Ensure that type provider is created.
   void _createElementFactoryTypeProvider() {
     if (!analysisContext.hasTypeProvider) {
@@ -361,15 +378,16 @@
 }
 
 class _MacroFileEntry implements MacroFileEntry {
-  final FileState fileState;
-
-  _MacroFileEntry(this.fileState);
+  @override
+  final String content;
 
   @override
-  String get content => fileState.content;
+  final bool exists;
 
-  @override
-  bool get exists => fileState.exists;
+  _MacroFileEntry({
+    required this.content,
+    required this.exists,
+  });
 }
 
 class _MacroFileSystem implements MacroFileSystem {
@@ -382,7 +400,18 @@
 
   @override
   MacroFileEntry getFile(String path) {
-    var fileState = fileSystemState.getFileForPath(path);
-    return _MacroFileEntry(fileState);
+    final fileState = fileSystemState.getExistingFromPath(path);
+    if (fileState != null) {
+      return _MacroFileEntry(
+        content: fileState.content,
+        exists: fileState.exists,
+      );
+    }
+
+    final fileContent = fileSystemState.fileContentStrategy.get(path);
+    return _MacroFileEntry(
+      content: fileContent.content,
+      exists: fileContent.exists,
+    );
   }
 }
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 11b35b3..84c7722 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -3947,7 +3947,7 @@
   @override
   final LibraryOrAugmentationElementImpl augmentationTarget;
 
-  MacroGenerationAugmentationLibrary? macroGenerated;
+  MacroGeneratedAugmentationLibrary? macroGenerated;
 
   LibraryAugmentationElementLinkedData? linkedData;
 
@@ -4799,11 +4799,11 @@
 }
 
 /// Additional information for a macro generated augmentation library.
-class MacroGenerationAugmentationLibrary {
+class MacroGeneratedAugmentationLibrary {
   final String code;
   final Uint8List informativeBytes;
 
-  MacroGenerationAugmentationLibrary({
+  MacroGeneratedAugmentationLibrary({
     required this.code,
     required this.informativeBytes,
   });
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index ecbd9bf..318a2ce 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -68,6 +68,9 @@
         uri: uriCache.parse(_reader.readStringReference()),
         offset: _reader.readUInt30(),
         classMembersLengths: _reader.readUInt30List(),
+        macroGeneratedCode: _reader.readOptionalObject((reader) {
+          return _reader.readStringUtf8();
+        }),
       );
     });
 
@@ -77,6 +80,7 @@
       libraryMap[uri] = LibraryReader._(
         elementFactory: elementFactory,
         reader: _reader,
+        uri: uri,
         unitsInformativeBytes: _unitsInformativeBytes,
         baseResolutionOffset: baseResolutionOffset,
         referenceReader: referenceReader,
@@ -84,6 +88,7 @@
         offset: libraryHeader.offset,
         classMembersLengths: libraryHeader.classMembersLengths,
         infoDeclarationStore: _infoDeclarationStore,
+        macroGeneratedCode: libraryHeader.macroGeneratedCode,
       );
     }
   }
@@ -527,12 +532,14 @@
 class LibraryReader {
   final LinkedElementFactory _elementFactory;
   final SummaryDataReader _reader;
+  final Uri uri;
   final Map<Uri, Uint8List> _unitsInformativeBytes;
   final int _baseResolutionOffset;
   final _ReferenceReader _referenceReader;
   final Reference _reference;
   final int _offset;
   final InfoDeclarationStore _deserializedDataStore;
+  final String? macroGeneratedCode;
 
   final Uint32List _classMembersLengths;
   int _classMembersLengthsIndex = 0;
@@ -540,6 +547,7 @@
   LibraryReader._({
     required LinkedElementFactory elementFactory,
     required SummaryDataReader reader,
+    required this.uri,
     required Map<Uri, Uint8List> unitsInformativeBytes,
     required int baseResolutionOffset,
     required _ReferenceReader referenceReader,
@@ -547,6 +555,7 @@
     required int offset,
     required Uint32List classMembersLengths,
     required InfoDeclarationStore infoDeclarationStore,
+    required this.macroGeneratedCode,
   })  : _elementFactory = elementFactory,
         _reader = reader,
         _unitsInformativeBytes = unitsInformativeBytes,
@@ -634,7 +643,7 @@
     required Source unitSource,
   }) {
     final macroGenerated = _reader.readOptionalObject((reader) {
-      return MacroGenerationAugmentationLibrary(
+      return MacroGeneratedAugmentationLibrary(
         code: _reader.readStringUtf8(),
         informativeBytes: _reader.readUint8List(),
       );
@@ -2335,10 +2344,14 @@
   /// we need to know how much data to skip for each class.
   final Uint32List classMembersLengths;
 
+  /// The only (if any) macro generated augmentation code.
+  final String? macroGeneratedCode;
+
   _LibraryHeader({
     required this.uri,
     required this.offset,
     required this.classMembersLengths,
+    required this.macroGeneratedCode,
   });
 }
 
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index 4619a84..f64f408 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -84,6 +84,9 @@
       _sink._writeStringReference(library.uriStr);
       _sink.writeUInt30(library.offset);
       _sink.writeUint30List(library.classMembersOffsets);
+      _sink.writeOptionalObject(library.macroGenerated, (it) {
+        _sink.writeStringUtf8(it.code);
+      });
     });
 
     var referencesOffset = _sink.offset;
@@ -130,11 +133,15 @@
 
     _writePropertyAccessorAugmentations();
 
+    final lastAugmentation = libraryElement.augmentations.lastOrNull;
+    final macroGenerated = lastAugmentation?.macroGenerated;
+
     _libraries.add(
       _Library(
         uriStr: '${libraryElement.source.uri}',
         offset: libraryOffset,
         classMembersOffsets: _classMembersLengths,
+        macroGenerated: macroGenerated,
       ),
     );
   }
@@ -1129,10 +1136,14 @@
   final int offset;
   final List<int> classMembersOffsets;
 
+  /// The only (if any) macro generated augmentation.
+  final MacroGeneratedAugmentationLibrary? macroGenerated;
+
   _Library({
     required this.uriStr,
     required this.offset,
     required this.classMembersOffsets,
+    required this.macroGenerated,
   });
 }
 
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 0a27faa..ba68095 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -488,7 +488,10 @@
       return;
     }
 
-    final macroState = kind.addOrUpdateMacro(augmentationCode);
+    final macroState = kind.addOrUpdateMacro(
+      augmentationCode,
+      addLibraryAugmentDirective: true,
+    );
     if (macroState == null) return;
 
     final macroImport = _buildAugmentationImport(element, macroState);
@@ -507,7 +510,7 @@
     ).buildDeclarationElements(macroLinkingUnit.node);
 
     macroImport.importedAugmentation!.macroGenerated =
-        MacroGenerationAugmentationLibrary(
+        MacroGeneratedAugmentationLibrary(
       code: macroState.importedFile.content,
       informativeBytes: macroState.importedFile.unlinked2.informativeBytes,
     );
diff --git a/pkg/analyzer/test/src/dart/analysis/analyzer_state_printer.dart b/pkg/analyzer/test/src/dart/analysis/analyzer_state_printer.dart
index bd5154f..e326fd3 100644
--- a/pkg/analyzer/test/src/dart/analysis/analyzer_state_printer.dart
+++ b/pkg/analyzer/test/src/dart/analysis/analyzer_state_printer.dart
@@ -15,11 +15,16 @@
 import 'package:test/test.dart';
 
 class AnalyzerStatePrinter {
+  static const String _macroApiUriStr =
+      'package:_fe_analyzer_shared/src/macros/api.dart';
+
+  static const String _macroApiUriRewrite = 'package:macro/api.dart';
+
   final MemoryByteStore byteStore;
   final UnlinkedUnitStoreImpl unlinkedUnitStore;
   final IdProvider idProvider;
   final LibraryContext libraryContext;
-  final bool omitSdkFiles;
+  final AnalyzerStatePrinterConfiguration configuration;
   final ResourceProvider resourceProvider;
   final StringSink sink;
   final bool withKeysGetPut;
@@ -32,7 +37,7 @@
     required this.unlinkedUnitStore,
     required this.idProvider,
     required this.libraryContext,
-    required this.omitSdkFiles,
+    required this.configuration,
     required this.resourceProvider,
     required this.sink,
     required this.withKeysGetPut,
@@ -67,7 +72,7 @@
   }
 
   String _stringOfLibraryCycle(LibraryCycle cycle) {
-    if (omitSdkFiles) {
+    if (configuration.omitSdkFiles) {
       final isSdkLibrary = cycle.libraries.any((library) {
         return library.file.uri.isScheme('dart');
       });
@@ -79,6 +84,9 @@
         }
       }
     }
+    if (cycle.libraries.any((e) => e.file.uriStr == _macroApiUriStr)) {
+      return _macroApiUriRewrite;
+    }
     return idProvider.libraryCycle(cycle);
   }
 
@@ -171,12 +179,19 @@
   void _writeFile(FileState file) {
     _withIndent(() {
       _writelnWithIndent('id: ${idProvider.fileState(file)}');
+      _writeFileContent(file);
       _writeFileKind(file);
       _writeReferencingFiles(file);
       _writeFileUnlinkedKey(file);
     });
   }
 
+  void _writeFileContent(FileState file) {
+    if (configuration.filesToPrintContent.any((e) => e.path == file.path)) {
+      _writelnWithIndent('content\n---\n${file.content}---');
+    }
+  }
+
   void _writeFileKind(FileState file) {
     final kind = file.kind;
     expect(kind.file, same(file));
@@ -295,7 +310,7 @@
     fileDataList.sort((first, second) {
       final firstPath = first.file.path;
       final secondPath = second.file.path;
-      if (omitSdkFiles) {
+      if (configuration.omitSdkFiles) {
         final firstUri = first.uri;
         final secondUri = second.uri;
         final firstIsSdk = firstUri.isScheme('dart');
@@ -333,7 +348,10 @@
     _writelnWithIndent('files');
     _withIndent(() {
       for (final fileData in fileDataList) {
-        if (omitSdkFiles && fileData.uri.isScheme('dart')) {
+        if (configuration.omitSdkFiles && fileData.uri.isScheme('dart')) {
+          continue;
+        }
+        if (_isMacroApiUri(fileData.uri)) {
           continue;
         }
         final file = fileData.file;
@@ -368,7 +386,11 @@
     _withIndent(() {
       final cyclesToPrint = <_LibraryCycleToPrint>[];
       for (final entry in testData.libraryCycles.entries) {
-        if (omitSdkFiles && entry.key.any((e) => e.uri.isScheme('dart'))) {
+        if (configuration.omitSdkFiles &&
+            entry.key.any((e) => e.uri.isScheme('dart'))) {
+          continue;
+        }
+        if (entry.key.any((e) => _isMacroApiUri(e.uri))) {
           continue;
         }
         cyclesToPrint.add(
@@ -469,7 +491,7 @@
             sink.write('notLibrary ${idProvider.fileState(file)}');
           }
 
-          if (omitSdkFiles && file.uri.isScheme('dart')) {
+          if (configuration.omitSdkFiles && file.uri.isScheme('dart')) {
             sink.write(' ${file.uri}');
           }
           sink.writeln();
@@ -514,9 +536,12 @@
             sink.write('notLibrary ${idProvider.fileState(file)}');
           }
 
-          if (omitSdkFiles && file.uri.isScheme('dart')) {
+          if (configuration.omitSdkFiles && file.uri.isScheme('dart')) {
             sink.write(' ${file.uri}');
           }
+          if (file.uriStr == _macroApiUriStr) {
+            sink.write(' $_macroApiUriRewrite');
+          }
 
           if (import.isSyntheticDartCore) {
             sink.write(' synthetic');
@@ -617,7 +642,10 @@
   void _writeUriList(String name, Iterable<Uri> uriIterable) {
     final uriStrList = <String>[];
     for (final uri in uriIterable) {
-      if (omitSdkFiles && uri.isScheme('dart')) {
+      if (configuration.omitSdkFiles && uri.isScheme('dart')) {
+        continue;
+      }
+      if ('$uri' == _macroApiUriStr) {
         continue;
       }
       uriStrList.add('$uri');
@@ -633,6 +661,16 @@
       });
     }
   }
+
+  static bool _isMacroApiUri(Uri uri) {
+    return '$uri'.startsWith('package:_fe_analyzer_shared');
+  }
+}
+
+class AnalyzerStatePrinterConfiguration {
+  bool omitSdkFiles = true;
+
+  Set<File> filesToPrintContent = {};
 }
 
 /// Encoder of object identifies into short identifiers.
diff --git a/pkg/analyzer/test/src/dart/micro/file_resolution.dart b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
index 70f4b2b..47dc0ca 100644
--- a/pkg/analyzer/test/src/dart/micro/file_resolution.dart
+++ b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
@@ -41,6 +41,9 @@
 
   final printer.IdProvider _idProvider = printer.IdProvider();
 
+  printer.AnalyzerStatePrinterConfiguration analyzerStatePrinterConfiguration =
+      printer.AnalyzerStatePrinterConfiguration();
+
   FileSystemState get fsState => fileResolver.fsState!;
 
   LibraryContext get libraryContext {
@@ -63,17 +66,14 @@
     newFile(testFile.path, content);
   }
 
-  void assertStateString(
-    String expected, {
-    bool omitSdkFiles = true,
-  }) {
+  void assertStateString(String expected) {
     final buffer = StringBuffer();
     printer.AnalyzerStatePrinter(
       byteStore: byteStore,
       unlinkedUnitStore: fsState.unlinkedUnitStore as UnlinkedUnitStoreImpl,
       idProvider: _idProvider,
       libraryContext: libraryContext,
-      omitSdkFiles: omitSdkFiles,
+      configuration: analyzerStatePrinterConfiguration,
       resourceProvider: resourceProvider,
       sink: buffer,
       withKeysGetPut: true,
diff --git a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
index ce42635..e6b0ff8 100644
--- a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
@@ -136,6 +136,9 @@
   /// Optional summaries to provide for the collection.
   List<File>? librarySummaryFiles;
 
+  AnalyzerStatePrinterConfiguration analyzerStatePrinterConfiguration =
+      AnalyzerStatePrinterConfiguration();
+
   final IdProvider _idProvider = IdProvider();
 
   List<MockSdkLibrary> get additionalMockSdkLibraries => [];
@@ -195,11 +198,7 @@
     expect(workspace, TypeMatcher<BlazeWorkspace>());
   }
 
-  void assertDriverStateString(
-    File file,
-    String expected, {
-    bool omitSdkFiles = true,
-  }) {
+  void assertDriverStateString(File file, String expected) {
     final analysisDriver = driverFor(file);
 
     final buffer = StringBuffer();
@@ -209,7 +208,7 @@
           analysisDriver.fsState.unlinkedUnitStore as UnlinkedUnitStoreImpl,
       idProvider: _idProvider,
       libraryContext: analysisDriver.libraryContext,
-      omitSdkFiles: omitSdkFiles,
+      configuration: analyzerStatePrinterConfiguration,
       resourceProvider: resourceProvider,
       sink: buffer,
       withKeysGetPut: false,
diff --git a/pkg/analyzer/test/src/summary/macro_test.dart b/pkg/analyzer/test/src/summary/macro_test.dart
index b6d29bc..ca8d757 100644
--- a/pkg/analyzer/test/src/summary/macro_test.dart
+++ b/pkg/analyzer/test/src/summary/macro_test.dart
@@ -1326,6 +1326,9 @@
 }
 
 abstract class MacroTypesTest extends MacroElementsBaseTest {
+  @override
+  bool get retainDataForTesting => true;
+
   test_application_newInstance_withoutPrefix() async {
     newFile('$testPackageLibPath/a.dart', r'''
 import 'dart:async';
@@ -1525,17 +1528,24 @@
   }
 
   test_imports_class() async {
+    useEmptyByteStore();
+
     newFile('$testPackageLibPath/a.dart', r'''
+class A {}
+''');
+
+    newFile('$testPackageLibPath/b.dart', r'''
 import 'dart:async';
 import 'package:_fe_analyzer_shared/src/macros/api.dart';
+import 'a.dart';
 
 macro class MyMacro implements ClassTypesMacro {
   const MyMacro();
 
   FutureOr<void> buildTypesForClass(clazz, ClassTypeBuilder builder) async {
     final identifier = await builder.resolveIdentifier(
-      Uri.parse('dart:math'),
-      'Random',
+      Uri.parse('package:test/a.dart'),
+      'A',
     );
     builder.declareType(
       'MyClass',
@@ -1550,10 +1560,10 @@
 ''');
 
     var library = await buildLibrary(r'''
-import 'a.dart';
+import 'b.dart';
 
 @MyMacro()
-class A {}
+class X {}
 ''');
 
     configuration
@@ -1562,34 +1572,299 @@
     checkElementText(library, r'''
 library
   imports
-    package:test/a.dart
+    package:test/b.dart
   definingUnit
     classes
-      class A @35
+      class X @35
   augmentationImports
     package:test/test.macro.dart
       macroGeneratedCode
 ---
 library augment 'test.dart';
 
-import 'dart:math' as prefix0;
+import 'package:test/a.dart' as prefix0;
 
 class MyClass {
-  void foo(prefix0.Random _) {}
+  void foo(prefix0.A _) {}
 }
 ---
       imports
-        dart:math as prefix0 @52
+        package:test/a.dart as prefix0 @62
       definingUnit
         classes
-          class MyClass @68
+          class MyClass @78
             methods
-              foo @85
+              foo @95
                 parameters
-                  requiredPositional _ @104
-                    type: Random
+                  requiredPositional _ @109
+                    type: A
                 returnType: void
 ''');
+
+    analyzerStatePrinterConfiguration.filesToPrintContent.add(
+      getFile('$testPackageLibPath/test.macro.dart'),
+    );
+
+    if (keepLinkingLibraries) {
+      assertDriverStateString(testFile, r'''
+files
+  /home/test/lib/a.dart
+    uri: package:test/a.dart
+    current
+      id: file_0
+      kind: library_0
+        libraryImports
+          library_10 dart:core synthetic
+        cycle_0
+          dependencies: dart:core
+          libraries: library_0
+          apiSignature_0
+          users: cycle_1
+      referencingFiles: file_1 file_3
+      unlinkedKey: k00
+  /home/test/lib/b.dart
+    uri: package:test/b.dart
+    current
+      id: file_1
+      kind: library_1
+        libraryImports
+          library_12 dart:async
+          library_4 package:macro/api.dart
+          library_0
+          library_10 dart:core synthetic
+        cycle_1
+          dependencies: cycle_0 dart:core package:macro/api.dart
+          libraries: library_1
+          apiSignature_1
+          users: cycle_2
+      referencingFiles: file_2
+      unlinkedKey: k01
+  /home/test/lib/test.dart
+    uri: package:test/test.dart
+    current
+      id: file_2
+      kind: library_2
+        libraryImports
+          library_1
+          library_10 dart:core synthetic
+        augmentationImports
+          augmentation_3
+        cycle_2
+          dependencies: cycle_1 dart:core
+          libraries: library_2
+          apiSignature_2
+      unlinkedKey: k02
+  /home/test/lib/test.macro.dart
+    uri: package:test/test.macro.dart
+    current
+      id: file_3
+      content
+---
+library augment 'test.dart';
+
+import 'package:test/a.dart' as prefix0;
+
+class MyClass {
+  void foo(prefix0.A _) {}
+}
+---
+      kind: augmentation_3
+        augmented: library_2
+        library: library_2
+        libraryImports
+          library_0
+          library_10 dart:core synthetic
+      referencingFiles: file_2
+      unlinkedKey: k03
+libraryCycles
+  /home/test/lib/a.dart
+    current: cycle_0
+      key: k04
+    get: []
+    put: [k04]
+  /home/test/lib/b.dart
+    current: cycle_1
+      key: k05
+    get: []
+    put: [k05]
+  /home/test/lib/test.dart
+    current: cycle_2
+      key: k06
+    get: []
+    put: [k06]
+elementFactory
+  hasElement
+    package:test/a.dart
+    package:test/b.dart
+    package:test/test.dart
+''');
+
+      // When we discard the library, we remove its macro file.
+      driverFor(testFile).changeFile(testFile.path);
+      await driverFor(testFile).applyPendingFileChanges();
+      assertDriverStateString(testFile, r'''
+files
+  /home/test/lib/a.dart
+    uri: package:test/a.dart
+    current
+      id: file_0
+      kind: library_0
+        libraryImports
+          library_10 dart:core synthetic
+        cycle_0
+          dependencies: dart:core
+          libraries: library_0
+          apiSignature_0
+          users: cycle_1
+      referencingFiles: file_1
+      unlinkedKey: k00
+  /home/test/lib/b.dart
+    uri: package:test/b.dart
+    current
+      id: file_1
+      kind: library_1
+        libraryImports
+          library_12 dart:async
+          library_4 package:macro/api.dart
+          library_0
+          library_10 dart:core synthetic
+        cycle_1
+          dependencies: cycle_0 dart:core package:macro/api.dart
+          libraries: library_1
+          apiSignature_1
+          users: cycle_6
+      referencingFiles: file_2
+      unlinkedKey: k01
+  /home/test/lib/test.dart
+    uri: package:test/test.dart
+    current
+      id: file_2
+      kind: library_16
+        libraryImports
+          library_1
+          library_10 dart:core synthetic
+        cycle_6
+          dependencies: cycle_1 dart:core
+          libraries: library_16
+          apiSignature_2
+      unlinkedKey: k02
+  /home/test/lib/test.macro.dart
+    uri: package:test/test.macro.dart
+libraryCycles
+  /home/test/lib/a.dart
+    current: cycle_0
+      key: k04
+    get: []
+    put: [k04]
+  /home/test/lib/b.dart
+    current: cycle_1
+      key: k05
+    get: []
+    put: [k05]
+  /home/test/lib/test.dart
+    get: []
+    put: [k06]
+elementFactory
+  hasElement
+    package:test/a.dart
+    package:test/b.dart
+''');
+    } else {
+      assertDriverStateString(testFile, r'''
+files
+  /home/test/lib/a.dart
+    uri: package:test/a.dart
+    current
+      id: file_0
+      kind: library_0
+        libraryImports
+          library_10 dart:core synthetic
+        cycle_0
+          dependencies: dart:core
+          libraries: library_0
+          apiSignature_0
+          users: cycle_1
+      referencingFiles: file_1 file_3
+      unlinkedKey: k00
+  /home/test/lib/b.dart
+    uri: package:test/b.dart
+    current
+      id: file_1
+      kind: library_1
+        libraryImports
+          library_12 dart:async
+          library_4 package:macro/api.dart
+          library_0
+          library_10 dart:core synthetic
+        cycle_1
+          dependencies: cycle_0 dart:core package:macro/api.dart
+          libraries: library_1
+          apiSignature_1
+          users: cycle_2
+      referencingFiles: file_2
+      unlinkedKey: k01
+  /home/test/lib/test.dart
+    uri: package:test/test.dart
+    current
+      id: file_2
+      kind: library_2
+        libraryImports
+          library_1
+          library_10 dart:core synthetic
+        augmentationImports
+          augmentation_3
+        cycle_2
+          dependencies: cycle_1 dart:core
+          libraries: library_2
+          apiSignature_2
+      unlinkedKey: k02
+  /home/test/lib/test.macro.dart
+    uri: package:test/test.macro.dart
+    current
+      id: file_3
+      content
+---
+library augment 'test.dart';
+
+import 'package:test/a.dart' as prefix0;
+
+class MyClass {
+  void foo(prefix0.A _) {}
+}
+---
+      kind: augmentation_3
+        augmented: library_2
+        library: library_2
+        libraryImports
+          library_0
+          library_10 dart:core synthetic
+      referencingFiles: file_2
+      unlinkedKey: k03
+libraryCycles
+  /home/test/lib/a.dart
+    current: cycle_0
+      key: k04
+    get: []
+    put: [k04]
+  /home/test/lib/b.dart
+    current: cycle_1
+      key: k05
+    get: []
+    put: [k05]
+  /home/test/lib/test.dart
+    current: cycle_2
+      key: k06
+    get: [k06]
+    put: [k06]
+elementFactory
+  hasElement
+    package:test/a.dart
+    package:test/b.dart
+    package:test/test.dart
+  hasReader
+    package:test/test.dart
+''');
+    }
   }
 }