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 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 _priorityFiles.clear(); | 196 _priorityFiles.clear(); |
197 _priorityFiles.addAll(priorityPaths); | 197 _priorityFiles.addAll(priorityPaths); |
198 _transitionToAnalyzing(); | 198 _transitionToAnalyzing(); |
199 _hasWork.notify(); | 199 _hasWork.notify(); |
200 } | 200 } |
201 | 201 |
202 /** | 202 /** |
203 * Return the [Stream] that produces [AnalysisResult]s for added files. | 203 * Return the [Stream] that produces [AnalysisResult]s for added files. |
204 * | 204 * |
205 * Analysis starts when the client starts listening to the stream, and stops | 205 * Analysis starts when the client starts listening to the stream, and stops |
206 * when the client cancels the subscription. | 206 * when the client cancels the subscription. Note that the stream supports |
| 207 * only one single subscriber. |
207 * | 208 * |
208 * When the client starts listening, the analysis state transitions to | 209 * When the client starts listening, the analysis state transitions to |
209 * "analyzing" and an analysis result is produced for every added file prior | 210 * "analyzing" and an analysis result is produced for every added file prior |
210 * to the next time the analysis state transitions to "idle". | 211 * to the next time the analysis state transitions to "idle". |
211 * | 212 * |
212 * At least one analysis result is produced for every file passed to | 213 * At least one analysis result is produced for every file passed to |
213 * [addFile] or [changeFile] prior to the next time the analysis state | 214 * [addFile] or [changeFile] prior to the next time the analysis state |
214 * transitions to "idle", unless the file is later removed from analysis | 215 * transitions to "idle", unless the file is later removed from analysis |
215 * using [removeFile]. Analysis results for other files are produced only if | 216 * using [removeFile]. Analysis results for other files are produced only if |
216 * the changes affect analysis results of other files. | 217 * the changes affect analysis results of other files. |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 Stream<AnalysisStatus> get status => _statusController.stream; | 303 Stream<AnalysisStatus> get status => _statusController.stream; |
303 | 304 |
304 /** | 305 /** |
305 * Add the file with the given [path] to the set of files to analyze. | 306 * Add the file with the given [path] to the set of files to analyze. |
306 * | 307 * |
307 * The [path] must be absolute and normalized. | 308 * The [path] must be absolute and normalized. |
308 * | 309 * |
309 * The results of analysis are eventually produced by the [results] stream. | 310 * The results of analysis are eventually produced by the [results] stream. |
310 */ | 311 */ |
311 void addFile(String path) { | 312 void addFile(String path) { |
312 _explicitFiles.add(path); | 313 if (AnalysisEngine.isDartFileName(path)) { |
313 _filesToAnalyze.add(path); | 314 _explicitFiles.add(path); |
| 315 _filesToAnalyze.add(path); |
| 316 } |
314 _transitionToAnalyzing(); | 317 _transitionToAnalyzing(); |
315 _hasWork.notify(); | 318 _hasWork.notify(); |
316 } | 319 } |
317 | 320 |
318 /** | 321 /** |
319 * The file with the given [path] might have changed - updated, added or | 322 * The file with the given [path] might have changed - updated, added or |
320 * removed. Or not, we don't know. Or it might have, but then changed back. | 323 * removed. Or not, we don't know. Or it might have, but then changed back. |
321 * | 324 * |
322 * The [path] must be absolute and normalized. | 325 * The [path] must be absolute and normalized. |
323 * | 326 * |
324 * The [path] can be any file - explicitly or implicitly analyzed, or neither. | 327 * The [path] can be any file - explicitly or implicitly analyzed, or neither. |
325 * | 328 * |
326 * Causes the analysis state to transition to "analyzing" (if it is not in | 329 * Causes the analysis state to transition to "analyzing" (if it is not in |
327 * that state already). Schedules the file contents for [path] to be read | 330 * that state already). Schedules the file contents for [path] to be read |
328 * into the current file state prior to the next time the analysis state | 331 * into the current file state prior to the next time the analysis state |
329 * transitions to "idle". | 332 * transitions to "idle". |
330 * | 333 * |
331 * Invocation of this method will not prevent a [Future] returned from | 334 * Invocation of this method will not prevent a [Future] returned from |
332 * [getResult] from completing with a result, but the result is not | 335 * [getResult] from completing with a result, but the result is not |
333 * guaranteed to be consistent with the new current file state after this | 336 * guaranteed to be consistent with the new current file state after this |
334 * [changeFile] invocation. | 337 * [changeFile] invocation. |
335 */ | 338 */ |
336 void changeFile(String path) { | 339 void changeFile(String path) { |
337 _changedFiles.add(path); | 340 if (AnalysisEngine.isDartFileName(path)) { |
338 if (_explicitFiles.contains(path)) { | 341 _changedFiles.add(path); |
339 _filesToAnalyze.add(path); | 342 if (_explicitFiles.contains(path)) { |
| 343 _filesToAnalyze.add(path); |
| 344 } |
340 } | 345 } |
341 _transitionToAnalyzing(); | 346 _transitionToAnalyzing(); |
342 _hasWork.notify(); | 347 _hasWork.notify(); |
343 } | 348 } |
344 | 349 |
345 /** | 350 /** |
346 * Return the [Future] that completes with a [AnalysisResult] for the file | 351 * Return the [Future] that completes with a [AnalysisResult] for the file |
347 * with the given [path]. | 352 * with the given [path]. |
348 * | 353 * |
349 * The [path] must be absolute and normalized. | 354 * The [path] must be absolute and normalized. |
(...skipping 10 matching lines...) Expand all Loading... |
360 var completer = new Completer<AnalysisResult>(); | 365 var completer = new Completer<AnalysisResult>(); |
361 _requestedFiles | 366 _requestedFiles |
362 .putIfAbsent(path, () => <Completer<AnalysisResult>>[]) | 367 .putIfAbsent(path, () => <Completer<AnalysisResult>>[]) |
363 .add(completer); | 368 .add(completer); |
364 _transitionToAnalyzing(); | 369 _transitionToAnalyzing(); |
365 _hasWork.notify(); | 370 _hasWork.notify(); |
366 return completer.future; | 371 return completer.future; |
367 } | 372 } |
368 | 373 |
369 /** | 374 /** |
| 375 * Returns a [Future] that completes after pumping the event queue [times] |
| 376 * times. By default, this should pump the event queue enough times to allow |
| 377 * any code to run, as long as it's not waiting on some external event. |
| 378 */ |
| 379 Future pumpEventQueue([int times = 5000]) { |
| 380 if (times == 0) return new Future.value(); |
| 381 // We use a delayed future to allow microtask events to finish. The |
| 382 // Future.value or Future() constructors use scheduleMicrotask themselves an
d |
| 383 // would therefore not wait for microtask callbacks that are scheduled after |
| 384 // invoking this method. |
| 385 return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1)); |
| 386 } |
| 387 |
| 388 /** |
370 * Remove the file with the given [path] from the list of files to analyze. | 389 * Remove the file with the given [path] from the list of files to analyze. |
371 * | 390 * |
372 * The [path] must be absolute and normalized. | 391 * The [path] must be absolute and normalized. |
373 * | 392 * |
374 * The results of analysis of the file might still be produced by the | 393 * The results of analysis of the file might still be produced by the |
375 * [results] stream. The driver will try to stop producing these results, | 394 * [results] stream. The driver will try to stop producing these results, |
376 * but does not guarantee this. | 395 * but does not guarantee this. |
377 */ | 396 */ |
378 void removeFile(String path) { | 397 void removeFile(String path) { |
379 _explicitFiles.remove(path); | 398 _explicitFiles.remove(path); |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 } | 721 } |
703 | 722 |
704 /** | 723 /** |
705 * Remove and return the first item in the given [set]. | 724 * Remove and return the first item in the given [set]. |
706 */ | 725 */ |
707 static Object/*=T*/ _removeFirst/*<T>*/(LinkedHashSet<Object/*=T*/ > set) { | 726 static Object/*=T*/ _removeFirst/*<T>*/(LinkedHashSet<Object/*=T*/ > set) { |
708 Object/*=T*/ element = set.first; | 727 Object/*=T*/ element = set.first; |
709 set.remove(element); | 728 set.remove(element); |
710 return element; | 729 return element; |
711 } | 730 } |
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]) { | |
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 } | |
726 } | 731 } |
727 | 732 |
728 /** | 733 /** |
729 * The result of analyzing of a single file. | 734 * The result of analyzing of a single file. |
730 * | 735 * |
731 * These results are self-consistent, i.e. [content], [contentHash], the | 736 * These results are self-consistent, i.e. [content], [contentHash], the |
732 * resolved [unit] correspond to each other. All referenced elements, even | 737 * resolved [unit] correspond to each other. All referenced elements, even |
733 * external ones, are also self-consistent. But none of the results is | 738 * external ones, are also self-consistent. But none of the results is |
734 * guaranteed to be consistent with the state of the files. | 739 * guaranteed to be consistent with the state of the files. |
735 * | 740 * |
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1213 } | 1218 } |
1214 } | 1219 } |
1215 for (UnlinkedExportPublic export in unit.publicNamespace.exports) { | 1220 for (UnlinkedExportPublic export in unit.publicNamespace.exports) { |
1216 referenced.exported.add(export.uri); | 1221 referenced.exported.add(export.uri); |
1217 } | 1222 } |
1218 return referenced; | 1223 return referenced; |
1219 } | 1224 } |
1220 | 1225 |
1221 _ReferencedUris._(); | 1226 _ReferencedUris._(); |
1222 } | 1227 } |
OLD | NEW |