OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:collection'; | 6 import 'dart:collection'; |
7 import 'dart:convert'; | 7 import 'dart:convert'; |
8 | 8 |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/ast/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
224 * More than one result might be produced for the same file, even if the | 224 * More than one result might be produced for the same file, even if the |
225 * client does not change the state of the files. | 225 * client does not change the state of the files. |
226 * | 226 * |
227 * Results might be produced even for files that have never been added | 227 * Results might be produced even for files that have never been added |
228 * using [addFile], for example when [getResult] was called for a file. | 228 * using [addFile], for example when [getResult] was called for a file. |
229 */ | 229 */ |
230 Stream<AnalysisResult> get results async* { | 230 Stream<AnalysisResult> get results async* { |
231 try { | 231 try { |
232 PerformanceLogSection analysisSection = null; | 232 PerformanceLogSection analysisSection = null; |
233 while (true) { | 233 while (true) { |
234 await pumpEventQueue(100); | 234 // Pump the event queue to allow IO and other asynchronous data |
235 // processing while analysis is active. For example Analysis Server | |
236 // need to be able to process update content or set priority requests | |
Brian Wilkerson
2016/10/31 20:41:04
"need" --> "needs"
"update content" --> "updateCon
scheglov
2016/10/31 20:48:14
Done.
| |
237 // while background analysis is in progress. | |
238 // | |
239 // The number of pumpings is arbitrary, might be changed if we see that | |
240 // analysis or other data processing tasks are starving. Ideally we | |
241 // would need to be able to set priority of (continuous) asynchronous | |
242 // tasks. | |
243 await _pumpEventQueue(128); | |
Florian Schneider
2016/10/31 20:41:01
dbc: This seems arbitrary. Why not wait on the com
scheglov
2016/10/31 20:48:14
Yes, the number is arbitrary.
The question does n
Florian Schneider
2016/10/31 22:16:50
What happens if this number is too low, or too hig
Paul Berry
2016/10/31 22:40:33
Unfortunately this is a different situation from t
| |
244 | |
235 await _hasWork.signal; | 245 await _hasWork.signal; |
236 | 246 |
237 if (analysisSection == null) { | 247 if (analysisSection == null) { |
238 analysisSection = _logger.enter('Analyzing'); | 248 analysisSection = _logger.enter('Analyzing'); |
239 } | 249 } |
240 | 250 |
241 // Verify all changed files one at a time. | 251 // Verify all changed files one at a time. |
242 if (_changedFiles.isNotEmpty) { | 252 if (_changedFiles.isNotEmpty) { |
243 String path = _removeFirst(_changedFiles); | 253 String path = _removeFirst(_changedFiles); |
244 _verifyApiSignatureOfChangedFile(path); | 254 _verifyApiSignatureOfChangedFile(path); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
370 var completer = new Completer<AnalysisResult>(); | 380 var completer = new Completer<AnalysisResult>(); |
371 _requestedFiles | 381 _requestedFiles |
372 .putIfAbsent(path, () => <Completer<AnalysisResult>>[]) | 382 .putIfAbsent(path, () => <Completer<AnalysisResult>>[]) |
373 .add(completer); | 383 .add(completer); |
374 _transitionToAnalyzing(); | 384 _transitionToAnalyzing(); |
375 _hasWork.notify(); | 385 _hasWork.notify(); |
376 return completer.future; | 386 return completer.future; |
377 } | 387 } |
378 | 388 |
379 /** | 389 /** |
380 * Returns a [Future] that completes after pumping the event queue [times] | |
381 * times. By default, this should pump the event queue enough times to allow | |
382 * any code to run, as long as it's not waiting on some external event. | |
383 */ | |
384 Future pumpEventQueue([int times = 5000]) { | |
385 if (times == 0) return new Future.value(); | |
386 // We use a delayed future to allow microtask events to finish. The | |
387 // Future.value or Future() constructors use scheduleMicrotask themselves an d | |
388 // would therefore not wait for microtask callbacks that are scheduled after | |
389 // invoking this method. | |
390 return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1)); | |
391 } | |
392 | |
393 /** | |
394 * Remove the file with the given [path] from the list of files to analyze. | 390 * Remove the file with the given [path] from the list of files to analyze. |
395 * | 391 * |
396 * The [path] must be absolute and normalized. | 392 * The [path] must be absolute and normalized. |
397 * | 393 * |
398 * The results of analysis of the file might still be produced by the | 394 * The results of analysis of the file might still be produced by the |
399 * [results] stream. The driver will try to stop producing these results, | 395 * [results] stream. The driver will try to stop producing these results, |
400 * but does not guarantee this. | 396 * but does not guarantee this. |
401 */ | 397 */ |
402 void removeFile(String path) { | 398 void removeFile(String path) { |
403 _explicitFiles.remove(path); | 399 _explicitFiles.remove(path); |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
718 // resolution results are invalid. | 714 // resolution results are invalid. |
719 if (oldSignature != null && oldSignature != newSignature) { | 715 if (oldSignature != null && oldSignature != newSignature) { |
720 _logger.writeln('API signatures mismatch found for $newFile'); | 716 _logger.writeln('API signatures mismatch found for $newFile'); |
721 _dependencySignatureMap.clear(); | 717 _dependencySignatureMap.clear(); |
722 _filesToAnalyze.addAll(_explicitFiles); | 718 _filesToAnalyze.addAll(_explicitFiles); |
723 } | 719 } |
724 }); | 720 }); |
725 } | 721 } |
726 | 722 |
727 /** | 723 /** |
724 * Returns a [Future] that completes after performing [times] pumpings of | |
725 * the event queue. | |
726 */ | |
727 static Future _pumpEventQueue(int times) { | |
728 if (times == 0) { | |
729 return new Future.value(); | |
730 } | |
731 return new Future.delayed(Duration.ZERO, () => _pumpEventQueue(times - 1)); | |
732 } | |
733 | |
734 /** | |
728 * Remove and return the first item in the given [set]. | 735 * Remove and return the first item in the given [set]. |
729 */ | 736 */ |
730 static Object/*=T*/ _removeFirst/*<T>*/(LinkedHashSet<Object/*=T*/ > set) { | 737 static Object/*=T*/ _removeFirst/*<T>*/(LinkedHashSet<Object/*=T*/ > set) { |
731 Object/*=T*/ element = set.first; | 738 Object/*=T*/ element = set.first; |
732 set.remove(element); | 739 set.remove(element); |
733 return element; | 740 return element; |
734 } | 741 } |
735 } | 742 } |
736 | 743 |
737 /** | 744 /** |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1222 } | 1229 } |
1223 } | 1230 } |
1224 for (UnlinkedExportPublic export in unit.publicNamespace.exports) { | 1231 for (UnlinkedExportPublic export in unit.publicNamespace.exports) { |
1225 referenced.exported.add(export.uri); | 1232 referenced.exported.add(export.uri); |
1226 } | 1233 } |
1227 return referenced; | 1234 return referenced; |
1228 } | 1235 } |
1229 | 1236 |
1230 _ReferencedUris._(); | 1237 _ReferencedUris._(); |
1231 } | 1238 } |
OLD | NEW |