@@ -192,23 +192,54 @@ class FileState {
192
192
193
193
/// Return the set of all directly referenced files - imported, exported or
194
194
/// parted.
195
- Set <FileState > get directReferencedFiles => _directReferencedFiles;
195
+ Set <FileState > get directReferencedFiles {
196
+ return _directReferencedFiles ?? = < FileState > {
197
+ ...importedFiles,
198
+ ...exportedFiles,
199
+ ...partedFiles,
200
+ };
201
+ }
196
202
197
203
/// Return the set of all directly referenced libraries - imported or
198
204
/// exported.
199
- Set <FileState > get directReferencedLibraries => _directReferencedLibraries;
205
+ Set <FileState > get directReferencedLibraries {
206
+ return _directReferencedLibraries ?? = < FileState > {
207
+ ...importedFiles,
208
+ ...exportedFiles,
209
+ };
210
+ }
200
211
201
212
/// Return `true` if the file exists.
202
213
bool get exists => _exists;
203
214
204
215
/// The list of files this file exports.
205
- List <FileState > get exportedFiles => _exportedFiles;
216
+ List <FileState > get exportedFiles {
217
+ if (_exportedFiles == null ) {
218
+ _exportedFiles = < FileState > [];
219
+ for (var directive in _unlinked2.exports) {
220
+ var uri = _selectRelativeUri (directive);
221
+ var file = _fileForRelativeUri (uri);
222
+ _exportedFiles.add (file);
223
+ }
224
+ }
225
+ return _exportedFiles;
226
+ }
206
227
207
228
@override
208
229
int get hashCode => uri.hashCode;
209
230
210
231
/// The list of files this file imports.
211
- List <FileState > get importedFiles => _importedFiles;
232
+ List <FileState > get importedFiles {
233
+ if (_importedFiles == null ) {
234
+ _importedFiles = < FileState > [];
235
+ for (var directive in _unlinked2.imports) {
236
+ var uri = _selectRelativeUri (directive);
237
+ var file = _fileForRelativeUri (uri);
238
+ _importedFiles.add (file);
239
+ }
240
+ }
241
+ return _importedFiles;
242
+ }
212
243
213
244
LibraryCycle get internal_libraryCycle => _libraryCycle;
214
245
@@ -237,6 +268,7 @@ class FileState {
237
268
/// of. Return `null` if a library is not known, for example because we have
238
269
/// not processed a library file yet.
239
270
FileState get library {
271
+ _fsState.readPartsForLibraries ();
240
272
List <FileState > libraries = _fsState._partToLibraries[this ];
241
273
if (libraries == null || libraries.isEmpty) {
242
274
return null ;
@@ -264,13 +296,27 @@ class FileState {
264
296
265
297
/// The list of files files that this library consists of, i.e. this library
266
298
/// file itself and its [partedFiles] .
267
- List <FileState > get libraryFiles => _libraryFiles;
299
+ List <FileState > get libraryFiles {
300
+ return _libraryFiles ?? = [this , ...partedFiles];
301
+ }
268
302
269
303
/// Return information about line in the file.
270
304
LineInfo get lineInfo => _lineInfo;
271
305
272
306
/// The list of files this library file references as parts.
273
- List <FileState > get partedFiles => _partedFiles;
307
+ List <FileState > get partedFiles {
308
+ if (_partedFiles == null ) {
309
+ _partedFiles = < FileState > [];
310
+ for (var uri in _unlinked2.parts) {
311
+ var file = _fileForRelativeUri (uri);
312
+ _partedFiles.add (file);
313
+ _fsState._partToLibraries
314
+ .putIfAbsent (file, () => < FileState > [])
315
+ .add (this );
316
+ }
317
+ }
318
+ return _partedFiles;
319
+ }
274
320
275
321
/// The external names referenced by the file.
276
322
Set <String > get referencedNames {
@@ -287,7 +333,7 @@ class FileState {
287
333
288
334
void appendReferenced (FileState file) {
289
335
if (transitiveFiles.add (file)) {
290
- file._directReferencedFiles ? .forEach (appendReferenced);
336
+ file.directReferencedFiles .forEach (appendReferenced);
291
337
}
292
338
}
293
339
@@ -436,39 +482,16 @@ class FileState {
436
482
}
437
483
}
438
484
439
- // Build the graph.
440
- _importedFiles = < FileState > [];
441
- _exportedFiles = < FileState > [];
442
- _partedFiles = < FileState > [];
443
- for (var directive in _unlinked2.imports) {
444
- var uri = _selectRelativeUri (directive);
445
- var file = _fileForRelativeUri (uri);
446
- _importedFiles.add (file);
447
- }
448
- for (var directive in _unlinked2.exports) {
449
- var uri = _selectRelativeUri (directive);
450
- var file = _fileForRelativeUri (uri);
451
- _exportedFiles.add (file);
452
- }
453
- for (var uri in _unlinked2.parts) {
454
- var file = _fileForRelativeUri (uri);
455
- _partedFiles.add (file);
456
- _fsState._partToLibraries
457
- .putIfAbsent (file, () => < FileState > [])
458
- .add (this );
459
- }
460
- _libraryFiles = [this , ..._partedFiles];
485
+ // Read imports/exports on demand.
486
+ _importedFiles = null ;
487
+ _exportedFiles = null ;
488
+ _directReferencedFiles = null ;
489
+ _directReferencedLibraries = null ;
461
490
462
- // Compute referenced files.
463
- _directReferencedFiles = < FileState > {
464
- ..._importedFiles,
465
- ..._exportedFiles,
466
- ..._partedFiles,
467
- };
468
- _directReferencedLibraries = < FileState > {
469
- ..._importedFiles,
470
- ..._exportedFiles,
471
- };
491
+ // Read parts on demand.
492
+ _fsState._librariesWithoutPartsRead.add (this );
493
+ _partedFiles = null ;
494
+ _libraryFiles = null ;
472
495
473
496
// Update mapping from subtyped names to files.
474
497
for (var name in _driverUnlinkedUnit.subtypedNames) {
@@ -748,6 +771,11 @@ class FileSystemState {
748
771
/// Mapping from a path to the corresponding canonical [FileState] .
749
772
final Map <String , FileState > _pathToCanonicalFile = {};
750
773
774
+ /// We don't read parts until requested, but if we need to know the
775
+ /// library for a file, we need to read parts of every file to know
776
+ /// which libraries reference this part.
777
+ final List <FileState > _librariesWithoutPartsRead = [];
778
+
751
779
/// Mapping from a part to the libraries it is a part of.
752
780
final Map <FileState , List <FileState >> _partToLibraries = {};
753
781
@@ -950,6 +978,19 @@ class FileSystemState {
950
978
_fileContentCache.remove (path);
951
979
}
952
980
981
+ void readPartsForLibraries () {
982
+ // Make a copy, because reading new files will update it.
983
+ var libraryToProcess = _librariesWithoutPartsRead.toList ();
984
+
985
+ // We will process these files, so clear it now.
986
+ // It will be filled with new files during the loop below.
987
+ _librariesWithoutPartsRead.clear ();
988
+
989
+ for (var library in libraryToProcess) {
990
+ library.partedFiles;
991
+ }
992
+ }
993
+
953
994
/// Remove the file with the given [path] .
954
995
void removeFile (String path) {
955
996
markFileForReading (path);
0 commit comments