@@ -60,6 +60,9 @@ abstract class AugmentationFileStateKind extends LibraryOrAugmentationFileKind {
6060 // TODO(scheglov): implement asLibrary
6161 throw UnimplementedError ();
6262 }
63+
64+ /// Returns `true` if the `library augment` directive confirms [container] .
65+ bool isAugmentationOf (LibraryOrAugmentationFileKind container);
6366}
6467
6568/// The URI of the [directive] can be resolved.
@@ -100,6 +103,11 @@ class AugmentationKnownFileStateKind extends AugmentationFileStateKind {
100103 }
101104 return null ;
102105 }
106+
107+ @override
108+ bool isAugmentationOf (LibraryOrAugmentationFileKind container) {
109+ return uriFile == container.file;
110+ }
103111}
104112
105113/// The URI of the [directive] can not be resolved.
@@ -111,6 +119,9 @@ class AugmentationUnknownFileStateKind extends AugmentationFileStateKind {
111119
112120 @override
113121 LibraryFileStateKind ? get library => null ;
122+
123+ @override
124+ bool isAugmentationOf (LibraryOrAugmentationFileKind container) => false ;
114125}
115126
116127/// Information about a single `import` directive.
@@ -278,7 +289,6 @@ class FileState {
278289 /// Files that reference this file.
279290 final Set <FileState > referencingFiles = {};
280291
281- List <FileState ?> _augmentationFiles = [];
282292 List <FileState ?>? _importedFiles;
283293 List <FileState ?>? _exportedFiles;
284294
@@ -306,11 +316,6 @@ class FileState {
306316 /// The unlinked API signature of the file.
307317 Uint8List get apiSignature => _apiSignature! ;
308318
309- /// The list of imported augmentations.
310- List <FileState ?> get augmentationFiles {
311- return _augmentationFiles;
312- }
313-
314319 /// The content of the file.
315320 String get content => _fileContent! .content;
316321
@@ -568,7 +573,6 @@ class FileState {
568573
569574 // Read parts eagerly to link parts to libraries.
570575 _updateKind ();
571- _updateAugmentationFiles ();
572576
573577 // Update mapping from subtyped names to files.
574578 for (var name in _driverUnlinkedUnit! .subtypedNames) {
@@ -743,23 +747,10 @@ class FileState {
743747 }
744748 }
745749
746- removeForOne (_augmentationFiles);
747750 removeForOne (_exportedFiles);
748751 removeForOne (_importedFiles);
749752 }
750753
751- void _updateAugmentationFiles () {
752- _augmentationFiles = unlinked2.augmentations.map ((directive) {
753- return _fileForRelativeUri (directive.uri).map (
754- (augmentation) {
755- augmentation? .referencingFiles.add (this );
756- return augmentation;
757- },
758- (_) => null ,
759- );
760- }).toList ();
761- }
762-
763754 void _updateKind () {
764755 _kind? .dispose ();
765756
@@ -1026,6 +1017,7 @@ abstract class FileStateKind {
10261017 /// Returns the library in which this file should be analyzed.
10271018 LibraryFileStateKind ? get library;
10281019
1020+ @mustCallSuper
10291021 void dispose () {}
10301022}
10311023
@@ -1502,6 +1494,47 @@ class FileUriProperties {
15021494 bool get isSrc => (_flags & _isSrc) != 0 ;
15031495}
15041496
1497+ /// Information about a single `import augment` directive.
1498+ class ImportAugmentationDirectiveState {
1499+ final LibraryOrAugmentationFileKind container;
1500+ final UnlinkedImportAugmentationDirective directive;
1501+
1502+ ImportAugmentationDirectiveState ({
1503+ required this .container,
1504+ required this .directive,
1505+ });
1506+
1507+ /// Returns a [Source] that is referenced by this directive.
1508+ ///
1509+ /// Returns `null` if the URI cannot be resolved into a [Source] .
1510+ Source ? get importedSource => null ;
1511+ }
1512+
1513+ /// [PartDirectiveState] that has a valid URI that references a file.
1514+ class ImportAugmentationDirectiveWithFile
1515+ extends ImportAugmentationDirectiveState {
1516+ final FileState importedFile;
1517+
1518+ ImportAugmentationDirectiveWithFile ({
1519+ required super .container,
1520+ required super .directive,
1521+ required this .importedFile,
1522+ });
1523+
1524+ /// If [importedFile] is a [AugmentationFileStateKind] , and it confirms that
1525+ /// it is an augmentation of the [container] , returns the [importedFile] .
1526+ AugmentationFileStateKind ? get importedAugmentation {
1527+ final kind = importedFile.kind;
1528+ if (kind is AugmentationFileStateKind && kind.isAugmentationOf (container)) {
1529+ return kind;
1530+ }
1531+ return null ;
1532+ }
1533+
1534+ @override
1535+ Source ? get importedSource => importedFile.source;
1536+ }
1537+
15051538/// Information about a single `import` directive.
15061539class ImportDirectiveState {
15071540 final UnlinkedNamespaceDirective directive;
@@ -1673,23 +1706,7 @@ class LibraryFileStateKind extends LibraryOrAugmentationFileKind {
16731706 }
16741707 }
16751708
1676- final imports = _imports;
1677- if (imports != null ) {
1678- for (final import in imports) {
1679- if (import is ImportDirectiveWithFile ) {
1680- import.importedFile.referencingFiles.remove (file);
1681- }
1682- }
1683- }
1684-
1685- final exports = _exports;
1686- if (exports != null ) {
1687- for (final export in exports) {
1688- if (export is ExportDirectiveWithFile ) {
1689- export.exportedFile.referencingFiles.remove (file);
1690- }
1691- }
1692- }
1709+ super .dispose ();
16931710 }
16941711
16951712 bool hasPart (PartFileStateKind partKind) {
@@ -1714,13 +1731,42 @@ class LibraryFileStateKind extends LibraryOrAugmentationFileKind {
17141731}
17151732
17161733abstract class LibraryOrAugmentationFileKind extends FileStateKind {
1734+ List <ImportAugmentationDirectiveState >? _augmentations;
17171735 List <ExportDirectiveState >? _exports;
17181736 List <ImportDirectiveState >? _imports;
17191737
17201738 LibraryOrAugmentationFileKind ({
17211739 required super .file,
17221740 });
17231741
1742+ List <ImportAugmentationDirectiveState > get augmentations {
1743+ return _augmentations ?? = file.unlinked2.augmentations.map ((directive) {
1744+ return file._fileForRelativeUri (directive.uri).map (
1745+ (refFile) {
1746+ if (refFile != null ) {
1747+ refFile.referencingFiles.add (file);
1748+ return ImportAugmentationDirectiveWithFile (
1749+ container: this ,
1750+ directive: directive,
1751+ importedFile: refFile,
1752+ );
1753+ } else {
1754+ return ImportAugmentationDirectiveState (
1755+ container: this ,
1756+ directive: directive,
1757+ );
1758+ }
1759+ },
1760+ (externalLibrary) {
1761+ return ImportAugmentationDirectiveState (
1762+ container: this ,
1763+ directive: directive,
1764+ );
1765+ },
1766+ );
1767+ }).toList ();
1768+ }
1769+
17241770 List <ExportDirectiveState > get exports {
17251771 return _exports ?? = file.unlinked2.exports.map ((directive) {
17261772 final uriStr = file._selectRelativeUri (directive);
@@ -1782,12 +1828,56 @@ abstract class LibraryOrAugmentationFileKind extends FileStateKind {
17821828 /// we register available objects.
17831829 @visibleForTesting
17841830 void discoverReferencedFiles () {
1785- imports;
17861831 exports;
1832+ imports;
1833+ for (final import in augmentations) {
1834+ if (import is ImportAugmentationDirectiveWithFile ) {
1835+ import.importedAugmentation? .discoverReferencedFiles ();
1836+ }
1837+ }
1838+ }
1839+
1840+ @override
1841+ void dispose () {
1842+ final augmentations = _augmentations;
1843+ if (augmentations != null ) {
1844+ for (final import in augmentations) {
1845+ if (import is ImportAugmentationDirectiveWithFile ) {
1846+ import.importedFile.referencingFiles.remove (file);
1847+ }
1848+ }
1849+ }
1850+
1851+ final exports = _exports;
1852+ if (exports != null ) {
1853+ for (final export in exports) {
1854+ if (export is ExportDirectiveWithFile ) {
1855+ export.exportedFile.referencingFiles.remove (file);
1856+ }
1857+ }
1858+ }
1859+
1860+ final imports = _imports;
1861+ if (imports != null ) {
1862+ for (final import in imports) {
1863+ if (import is ImportDirectiveWithFile ) {
1864+ import.importedFile.referencingFiles.remove (file);
1865+ }
1866+ }
1867+ }
1868+
1869+ super .dispose ();
17871870 }
17881871
17891872 bool hasAugmentation (AugmentationFileStateKind augmentation) {
1790- return file.augmentationFiles.contains (augmentation.file);
1873+ for (final import in augmentations) {
1874+ if (import is ImportAugmentationDirectiveWithFile ) {
1875+ if (import.importedFile == augmentation.file) {
1876+ return true ;
1877+ }
1878+ }
1879+ }
1880+ return false ;
17911881 }
17921882}
17931883
0 commit comments