@@ -192,8 +192,12 @@ class AnalysisDriver {
192
192
/// Set to `true` after first [discoverAvailableFiles] .
193
193
bool _hasAvailableFilesDiscovered = false ;
194
194
195
- /// The list of tasks to compute files referencing a name.
196
- final _referencingNameTasks = < _FilesReferencingNameTask > [];
195
+ /// The requests to compute files defining a class member with the name.
196
+ final _definingClassMemberNameRequests =
197
+ < _GetFilesDefiningClassMemberNameRequest > [];
198
+
199
+ /// The requests to compute files referencing a name.
200
+ final _referencingNameRequests = < _GetFilesReferencingNameRequest > [];
197
201
198
202
/// The mapping from the files for which errors were requested using
199
203
/// [getErrors] to the [Completer] s to report the result.
@@ -437,7 +441,10 @@ class AnalysisDriver {
437
441
if (_requestedLibraries.isNotEmpty) {
438
442
return AnalysisDriverPriority .interactive;
439
443
}
440
- if (_referencingNameTasks.isNotEmpty) {
444
+ if (_definingClassMemberNameRequests.isNotEmpty) {
445
+ return AnalysisDriverPriority .interactive;
446
+ }
447
+ if (_referencingNameRequests.isNotEmpty) {
441
448
return AnalysisDriverPriority .interactive;
442
449
}
443
450
if (_errorsRequestedFiles.isNotEmpty) {
@@ -488,7 +495,8 @@ class AnalysisDriver {
488
495
_requestedLibraries.isNotEmpty ||
489
496
_requestedFiles.isNotEmpty ||
490
497
_errorsRequestedFiles.isNotEmpty ||
491
- _referencingNameTasks.isNotEmpty ||
498
+ _definingClassMemberNameRequests.isNotEmpty ||
499
+ _referencingNameRequests.isNotEmpty ||
492
500
_indexRequestedFiles.isNotEmpty ||
493
501
_unitElementRequestedFiles.isNotEmpty ||
494
502
_disposeRequests.isNotEmpty;
@@ -783,36 +791,19 @@ class AnalysisDriver {
783
791
/// Completes with files that define a class member with the [name] .
784
792
Future <List <FileState >> getFilesDefiningClassMemberName (String name) async {
785
793
await discoverAvailableFiles ();
786
-
787
- // Get library elements, so macro generated files are added.
788
- for (var file in knownFiles.toList ()) {
789
- await getLibraryByUri (file.uriStr);
790
- }
791
-
792
- var definingFiles = < FileState > [];
793
- for (var file in knownFiles) {
794
- if (file.definedClassMemberNames.contains (name)) {
795
- definingFiles.add (file);
796
- }
797
- }
798
-
799
- return definingFiles;
800
- }
801
-
802
- /// Return a [Future] that completes with the list of known files that
803
- /// reference the given external [name] .
804
- Future <List <String >> getFilesReferencingName (String name) {
805
- discoverAvailableFiles ();
806
- var task = _FilesReferencingNameTask (this , name);
807
- _referencingNameTasks.add (task);
794
+ var request = _GetFilesDefiningClassMemberNameRequest (name);
795
+ _definingClassMemberNameRequests.add (request);
808
796
_scheduler.notify ();
809
- return task .completer.future;
797
+ return request .completer.future;
810
798
}
811
799
812
- /// See [getFilesReferencingName] .
813
- Future <List <File >> getFilesReferencingName2 (String name) async {
814
- final pathList = await getFilesReferencingName (name);
815
- return pathList.map ((path) => resourceProvider.getFile (path)).toList ();
800
+ /// Completes with files that reference the given external [name] .
801
+ Future <List <FileState >> getFilesReferencingName (String name) async {
802
+ await discoverAvailableFiles ();
803
+ var request = _GetFilesReferencingNameRequest (name);
804
+ _referencingNameRequests.add (request);
805
+ _scheduler.notify ();
806
+ return request.completer.future;
816
807
}
817
808
818
809
/// Return the [FileResult] for the Dart file with the given [path] .
@@ -1223,12 +1214,15 @@ class AnalysisDriver {
1223
1214
return ;
1224
1215
}
1225
1216
1217
+ // Compute files defining a class member.
1218
+ if (_definingClassMemberNameRequests.removeLastOrNull () case var request? ) {
1219
+ await _getFilesDefiningClassMemberName (request);
1220
+ return ;
1221
+ }
1222
+
1226
1223
// Compute files referencing a name.
1227
- if (_referencingNameTasks.firstOrNull case var task? ) {
1228
- bool isDone = task.perform ();
1229
- if (isDone) {
1230
- _referencingNameTasks.remove (task);
1231
- }
1224
+ if (_referencingNameRequests.removeLastOrNull () case var request? ) {
1225
+ await _getFilesReferencingName (request);
1232
1226
return ;
1233
1227
}
1234
1228
@@ -1637,6 +1631,24 @@ class AnalysisDriver {
1637
1631
}
1638
1632
}
1639
1633
1634
+ Future <void > _ensureMacroGeneratedFiles () async {
1635
+ for (var file in knownFiles.toList ()) {
1636
+ if (file.kind case LibraryFileKind libraryKind) {
1637
+ var libraryCycle = libraryKind.libraryCycle;
1638
+ if (libraryCycle.importsMacroClass) {
1639
+ if (! libraryCycle.hasMacroFilesCreated) {
1640
+ libraryCycle.hasMacroFilesCreated = true ;
1641
+ // We create macro-generated FileState(s) when load bundles.
1642
+ await libraryContext.load (
1643
+ targetLibrary: libraryKind,
1644
+ performance: OperationPerformanceImpl ('<root>' ),
1645
+ );
1646
+ }
1647
+ }
1648
+ }
1649
+ }
1650
+ }
1651
+
1640
1652
void _fillSalt () {
1641
1653
_fillSaltForUnlinked ();
1642
1654
_fillSaltForElements ();
@@ -1707,6 +1719,34 @@ class AnalysisDriver {
1707
1719
return errors;
1708
1720
}
1709
1721
1722
+ Future <void > _getFilesDefiningClassMemberName (
1723
+ _GetFilesDefiningClassMemberNameRequest request,
1724
+ ) async {
1725
+ await _ensureMacroGeneratedFiles ();
1726
+
1727
+ var result = < FileState > [];
1728
+ for (var file in knownFiles) {
1729
+ if (file.definedClassMemberNames.contains (request.name)) {
1730
+ result.add (file);
1731
+ }
1732
+ }
1733
+ request.completer.complete (result);
1734
+ }
1735
+
1736
+ Future <void > _getFilesReferencingName (
1737
+ _GetFilesReferencingNameRequest request,
1738
+ ) async {
1739
+ await _ensureMacroGeneratedFiles ();
1740
+
1741
+ var result = < FileState > [];
1742
+ for (var file in knownFiles) {
1743
+ if (file.referencedNames.contains (request.name)) {
1744
+ result.add (file);
1745
+ }
1746
+ }
1747
+ request.completer.complete (result);
1748
+ }
1749
+
1710
1750
Future <void > _getIndex (String path) async {
1711
1751
final file = _fsState.getFileForPath (path);
1712
1752
@@ -2518,62 +2558,18 @@ class _FileChange {
2518
2558
2519
2559
enum _FileChangeKind { add, change, remove }
2520
2560
2521
- /// Task that computes the list of files that were added to the driver and
2522
- /// have at least one reference to an identifier [name] defined outside of the
2523
- /// file.
2524
- class _FilesReferencingNameTask {
2525
- static const int _WORK_FILES = 100 ;
2526
- static const int _MS_WORK_INTERVAL = 5 ;
2527
-
2528
- final AnalysisDriver driver;
2561
+ class _GetFilesDefiningClassMemberNameRequest {
2529
2562
final String name;
2530
- final Completer < List < String >> completer = Completer <List <String >>();
2563
+ final completer = Completer <List <FileState >>();
2531
2564
2532
- int fileStamp = - 1 ;
2533
- List <FileState >? filesToCheck;
2534
- int filesToCheckIndex = - 1 ;
2535
-
2536
- final List <String > referencingFiles = < String > [];
2537
-
2538
- _FilesReferencingNameTask (this .driver, this .name);
2539
-
2540
- /// Perform work for a fixed length of time, and complete the [completer] to
2541
- /// either return `true` to indicate that the task is done, or return `false`
2542
- /// to indicate that the task should continue to be run.
2543
- ///
2544
- /// Each invocation of an asynchronous method has overhead, which looks as
2545
- /// `_SyncCompleter.complete` invocation, we see as much as 62% in some
2546
- /// scenarios. Instead we use a fixed length of time, so we can spend less time
2547
- /// overall and keep quick enough response time.
2548
- bool perform () {
2549
- if (driver._fsState.fileStamp != fileStamp) {
2550
- filesToCheck = null ;
2551
- referencingFiles.clear ();
2552
- }
2553
-
2554
- // Prepare files to check.
2555
- if (filesToCheck == null ) {
2556
- fileStamp = driver._fsState.fileStamp;
2557
- filesToCheck = driver._fsState.knownFiles.toList ();
2558
- filesToCheckIndex = 0 ;
2559
- }
2565
+ _GetFilesDefiningClassMemberNameRequest (this .name);
2566
+ }
2560
2567
2561
- Stopwatch timer = Stopwatch ()..start ();
2562
- while (filesToCheckIndex < filesToCheck! .length) {
2563
- if (filesToCheckIndex % _WORK_FILES == 0 &&
2564
- timer.elapsedMilliseconds > _MS_WORK_INTERVAL ) {
2565
- return false ;
2566
- }
2567
- FileState file = filesToCheck! [filesToCheckIndex++ ];
2568
- if (file.referencedNames.contains (name)) {
2569
- referencingFiles.add (file.path);
2570
- }
2571
- }
2568
+ class _GetFilesReferencingNameRequest {
2569
+ final String name;
2570
+ final completer = Completer <List <FileState >>();
2572
2571
2573
- // If no more files to check, complete and done.
2574
- completer.complete (referencingFiles);
2575
- return true ;
2576
- }
2572
+ _GetFilesReferencingNameRequest (this .name);
2577
2573
}
2578
2574
2579
2575
class _ResolveForCompletionRequest {
0 commit comments