| 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:typed_data'; | 7 import 'dart:typed_data'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/element/element.dart' show CompilationUnitElement; | 10 import 'package:analyzer/dart/element/element.dart' show CompilationUnitElement; |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 * The set of part files that are currently scheduled for analysis. | 198 * The set of part files that are currently scheduled for analysis. |
| 199 */ | 199 */ |
| 200 final _partsToAnalyze = new LinkedHashSet<String>(); | 200 final _partsToAnalyze = new LinkedHashSet<String>(); |
| 201 | 201 |
| 202 /** | 202 /** |
| 203 * The controller for the [results] stream. | 203 * The controller for the [results] stream. |
| 204 */ | 204 */ |
| 205 final _resultController = new StreamController<AnalysisResult>(); | 205 final _resultController = new StreamController<AnalysisResult>(); |
| 206 | 206 |
| 207 /** | 207 /** |
| 208 * Cached results for [_priorityFiles]. |
| 209 */ |
| 210 final Map<String, AnalysisResult> _priorityResults = {}; |
| 211 |
| 212 /** |
| 208 * The instance of the status helper. | 213 * The instance of the status helper. |
| 209 */ | 214 */ |
| 210 final StatusSupport _statusSupport = new StatusSupport(); | 215 final StatusSupport _statusSupport = new StatusSupport(); |
| 211 | 216 |
| 212 /** | 217 /** |
| 213 * The controller for the [exceptions] stream. | 218 * The controller for the [exceptions] stream. |
| 214 */ | 219 */ |
| 215 final StreamController<ExceptionResult> _exceptionController = | 220 final StreamController<ExceptionResult> _exceptionController = |
| 216 new StreamController<ExceptionResult>(); | 221 new StreamController<ExceptionResult>(); |
| 217 | 222 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 /** | 304 /** |
| 300 * Set the list of files that the driver should try to analyze sooner. | 305 * Set the list of files that the driver should try to analyze sooner. |
| 301 * | 306 * |
| 302 * Every path in the list must be absolute and normalized. | 307 * Every path in the list must be absolute and normalized. |
| 303 * | 308 * |
| 304 * The driver will produce the results through the [results] stream. The | 309 * The driver will produce the results through the [results] stream. The |
| 305 * exact order in which results are produced is not defined, neither | 310 * exact order in which results are produced is not defined, neither |
| 306 * between priority files, nor between priority and non-priority files. | 311 * between priority files, nor between priority and non-priority files. |
| 307 */ | 312 */ |
| 308 void set priorityFiles(List<String> priorityPaths) { | 313 void set priorityFiles(List<String> priorityPaths) { |
| 314 _priorityFiles |
| 315 .toSet() |
| 316 .difference(priorityPaths.toSet()) |
| 317 .forEach(_priorityResults.remove); |
| 309 _priorityFiles.clear(); | 318 _priorityFiles.clear(); |
| 310 _priorityFiles.addAll(priorityPaths); | 319 _priorityFiles.addAll(priorityPaths); |
| 311 _statusSupport.transitionToAnalyzing(); | 320 _statusSupport.transitionToAnalyzing(); |
| 312 _scheduler._notify(this); | 321 _scheduler._notify(this); |
| 313 } | 322 } |
| 314 | 323 |
| 315 /** | 324 /** |
| 316 * Return the [Stream] that produces [AnalysisResult]s for added files. | 325 * Return the [Stream] that produces [AnalysisResult]s for added files. |
| 317 * | 326 * |
| 318 * Note that the stream supports only one single subscriber. | 327 * Note that the stream supports only one single subscriber. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 * Add the file with the given [path] to the set of files to analyze. | 407 * Add the file with the given [path] to the set of files to analyze. |
| 399 * | 408 * |
| 400 * The [path] must be absolute and normalized. | 409 * The [path] must be absolute and normalized. |
| 401 * | 410 * |
| 402 * The results of analysis are eventually produced by the [results] stream. | 411 * The results of analysis are eventually produced by the [results] stream. |
| 403 */ | 412 */ |
| 404 void addFile(String path) { | 413 void addFile(String path) { |
| 405 if (AnalysisEngine.isDartFileName(path)) { | 414 if (AnalysisEngine.isDartFileName(path)) { |
| 406 _addedFiles.add(path); | 415 _addedFiles.add(path); |
| 407 _filesToAnalyze.add(path); | 416 _filesToAnalyze.add(path); |
| 417 _priorityResults.clear(); |
| 408 } | 418 } |
| 409 _statusSupport.transitionToAnalyzing(); | 419 _statusSupport.transitionToAnalyzing(); |
| 410 _scheduler._notify(this); | 420 _scheduler._notify(this); |
| 411 } | 421 } |
| 412 | 422 |
| 413 /** | 423 /** |
| 414 * The file with the given [path] might have changed - updated, added or | 424 * The file with the given [path] might have changed - updated, added or |
| 415 * removed. Or not, we don't know. Or it might have, but then changed back. | 425 * removed. Or not, we don't know. Or it might have, but then changed back. |
| 416 * | 426 * |
| 417 * The [path] must be absolute and normalized. | 427 * The [path] must be absolute and normalized. |
| 418 * | 428 * |
| 419 * The [path] can be any file - explicitly or implicitly analyzed, or neither. | 429 * The [path] can be any file - explicitly or implicitly analyzed, or neither. |
| 420 * | 430 * |
| 421 * Causes the analysis state to transition to "analyzing" (if it is not in | 431 * Causes the analysis state to transition to "analyzing" (if it is not in |
| 422 * that state already). Schedules the file contents for [path] to be read | 432 * that state already). Schedules the file contents for [path] to be read |
| 423 * into the current file state prior to the next time the analysis state | 433 * into the current file state prior to the next time the analysis state |
| 424 * transitions to "idle". | 434 * transitions to "idle". |
| 425 * | 435 * |
| 426 * Invocation of this method will not prevent a [Future] returned from | 436 * Invocation of this method will not prevent a [Future] returned from |
| 427 * [getResult] from completing with a result, but the result is not | 437 * [getResult] from completing with a result, but the result is not |
| 428 * guaranteed to be consistent with the new current file state after this | 438 * guaranteed to be consistent with the new current file state after this |
| 429 * [changeFile] invocation. | 439 * [changeFile] invocation. |
| 430 */ | 440 */ |
| 431 void changeFile(String path) { | 441 void changeFile(String path) { |
| 432 if (AnalysisEngine.isDartFileName(path)) { | 442 if (AnalysisEngine.isDartFileName(path)) { |
| 433 _changedFiles.add(path); | 443 _changedFiles.add(path); |
| 434 if (_addedFiles.contains(path)) { | 444 if (_addedFiles.contains(path)) { |
| 435 _filesToAnalyze.add(path); | 445 _filesToAnalyze.add(path); |
| 436 } | 446 } |
| 447 _priorityResults.clear(); |
| 437 } | 448 } |
| 438 _statusSupport.transitionToAnalyzing(); | 449 _statusSupport.transitionToAnalyzing(); |
| 439 _scheduler._notify(this); | 450 _scheduler._notify(this); |
| 440 } | 451 } |
| 441 | 452 |
| 442 /** | 453 /** |
| 443 * Some state on which analysis depends has changed, so the driver needs to be | 454 * Some state on which analysis depends has changed, so the driver needs to be |
| 444 * re-configured with the new state. | 455 * re-configured with the new state. |
| 445 * | 456 * |
| 446 * At least one of the optional parameters should be provided, but only those | 457 * At least one of the optional parameters should be provided, but only those |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 | 519 |
| 509 /** | 520 /** |
| 510 * Return a [Future] that completes with a [AnalysisResult] for the Dart | 521 * Return a [Future] that completes with a [AnalysisResult] for the Dart |
| 511 * file with the given [path]. If the file is not a Dart file, the [Future] | 522 * file with the given [path]. If the file is not a Dart file, the [Future] |
| 512 * completes with `null`. | 523 * completes with `null`. |
| 513 * | 524 * |
| 514 * The [path] must be absolute and normalized. | 525 * The [path] must be absolute and normalized. |
| 515 * | 526 * |
| 516 * The [path] can be any file - explicitly or implicitly analyzed, or neither. | 527 * The [path] can be any file - explicitly or implicitly analyzed, or neither. |
| 517 * | 528 * |
| 518 * Causes the analysis state to transition to "analyzing" (if it is not in | 529 * If the driver has the cached analysis result for the file, it is returned. |
| 519 * that state already), the driver will read the file and produce the analysis | 530 * |
| 520 * result for it, which is consistent with the current file state (including | 531 * Otherwise causes the analysis state to transition to "analyzing" (if it is |
| 521 * the new state of the file), prior to the next time the analysis state | 532 * not in that state already), the driver will read the file and produce the |
| 522 * transitions to "idle". | 533 * analysis result for it, which is consistent with the current file state |
| 534 * (including the new state of the file), prior to the next time the analysis |
| 535 * state transitions to "idle". |
| 523 */ | 536 */ |
| 524 Future<AnalysisResult> getResult(String path) { | 537 Future<AnalysisResult> getResult(String path) { |
| 525 if (AnalysisEngine.isDartFileName(path)) { | 538 if (!AnalysisEngine.isDartFileName(path)) { |
| 526 var completer = new Completer<AnalysisResult>(); | 539 return new Future.value(); |
| 527 _requestedFiles | |
| 528 .putIfAbsent(path, () => <Completer<AnalysisResult>>[]) | |
| 529 .add(completer); | |
| 530 _statusSupport.transitionToAnalyzing(); | |
| 531 _scheduler._notify(this); | |
| 532 return completer.future; | |
| 533 } | 540 } |
| 534 return new Future.value(); | 541 |
| 542 // Return the cached result. |
| 543 { |
| 544 AnalysisResult result = _priorityResults[path]; |
| 545 if (result != null) { |
| 546 return new Future.value(result); |
| 547 } |
| 548 } |
| 549 |
| 550 // Schedule analysis. |
| 551 var completer = new Completer<AnalysisResult>(); |
| 552 _requestedFiles |
| 553 .putIfAbsent(path, () => <Completer<AnalysisResult>>[]) |
| 554 .add(completer); |
| 555 _statusSupport.transitionToAnalyzing(); |
| 556 _scheduler._notify(this); |
| 557 return completer.future; |
| 535 } | 558 } |
| 536 | 559 |
| 537 /** | 560 /** |
| 538 * Return a [Future] that completes with top-level declarations with the | 561 * Return a [Future] that completes with top-level declarations with the |
| 539 * given [name] in all known libraries. | 562 * given [name] in all known libraries. |
| 540 */ | 563 */ |
| 541 Future<List<TopLevelDeclarationInSource>> getTopLevelNameDeclarations( | 564 Future<List<TopLevelDeclarationInSource>> getTopLevelNameDeclarations( |
| 542 String name) { | 565 String name) { |
| 543 var task = new _TopLevelNameDeclarationsTask(this, name); | 566 var task = new _TopLevelNameDeclarationsTask(this, name); |
| 544 _topLevelNameDeclarationsTasks.add(task); | 567 _topLevelNameDeclarationsTasks.add(task); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 * | 614 * |
| 592 * The results of analysis of the file might still be produced by the | 615 * The results of analysis of the file might still be produced by the |
| 593 * [results] stream. The driver will try to stop producing these results, | 616 * [results] stream. The driver will try to stop producing these results, |
| 594 * but does not guarantee this. | 617 * but does not guarantee this. |
| 595 */ | 618 */ |
| 596 void removeFile(String path) { | 619 void removeFile(String path) { |
| 597 _addedFiles.remove(path); | 620 _addedFiles.remove(path); |
| 598 _filesToAnalyze.remove(path); | 621 _filesToAnalyze.remove(path); |
| 599 _fsState.removeFile(path); | 622 _fsState.removeFile(path); |
| 600 _filesToAnalyze.addAll(_addedFiles); | 623 _filesToAnalyze.addAll(_addedFiles); |
| 624 _priorityResults.clear(); |
| 601 _statusSupport.transitionToAnalyzing(); | 625 _statusSupport.transitionToAnalyzing(); |
| 602 _scheduler._notify(this); | 626 _scheduler._notify(this); |
| 603 } | 627 } |
| 604 | 628 |
| 605 /** | 629 /** |
| 606 * Return the cached or newly computed analysis result of the file with the | 630 * Return the cached or newly computed analysis result of the file with the |
| 607 * given [path]. | 631 * given [path]. |
| 608 * | 632 * |
| 609 * The result will have the fully resolved unit and will always be newly | 633 * The result will have the fully resolved unit and will always be newly |
| 610 * compute only if [withUnit] is `true`. | 634 * compute only if [withUnit] is `true`. |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 correction: error.correction)) | 712 correction: error.correction)) |
| 689 .toList(), | 713 .toList(), |
| 690 index: index) | 714 index: index) |
| 691 .toBuffer(); | 715 .toBuffer(); |
| 692 String key = _getResolvedUnitKey(libraryFile, file); | 716 String key = _getResolvedUnitKey(libraryFile, file); |
| 693 _byteStore.put(key, bytes); | 717 _byteStore.put(key, bytes); |
| 694 } | 718 } |
| 695 | 719 |
| 696 // Return the result, full or partial. | 720 // Return the result, full or partial. |
| 697 _logger.writeln('Computed new analysis result.'); | 721 _logger.writeln('Computed new analysis result.'); |
| 698 return _getAnalysisResultFromBytes(file, bytes, | 722 AnalysisResult result = _getAnalysisResultFromBytes(file, bytes, |
| 699 content: withUnit ? file.content : null, | 723 content: withUnit ? file.content : null, |
| 700 withErrors: _addedFiles.contains(path), | 724 withErrors: _addedFiles.contains(path), |
| 701 resolvedUnit: withUnit ? resolvedUnit : null); | 725 resolvedUnit: withUnit ? resolvedUnit : null); |
| 726 if (withUnit && _priorityFiles.contains(path)) { |
| 727 _priorityResults[path] = result; |
| 728 } |
| 729 return result; |
| 702 } finally { | 730 } finally { |
| 703 analysisContext.dispose(); | 731 analysisContext.dispose(); |
| 704 } | 732 } |
| 705 }); | 733 }); |
| 706 } | 734 } |
| 707 | 735 |
| 708 AnalysisDriverUnitIndex _computeIndex(String path) { | 736 AnalysisDriverUnitIndex _computeIndex(String path) { |
| 709 AnalysisResult analysisResult = _computeAnalysisResult(path, | 737 AnalysisResult analysisResult = _computeAnalysisResult(path, |
| 710 withUnit: false, asIsIfPartWithoutLibrary: true); | 738 withUnit: false, asIsIfPartWithoutLibrary: true); |
| 711 return analysisResult._index; | 739 return analysisResult._index; |
| (...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1268 } | 1296 } |
| 1269 } | 1297 } |
| 1270 | 1298 |
| 1271 @visibleForTesting | 1299 @visibleForTesting |
| 1272 class AnalysisDriverTestView { | 1300 class AnalysisDriverTestView { |
| 1273 final AnalysisDriver driver; | 1301 final AnalysisDriver driver; |
| 1274 | 1302 |
| 1275 AnalysisDriverTestView(this.driver); | 1303 AnalysisDriverTestView(this.driver); |
| 1276 | 1304 |
| 1277 Set<String> get filesToAnalyze => driver._filesToAnalyze; | 1305 Set<String> get filesToAnalyze => driver._filesToAnalyze; |
| 1306 |
| 1307 Map<String, AnalysisResult> get priorityResults => driver._priorityResults; |
| 1278 } | 1308 } |
| 1279 | 1309 |
| 1280 /** | 1310 /** |
| 1281 * The result of analyzing of a single file. | 1311 * The result of analyzing of a single file. |
| 1282 * | 1312 * |
| 1283 * These results are self-consistent, i.e. [content], [contentHash], the | 1313 * These results are self-consistent, i.e. [content], [contentHash], the |
| 1284 * resolved [unit] correspond to each other. All referenced elements, even | 1314 * resolved [unit] correspond to each other. All referenced elements, even |
| 1285 * external ones, are also self-consistent. But none of the results is | 1315 * external ones, are also self-consistent. But none of the results is |
| 1286 * guaranteed to be consistent with the state of the files. | 1316 * guaranteed to be consistent with the state of the files. |
| 1287 * | 1317 * |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1619 libraryDeclarations.add(new TopLevelDeclarationInSource( | 1649 libraryDeclarations.add(new TopLevelDeclarationInSource( |
| 1620 file.source, declaration, isExported)); | 1650 file.source, declaration, isExported)); |
| 1621 } | 1651 } |
| 1622 } | 1652 } |
| 1623 } | 1653 } |
| 1624 | 1654 |
| 1625 // We're not done yet. | 1655 // We're not done yet. |
| 1626 return false; | 1656 return false; |
| 1627 } | 1657 } |
| 1628 } | 1658 } |
| OLD | NEW |