55import 'dart:async' ;
66import 'dart:collection' ;
77
8+ import 'package:analysis_server/src/analysis_server.dart' ;
89import 'package:analysis_server/src/lsp/handlers/handlers.dart' ;
10+ import 'package:analysis_server/src/scheduler/scheduled_message.dart' ;
911import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_parser.dart' ;
1012import 'package:analyzer/dart/analysis/analysis_context.dart' ;
1113import 'package:analyzer/dart/analysis/features.dart' ;
@@ -91,6 +93,9 @@ abstract class ContextManager {
9193 /// If no driver contains the given path, `null` is returned.
9294 AnalysisDriver ? getDriverFor (String path);
9395
96+ /// Handle an [event] from a file watcher.
97+ void handleWatchEvent (WatchEvent event);
98+
9499 /// Return `true` if the file or directory with the given [path] will be
95100 /// analyzed in one of the analysis contexts.
96101 bool isAnalyzed (String path);
@@ -123,6 +128,9 @@ abstract class ContextManager {
123128// operations return data structures describing how context state should be
124129// modified.
125130abstract class ContextManagerCallbacks {
131+ /// The analysis server that created this callback object.
132+ AnalysisServer get analysisServer;
133+
126134 /// Called after analysis contexts are created, usually when new analysis
127135 /// roots are set, or after detecting a change that required rebuilding
128136 /// the set of analysis contexts.
@@ -140,7 +148,7 @@ abstract class ContextManagerCallbacks {
140148 /// Sent the given watch [event] to any interested plugins.
141149 void broadcastWatchEvent (WatchEvent event);
142150
143- /// Invoked on any [FileResult] in the analyzer events stream.
151+ /// Invoked on every [FileResult] in the analyzer events stream.
144152 void handleFileResult (FileResult result);
145153
146154 /// Add listeners to the [driver] . This must be the only listener.
@@ -309,6 +317,13 @@ class ContextManagerImpl implements ContextManager {
309317 return getContextFor (path)? .driver;
310318 }
311319
320+ @override
321+ void handleWatchEvent (WatchEvent event) {
322+ callbacks.broadcastWatchEvent (event);
323+ _handleWatchEvent (event);
324+ callbacks.afterWatchEvent (event);
325+ }
326+
312327 @override
313328 bool isAnalyzed (String path) {
314329 var collection = _collection;
@@ -610,7 +625,7 @@ class ContextManagerImpl implements ContextManager {
610625 watchers.add (watcher);
611626 watcherSubscriptions.add (
612627 watcher.changes.listen (
613- _handleWatchEvent ,
628+ _scheduleWatchEvent ,
614629 onError: _handleWatchInterruption,
615630 ),
616631 );
@@ -808,18 +823,14 @@ class ContextManagerImpl implements ContextManager {
808823 }
809824 }
810825
826+ /// Handle an [event] from a file watcher.
811827 void _handleWatchEvent (WatchEvent event) {
812- callbacks.broadcastWatchEvent (event);
813- _handleWatchEventImpl (event);
814- callbacks.afterWatchEvent (event);
815- }
816-
817- void _handleWatchEventImpl (WatchEvent event) {
818828 // Figure out which context this event applies to.
819- // TODO(brianwilkerson): If a file is explicitly included in one context
820- // but implicitly referenced in another context, we will only send a
821- // changeSet to the context that explicitly includes the file (because
822- // that's the only context that's watching the file).
829+ //
830+ // If a file is explicitly included in one context but implicitly referenced
831+ // in another context, we will only notify the context that explicitly
832+ // includes the file (because that's the only context that's watching the
833+ // file).
823834 var path = event.path;
824835 var type = event.type;
825836
@@ -915,6 +926,15 @@ class ContextManagerImpl implements ContextManager {
915926 existingExcludedSet.containsAll (excludedPaths);
916927 }
917928
929+ /// Schedule the handling of a watch event.
930+ ///
931+ /// This places the watch event on the message scheduler's queue so that it
932+ /// can be processed when we're not in the middle of handling some other
933+ /// message.
934+ void _scheduleWatchEvent (WatchEvent event) {
935+ callbacks.analysisServer.messageScheduler.add (WatcherMessage (event));
936+ }
937+
918938 /// Listens to files generated by Blaze that were found or searched for.
919939 ///
920940 /// This is handled specially because the files are outside the package
@@ -941,6 +961,12 @@ class ContextManagerImpl implements ContextManager {
941961}
942962
943963class NoopContextManagerCallbacks implements ContextManagerCallbacks {
964+ @override
965+ AnalysisServer get analysisServer =>
966+ throw StateError (
967+ 'The callback object should have been set by the server.' ,
968+ );
969+
944970 @override
945971 void afterContextsCreated () {}
946972
0 commit comments