@@ -189,13 +189,8 @@ class AnalysisDriver {
189
189
/// The queue of requests for completion.
190
190
final List <_ResolveForCompletionRequest > _resolveForCompletionRequests = [];
191
191
192
- /// The task that discovers available files. If this field is not `null` ,
193
- /// and the task is not completed, it should be performed and completed
194
- /// before any name searching task.
195
- _DiscoverAvailableFilesTask ? _discoverAvailableFilesTask;
196
-
197
- /// The list of tasks to compute files defining a class member name.
198
- final _definingClassMemberNameTasks = < _FilesDefiningClassMemberNameTask > [];
192
+ /// Set to `true` after first [discoverAvailableFiles] .
193
+ bool _hasAvailableFilesDiscovered = false ;
199
194
200
195
/// The list of tasks to compute files referencing a name.
201
196
final _referencingNameTasks = < _FilesReferencingNameTask > [];
@@ -442,12 +437,7 @@ class AnalysisDriver {
442
437
if (_requestedLibraries.isNotEmpty) {
443
438
return AnalysisDriverPriority .interactive;
444
439
}
445
- if (_discoverAvailableFilesTask != null &&
446
- ! _discoverAvailableFilesTask! .isCompleted) {
447
- return AnalysisDriverPriority .interactive;
448
- }
449
- if (_definingClassMemberNameTasks.isNotEmpty ||
450
- _referencingNameTasks.isNotEmpty) {
440
+ if (_referencingNameTasks.isNotEmpty) {
451
441
return AnalysisDriverPriority .interactive;
452
442
}
453
443
if (_errorsRequestedFiles.isNotEmpty) {
@@ -639,14 +629,49 @@ class AnalysisDriver {
639
629
640
630
/// Return a [Future] that completes when discovery of all files that are
641
631
/// potentially available is done, so that they are included in [knownFiles] .
642
- Future <void > discoverAvailableFiles () {
643
- if (_discoverAvailableFilesTask != null &&
644
- _discoverAvailableFilesTask! .isCompleted) {
645
- return Future .value ();
632
+ Future <void > discoverAvailableFiles () async {
633
+ if (_hasAvailableFilesDiscovered) {
634
+ return ;
635
+ }
636
+ _hasAvailableFilesDiscovered = true ;
637
+
638
+ // Discover added files.
639
+ for (var path in addedFiles) {
640
+ _fsState.getFileForPath (path);
641
+ }
642
+
643
+ // Discover SDK libraries.
644
+ if (_sourceFactory.dartSdk case var dartSdk? ) {
645
+ for (var sdkLibrary in dartSdk.sdkLibraries) {
646
+ var source = dartSdk.mapDartUri (sdkLibrary.shortName);
647
+ var path = source! .fullName;
648
+ _fsState.getFileForPath (path);
649
+ }
650
+ }
651
+
652
+ void discoverRecursively (Folder folder) {
653
+ try {
654
+ var pathContext = resourceProvider.pathContext;
655
+ for (var child in folder.getChildren ()) {
656
+ if (child is File ) {
657
+ var path = child.path;
658
+ if (file_paths.isDart (pathContext, path)) {
659
+ _fsState.getFileForPath (path);
660
+ }
661
+ } else if (child is Folder ) {
662
+ discoverRecursively (child);
663
+ }
664
+ }
665
+ } catch (_) {}
666
+ }
667
+
668
+ // Discover files in package/lib folders.
669
+ if (_sourceFactory.packageMap case var packageMap? ) {
670
+ var folders = packageMap.values.flattenedToList2;
671
+ for (var folder in folders) {
672
+ discoverRecursively (folder);
673
+ }
646
674
}
647
- _discoverAvailableFiles ();
648
- _scheduler.notify ();
649
- return _discoverAvailableFilesTask! .completer.future;
650
675
}
651
676
652
677
/// Notify the driver that the client is going to stop using it.
@@ -757,17 +782,27 @@ class AnalysisDriver {
757
782
758
783
/// Completes with files that define a class member with the [name] .
759
784
Future <List <FileState >> getFilesDefiningClassMemberName (String name) async {
760
- _discoverAvailableFiles ();
761
- var task = _FilesDefiningClassMemberNameTask (this , name);
762
- _definingClassMemberNameTasks.add (task);
763
- _scheduler.notify ();
764
- return await task.completer.future;
785
+ 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;
765
800
}
766
801
767
802
/// Return a [Future] that completes with the list of known files that
768
803
/// reference the given external [name] .
769
804
Future <List <String >> getFilesReferencingName (String name) {
770
- _discoverAvailableFiles ();
805
+ discoverAvailableFiles ();
771
806
var task = _FilesReferencingNameTask (this , name);
772
807
_referencingNameTasks.add (task);
773
808
_scheduler.notify ();
@@ -1188,23 +1223,6 @@ class AnalysisDriver {
1188
1223
return ;
1189
1224
}
1190
1225
1191
- // Discover available files.
1192
- if (_discoverAvailableFilesTask case var task? ) {
1193
- if (! task.isCompleted) {
1194
- task.perform ();
1195
- return ;
1196
- }
1197
- }
1198
-
1199
- // Compute files defining a name.
1200
- if (_definingClassMemberNameTasks.firstOrNull case var task? ) {
1201
- bool isDone = task.perform ();
1202
- if (isDone) {
1203
- _definingClassMemberNameTasks.remove (task);
1204
- }
1205
- return ;
1206
- }
1207
-
1208
1226
// Compute files referencing a name.
1209
1227
if (_referencingNameTasks.firstOrNull case var task? ) {
1210
1228
bool isDone = task.perform ();
@@ -1579,12 +1597,6 @@ class AnalysisDriver {
1579
1597
);
1580
1598
}
1581
1599
1582
- /// If this has not been done yet, schedule discovery of all files that are
1583
- /// potentially available, so that they are included in [knownFiles] .
1584
- void _discoverAvailableFiles () {
1585
- _discoverAvailableFilesTask ?? = _DiscoverAvailableFilesTask (this );
1586
- }
1587
-
1588
1600
/// When we look at a part that has a `part of name;` directive, we
1589
1601
/// usually don't know the library (in contrast to `part of uri;` ).
1590
1602
/// So, we have no choice than to resolve this part as its own library.
@@ -2492,95 +2504,6 @@ abstract class SchedulerWorker {
2492
2504
Future <void > performWork ();
2493
2505
}
2494
2506
2495
- /// Task that discovers all files that are available to the driver, and makes
2496
- /// them known.
2497
- class _DiscoverAvailableFilesTask {
2498
- static const int _MS_WORK_INTERVAL = 5 ;
2499
-
2500
- final AnalysisDriver driver;
2501
-
2502
- final Completer <void > completer = Completer <void >();
2503
-
2504
- Iterator <Folder >? folderIterator;
2505
-
2506
- final List <String > files = [];
2507
-
2508
- int fileIndex = 0 ;
2509
-
2510
- _DiscoverAvailableFilesTask (this .driver);
2511
-
2512
- bool get isCompleted => completer.isCompleted;
2513
-
2514
- /// Perform the next piece of work, and set [isCompleted] to `true` to
2515
- /// indicate that the task is done, or keeps it `false` to indicate that the
2516
- /// task should continue to be run.
2517
- void perform () {
2518
- if (folderIterator == null ) {
2519
- files.addAll (driver.addedFiles);
2520
-
2521
- // Discover SDK libraries.
2522
- var dartSdk = driver._sourceFactory.dartSdk;
2523
- if (dartSdk != null ) {
2524
- for (var sdkLibrary in dartSdk.sdkLibraries) {
2525
- var file = dartSdk.mapDartUri (sdkLibrary.shortName)! .fullName;
2526
- files.add (file);
2527
- }
2528
- }
2529
-
2530
- // Discover files in package/lib folders.
2531
- var packageMap = driver._sourceFactory.packageMap;
2532
- if (packageMap != null ) {
2533
- folderIterator = packageMap.values.flattenedToList2.iterator;
2534
- } else {
2535
- folderIterator = < Folder > [].iterator;
2536
- }
2537
- }
2538
-
2539
- // List each package/lib folder recursively.
2540
- Stopwatch timer = Stopwatch ()..start ();
2541
- while (folderIterator! .moveNext ()) {
2542
- var folder = folderIterator! .current;
2543
- _appendFilesRecursively (folder);
2544
-
2545
- // Note: must check if we are exiting before calling moveNext()
2546
- // otherwise we will skip one iteration of the loop when we come back.
2547
- if (timer.elapsedMilliseconds > _MS_WORK_INTERVAL ) {
2548
- return ;
2549
- }
2550
- }
2551
-
2552
- // Get know files one by one.
2553
- while (fileIndex < files.length) {
2554
- if (timer.elapsedMilliseconds > _MS_WORK_INTERVAL ) {
2555
- return ;
2556
- }
2557
- var file = files[fileIndex++ ];
2558
- driver._fsState.getFileForPath (file);
2559
- }
2560
-
2561
- // The task is done, clean up.
2562
- folderIterator = null ;
2563
- files.clear ();
2564
- completer.complete ();
2565
- }
2566
-
2567
- void _appendFilesRecursively (Folder folder) {
2568
- try {
2569
- var pathContext = driver.resourceProvider.pathContext;
2570
- for (var child in folder.getChildren ()) {
2571
- if (child is File ) {
2572
- var path = child.path;
2573
- if (file_paths.isDart (pathContext, path)) {
2574
- files.add (path);
2575
- }
2576
- } else if (child is Folder ) {
2577
- _appendFilesRecursively (child);
2578
- }
2579
- }
2580
- } catch (_) {}
2581
- }
2582
- }
2583
-
2584
2507
class _FileChange {
2585
2508
final String path;
2586
2509
final _FileChangeKind kind;
@@ -2595,57 +2518,6 @@ class _FileChange {
2595
2518
2596
2519
enum _FileChangeKind { add, change, remove }
2597
2520
2598
- /// Task that computes the list of files that were added to the driver and
2599
- /// declare a class member with the given [name] .
2600
- class _FilesDefiningClassMemberNameTask {
2601
- static const int _MS_WORK_INTERVAL = 5 ;
2602
-
2603
- final AnalysisDriver driver;
2604
- final String name;
2605
- final Completer <List <FileState >> completer = Completer <List <FileState >>();
2606
-
2607
- final List <FileState > definingFiles = [];
2608
- final Set <FileState > checkedFiles = {};
2609
- final List <FileState > filesToCheck = [];
2610
-
2611
- _FilesDefiningClassMemberNameTask (this .driver, this .name);
2612
-
2613
- /// Perform work for a fixed length of time, and complete the [completer] to
2614
- /// either return `true` to indicate that the task is done, or return `false`
2615
- /// to indicate that the task should continue to be run.
2616
- ///
2617
- /// Each invocation of an asynchronous method has overhead, which looks as
2618
- /// `_SyncCompleter.complete` invocation, we see as much as 62% in some
2619
- /// scenarios. Instead we use a fixed length of time, so we can spend less time
2620
- /// overall and keep quick enough response time.
2621
- bool perform () {
2622
- Stopwatch timer = Stopwatch ()..start ();
2623
- while (timer.elapsedMilliseconds < _MS_WORK_INTERVAL ) {
2624
- // Prepare files to check.
2625
- if (filesToCheck.isEmpty) {
2626
- var newFiles = driver.knownFiles.difference (checkedFiles);
2627
- filesToCheck.addAll (newFiles);
2628
- }
2629
-
2630
- // If no more files to check, complete and done.
2631
- if (filesToCheck.isEmpty) {
2632
- completer.complete (definingFiles);
2633
- return true ;
2634
- }
2635
-
2636
- // Check the next file.
2637
- var file = filesToCheck.removeLast ();
2638
- if (file.definedClassMemberNames.contains (name)) {
2639
- definingFiles.add (file);
2640
- }
2641
- checkedFiles.add (file);
2642
- }
2643
-
2644
- // We're not done yet.
2645
- return false ;
2646
- }
2647
- }
2648
-
2649
2521
/// Task that computes the list of files that were added to the driver and
2650
2522
/// have at least one reference to an identifier [name] defined outside of the
2651
2523
/// file.
@@ -2723,12 +2595,20 @@ extension<K, V> on Map<K, List<Completer<V>>> {
2723
2595
}
2724
2596
}
2725
2597
2726
- extension on File {
2598
+ extension FileExtension on File {
2727
2599
File ? get libraryForMacro {
2728
2600
if (path.removeSuffix ('.macro.dart' ) case var noExtPath? ) {
2729
2601
var libraryPath = '$noExtPath .dart' ;
2730
2602
return provider.getFile (libraryPath);
2731
2603
}
2732
2604
return null ;
2733
2605
}
2606
+
2607
+ File ? get macroForLibrary {
2608
+ if (path.removeSuffix ('.dart' ) case var noExtPath? ) {
2609
+ var libraryPath = '$noExtPath .macro.dart' ;
2610
+ return provider.getFile (libraryPath);
2611
+ }
2612
+ return null ;
2613
+ }
2734
2614
}
0 commit comments