Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(438)

Side by Side Diff: pkg/analysis_server/lib/src/analysis_server.dart

Issue 587783003: Replace AnalysisServerListener with Stream. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Merges and fixes for comments Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/domain_execution.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analysis.server; 5 library analysis.server;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'package:analyzer/file_system/file_system.dart'; 10 import 'package:analyzer/file_system/file_system.dart';
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 new HashMap<AnalysisService, Set<String>>(); 201 new HashMap<AnalysisService, Set<String>>();
202 202
203 /** 203 /**
204 * A table mapping [AnalysisContext]s to the completers that should be 204 * A table mapping [AnalysisContext]s to the completers that should be
205 * completed when analysis of this context is finished. 205 * completed when analysis of this context is finished.
206 */ 206 */
207 Map<AnalysisContext, Completer<AnalysisDoneReason>> contextAnalysisDoneComplet ers = 207 Map<AnalysisContext, Completer<AnalysisDoneReason>> contextAnalysisDoneComplet ers =
208 new HashMap<AnalysisContext, Completer<AnalysisDoneReason>>(); 208 new HashMap<AnalysisContext, Completer<AnalysisDoneReason>>();
209 209
210 /** 210 /**
211 * The listeners that are listening for lifecycle events from this server. 211 * The controller that is notified when analysis is started.
212 */ 212 */
213 List<AnalysisServerListener> listeners = <AnalysisServerListener>[]; 213 StreamController<AnalysisContext> _onAnalysisStartedController;
214
215 /**
216 * The controller that is notified when analysis is complete.
217 */
218 StreamController _onAnalysisCompleteController;
214 219
215 /** 220 /**
216 * True if any exceptions thrown by analysis should be propagated up the call 221 * True if any exceptions thrown by analysis should be propagated up the call
217 * stack. 222 * stack.
218 */ 223 */
219 bool rethrowExceptions; 224 bool rethrowExceptions;
220 225
221 /** 226 /**
222 * Initialize a newly created server to receive requests from and send 227 * Initialize a newly created server to receive requests from and send
223 * responses to the given [channel]. 228 * responses to the given [channel].
224 * 229 *
225 * If [rethrowExceptions] is true, then any exceptions thrown by analysis are 230 * If [rethrowExceptions] is true, then any exceptions thrown by analysis are
226 * propagated up the call stack. The default is true to allow analysis 231 * propagated up the call stack. The default is true to allow analysis
227 * exceptions to show up in unit tests, but it should be set to false when 232 * exceptions to show up in unit tests, but it should be set to false when
228 * running a full analysis server. 233 * running a full analysis server.
229 */ 234 */
230 AnalysisServer(this.channel, this.resourceProvider, 235 AnalysisServer(this.channel, this.resourceProvider,
231 PackageMapProvider packageMapProvider, this.index, this.defaultSdk, 236 PackageMapProvider packageMapProvider, this.index, this.defaultSdk,
232 {this.rethrowExceptions: true}) { 237 {this.rethrowExceptions: true}) {
233 searchEngine = createSearchEngine(index); 238 searchEngine = createSearchEngine(index);
234 operationQueue = new ServerOperationQueue(this); 239 operationQueue = new ServerOperationQueue(this);
235 contextDirectoryManager = 240 contextDirectoryManager =
236 new ServerContextManager(this, resourceProvider, packageMapProvider); 241 new ServerContextManager(this, resourceProvider, packageMapProvider);
237 AnalysisEngine.instance.logger = new AnalysisLogger(); 242 AnalysisEngine.instance.logger = new AnalysisLogger();
243 _onAnalysisStartedController = new StreamController.broadcast();
244 _onAnalysisCompleteController = new StreamController.broadcast();
238 running = true; 245 running = true;
239 Notification notification = new ServerConnectedParams().toNotification(); 246 Notification notification = new ServerConnectedParams().toNotification();
240 channel.sendNotification(notification); 247 channel.sendNotification(notification);
241 channel.listen(handleRequest, onDone: done, onError: error); 248 channel.listen(handleRequest, onDone: done, onError: error);
242 } 249 }
243 250
244 /** 251 /**
245 * Schedules execution of the given [ServerOperation]. 252 * Schedules execution of the given [ServerOperation].
246 */ 253 */
247 void scheduleOperation(ServerOperation operation) { 254 void scheduleOperation(ServerOperation operation) {
248 bool wasEmpty = operationQueue.isEmpty; 255 bool wasEmpty = operationQueue.isEmpty;
249 addOperation(operation); 256 addOperation(operation);
250 if (wasEmpty) { 257 if (wasEmpty) {
251 _schedulePerformOperation(); 258 _schedulePerformOperation();
252 } 259 }
253 } 260 }
254 261
255 /** 262 /**
256 * Schedules analysis of the given context. 263 * Schedules analysis of the given context.
257 */ 264 */
258 void schedulePerformAnalysisOperation(AnalysisContext context) { 265 void schedulePerformAnalysisOperation(AnalysisContext context) {
259 _notifyAnalysisStarted(context); 266 _onAnalysisStartedController.add(context);
260 scheduleOperation(new PerformAnalysisOperation(context, false)); 267 scheduleOperation(new PerformAnalysisOperation(context, false));
261 } 268 }
262 269
263 /** 270 /**
264 * Send the given [notification] to the client. 271 * Send the given [notification] to the client.
265 */ 272 */
266 void sendNotification(Notification notification) { 273 void sendNotification(Notification notification) {
267 channel.sendNotification(notification); 274 channel.sendNotification(notification);
268 } 275 }
269 276
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 // 335 //
329 // Update the defaults used to create new contexts. 336 // Update the defaults used to create new contexts.
330 // 337 //
331 AnalysisOptionsImpl options = contextDirectoryManager.defaultOptions; 338 AnalysisOptionsImpl options = contextDirectoryManager.defaultOptions;
332 optionUpdaters.forEach((OptionUpdater optionUpdater) { 339 optionUpdaters.forEach((OptionUpdater optionUpdater) {
333 optionUpdater(options); 340 optionUpdater(options);
334 }); 341 });
335 } 342 }
336 343
337 /** 344 /**
338 * Add the given [listener] to the list of listeners that are listening for 345 * The stream that is notified when analysis of a context is started.
339 * lifecycle events from this server.
340 */ 346 */
341 void addAnalysisServerListener(AnalysisServerListener listener) { 347 Stream<AnalysisContext> get onAnalysisStarted {
342 if (!listeners.contains(listener)) { 348 return _onAnalysisStartedController.stream;
343 listeners.add(listener);
344 }
345 } 349 }
346 350
347 /** 351 /**
352 * The stream that is notified when analysis is complete.
353 */
354 Stream get onAnalysisComplete => _onAnalysisCompleteController.stream;
355
356 /**
348 * Adds the given [ServerOperation] to the queue, but does not schedule 357 * Adds the given [ServerOperation] to the queue, but does not schedule
349 * operations execution. 358 * operations execution.
350 */ 359 */
351 void addOperation(ServerOperation operation) { 360 void addOperation(ServerOperation operation) {
352 operationQueue.add(operation); 361 operationQueue.add(operation);
353 } 362 }
354 363
355 /** 364 /**
356 * The socket from which requests are being read has been closed. 365 * The socket from which requests are being read has been closed.
357 */ 366 */
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 'Unexpected exception during analysis', 485 'Unexpected exception during analysis',
477 new CaughtException(exception, stackTrace)); 486 new CaughtException(exception, stackTrace));
478 } 487 }
479 _sendServerErrorNotification(exception, stackTrace); 488 _sendServerErrorNotification(exception, stackTrace);
480 shutdown(); 489 shutdown();
481 } finally { 490 } finally {
482 if (!operationQueue.isEmpty) { 491 if (!operationQueue.isEmpty) {
483 _schedulePerformOperation(); 492 _schedulePerformOperation();
484 } else { 493 } else {
485 sendStatusNotification(null); 494 sendStatusNotification(null);
486 _notifyAnalysisComplete(); 495 _onAnalysisCompleteController.add(null);
487 } 496 }
488 } 497 }
489 } 498 }
490 499
491 /** 500 /**
492 * Trigger reanalysis of all files from disk. 501 * Trigger reanalysis of all files from disk.
493 */ 502 */
494 void reanalyze() { 503 void reanalyze() {
495 // Clear any operations that are pending. 504 // Clear any operations that are pending.
496 operationQueue.clear(); 505 operationQueue.clear();
497 // Instruct the contextDirectoryManager to rebuild all contexts from 506 // Instruct the contextDirectoryManager to rebuild all contexts from
498 // scratch. 507 // scratch.
499 contextDirectoryManager.refresh(); 508 contextDirectoryManager.refresh();
500 } 509 }
501 510
502 /** 511 /**
503 * Remove the given [listener] from the list of listeners that are listening
504 * for lifecycle events from this server.
505 */
506 void removeAnalysisServerListener(AnalysisServerListener listener) {
507 listeners.remove(listener);
508 }
509
510 /**
511 * Send status notification to the client. The `operation` is the operation 512 * Send status notification to the client. The `operation` is the operation
512 * being performed or `null` if analysis is complete. 513 * being performed or `null` if analysis is complete.
513 */ 514 */
514 void sendStatusNotification(ServerOperation operation) { 515 void sendStatusNotification(ServerOperation operation) {
515 // Only send status when subscribed. 516 // Only send status when subscribed.
516 if (!serverServices.contains(ServerService.STATUS)) { 517 if (!serverServices.contains(ServerService.STATUS)) {
517 return; 518 return;
518 } 519 }
519 // Only send status when it changes 520 // Only send status when it changes
520 bool isAnalyzing = operation != null; 521 bool isAnalyzing = operation != null;
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 } 898 }
898 899
899 /** 900 /**
900 * Return `true` if all operations have been performed in this [AnalysisServer ]. 901 * Return `true` if all operations have been performed in this [AnalysisServer ].
901 */ 902 */
902 bool test_areOperationsFinished() { 903 bool test_areOperationsFinished() {
903 return operationQueue.isEmpty; 904 return operationQueue.isEmpty;
904 } 905 }
905 906
906 /** 907 /**
907 * Notify all listeners that analysis of [context] is started.
908 */
909 void _notifyAnalysisStarted(AnalysisContext context) {
910 listeners.forEach((AnalysisServerListener listener) {
911 listener.analysisStarted(context);
912 });
913 }
914
915 /**
916 * Notify all listeners that analysis is complete.
917 */
918 void _notifyAnalysisComplete() {
919 listeners.forEach((AnalysisServerListener listener) {
920 listener.analysisComplete();
921 });
922 }
923
924 /**
925 * Schedules [performOperation] exection. 908 * Schedules [performOperation] exection.
926 */ 909 */
927 void _schedulePerformOperation() { 910 void _schedulePerformOperation() {
928 new Future(performOperation); 911 new Future(performOperation);
929 } 912 }
930 913
931 /** 914 /**
932 * Sends a fatal `server.error` notification. 915 * Sends a fatal `server.error` notification.
933 */ 916 */
934 void _sendServerErrorNotification(exception, stackTrace) { 917 void _sendServerErrorNotification(exception, stackTrace) {
(...skipping 13 matching lines...) Expand all
948 } 931 }
949 // send the notification 932 // send the notification
950 channel.sendNotification( 933 channel.sendNotification(
951 new ServerErrorParams( 934 new ServerErrorParams(
952 true, 935 true,
953 exceptionString, 936 exceptionString,
954 stackTraceString).toNotification()); 937 stackTraceString).toNotification());
955 } 938 }
956 } 939 }
957 940
958 /**
959 * An object that is listening for lifecycle events from an analysis server.
960 */
961 abstract class AnalysisServerListener {
962 /**
963 * Analysis is complete.
964 */
965 void analysisComplete();
966
967 /**
968 * Analysis is started.
969 */
970 void analysisStarted(AnalysisContext context);
971 }
972
973 typedef void OptionUpdater(AnalysisOptionsImpl options); 941 typedef void OptionUpdater(AnalysisOptionsImpl options);
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/domain_execution.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698