| 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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 final StreamController<ExceptionResult> _exceptionController = | 233 final StreamController<ExceptionResult> _exceptionController = |
| 234 new StreamController<ExceptionResult>(); | 234 new StreamController<ExceptionResult>(); |
| 235 | 235 |
| 236 /** | 236 /** |
| 237 * The instance of the [Search] helper. | 237 * The instance of the [Search] helper. |
| 238 */ | 238 */ |
| 239 Search _search; | 239 Search _search; |
| 240 | 240 |
| 241 AnalysisDriverTestView _testView; | 241 AnalysisDriverTestView _testView; |
| 242 | 242 |
| 243 FileSystemState _fsState; |
| 244 |
| 243 /** | 245 /** |
| 244 * The [FileTracker] used by this driver. | 246 * The [FileTracker] used by this driver. |
| 245 */ | 247 */ |
| 246 FileTracker _fileTracker; | 248 FileTracker _fileTracker; |
| 247 | 249 |
| 248 /** | 250 /** |
| 249 * When this flag is set to `true`, the set of analyzed files must not change, | 251 * When this flag is set to `true`, the set of analyzed files must not change, |
| 250 * and all [AnalysisResult]s are cached infinitely. | 252 * and all [AnalysisResult]s are cached infinitely. |
| 251 * | 253 * |
| 252 * The flag is intended to be used for non-interactive clients, like DDC, | 254 * The flag is intended to be used for non-interactive clients, like DDC, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 this._analysisOptions, | 287 this._analysisOptions, |
| 286 {PackageBundle sdkBundle, | 288 {PackageBundle sdkBundle, |
| 287 this.disableChangesAndCacheAllResults: false, | 289 this.disableChangesAndCacheAllResults: false, |
| 288 SummaryDataStore externalSummaries}) | 290 SummaryDataStore externalSummaries}) |
| 289 : _logger = logger, | 291 : _logger = logger, |
| 290 _sourceFactory = sourceFactory.clone(), | 292 _sourceFactory = sourceFactory.clone(), |
| 291 _sdkBundle = sdkBundle, | 293 _sdkBundle = sdkBundle, |
| 292 _externalSummaries = externalSummaries { | 294 _externalSummaries = externalSummaries { |
| 293 _onResults = _resultController.stream.asBroadcastStream(); | 295 _onResults = _resultController.stream.asBroadcastStream(); |
| 294 _testView = new AnalysisDriverTestView(this); | 296 _testView = new AnalysisDriverTestView(this); |
| 295 _createFileTracker(logger); | 297 _createFileTracker(); |
| 296 _scheduler.add(this); | 298 _scheduler.add(this); |
| 297 _search = new Search(this); | 299 _search = new Search(this); |
| 298 } | 300 } |
| 299 | 301 |
| 300 /** | 302 /** |
| 301 * Return the set of files explicitly added to analysis using [addFile]. | 303 * Return the set of files explicitly added to analysis using [addFile]. |
| 302 */ | 304 */ |
| 303 Set<String> get addedFiles => _fileTracker.addedFiles; | 305 Set<String> get addedFiles => _fileTracker.addedFiles; |
| 304 | 306 |
| 305 /** | 307 /** |
| 306 * Return the analysis options used to control analysis. | 308 * Return the analysis options used to control analysis. |
| 307 */ | 309 */ |
| 308 AnalysisOptions get analysisOptions => _analysisOptions; | 310 AnalysisOptions get analysisOptions => _analysisOptions; |
| 309 | 311 |
| 310 /** | 312 /** |
| 311 * Return the stream that produces [ExceptionResult]s. | 313 * Return the stream that produces [ExceptionResult]s. |
| 312 */ | 314 */ |
| 313 Stream<ExceptionResult> get exceptions => _exceptionController.stream; | 315 Stream<ExceptionResult> get exceptions => _exceptionController.stream; |
| 314 | 316 |
| 315 /** | 317 /** |
| 316 * The current file system state. | 318 * The current file system state. |
| 317 */ | 319 */ |
| 318 FileSystemState get fsState => _fileTracker.fsState; | 320 FileSystemState get fsState => _fsState; |
| 319 | 321 |
| 320 /** | 322 /** |
| 321 * Return `true` if the driver has a file to analyze. | 323 * Return `true` if the driver has a file to analyze. |
| 322 */ | 324 */ |
| 323 bool get hasFilesToAnalyze { | 325 bool get hasFilesToAnalyze { |
| 324 return _fileTracker.hasChangedFiles || | 326 return _fileTracker.hasChangedFiles || |
| 325 _requestedFiles.isNotEmpty || | 327 _requestedFiles.isNotEmpty || |
| 326 _requestedParts.isNotEmpty || | 328 _requestedParts.isNotEmpty || |
| 327 _fileTracker.hasPendingFiles || | 329 _fileTracker.hasPendingFiles || |
| 328 _partsToAnalyze.isNotEmpty; | 330 _partsToAnalyze.isNotEmpty; |
| 329 } | 331 } |
| 330 | 332 |
| 331 /** | 333 /** |
| 332 * Return the set of files that are known at this moment. This set does not | 334 * Return the set of files that are known at this moment. This set does not |
| 333 * always include all added files or all implicitly used file. If a file has | 335 * always include all added files or all implicitly used file. If a file has |
| 334 * not been processed yet, it might be missing. | 336 * not been processed yet, it might be missing. |
| 335 */ | 337 */ |
| 336 Set<String> get knownFiles => _fileTracker.fsState.knownFilePaths; | 338 Set<String> get knownFiles => _fsState.knownFilePaths; |
| 337 | 339 |
| 338 /** | 340 /** |
| 339 * Return the path of the folder at the root of the context. | 341 * Return the path of the folder at the root of the context. |
| 340 */ | 342 */ |
| 341 String get name => contextRoot?.root ?? ''; | 343 String get name => contextRoot?.root ?? ''; |
| 342 | 344 |
| 343 /** | 345 /** |
| 344 * Return the number of files scheduled for analysis. | 346 * Return the number of files scheduled for analysis. |
| 345 */ | 347 */ |
| 346 int get numberOfFilesToAnalyze => _fileTracker.numberOfPendingFiles; | 348 int get numberOfFilesToAnalyze => _fileTracker.numberOfPendingFiles; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 } | 461 } |
| 460 | 462 |
| 461 /** | 463 /** |
| 462 * Add the file with the given [path] to the set of files to analyze. | 464 * Add the file with the given [path] to the set of files to analyze. |
| 463 * | 465 * |
| 464 * The [path] must be absolute and normalized. | 466 * The [path] must be absolute and normalized. |
| 465 * | 467 * |
| 466 * The results of analysis are eventually produced by the [results] stream. | 468 * The results of analysis are eventually produced by the [results] stream. |
| 467 */ | 469 */ |
| 468 void addFile(String path) { | 470 void addFile(String path) { |
| 469 if (!_fileTracker.fsState.hasUri(path)) { | 471 if (!_fsState.hasUri(path)) { |
| 470 return; | 472 return; |
| 471 } | 473 } |
| 472 if (AnalysisEngine.isDartFileName(path)) { | 474 if (AnalysisEngine.isDartFileName(path)) { |
| 473 _fileTracker.addFile(path); | 475 _fileTracker.addFile(path); |
| 474 } | 476 } |
| 475 } | 477 } |
| 476 | 478 |
| 477 /** | 479 /** |
| 478 * The file with the given [path] might have changed - updated, added or | 480 * The file with the given [path] might have changed - updated, added or |
| 479 * removed. Or not, we don't know. Or it might have, but then changed back. | 481 * removed. Or not, we don't know. Or it might have, but then changed back. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 507 */ | 509 */ |
| 508 void configure( | 510 void configure( |
| 509 {AnalysisOptions analysisOptions, SourceFactory sourceFactory}) { | 511 {AnalysisOptions analysisOptions, SourceFactory sourceFactory}) { |
| 510 if (analysisOptions != null) { | 512 if (analysisOptions != null) { |
| 511 _analysisOptions = analysisOptions; | 513 _analysisOptions = analysisOptions; |
| 512 } | 514 } |
| 513 if (sourceFactory != null) { | 515 if (sourceFactory != null) { |
| 514 _sourceFactory = sourceFactory; | 516 _sourceFactory = sourceFactory; |
| 515 } | 517 } |
| 516 Iterable<String> addedFiles = _fileTracker.addedFiles; | 518 Iterable<String> addedFiles = _fileTracker.addedFiles; |
| 517 _createFileTracker(_logger); | 519 _createFileTracker(); |
| 518 _fileTracker.addFiles(addedFiles); | 520 _fileTracker.addFiles(addedFiles); |
| 519 } | 521 } |
| 520 | 522 |
| 521 /** | 523 /** |
| 522 * Notify the driver that the client is going to stop using it. | 524 * Notify the driver that the client is going to stop using it. |
| 523 */ | 525 */ |
| 524 void dispose() { | 526 void dispose() { |
| 525 _scheduler._remove(this); | 527 _scheduler._remove(this); |
| 526 } | 528 } |
| 527 | 529 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 _scheduler.notify(this); | 578 _scheduler.notify(this); |
| 577 return task.completer.future; | 579 return task.completer.future; |
| 578 } | 580 } |
| 579 | 581 |
| 580 /** | 582 /** |
| 581 * Return a [Future] that completes with the [AnalysisDriverUnitIndex] for | 583 * Return a [Future] that completes with the [AnalysisDriverUnitIndex] for |
| 582 * the file with the given [path], or with `null` if the file cannot be | 584 * the file with the given [path], or with `null` if the file cannot be |
| 583 * analyzed. | 585 * analyzed. |
| 584 */ | 586 */ |
| 585 Future<AnalysisDriverUnitIndex> getIndex(String path) { | 587 Future<AnalysisDriverUnitIndex> getIndex(String path) { |
| 586 if (!_fileTracker.fsState.hasUri(path)) { | 588 if (!_fsState.hasUri(path)) { |
| 587 return new Future.value(); | 589 return new Future.value(); |
| 588 } | 590 } |
| 589 var completer = new Completer<AnalysisDriverUnitIndex>(); | 591 var completer = new Completer<AnalysisDriverUnitIndex>(); |
| 590 _indexRequestedFiles | 592 _indexRequestedFiles |
| 591 .putIfAbsent(path, () => <Completer<AnalysisDriverUnitIndex>>[]) | 593 .putIfAbsent(path, () => <Completer<AnalysisDriverUnitIndex>>[]) |
| 592 .add(completer); | 594 .add(completer); |
| 593 _scheduler.notify(this); | 595 _scheduler.notify(this); |
| 594 return completer.future; | 596 return completer.future; |
| 595 } | 597 } |
| 596 | 598 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 612 * | 614 * |
| 613 * If the driver has the cached analysis result for the file, it is returned. | 615 * If the driver has the cached analysis result for the file, it is returned. |
| 614 * | 616 * |
| 615 * Otherwise causes the analysis state to transition to "analyzing" (if it is | 617 * Otherwise causes the analysis state to transition to "analyzing" (if it is |
| 616 * not in that state already), the driver will produce the analysis result for | 618 * not in that state already), the driver will produce the analysis result for |
| 617 * it, which is consistent with the current file state (including new states | 619 * it, which is consistent with the current file state (including new states |
| 618 * of the files previously reported using [changeFile]), prior to the next | 620 * of the files previously reported using [changeFile]), prior to the next |
| 619 * time the analysis state transitions to "idle". | 621 * time the analysis state transitions to "idle". |
| 620 */ | 622 */ |
| 621 Future<AnalysisResult> getResult(String path) { | 623 Future<AnalysisResult> getResult(String path) { |
| 622 if (!_fileTracker.fsState.hasUri(path)) { | 624 if (!_fsState.hasUri(path)) { |
| 623 return new Future.value(); | 625 return new Future.value(); |
| 624 } | 626 } |
| 625 | 627 |
| 626 // Return the cached result. | 628 // Return the cached result. |
| 627 { | 629 { |
| 628 AnalysisResult result = _priorityResults[path]; | 630 AnalysisResult result = _priorityResults[path]; |
| 629 if (disableChangesAndCacheAllResults) { | 631 if (disableChangesAndCacheAllResults) { |
| 630 result ??= _allCachedResults[path]; | 632 result ??= _allCachedResults[path]; |
| 631 } | 633 } |
| 632 if (result != null) { | 634 if (result != null) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 645 | 647 |
| 646 /** | 648 /** |
| 647 * Return a [Future] that completes with the [SourceKind] for the Dart | 649 * Return a [Future] that completes with the [SourceKind] for the Dart |
| 648 * file with the given [path]. If the file is not a Dart file or cannot | 650 * file with the given [path]. If the file is not a Dart file or cannot |
| 649 * be analyzed, the [Future] completes with `null`. | 651 * be analyzed, the [Future] completes with `null`. |
| 650 * | 652 * |
| 651 * The [path] must be absolute and normalized. | 653 * The [path] must be absolute and normalized. |
| 652 */ | 654 */ |
| 653 Future<SourceKind> getSourceKind(String path) async { | 655 Future<SourceKind> getSourceKind(String path) async { |
| 654 if (AnalysisEngine.isDartFileName(path)) { | 656 if (AnalysisEngine.isDartFileName(path)) { |
| 655 FileState file = _fileTracker.fsState.getFileForPath(path); | 657 FileState file = _fsState.getFileForPath(path); |
| 656 return file.isPart ? SourceKind.PART : SourceKind.LIBRARY; | 658 return file.isPart ? SourceKind.PART : SourceKind.LIBRARY; |
| 657 } | 659 } |
| 658 return null; | 660 return null; |
| 659 } | 661 } |
| 660 | 662 |
| 661 /** | 663 /** |
| 662 * Return a [Future] that completes with top-level declarations with the | 664 * Return a [Future] that completes with top-level declarations with the |
| 663 * given [name] in all known libraries. | 665 * given [name] in all known libraries. |
| 664 */ | 666 */ |
| 665 Future<List<TopLevelDeclarationInSource>> getTopLevelNameDeclarations( | 667 Future<List<TopLevelDeclarationInSource>> getTopLevelNameDeclarations( |
| 666 String name) { | 668 String name) { |
| 667 var task = new _TopLevelNameDeclarationsTask(this, name); | 669 var task = new _TopLevelNameDeclarationsTask(this, name); |
| 668 _topLevelNameDeclarationsTasks.add(task); | 670 _topLevelNameDeclarationsTasks.add(task); |
| 669 _scheduler.notify(this); | 671 _scheduler.notify(this); |
| 670 return task.completer.future; | 672 return task.completer.future; |
| 671 } | 673 } |
| 672 | 674 |
| 673 /** | 675 /** |
| 674 * Return a [Future] that completes with the [UnitElementResult] for the | 676 * Return a [Future] that completes with the [UnitElementResult] for the |
| 675 * file with the given [path], or with `null` if the file cannot be analyzed. | 677 * file with the given [path], or with `null` if the file cannot be analyzed. |
| 676 */ | 678 */ |
| 677 Future<UnitElementResult> getUnitElement(String path) { | 679 Future<UnitElementResult> getUnitElement(String path) { |
| 678 if (!_fileTracker.fsState.hasUri(path)) { | 680 if (!_fsState.hasUri(path)) { |
| 679 return new Future.value(); | 681 return new Future.value(); |
| 680 } | 682 } |
| 681 var completer = new Completer<UnitElementResult>(); | 683 var completer = new Completer<UnitElementResult>(); |
| 682 _unitElementRequestedFiles | 684 _unitElementRequestedFiles |
| 683 .putIfAbsent(path, () => <Completer<UnitElementResult>>[]) | 685 .putIfAbsent(path, () => <Completer<UnitElementResult>>[]) |
| 684 .add(completer); | 686 .add(completer); |
| 685 _scheduler.notify(this); | 687 _scheduler.notify(this); |
| 686 return completer.future; | 688 return completer.future; |
| 687 } | 689 } |
| 688 | 690 |
| 689 /** | 691 /** |
| 690 * Return a [Future] that completes with the signature for the | 692 * Return a [Future] that completes with the signature for the |
| 691 * [UnitElementResult] for the file with the given [path], or with `null` if | 693 * [UnitElementResult] for the file with the given [path], or with `null` if |
| 692 * the file cannot be analyzed. | 694 * the file cannot be analyzed. |
| 693 * | 695 * |
| 694 * The signature is based the APIs of the files of the library (including | 696 * The signature is based the APIs of the files of the library (including |
| 695 * the file itself) of the requested file and the transitive closure of files | 697 * the file itself) of the requested file and the transitive closure of files |
| 696 * imported and exported by the the library. | 698 * imported and exported by the the library. |
| 697 */ | 699 */ |
| 698 Future<String> getUnitElementSignature(String path) { | 700 Future<String> getUnitElementSignature(String path) { |
| 699 if (!_fileTracker.fsState.hasUri(path)) { | 701 if (!_fsState.hasUri(path)) { |
| 700 return new Future.value(); | 702 return new Future.value(); |
| 701 } | 703 } |
| 702 var completer = new Completer<String>(); | 704 var completer = new Completer<String>(); |
| 703 _unitElementSignatureRequests | 705 _unitElementSignatureRequests |
| 704 .putIfAbsent(path, () => <Completer<String>>[]) | 706 .putIfAbsent(path, () => <Completer<String>>[]) |
| 705 .add(completer); | 707 .add(completer); |
| 706 _scheduler.notify(this); | 708 _scheduler.notify(this); |
| 707 return completer.future; | 709 return completer.future; |
| 708 } | 710 } |
| 709 | 711 |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 * analyzed anyway, even without a library. | 953 * analyzed anyway, even without a library. |
| 952 * | 954 * |
| 953 * Return [AnalysisResult._UNCHANGED] if [skipIfSameSignature] is `true` and | 955 * Return [AnalysisResult._UNCHANGED] if [skipIfSameSignature] is `true` and |
| 954 * the resolved signature of the file in its library is the same as the one | 956 * the resolved signature of the file in its library is the same as the one |
| 955 * that was the most recently produced to the client. | 957 * that was the most recently produced to the client. |
| 956 */ | 958 */ |
| 957 AnalysisResult _computeAnalysisResult(String path, | 959 AnalysisResult _computeAnalysisResult(String path, |
| 958 {bool withUnit: false, | 960 {bool withUnit: false, |
| 959 bool asIsIfPartWithoutLibrary: false, | 961 bool asIsIfPartWithoutLibrary: false, |
| 960 bool skipIfSameSignature: false}) { | 962 bool skipIfSameSignature: false}) { |
| 961 FileState file = _fileTracker.fsState.getFileForPath(path); | 963 FileState file = _fsState.getFileForPath(path); |
| 962 | 964 |
| 963 // Prepare the library - the file itself, or the known library. | 965 // Prepare the library - the file itself, or the known library. |
| 964 FileState library = file.isPart ? file.library : file; | 966 FileState library = file.isPart ? file.library : file; |
| 965 if (library == null) { | 967 if (library == null) { |
| 966 if (asIsIfPartWithoutLibrary) { | 968 if (asIsIfPartWithoutLibrary) { |
| 967 library = file; | 969 library = file; |
| 968 } else { | 970 } else { |
| 969 return null; | 971 return null; |
| 970 } | 972 } |
| 971 } | 973 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 993 // We need the fully resolved unit, or the result is not cached. | 995 // We need the fully resolved unit, or the result is not cached. |
| 994 return _logger.run('Compute analysis result for $path', () { | 996 return _logger.run('Compute analysis result for $path', () { |
| 995 try { | 997 try { |
| 996 LibraryContext libraryContext = _createLibraryContext(library); | 998 LibraryContext libraryContext = _createLibraryContext(library); |
| 997 try { | 999 try { |
| 998 _testView.numOfAnalyzedLibraries++; | 1000 _testView.numOfAnalyzedLibraries++; |
| 999 LibraryAnalyzer analyzer = new LibraryAnalyzer( | 1001 LibraryAnalyzer analyzer = new LibraryAnalyzer( |
| 1000 analysisOptions, | 1002 analysisOptions, |
| 1001 declaredVariables, | 1003 declaredVariables, |
| 1002 sourceFactory, | 1004 sourceFactory, |
| 1003 _fileTracker.fsState, | 1005 _fsState, |
| 1004 libraryContext.store, | 1006 libraryContext.store, |
| 1005 library); | 1007 library); |
| 1006 Map<FileState, UnitAnalysisResult> results = analyzer.analyze(); | 1008 Map<FileState, UnitAnalysisResult> results = analyzer.analyze(); |
| 1007 | 1009 |
| 1008 List<int> bytes; | 1010 List<int> bytes; |
| 1009 CompilationUnit resolvedUnit; | 1011 CompilationUnit resolvedUnit; |
| 1010 for (FileState unitFile in results.keys) { | 1012 for (FileState unitFile in results.keys) { |
| 1011 UnitAnalysisResult unitResult = results[unitFile]; | 1013 UnitAnalysisResult unitResult = results[unitFile]; |
| 1012 List<int> unitBytes = | 1014 List<int> unitBytes = |
| 1013 _serializeResolvedUnit(unitResult.unit, unitResult.errors); | 1015 _serializeResolvedUnit(unitResult.unit, unitResult.errors); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1047 }); | 1049 }); |
| 1048 } | 1050 } |
| 1049 | 1051 |
| 1050 AnalysisDriverUnitIndex _computeIndex(String path) { | 1052 AnalysisDriverUnitIndex _computeIndex(String path) { |
| 1051 AnalysisResult analysisResult = _computeAnalysisResult(path, | 1053 AnalysisResult analysisResult = _computeAnalysisResult(path, |
| 1052 withUnit: false, asIsIfPartWithoutLibrary: true); | 1054 withUnit: false, asIsIfPartWithoutLibrary: true); |
| 1053 return analysisResult._index; | 1055 return analysisResult._index; |
| 1054 } | 1056 } |
| 1055 | 1057 |
| 1056 UnitElementResult _computeUnitElement(String path) { | 1058 UnitElementResult _computeUnitElement(String path) { |
| 1057 FileState file = _fileTracker.fsState.getFileForPath(path); | 1059 FileState file = _fsState.getFileForPath(path); |
| 1058 FileState library = file.library ?? file; | 1060 FileState library = file.library ?? file; |
| 1059 | 1061 |
| 1060 // Create the AnalysisContext to resynthesize elements in. | 1062 // Create the AnalysisContext to resynthesize elements in. |
| 1061 LibraryContext libraryContext = _createLibraryContext(library); | 1063 LibraryContext libraryContext = _createLibraryContext(library); |
| 1062 | 1064 |
| 1063 // Resynthesize the CompilationUnitElement in the context. | 1065 // Resynthesize the CompilationUnitElement in the context. |
| 1064 try { | 1066 try { |
| 1065 CompilationUnitElement element = | 1067 CompilationUnitElement element = |
| 1066 libraryContext.computeUnitElement(library.source, file.source); | 1068 libraryContext.computeUnitElement(library.source, file.source); |
| 1067 String signature = library.transitiveSignature; | 1069 String signature = library.transitiveSignature; |
| 1068 return new UnitElementResult(path, file.contentHash, signature, element); | 1070 return new UnitElementResult(path, file.contentHash, signature, element); |
| 1069 } finally { | 1071 } finally { |
| 1070 libraryContext.dispose(); | 1072 libraryContext.dispose(); |
| 1071 } | 1073 } |
| 1072 } | 1074 } |
| 1073 | 1075 |
| 1074 String _computeUnitElementSignature(String path) { | 1076 String _computeUnitElementSignature(String path) { |
| 1075 FileState file = _fileTracker.fsState.getFileForPath(path); | 1077 FileState file = _fsState.getFileForPath(path); |
| 1076 FileState library = file.library ?? file; | 1078 FileState library = file.library ?? file; |
| 1077 return library.transitiveSignature; | 1079 return library.transitiveSignature; |
| 1078 } | 1080 } |
| 1079 | 1081 |
| 1080 /** | 1082 /** |
| 1081 * Creates a new [FileTracker] object and stores it in [_fileTracker]. | 1083 * Creates new [FileSystemState] and [FileTracker] objects. |
| 1082 * | 1084 * |
| 1083 * This is used both on initial construction and whenever the configuration | 1085 * This is used both on initial construction and whenever the configuration |
| 1084 * changes. | 1086 * changes. |
| 1085 */ | 1087 */ |
| 1086 void _createFileTracker(PerformanceLog logger) { | 1088 void _createFileTracker() { |
| 1087 _fillSalt(); | 1089 _fillSalt(); |
| 1088 _fileTracker = new FileTracker( | 1090 _fsState = new FileSystemState(_logger, _byteStore, _contentOverlay, |
| 1089 logger, | 1091 _resourceProvider, sourceFactory, analysisOptions, _salt, |
| 1090 _byteStore, | 1092 externalSummaries: _externalSummaries); |
| 1091 _contentOverlay, | 1093 _fileTracker = new FileTracker(_logger, _fsState, _changeHook); |
| 1092 _resourceProvider, | |
| 1093 sourceFactory, | |
| 1094 _analysisOptions, | |
| 1095 _salt, | |
| 1096 _externalSummaries, | |
| 1097 _changeHook); | |
| 1098 } | 1094 } |
| 1099 | 1095 |
| 1100 /** | 1096 /** |
| 1101 * Return the context in which the [library] should be analyzed. | 1097 * Return the context in which the [library] should be analyzed. |
| 1102 */ | 1098 */ |
| 1103 LibraryContext _createLibraryContext(FileState library) => | 1099 LibraryContext _createLibraryContext(FileState library) => |
| 1104 new LibraryContext.forSingleLibrary( | 1100 new LibraryContext.forSingleLibrary( |
| 1105 library, | 1101 library, |
| 1106 _logger, | 1102 _logger, |
| 1107 _sdkBundle, | 1103 _sdkBundle, |
| (...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1956 } | 1952 } |
| 1957 | 1953 |
| 1958 // If no more files to check, complete and done. | 1954 // If no more files to check, complete and done. |
| 1959 if (filesToCheck.isEmpty) { | 1955 if (filesToCheck.isEmpty) { |
| 1960 completer.complete(definingFiles); | 1956 completer.complete(definingFiles); |
| 1961 return true; | 1957 return true; |
| 1962 } | 1958 } |
| 1963 | 1959 |
| 1964 // Check the next file. | 1960 // Check the next file. |
| 1965 String path = filesToCheck.removeLast(); | 1961 String path = filesToCheck.removeLast(); |
| 1966 FileState file = driver._fileTracker.fsState.getFileForPath(path); | 1962 FileState file = driver._fsState.getFileForPath(path); |
| 1967 if (file.definedClassMemberNames.contains(name)) { | 1963 if (file.definedClassMemberNames.contains(name)) { |
| 1968 definingFiles.add(path); | 1964 definingFiles.add(path); |
| 1969 } | 1965 } |
| 1970 checkedFiles.add(path); | 1966 checkedFiles.add(path); |
| 1971 } | 1967 } |
| 1972 | 1968 |
| 1973 // We're not done yet. | 1969 // We're not done yet. |
| 1974 return false; | 1970 return false; |
| 1975 } | 1971 } |
| 1976 } | 1972 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2013 } | 2009 } |
| 2014 | 2010 |
| 2015 // If no more files to check, complete and done. | 2011 // If no more files to check, complete and done. |
| 2016 if (filesToCheck.isEmpty) { | 2012 if (filesToCheck.isEmpty) { |
| 2017 completer.complete(referencingFiles); | 2013 completer.complete(referencingFiles); |
| 2018 return true; | 2014 return true; |
| 2019 } | 2015 } |
| 2020 | 2016 |
| 2021 // Check the next file. | 2017 // Check the next file. |
| 2022 String path = filesToCheck.removeLast(); | 2018 String path = filesToCheck.removeLast(); |
| 2023 FileState file = driver._fileTracker.fsState.getFileForPath(path); | 2019 FileState file = driver._fsState.getFileForPath(path); |
| 2024 if (file.referencedNames.contains(name)) { | 2020 if (file.referencedNames.contains(name)) { |
| 2025 referencingFiles.add(path); | 2021 referencingFiles.add(path); |
| 2026 } | 2022 } |
| 2027 checkedFiles.add(path); | 2023 checkedFiles.add(path); |
| 2028 } | 2024 } |
| 2029 | 2025 |
| 2030 // We're not done yet. | 2026 // We're not done yet. |
| 2031 return false; | 2027 return false; |
| 2032 } | 2028 } |
| 2033 } | 2029 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2063 | 2059 |
| 2064 // If no more files to check, complete and done. | 2060 // If no more files to check, complete and done. |
| 2065 if (filesToCheck.isEmpty) { | 2061 if (filesToCheck.isEmpty) { |
| 2066 completer.complete(libraryDeclarations); | 2062 completer.complete(libraryDeclarations); |
| 2067 return true; | 2063 return true; |
| 2068 } | 2064 } |
| 2069 | 2065 |
| 2070 // Check the next file. | 2066 // Check the next file. |
| 2071 String path = filesToCheck.removeLast(); | 2067 String path = filesToCheck.removeLast(); |
| 2072 if (checkedFiles.add(path)) { | 2068 if (checkedFiles.add(path)) { |
| 2073 FileState file = driver._fileTracker.fsState.getFileForPath(path); | 2069 FileState file = driver._fsState.getFileForPath(path); |
| 2074 if (!file.isPart) { | 2070 if (!file.isPart) { |
| 2075 bool isExported = false; | 2071 bool isExported = false; |
| 2076 TopLevelDeclaration declaration = file.topLevelDeclarations[name]; | 2072 TopLevelDeclaration declaration = file.topLevelDeclarations[name]; |
| 2077 for (FileState part in file.partedFiles) { | 2073 for (FileState part in file.partedFiles) { |
| 2078 declaration ??= part.topLevelDeclarations[name]; | 2074 declaration ??= part.topLevelDeclarations[name]; |
| 2079 } | 2075 } |
| 2080 if (declaration == null) { | 2076 if (declaration == null) { |
| 2081 declaration = file.exportedTopLevelDeclarations[name]; | 2077 declaration = file.exportedTopLevelDeclarations[name]; |
| 2082 isExported = true; | 2078 isExported = true; |
| 2083 } | 2079 } |
| 2084 if (declaration != null) { | 2080 if (declaration != null) { |
| 2085 libraryDeclarations.add(new TopLevelDeclarationInSource( | 2081 libraryDeclarations.add(new TopLevelDeclarationInSource( |
| 2086 file.source, declaration, isExported)); | 2082 file.source, declaration, isExported)); |
| 2087 } | 2083 } |
| 2088 } | 2084 } |
| 2089 } | 2085 } |
| 2090 | 2086 |
| 2091 // We're not done yet. | 2087 // We're not done yet. |
| 2092 return false; | 2088 return false; |
| 2093 } | 2089 } |
| 2094 } | 2090 } |
| OLD | NEW |