| 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 |