Chromium Code Reviews| 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 63 * "idle" after a finite amount of processing. | 63 * "idle" after a finite amount of processing. |
| 64 * | 64 * |
| 65 * As a result of these guarantees, a client may ensure that the analysis | 65 * As a result of these guarantees, a client may ensure that the analysis |
| 66 * results are "eventually consistent" with the file system by simply calling | 66 * results are "eventually consistent" with the file system by simply calling |
| 67 * [changeFile] any time the contents of a file on the file system have changed. | 67 * [changeFile] any time the contents of a file on the file system have changed. |
| 68 * | 68 * |
| 69 * | 69 * |
| 70 * TODO(scheglov) Clean up the list of implicitly analyzed files. | 70 * TODO(scheglov) Clean up the list of implicitly analyzed files. |
| 71 */ | 71 */ |
| 72 class AnalysisDriver { | 72 class AnalysisDriver { |
| 73 String name; | |
| 73 final PerformanceLog _logger; | 74 final PerformanceLog _logger; |
| 74 | 75 |
| 75 /** | 76 /** |
| 76 * The resource provider for working with files. | 77 * The resource provider for working with files. |
| 77 */ | 78 */ |
| 78 final ResourceProvider _resourceProvider; | 79 final ResourceProvider _resourceProvider; |
| 79 | 80 |
| 80 /** | 81 /** |
| 81 * The byte storage to get and put serialized data. | 82 * The byte storage to get and put serialized data. |
| 82 * | 83 * |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 217 * More than one result might be produced for the same file, even if the | 218 * More than one result might be produced for the same file, even if the |
| 218 * client does not change the state of the files. | 219 * client does not change the state of the files. |
| 219 * | 220 * |
| 220 * Results might be produced even for files that have never been added | 221 * Results might be produced even for files that have never been added |
| 221 * using [addFile], for example when [getResult] was called for a file. | 222 * using [addFile], for example when [getResult] was called for a file. |
| 222 */ | 223 */ |
| 223 Stream<AnalysisResult> get results async* { | 224 Stream<AnalysisResult> get results async* { |
| 224 try { | 225 try { |
| 225 PerformanceLogSection analysisSection = null; | 226 PerformanceLogSection analysisSection = null; |
| 226 while (true) { | 227 while (true) { |
| 228 await pumpEventQueue(100); | |
|
Paul Berry
2016/10/31 20:09:39
Can you add a comment explaining why this is neede
scheglov
2016/10/31 20:37:11
Done in https://codereview.chromium.org/2466713002
| |
| 227 await _hasWork.signal; | 229 await _hasWork.signal; |
| 228 | 230 |
| 229 if (analysisSection == null) { | 231 if (analysisSection == null) { |
| 230 analysisSection = _logger.enter('Analyzing'); | 232 analysisSection = _logger.enter('Analyzing'); |
| 231 } | 233 } |
| 232 | 234 |
| 233 // Verify all changed files one at a time. | 235 // Verify all changed files one at a time. |
| 234 if (_changedFiles.isNotEmpty) { | 236 if (_changedFiles.isNotEmpty) { |
| 235 String path = _removeFirst(_changedFiles); | 237 String path = _removeFirst(_changedFiles); |
| 236 _verifyApiSignatureOfChangedFile(path); | 238 _verifyApiSignatureOfChangedFile(path); |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 700 } | 702 } |
| 701 | 703 |
| 702 /** | 704 /** |
| 703 * Remove and return the first item in the given [set]. | 705 * Remove and return the first item in the given [set]. |
| 704 */ | 706 */ |
| 705 static Object/*=T*/ _removeFirst/*<T>*/(LinkedHashSet<Object/*=T*/ > set) { | 707 static Object/*=T*/ _removeFirst/*<T>*/(LinkedHashSet<Object/*=T*/ > set) { |
| 706 Object/*=T*/ element = set.first; | 708 Object/*=T*/ element = set.first; |
| 707 set.remove(element); | 709 set.remove(element); |
| 708 return element; | 710 return element; |
| 709 } | 711 } |
| 712 | |
| 713 /** | |
| 714 * Returns a [Future] that completes after pumping the event queue [times] | |
| 715 * times. By default, this should pump the event queue enough times to allow | |
| 716 * any code to run, as long as it's not waiting on some external event. | |
| 717 */ | |
| 718 Future pumpEventQueue([int times = 5000]) { | |
|
Paul Berry
2016/10/31 20:09:38
Can we make this private? It seems hacky to use i
| |
| 719 if (times == 0) return new Future.value(); | |
| 720 // We use a delayed future to allow microtask events to finish. The | |
| 721 // Future.value or Future() constructors use scheduleMicrotask themselves an d | |
| 722 // would therefore not wait for microtask callbacks that are scheduled after | |
| 723 // invoking this method. | |
| 724 return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1)); | |
| 725 } | |
| 710 } | 726 } |
| 711 | 727 |
| 712 /** | 728 /** |
| 713 * The result of analyzing of a single file. | 729 * The result of analyzing of a single file. |
| 714 * | 730 * |
| 715 * These results are self-consistent, i.e. [content], [contentHash], the | 731 * These results are self-consistent, i.e. [content], [contentHash], the |
| 716 * resolved [unit] correspond to each other. All referenced elements, even | 732 * resolved [unit] correspond to each other. All referenced elements, even |
| 717 * external ones, are also self-consistent. But none of the results is | 733 * external ones, are also self-consistent. But none of the results is |
| 718 * guaranteed to be consistent with the state of the files. | 734 * guaranteed to be consistent with the state of the files. |
| 719 * | 735 * |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1197 } | 1213 } |
| 1198 } | 1214 } |
| 1199 for (UnlinkedExportPublic export in unit.publicNamespace.exports) { | 1215 for (UnlinkedExportPublic export in unit.publicNamespace.exports) { |
| 1200 referenced.exported.add(export.uri); | 1216 referenced.exported.add(export.uri); |
| 1201 } | 1217 } |
| 1202 return referenced; | 1218 return referenced; |
| 1203 } | 1219 } |
| 1204 | 1220 |
| 1205 _ReferencedUris._(); | 1221 _ReferencedUris._(); |
| 1206 } | 1222 } |
| OLD | NEW |