| 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/context/context_root.dart'; | 9 import 'package:analyzer/context/context_root.dart'; |
| 10 import 'package:analyzer/context/declared_variables.dart'; | 10 import 'package:analyzer/context/declared_variables.dart'; |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 /** | 313 /** |
| 314 * Return the stream that produces [ExceptionResult]s. | 314 * Return the stream that produces [ExceptionResult]s. |
| 315 */ | 315 */ |
| 316 Stream<ExceptionResult> get exceptions => _exceptionController.stream; | 316 Stream<ExceptionResult> get exceptions => _exceptionController.stream; |
| 317 | 317 |
| 318 /** | 318 /** |
| 319 * The current file system state. | 319 * The current file system state. |
| 320 */ | 320 */ |
| 321 FileSystemState get fsState => _fsState; | 321 FileSystemState get fsState => _fsState; |
| 322 | 322 |
| 323 /** | 323 @override |
| 324 * Return `true` if the driver has a file to analyze. | |
| 325 */ | |
| 326 bool get hasFilesToAnalyze { | 324 bool get hasFilesToAnalyze { |
| 327 return _fileTracker.hasChangedFiles || | 325 return _fileTracker.hasChangedFiles || |
| 328 _requestedFiles.isNotEmpty || | 326 _requestedFiles.isNotEmpty || |
| 329 _requestedParts.isNotEmpty || | 327 _requestedParts.isNotEmpty || |
| 330 _fileTracker.hasPendingFiles || | 328 _fileTracker.hasPendingFiles || |
| 331 _partsToAnalyze.isNotEmpty; | 329 _partsToAnalyze.isNotEmpty; |
| 332 } | 330 } |
| 333 | 331 |
| 334 /** | 332 /** |
| 335 * Return the set of files that are known at this moment. This set does not | 333 * Return the set of files that are known at this moment. This set does not |
| (...skipping 10 matching lines...) Expand all Loading... |
| 346 /** | 344 /** |
| 347 * Return the number of files scheduled for analysis. | 345 * Return the number of files scheduled for analysis. |
| 348 */ | 346 */ |
| 349 int get numberOfFilesToAnalyze => _fileTracker.numberOfPendingFiles; | 347 int get numberOfFilesToAnalyze => _fileTracker.numberOfPendingFiles; |
| 350 | 348 |
| 351 /** | 349 /** |
| 352 * Return the list of files that the driver should try to analyze sooner. | 350 * Return the list of files that the driver should try to analyze sooner. |
| 353 */ | 351 */ |
| 354 List<String> get priorityFiles => _priorityFiles.toList(growable: false); | 352 List<String> get priorityFiles => _priorityFiles.toList(growable: false); |
| 355 | 353 |
| 356 /** | 354 @override |
| 357 * Set the list of files that the driver should try to analyze sooner. | |
| 358 * | |
| 359 * Every path in the list must be absolute and normalized. | |
| 360 * | |
| 361 * The driver will produce the results through the [results] stream. The | |
| 362 * exact order in which results are produced is not defined, neither | |
| 363 * between priority files, nor between priority and non-priority files. | |
| 364 */ | |
| 365 void set priorityFiles(List<String> priorityPaths) { | 355 void set priorityFiles(List<String> priorityPaths) { |
| 366 _priorityResults.keys | 356 _priorityResults.keys |
| 367 .toSet() | 357 .toSet() |
| 368 .difference(priorityPaths.toSet()) | 358 .difference(priorityPaths.toSet()) |
| 369 .forEach(_priorityResults.remove); | 359 .forEach(_priorityResults.remove); |
| 370 _priorityFiles.clear(); | 360 _priorityFiles.clear(); |
| 371 _priorityFiles.addAll(priorityPaths); | 361 _priorityFiles.addAll(priorityPaths); |
| 372 _scheduler.notify(this); | 362 _scheduler.notify(this); |
| 373 } | 363 } |
| 374 | 364 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 403 | 393 |
| 404 /** | 394 /** |
| 405 * Return the source factory used to resolve URIs to paths and restore URIs | 395 * Return the source factory used to resolve URIs to paths and restore URIs |
| 406 * from file paths. | 396 * from file paths. |
| 407 */ | 397 */ |
| 408 SourceFactory get sourceFactory => _sourceFactory; | 398 SourceFactory get sourceFactory => _sourceFactory; |
| 409 | 399 |
| 410 @visibleForTesting | 400 @visibleForTesting |
| 411 AnalysisDriverTestView get test => _testView; | 401 AnalysisDriverTestView get test => _testView; |
| 412 | 402 |
| 413 /** | 403 @override |
| 414 * Return the priority of work that the driver needs to perform. | |
| 415 */ | |
| 416 AnalysisDriverPriority get workPriority { | 404 AnalysisDriverPriority get workPriority { |
| 417 if (_requestedFiles.isNotEmpty) { | 405 if (_requestedFiles.isNotEmpty) { |
| 418 return AnalysisDriverPriority.interactive; | 406 return AnalysisDriverPriority.interactive; |
| 419 } | 407 } |
| 420 if (_definingClassMemberNameTasks.isNotEmpty || | 408 if (_definingClassMemberNameTasks.isNotEmpty || |
| 421 _referencingNameTasks.isNotEmpty) { | 409 _referencingNameTasks.isNotEmpty) { |
| 422 return AnalysisDriverPriority.interactive; | 410 return AnalysisDriverPriority.interactive; |
| 423 } | 411 } |
| 424 if (_indexRequestedFiles.isNotEmpty) { | 412 if (_indexRequestedFiles.isNotEmpty) { |
| 425 return AnalysisDriverPriority.interactive; | 413 return AnalysisDriverPriority.interactive; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 _analysisOptions = analysisOptions; | 502 _analysisOptions = analysisOptions; |
| 515 } | 503 } |
| 516 if (sourceFactory != null) { | 504 if (sourceFactory != null) { |
| 517 _sourceFactory = sourceFactory; | 505 _sourceFactory = sourceFactory; |
| 518 } | 506 } |
| 519 Iterable<String> addedFiles = _fileTracker.addedFiles; | 507 Iterable<String> addedFiles = _fileTracker.addedFiles; |
| 520 _createFileTracker(); | 508 _createFileTracker(); |
| 521 _fileTracker.addFiles(addedFiles); | 509 _fileTracker.addFiles(addedFiles); |
| 522 } | 510 } |
| 523 | 511 |
| 524 /** | 512 @override |
| 525 * Notify the driver that the client is going to stop using it. | |
| 526 */ | |
| 527 void dispose() { | 513 void dispose() { |
| 528 _scheduler._remove(this); | 514 _scheduler.remove(this); |
| 529 } | 515 } |
| 530 | 516 |
| 531 /** | 517 /** |
| 532 * Return a [Future] that completes with the [ErrorsResult] for the Dart | 518 * Return a [Future] that completes with the [ErrorsResult] for the Dart |
| 533 * file with the given [path]. If the file is not a Dart file or cannot | 519 * file with the given [path]. If the file is not a Dart file or cannot |
| 534 * be analyzed, the [Future] completes with `null`. | 520 * be analyzed, the [Future] completes with `null`. |
| 535 * | 521 * |
| 536 * The [path] must be absolute and normalized. | 522 * The [path] must be absolute and normalized. |
| 537 * | 523 * |
| 538 * This method does not use analysis priorities, and must not be used in | 524 * This method does not use analysis priorities, and must not be used in |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 * resolved unit). | 732 * resolved unit). |
| 747 */ | 733 */ |
| 748 Future<ParseResult> parseFile(String path) async { | 734 Future<ParseResult> parseFile(String path) async { |
| 749 FileState file = _fileTracker.verifyApiSignature(path); | 735 FileState file = _fileTracker.verifyApiSignature(path); |
| 750 RecordingErrorListener listener = new RecordingErrorListener(); | 736 RecordingErrorListener listener = new RecordingErrorListener(); |
| 751 CompilationUnit unit = file.parse(listener); | 737 CompilationUnit unit = file.parse(listener); |
| 752 return new ParseResult(file.path, file.uri, file.content, file.contentHash, | 738 return new ParseResult(file.path, file.uri, file.content, file.contentHash, |
| 753 unit.lineInfo, unit, listener.errors); | 739 unit.lineInfo, unit, listener.errors); |
| 754 } | 740 } |
| 755 | 741 |
| 756 /** | 742 @override |
| 757 * Perform a single chunk of work and produce [results]. | |
| 758 */ | |
| 759 Future<Null> performWork() async { | 743 Future<Null> performWork() async { |
| 760 if (_fileTracker.verifyChangedFilesIfNeeded()) { | 744 if (_fileTracker.verifyChangedFilesIfNeeded()) { |
| 761 return; | 745 return; |
| 762 } | 746 } |
| 763 | 747 |
| 764 // Analyze a requested file. | 748 // Analyze a requested file. |
| 765 if (_requestedFiles.isNotEmpty) { | 749 if (_requestedFiles.isNotEmpty) { |
| 766 String path = _requestedFiles.keys.first; | 750 String path = _requestedFiles.keys.first; |
| 767 try { | 751 try { |
| 768 AnalysisResult result = _computeAnalysisResult(path, withUnit: true); | 752 AnalysisResult result = _computeAnalysisResult(path, withUnit: true); |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1341 * a temporary measure until the official plugin API is ready (and a different | 1325 * a temporary measure until the official plugin API is ready (and a different |
| 1342 * scheduler is used) | 1326 * scheduler is used) |
| 1343 */ | 1327 */ |
| 1344 abstract class AnalysisDriverGeneric { | 1328 abstract class AnalysisDriverGeneric { |
| 1345 /** | 1329 /** |
| 1346 * Return `true` if the driver has a file to analyze. | 1330 * Return `true` if the driver has a file to analyze. |
| 1347 */ | 1331 */ |
| 1348 bool get hasFilesToAnalyze; | 1332 bool get hasFilesToAnalyze; |
| 1349 | 1333 |
| 1350 /** | 1334 /** |
| 1335 * Set the list of files that the driver should try to analyze sooner. |
| 1336 * |
| 1337 * Every path in the list must be absolute and normalized. |
| 1338 * |
| 1339 * The driver will produce the results through the [results] stream. The |
| 1340 * exact order in which results are produced is not defined, neither |
| 1341 * between priority files, nor between priority and non-priority files. |
| 1342 */ |
| 1343 void set priorityFiles(List<String> priorityPaths); |
| 1344 |
| 1345 /** |
| 1351 * Return the priority of work that the driver needs to perform. | 1346 * Return the priority of work that the driver needs to perform. |
| 1352 */ | 1347 */ |
| 1353 AnalysisDriverPriority get workPriority; | 1348 AnalysisDriverPriority get workPriority; |
| 1354 | 1349 |
| 1355 /** | 1350 /** |
| 1351 * Notify the driver that the client is going to stop using it. |
| 1352 */ |
| 1353 void dispose(); |
| 1354 |
| 1355 /** |
| 1356 * Perform a single chunk of work and produce [results]. | 1356 * Perform a single chunk of work and produce [results]. |
| 1357 */ | 1357 */ |
| 1358 Future<Null> performWork(); | 1358 Future<Null> performWork(); |
| 1359 } | 1359 } |
| 1360 | 1360 |
| 1361 /** | 1361 /** |
| 1362 * Priorities of [AnalysisDriver] work. The farther a priority to the beginning | 1362 * Priorities of [AnalysisDriver] work. The farther a priority to the beginning |
| 1363 * of the list, the earlier the corresponding [AnalysisDriver] should be asked | 1363 * of the list, the earlier the corresponding [AnalysisDriver] should be asked |
| 1364 * to perform work. | 1364 * to perform work. |
| 1365 */ | 1365 */ |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1451 /** | 1451 /** |
| 1452 * Notify that there is a change to the [driver], it it might need to | 1452 * Notify that there is a change to the [driver], it it might need to |
| 1453 * perform some work. | 1453 * perform some work. |
| 1454 */ | 1454 */ |
| 1455 void notify(AnalysisDriverGeneric driver) { | 1455 void notify(AnalysisDriverGeneric driver) { |
| 1456 _hasWork.notify(); | 1456 _hasWork.notify(); |
| 1457 _statusSupport.preTransitionToAnalyzing(); | 1457 _statusSupport.preTransitionToAnalyzing(); |
| 1458 } | 1458 } |
| 1459 | 1459 |
| 1460 /** | 1460 /** |
| 1461 * Remove the given [driver] from the scheduler, so that it will not be |
| 1462 * asked to perform any new work. |
| 1463 */ |
| 1464 void remove(AnalysisDriverGeneric driver) { |
| 1465 if (driver is AnalysisDriver) { |
| 1466 driverWatcher?.removedDriver(driver); |
| 1467 } |
| 1468 _drivers.remove(driver); |
| 1469 _hasWork.notify(); |
| 1470 } |
| 1471 |
| 1472 /** |
| 1461 * Start the scheduler, so that any [AnalysisDriver] created before or | 1473 * Start the scheduler, so that any [AnalysisDriver] created before or |
| 1462 * after will be asked to perform work. | 1474 * after will be asked to perform work. |
| 1463 */ | 1475 */ |
| 1464 void start() { | 1476 void start() { |
| 1465 if (_started) { | 1477 if (_started) { |
| 1466 throw new StateError('The scheduler has already been started.'); | 1478 throw new StateError('The scheduler has already been started.'); |
| 1467 } | 1479 } |
| 1468 _started = true; | 1480 _started = true; |
| 1469 _run(); | 1481 _run(); |
| 1470 } | 1482 } |
| 1471 | 1483 |
| 1472 /** | 1484 /** |
| 1473 * Return a future that will be completed the next time the status is idle. | 1485 * Return a future that will be completed the next time the status is idle. |
| 1474 * | 1486 * |
| 1475 * If the status is currently idle, the returned future will be signaled | 1487 * If the status is currently idle, the returned future will be signaled |
| 1476 * immediately. | 1488 * immediately. |
| 1477 */ | 1489 */ |
| 1478 Future<Null> waitForIdle() => _statusSupport.waitForIdle(); | 1490 Future<Null> waitForIdle() => _statusSupport.waitForIdle(); |
| 1479 | 1491 |
| 1480 /** | 1492 /** |
| 1481 * Remove the given [driver] from the scheduler, so that it will not be | |
| 1482 * asked to perform any new work. | |
| 1483 */ | |
| 1484 void _remove(AnalysisDriverGeneric driver) { | |
| 1485 if (driver is AnalysisDriver) { | |
| 1486 driverWatcher?.removedDriver(driver); | |
| 1487 } | |
| 1488 | |
| 1489 _drivers.remove(driver); | |
| 1490 _hasWork.notify(); | |
| 1491 } | |
| 1492 | |
| 1493 /** | |
| 1494 * Run infinitely analysis cycle, selecting the drivers with the highest | 1493 * Run infinitely analysis cycle, selecting the drivers with the highest |
| 1495 * priority first. | 1494 * priority first. |
| 1496 */ | 1495 */ |
| 1497 Future<Null> _run() async { | 1496 Future<Null> _run() async { |
| 1498 Stopwatch timer = new Stopwatch()..start(); | 1497 Stopwatch timer = new Stopwatch()..start(); |
| 1499 PerformanceLogSection analysisSection; | 1498 PerformanceLogSection analysisSection; |
| 1500 while (true) { | 1499 while (true) { |
| 1501 // Pump the event queue. | 1500 // Pump the event queue. |
| 1502 if (timer.elapsedMilliseconds > _MS_BEFORE_PUMPING_EVENT_QUEUE) { | 1501 if (timer.elapsedMilliseconds > _MS_BEFORE_PUMPING_EVENT_QUEUE) { |
| 1503 await _pumpEventQueue(_NUMBER_OF_EVENT_QUEUE_PUMPINGS); | 1502 await _pumpEventQueue(_NUMBER_OF_EVENT_QUEUE_PUMPINGS); |
| (...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2101 libraryDeclarations.add(new TopLevelDeclarationInSource( | 2100 libraryDeclarations.add(new TopLevelDeclarationInSource( |
| 2102 file.source, declaration, isExported)); | 2101 file.source, declaration, isExported)); |
| 2103 } | 2102 } |
| 2104 } | 2103 } |
| 2105 } | 2104 } |
| 2106 | 2105 |
| 2107 // We're not done yet. | 2106 // We're not done yet. |
| 2108 return false; | 2107 return false; |
| 2109 } | 2108 } |
| 2110 } | 2109 } |
| OLD | NEW |