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

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

Issue 757613002: new onPriorityChanged event stream (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix test Created 6 years 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_analysis.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:analysis_server/src/analysis_logger.dart'; 10 import 'package:analysis_server/src/analysis_logger.dart';
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 * The controller that is notified when analysis is complete. 156 * The controller that is notified when analysis is complete.
157 */ 157 */
158 StreamController _onAnalysisCompleteController; 158 StreamController _onAnalysisCompleteController;
159 159
160 /** 160 /**
161 * The controller that is notified when a single file has been analyzed. 161 * The controller that is notified when a single file has been analyzed.
162 */ 162 */
163 StreamController<ChangeNotice> _onFileAnalyzedController; 163 StreamController<ChangeNotice> _onFileAnalyzedController;
164 164
165 /** 165 /**
166 * The controller used to notify others when priority sources change.
167 */
168 StreamController<PriorityChangeEvent> _onPriorityChangeController;
169
170 /**
166 * True if any exceptions thrown by analysis should be propagated up the call 171 * True if any exceptions thrown by analysis should be propagated up the call
167 * stack. 172 * stack.
168 */ 173 */
169 bool rethrowExceptions; 174 bool rethrowExceptions;
170 175
171 /** 176 /**
172 * The stream that is notified when contexts are added or removed. 177 * The stream that is notified when contexts are added or removed.
173 */ 178 */
174 Stream<ContextsChangedEvent> onContextsChanged; 179 Stream<ContextsChangedEvent> onContextsChanged;
175 180
(...skipping 12 matching lines...) Expand all
188 searchEngine = createSearchEngine(index); 193 searchEngine = createSearchEngine(index);
189 operationQueue = new ServerOperationQueue(this); 194 operationQueue = new ServerOperationQueue(this);
190 contextDirectoryManager = 195 contextDirectoryManager =
191 new ServerContextManager(this, resourceProvider, packageMapProvider); 196 new ServerContextManager(this, resourceProvider, packageMapProvider);
192 onContextsChanged = 197 onContextsChanged =
193 contextDirectoryManager.onContextsChanged.asBroadcastStream(); 198 contextDirectoryManager.onContextsChanged.asBroadcastStream();
194 AnalysisEngine.instance.logger = new AnalysisLogger(); 199 AnalysisEngine.instance.logger = new AnalysisLogger();
195 _onAnalysisStartedController = new StreamController.broadcast(); 200 _onAnalysisStartedController = new StreamController.broadcast();
196 _onAnalysisCompleteController = new StreamController.broadcast(); 201 _onAnalysisCompleteController = new StreamController.broadcast();
197 _onFileAnalyzedController = new StreamController.broadcast(); 202 _onFileAnalyzedController = new StreamController.broadcast();
203 _onPriorityChangeController =
204 new StreamController<PriorityChangeEvent>.broadcast();
198 running = true; 205 running = true;
199 Notification notification = new ServerConnectedParams().toNotification(); 206 Notification notification = new ServerConnectedParams().toNotification();
200 channel.sendNotification(notification); 207 channel.sendNotification(notification);
201 channel.listen(handleRequest, onDone: done, onError: error); 208 channel.listen(handleRequest, onDone: done, onError: error);
202 } 209 }
203 210
204 /** 211 /**
205 * The stream that is notified when analysis is complete. 212 * The stream that is notified when analysis is complete.
206 */ 213 */
207 Stream get onAnalysisComplete => _onAnalysisCompleteController.stream; 214 Stream get onAnalysisComplete => _onAnalysisCompleteController.stream;
208 215
209 /** 216 /**
210 * The stream that is notified when analysis of a context is started. 217 * The stream that is notified when analysis of a context is started.
211 */ 218 */
212 Stream<AnalysisContext> get onAnalysisStarted { 219 Stream<AnalysisContext> get onAnalysisStarted {
213 return _onAnalysisStartedController.stream; 220 return _onAnalysisStartedController.stream;
214 } 221 }
215 222
216 /** 223 /**
217 * The stream that is notified when a single file has been analyzed. 224 * The stream that is notified when a single file has been analyzed.
218 */ 225 */
219 Stream get onFileAnalyzed => _onFileAnalyzedController.stream; 226 Stream get onFileAnalyzed => _onFileAnalyzedController.stream;
220 227
221 /** 228 /**
229 * The stream that is notified when priority sources change.
230 */
231 Stream<PriorityChangeEvent> get onPriorityChange =>
232 _onPriorityChangeController.stream;
233
234 /**
222 * Adds the given [ServerOperation] to the queue, but does not schedule 235 * Adds the given [ServerOperation] to the queue, but does not schedule
223 * operations execution. 236 * operations execution.
224 */ 237 */
225 void addOperation(ServerOperation operation) { 238 void addOperation(ServerOperation operation) {
226 operationQueue.add(operation); 239 operationQueue.add(operation);
227 } 240 }
228 241
229 /** 242 /**
230 * The socket from which requests are being read has been closed. 243 * The socket from which requests are being read has been closed.
231 */ 244 */
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 } 352 }
340 // prepare Source 353 // prepare Source
341 Source source = getSource(file); 354 Source source = getSource(file);
342 if (context.getKindOf(source) == SourceKind.UNKNOWN) { 355 if (context.getKindOf(source) == SourceKind.UNKNOWN) {
343 return null; 356 return null;
344 } 357 }
345 // get errors for the file 358 // get errors for the file
346 return context.getErrors(source); 359 return context.getErrors(source);
347 } 360 }
348 361
349 /**
350 * Returns resolved [AstNode]s at the given [offset] of the given [file].
351 *
352 * May be empty, but not `null`.
353 */
354 List<AstNode> getNodesAtOffset(String file, int offset) {
355 List<CompilationUnit> units = getResolvedCompilationUnits(file);
356 List<AstNode> nodes = <AstNode>[];
357 for (CompilationUnit unit in units) {
358 AstNode node = new NodeLocator.con1(offset).searchWithin(unit);
359 if (node != null) {
360 nodes.add(node);
361 }
362 }
363 return nodes;
364 }
365
366 // TODO(brianwilkerson) Add the following method after 'prioritySources' has 362 // TODO(brianwilkerson) Add the following method after 'prioritySources' has
367 // been added to InternalAnalysisContext. 363 // been added to InternalAnalysisContext.
368 // /** 364 // /**
369 // * Return a list containing the full names of all of the sources that are 365 // * Return a list containing the full names of all of the sources that are
370 // * priority sources. 366 // * priority sources.
371 // */ 367 // */
372 // List<String> getPriorityFiles() { 368 // List<String> getPriorityFiles() {
373 // List<String> priorityFiles = new List<String>(); 369 // List<String> priorityFiles = new List<String>();
374 // folderMap.values.forEach((ContextDirectory directory) { 370 // folderMap.values.forEach((ContextDirectory directory) {
375 // InternalAnalysisContext context = directory.context; 371 // InternalAnalysisContext context = directory.context;
376 // context.prioritySources.forEach((Source source) { 372 // context.prioritySources.forEach((Source source) {
377 // priorityFiles.add(source.fullName); 373 // priorityFiles.add(source.fullName);
378 // }); 374 // });
379 // }); 375 // });
380 // return priorityFiles; 376 // return priorityFiles;
381 // } 377 // }
382 378
383 /** 379 /**
384 * Returns resolved [CompilationUnit]s of the Dart file with the given [path]. 380 * Returns resolved [AstNode]s at the given [offset] of the given [file].
385 * 381 *
386 * May be empty, but not `null`. 382 * May be empty, but not `null`.
387 */ 383 */
388 List<CompilationUnit> getResolvedCompilationUnits(String path) { 384 List<AstNode> getNodesAtOffset(String file, int offset) {
389 List<CompilationUnit> units = <CompilationUnit>[]; 385 List<CompilationUnit> units = getResolvedCompilationUnits(file);
390 // prepare AnalysisContext 386 List<AstNode> nodes = <AstNode>[];
391 AnalysisContext context = getAnalysisContext(path); 387 for (CompilationUnit unit in units) {
392 if (context == null) { 388 AstNode node = new NodeLocator.con1(offset).searchWithin(unit);
393 return units; 389 if (node != null) {
394 } 390 nodes.add(node);
395 // add a unit for each unit/library combination
396 Source unitSource = getSource(path);
397 List<Source> librarySources = context.getLibrariesContaining(unitSource);
398 for (Source librarySource in librarySources) {
399 CompilationUnit unit =
400 context.resolveCompilationUnit2(unitSource, librarySource);
401 if (unit != null) {
402 units.add(unit);
403 } 391 }
404 } 392 }
405 // done 393 return nodes;
406 return units;
407 } 394 }
408 395
409 /** 396 /**
410 * Returns the [CompilationUnit] of the Dart file with the given [path] that 397 * Returns the [CompilationUnit] of the Dart file with the given [path] that
411 * should be used to resend notifications for already resolved unit. 398 * should be used to resend notifications for already resolved unit.
412 * Returns `null` if the file is not a part of any context, library has not 399 * Returns `null` if the file is not a part of any context, library has not
413 * been yet resolved, or any problem happened. 400 * been yet resolved, or any problem happened.
414 */ 401 */
415 CompilationUnit getResolvedCompilationUnitToResendNotification(String path) { 402 CompilationUnit getResolvedCompilationUnitToResendNotification(String path) {
416 // prepare AnalysisContext 403 // prepare AnalysisContext
(...skipping 10 matching lines...) Expand all
427 // if library has not been resolved yet, the unit will be resolved later 414 // if library has not been resolved yet, the unit will be resolved later
428 Source librarySource = librarySources[0]; 415 Source librarySource = librarySources[0];
429 if (context.getLibraryElement(librarySource) == null) { 416 if (context.getLibraryElement(librarySource) == null) {
430 return null; 417 return null;
431 } 418 }
432 // if library has been already resolved, resolve unit 419 // if library has been already resolved, resolve unit
433 return context.resolveCompilationUnit2(unitSource, librarySource); 420 return context.resolveCompilationUnit2(unitSource, librarySource);
434 } 421 }
435 422
436 /** 423 /**
424 * Returns resolved [CompilationUnit]s of the Dart file with the given [path].
425 *
426 * May be empty, but not `null`.
427 */
428 List<CompilationUnit> getResolvedCompilationUnits(String path) {
429 List<CompilationUnit> units = <CompilationUnit>[];
430 // prepare AnalysisContext
431 AnalysisContext context = getAnalysisContext(path);
432 if (context == null) {
433 return units;
434 }
435 // add a unit for each unit/library combination
436 Source unitSource = getSource(path);
437 List<Source> librarySources = context.getLibrariesContaining(unitSource);
438 for (Source librarySource in librarySources) {
439 CompilationUnit unit =
440 context.resolveCompilationUnit2(unitSource, librarySource);
441 if (unit != null) {
442 units.add(unit);
443 }
444 }
445 // done
446 return units;
447 }
448
449 /**
437 * Return the [Source] of the Dart file with the given [path]. 450 * Return the [Source] of the Dart file with the given [path].
438 */ 451 */
439 Source getSource(String path) { 452 Source getSource(String path) {
440 // try SDK 453 // try SDK
441 { 454 {
442 Uri uri = resourceProvider.pathContext.toUri(path); 455 Uri uri = resourceProvider.pathContext.toUri(path);
443 Source sdkSource = defaultSdk.fromFileUri(uri); 456 Source sdkSource = defaultSdk.fromFileUri(uri);
444 if (sdkSource != null) { 457 if (sdkSource != null) {
445 return sdkSource; 458 return sdkSource;
446 } 459 }
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 } 747 }
735 } 748 }
736 }); 749 });
737 // remember new subscriptions 750 // remember new subscriptions
738 this.analysisServices = subscriptions; 751 this.analysisServices = subscriptions;
739 } 752 }
740 753
741 /** 754 /**
742 * Set the priority files to the given [files]. 755 * Set the priority files to the given [files].
743 */ 756 */
744 void setPriorityFiles(Request request, List<String> files) { 757 void setPriorityFiles(String requestId, List<String> files) {
745 Map<AnalysisContext, List<Source>> sourceMap = 758 Map<AnalysisContext, List<Source>> sourceMap =
746 new HashMap<AnalysisContext, List<Source>>(); 759 new HashMap<AnalysisContext, List<Source>>();
747 List<String> unanalyzed = new List<String>(); 760 List<String> unanalyzed = new List<String>();
748 files.forEach((file) { 761 files.forEach((file) {
749 AnalysisContext analysisContext = getAnalysisContext(file); 762 AnalysisContext analysisContext = getAnalysisContext(file);
750 if (analysisContext == null) { 763 if (analysisContext == null) {
751 unanalyzed.add(file); 764 unanalyzed.add(file);
752 } else { 765 } else {
753 List<Source> sourceList = sourceMap[analysisContext]; 766 List<Source> sourceList = sourceMap[analysisContext];
754 if (sourceList == null) { 767 if (sourceList == null) {
755 sourceList = <Source>[]; 768 sourceList = <Source>[];
756 sourceMap[analysisContext] = sourceList; 769 sourceMap[analysisContext] = sourceList;
757 } 770 }
758 sourceList.add(getSource(file)); 771 sourceList.add(getSource(file));
759 } 772 }
760 }); 773 });
761 if (unanalyzed.isNotEmpty) { 774 if (unanalyzed.isNotEmpty) {
762 StringBuffer buffer = new StringBuffer(); 775 StringBuffer buffer = new StringBuffer();
763 buffer.writeAll(unanalyzed, ', '); 776 buffer.writeAll(unanalyzed, ', ');
764 throw new RequestFailure( 777 throw new RequestFailure(
765 new Response.unanalyzedPriorityFiles(request, buffer.toString())); 778 new Response.unanalyzedPriorityFiles(requestId, buffer.toString()));
766 } 779 }
767 folderMap.forEach((Folder folder, AnalysisContext context) { 780 folderMap.forEach((Folder folder, AnalysisContext context) {
768 List<Source> sourceList = sourceMap[context]; 781 List<Source> sourceList = sourceMap[context];
769 if (sourceList == null) { 782 if (sourceList == null) {
770 sourceList = Source.EMPTY_ARRAY; 783 sourceList = Source.EMPTY_ARRAY;
771 } 784 }
772 context.analysisPriorityOrder = sourceList; 785 context.analysisPriorityOrder = sourceList;
773 }); 786 });
787 Source firstSource = files.length > 0 ? getSource(files[0]) : null;
788 _onPriorityChangeController.add(new PriorityChangeEvent(firstSource));
774 } 789 }
775 790
776 /** 791 /**
777 * Returns `true` if errors should be reported for [file] with the given 792 * Returns `true` if errors should be reported for [file] with the given
778 * absolute path. 793 * absolute path.
779 */ 794 */
780 bool shouldSendErrorsNotificationFor(String file) { 795 bool shouldSendErrorsNotificationFor(String file) {
781 // TODO(scheglov) add support for the "--no-error-notification" flag. 796 // TODO(scheglov) add support for the "--no-error-notification" flag.
782 return contextDirectoryManager.isInAnalysisRoot(file); 797 return contextDirectoryManager.isInAnalysisRoot(file);
783 } 798 }
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 934
920 /** 935 /**
921 * The contexts that were removed from the server. 936 * The contexts that were removed from the server.
922 */ 937 */
923 final List<AnalysisContext> removed; 938 final List<AnalysisContext> removed;
924 939
925 ContextsChangedEvent({this.added: AnalysisContext.EMPTY_LIST, this.changed: 940 ContextsChangedEvent({this.added: AnalysisContext.EMPTY_LIST, this.changed:
926 AnalysisContext.EMPTY_LIST, this.removed: AnalysisContext.EMPTY_LIST}); 941 AnalysisContext.EMPTY_LIST, this.removed: AnalysisContext.EMPTY_LIST});
927 } 942 }
928 943
944 /**
945 * A [PriorityChangeEvent] indicates which sources are currently prioritized
Brian Wilkerson 2014/11/24 16:17:11 I think it indicates that the list of priority cha
danrubel 2014/11/24 17:54:06 Cleaned up.
946 * and should be analyzed before other sources.
947 */
948 class PriorityChangeEvent {
949 final Source firstSource;
Brian Wilkerson 2014/11/24 16:17:11 Shouldn't this be a List<Source>? Or possibly a Ma
danrubel 2014/11/24 17:54:05 I only need the first source if there is one and I
Brian Wilkerson 2014/11/24 18:14:38 Understood, and in general I agree with only doing
950
951 PriorityChangeEvent(this.firstSource);
952 }
953
929 class ServerContextManager extends ContextManager { 954 class ServerContextManager extends ContextManager {
930 final AnalysisServer analysisServer; 955 final AnalysisServer analysisServer;
931 956
932 /** 957 /**
933 * The default options used to create new analysis contexts. 958 * The default options used to create new analysis contexts.
934 */ 959 */
935 AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl(); 960 AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
936 961
937 /** 962 /**
938 * The controller for sending [ContextsChangedEvent]s. 963 * The controller for sending [ContextsChangedEvent]s.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 * [packageUriResolver]. 1024 * [packageUriResolver].
1000 */ 1025 */
1001 SourceFactory _createSourceFactory(UriResolver packageUriResolver) { 1026 SourceFactory _createSourceFactory(UriResolver packageUriResolver) {
1002 List<UriResolver> resolvers = <UriResolver>[ 1027 List<UriResolver> resolvers = <UriResolver>[
1003 new DartUriResolver(analysisServer.defaultSdk), 1028 new DartUriResolver(analysisServer.defaultSdk),
1004 new ResourceUriResolver(resourceProvider), 1029 new ResourceUriResolver(resourceProvider),
1005 packageUriResolver]; 1030 packageUriResolver];
1006 return new SourceFactory(resolvers); 1031 return new SourceFactory(resolvers);
1007 } 1032 }
1008 } 1033 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/domain_analysis.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698