Skip to content

Commit fd185c0

Browse files
scheglovCommit Bot
authored andcommitted
Add LibraryOrAugmentationFileKind.augmentations
Change-Id: Id339b36d37ae904693c27173cd606856b0114eec Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/250182 Reviewed-by: Samuel Rawlins <srawlins@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
1 parent 8a0289e commit fd185c0

File tree

3 files changed

+272
-77
lines changed

3 files changed

+272
-77
lines changed

pkg/analyzer/lib/src/dart/analysis/file_state.dart

Lines changed: 129 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
15061539
class 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

17161733
abstract 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

pkg/analyzer/test/src/dart/analysis/analyzer_state_printer.dart

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,31 @@ class AnalyzerStatePrinter {
9292
_indent = indent;
9393
}
9494

95-
/// TODO(scheglov) Support unresolved URIs, not augmentations, etc.
96-
void _writeAugmentations(LibraryOrAugmentationFileKind kind) {
97-
final files = kind.file.augmentationFiles.whereNotNull();
98-
if (files.isNotEmpty) {
99-
final keys = files.map(idProvider.fileState).join(' ');
100-
_writelnWithIndent('augmentations: $keys');
101-
}
95+
void _writeAugmentations(LibraryOrAugmentationFileKind container) {
96+
_writeElements<ImportAugmentationDirectiveState>(
97+
'augmentations',
98+
container.augmentations,
99+
(augmentation) {
100+
expect(augmentation.container, same(container));
101+
if (augmentation is ImportAugmentationDirectiveWithFile) {
102+
final file = augmentation.importedFile;
103+
sink.write(_indent);
104+
105+
final importedAugmentation = augmentation.importedAugmentation;
106+
if (importedAugmentation != null) {
107+
expect(importedAugmentation.file, file);
108+
sink.write(idProvider.fileStateKind(importedAugmentation));
109+
} else {
110+
sink.write('notAugmentation ${idProvider.fileState(file)}');
111+
}
112+
sink.writeln();
113+
} else {
114+
sink.write(_indent);
115+
sink.write('uri: ${_stringOfUriStr(augmentation.directive.uri)}');
116+
sink.writeln();
117+
}
118+
},
119+
);
102120
}
103121

104122
void _writeByteStore() {

0 commit comments

Comments
 (0)