Chromium Code Reviews| 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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 102 */ | 102 */ |
| 103 final ByteStore _byteStore; | 103 final ByteStore _byteStore; |
| 104 | 104 |
| 105 /** | 105 /** |
| 106 * This [ContentCache] is consulted for a file content before reading | 106 * This [ContentCache] is consulted for a file content before reading |
| 107 * the content from the file. | 107 * the content from the file. |
| 108 */ | 108 */ |
| 109 final FileContentOverlay _contentOverlay; | 109 final FileContentOverlay _contentOverlay; |
| 110 | 110 |
| 111 /** | 111 /** |
| 112 * The analysis options to analyze with. | |
| 113 */ | |
| 114 AnalysisOptions _analysisOptions; | |
| 115 | |
| 116 /** | |
| 112 * The [SourceFactory] is used to resolve URIs to paths and restore URIs | 117 * The [SourceFactory] is used to resolve URIs to paths and restore URIs |
| 113 * from file paths. | 118 * from file paths. |
| 114 */ | 119 */ |
| 115 final SourceFactory sourceFactory; | 120 SourceFactory _sourceFactory; |
| 116 | |
| 117 /** | |
| 118 * The analysis options to analyze with. | |
| 119 */ | |
| 120 final AnalysisOptions analysisOptions; | |
| 121 | 121 |
| 122 /** | 122 /** |
| 123 * The salt to mix into all hashes used as keys for serialized data. | 123 * The salt to mix into all hashes used as keys for serialized data. |
| 124 */ | 124 */ |
| 125 final Uint32List _salt = | 125 final Uint32List _salt = |
| 126 new Uint32List(1 + AnalysisOptions.crossContextOptionsLength); | 126 new Uint32List(1 + AnalysisOptions.crossContextOptionsLength); |
| 127 | 127 |
| 128 /** | 128 /** |
| 129 * The current file system state. | 129 * The current file system state. |
| 130 */ | 130 */ |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 226 * The given [SourceFactory] is cloned to ensure that it does not contain a | 226 * The given [SourceFactory] is cloned to ensure that it does not contain a |
| 227 * reference to a [AnalysisContext] in which it could have been used. | 227 * reference to a [AnalysisContext] in which it could have been used. |
| 228 */ | 228 */ |
| 229 AnalysisDriver( | 229 AnalysisDriver( |
| 230 this._scheduler, | 230 this._scheduler, |
| 231 this._logger, | 231 this._logger, |
| 232 this._resourceProvider, | 232 this._resourceProvider, |
| 233 this._byteStore, | 233 this._byteStore, |
| 234 this._contentOverlay, | 234 this._contentOverlay, |
| 235 SourceFactory sourceFactory, | 235 SourceFactory sourceFactory, |
| 236 this.analysisOptions) | 236 this._analysisOptions) |
| 237 : sourceFactory = sourceFactory.clone() { | 237 : _sourceFactory = sourceFactory.clone() { |
| 238 _fillSalt(); | 238 _fillSalt(); |
| 239 _sdkBundle = sourceFactory.dartSdk.getLinkedBundle(); | 239 _sdkBundle = sourceFactory.dartSdk.getLinkedBundle(); |
| 240 _fsState = new FileSystemState( | 240 _fsState = new FileSystemState( |
| 241 _logger, | 241 _logger, |
| 242 _byteStore, | 242 _byteStore, |
| 243 _contentOverlay, | 243 _contentOverlay, |
| 244 _resourceProvider, | 244 _resourceProvider, |
| 245 sourceFactory, | 245 sourceFactory, |
| 246 analysisOptions, | 246 _analysisOptions, |
| 247 _salt, | 247 _salt, |
| 248 _sdkBundle.apiSignature); | 248 _sdkBundle.apiSignature); |
| 249 _scheduler._add(this); | 249 _scheduler._add(this); |
| 250 _search = new Search(this); | 250 _search = new Search(this); |
| 251 } | 251 } |
| 252 | 252 |
| 253 /** | 253 /** |
| 254 * Return the set of files explicitly added to analysis using [addFile]. | 254 * Return the set of files explicitly added to analysis using [addFile]. |
| 255 */ | 255 */ |
| 256 Set<String> get addedFiles => _addedFiles; | 256 Set<String> get addedFiles => _addedFiles; |
| 257 | 257 |
| 258 /** | 258 /** |
| 259 * Return the analysis options used to control analysis. | |
| 260 */ | |
| 261 AnalysisOptions get analysisOptions => _analysisOptions; | |
| 262 | |
| 263 /** | |
| 259 * Return the stream that produces [ExceptionResult]s. | 264 * Return the stream that produces [ExceptionResult]s. |
| 260 */ | 265 */ |
| 261 Stream<ExceptionResult> get exceptions => _exceptionController.stream; | 266 Stream<ExceptionResult> get exceptions => _exceptionController.stream; |
| 262 | 267 |
| 263 /** | 268 /** |
| 264 * The current file system state. | 269 * The current file system state. |
| 265 */ | 270 */ |
| 266 FileSystemState get fsState => _fsState; | 271 FileSystemState get fsState => _fsState; |
| 267 | 272 |
| 268 /** | 273 /** |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 326 * using [addFile], for example when [getResult] was called for a file. | 331 * using [addFile], for example when [getResult] was called for a file. |
| 327 */ | 332 */ |
| 328 Stream<AnalysisResult> get results => _resultController.stream; | 333 Stream<AnalysisResult> get results => _resultController.stream; |
| 329 | 334 |
| 330 /** | 335 /** |
| 331 * Return the search support for the driver. | 336 * Return the search support for the driver. |
| 332 */ | 337 */ |
| 333 Search get search => _search; | 338 Search get search => _search; |
| 334 | 339 |
| 335 /** | 340 /** |
| 341 * Return the source factory used to resolve URIs to paths and restore URIs | |
| 342 * from file paths. | |
| 343 */ | |
| 344 SourceFactory get sourceFactory => _sourceFactory; | |
| 345 | |
| 346 /** | |
| 336 * Return the stream that produces [AnalysisStatus] events. | 347 * Return the stream that produces [AnalysisStatus] events. |
| 337 */ | 348 */ |
| 338 Stream<AnalysisStatus> get status => _statusSupport.stream; | 349 Stream<AnalysisStatus> get status => _statusSupport.stream; |
| 339 | 350 |
| 340 /** | 351 /** |
| 341 * Return the priority of work that the driver needs to perform. | 352 * Return the priority of work that the driver needs to perform. |
| 342 */ | 353 */ |
| 343 AnalysisDriverPriority get _workPriority { | 354 AnalysisDriverPriority get _workPriority { |
| 344 if (_requestedFiles.isNotEmpty) { | 355 if (_requestedFiles.isNotEmpty) { |
| 345 return AnalysisDriverPriority.interactive; | 356 return AnalysisDriverPriority.interactive; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 415 _changedFiles.add(path); | 426 _changedFiles.add(path); |
| 416 if (_addedFiles.contains(path)) { | 427 if (_addedFiles.contains(path)) { |
| 417 _filesToAnalyze.add(path); | 428 _filesToAnalyze.add(path); |
| 418 } | 429 } |
| 419 } | 430 } |
| 420 _statusSupport.transitionToAnalyzing(); | 431 _statusSupport.transitionToAnalyzing(); |
| 421 _scheduler._notify(this); | 432 _scheduler._notify(this); |
| 422 } | 433 } |
| 423 | 434 |
| 424 /** | 435 /** |
| 436 * Some state on which analysis depends has changed, so the driver needs to be | |
| 437 * re-configured with the new state. | |
| 438 * | |
| 439 * At least one of the optional parameters should be provided, but only those | |
| 440 * that represent state that has actually changed need be provided. | |
| 441 */ | |
| 442 void configure( | |
| 443 {AnalysisOptions analysisOptions, SourceFactory sourceFactory}) { | |
| 444 if (analysisOptions != null) { | |
| 445 _analysisOptions = analysisOptions; | |
| 446 _fillSalt(); | |
| 447 } | |
| 448 if (sourceFactory != null) { | |
| 449 _sourceFactory = sourceFactory; | |
| 450 _sdkBundle = sourceFactory.dartSdk.getLinkedBundle(); | |
|
scheglov
2016/12/12 21:48:52
In theory SDK can also change, so we need to _fill
| |
| 451 } | |
| 452 _fsState = new FileSystemState( | |
| 453 _logger, | |
| 454 _byteStore, | |
| 455 _contentOverlay, | |
| 456 _resourceProvider, | |
| 457 _sourceFactory, | |
| 458 _analysisOptions, | |
| 459 _salt, | |
| 460 _sdkBundle.apiSignature); | |
| 461 _filesToAnalyze.addAll(_addedFiles); | |
| 462 _statusSupport.transitionToAnalyzing(); | |
| 463 _scheduler._notify(this); | |
| 464 } | |
| 465 | |
| 466 /** | |
| 425 * Notify the driver that the client is going to stop using it. | 467 * Notify the driver that the client is going to stop using it. |
| 426 */ | 468 */ |
| 427 void dispose() { | 469 void dispose() { |
| 428 _scheduler._remove(this); | 470 _scheduler._remove(this); |
| 429 } | 471 } |
| 430 | 472 |
| 431 /** | 473 /** |
| 432 * Return a [Future] that completes with the list of added files that | 474 * Return a [Future] that completes with the list of added files that |
| 433 * reference the given external [name]. | 475 * reference the given external [name]. |
| 434 */ | 476 */ |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 666 new LibrarySpecificUnit(libraryFile.source, file.source), | 708 new LibrarySpecificUnit(libraryFile.source, file.source), |
| 667 COMPILATION_UNIT_ELEMENT); | 709 COMPILATION_UNIT_ELEMENT); |
| 668 } finally { | 710 } finally { |
| 669 analysisContext.dispose(); | 711 analysisContext.dispose(); |
| 670 } | 712 } |
| 671 } | 713 } |
| 672 | 714 |
| 673 AnalysisContext _createAnalysisContext(_LibraryContext libraryContext) { | 715 AnalysisContext _createAnalysisContext(_LibraryContext libraryContext) { |
| 674 AnalysisContextImpl analysisContext = | 716 AnalysisContextImpl analysisContext = |
| 675 AnalysisEngine.instance.createAnalysisContext(); | 717 AnalysisEngine.instance.createAnalysisContext(); |
| 676 analysisContext.analysisOptions = analysisOptions; | 718 analysisContext.analysisOptions = _analysisOptions; |
| 677 | 719 |
| 678 analysisContext.sourceFactory = sourceFactory.clone(); | 720 analysisContext.sourceFactory = _sourceFactory.clone(); |
| 679 analysisContext.resultProvider = | 721 analysisContext.resultProvider = |
| 680 new InputPackagesResultProvider(analysisContext, libraryContext.store); | 722 new InputPackagesResultProvider(analysisContext, libraryContext.store); |
| 681 analysisContext | 723 analysisContext |
| 682 .applyChanges(new ChangeSet()..addedSource(libraryContext.file.source)); | 724 .applyChanges(new ChangeSet()..addedSource(libraryContext.file.source)); |
| 683 return analysisContext; | 725 return analysisContext; |
| 684 } | 726 } |
| 685 | 727 |
| 686 /** | 728 /** |
| 687 * Return the context in which the [library] should be analyzed it. | 729 * Return the context in which the [library] should be analyzed it. |
| 688 */ | 730 */ |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 738 }); | 780 }); |
| 739 | 781 |
| 740 Map<String, LinkedLibraryBuilder> linkedLibraries = {}; | 782 Map<String, LinkedLibraryBuilder> linkedLibraries = {}; |
| 741 _logger.run('Link bundles', () { | 783 _logger.run('Link bundles', () { |
| 742 linkedLibraries = link(libraryUrisToLink, (String uri) { | 784 linkedLibraries = link(libraryUrisToLink, (String uri) { |
| 743 LinkedLibrary linkedLibrary = store.linkedMap[uri]; | 785 LinkedLibrary linkedLibrary = store.linkedMap[uri]; |
| 744 return linkedLibrary; | 786 return linkedLibrary; |
| 745 }, (String uri) { | 787 }, (String uri) { |
| 746 UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri]; | 788 UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri]; |
| 747 return unlinkedUnit; | 789 return unlinkedUnit; |
| 748 }, (_) => null, analysisOptions.strongMode); | 790 }, (_) => null, _analysisOptions.strongMode); |
| 749 _logger.writeln('Linked ${linkedLibraries.length} bundles.'); | 791 _logger.writeln('Linked ${linkedLibraries.length} bundles.'); |
| 750 }); | 792 }); |
| 751 | 793 |
| 752 linkedLibraries.forEach((uri, linkedBuilder) { | 794 linkedLibraries.forEach((uri, linkedBuilder) { |
| 753 FileState library = libraries[uri]; | 795 FileState library = libraries[uri]; |
| 754 String key = '${library.transitiveSignature}.linked'; | 796 String key = '${library.transitiveSignature}.linked'; |
| 755 List<int> bytes = linkedBuilder.toBuffer(); | 797 List<int> bytes = linkedBuilder.toBuffer(); |
| 756 LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes); | 798 LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes); |
| 757 store.addLinkedLibrary(uri, linked); | 799 store.addLinkedLibrary(uri, linked); |
| 758 _byteStore.put(key, bytes); | 800 _byteStore.put(key, bytes); |
| 759 }); | 801 }); |
| 760 | 802 |
| 761 return new _LibraryContext(library, store); | 803 return new _LibraryContext(library, store); |
| 762 }); | 804 }); |
| 763 } | 805 } |
| 764 | 806 |
| 765 /** | 807 /** |
| 766 * Fill [_salt] with data. | 808 * Fill [_salt] with data. |
| 767 */ | 809 */ |
| 768 void _fillSalt() { | 810 void _fillSalt() { |
| 769 _salt[0] = DATA_VERSION; | 811 _salt[0] = DATA_VERSION; |
| 770 List<int> crossContextOptions = analysisOptions.encodeCrossContextOptions(); | 812 List<int> crossContextOptions = |
| 813 _analysisOptions.encodeCrossContextOptions(); | |
| 771 assert(crossContextOptions.length == | 814 assert(crossContextOptions.length == |
| 772 AnalysisOptions.crossContextOptionsLength); | 815 AnalysisOptions.crossContextOptionsLength); |
| 773 for (int i = 0; i < crossContextOptions.length; i++) { | 816 for (int i = 0; i < crossContextOptions.length; i++) { |
| 774 _salt[i + 1] = crossContextOptions[i]; | 817 _salt[i + 1] = crossContextOptions[i]; |
| 775 } | 818 } |
| 776 } | 819 } |
| 777 | 820 |
| 778 /** | 821 /** |
| 779 * Load the [AnalysisResult] for the given [file] from the [bytes]. Set | 822 * Load the [AnalysisResult] for the given [file] from the [bytes]. Set |
| 780 * optional [content] and [resolvedUnit]. | 823 * optional [content] and [resolvedUnit]. |
| 781 */ | 824 */ |
| 782 AnalysisResult _getAnalysisResultFromBytes(FileState file, List<int> bytes, | 825 AnalysisResult _getAnalysisResultFromBytes(FileState file, List<int> bytes, |
| 783 {String content, bool withErrors: true, CompilationUnit resolvedUnit}) { | 826 {String content, bool withErrors: true, CompilationUnit resolvedUnit}) { |
| 784 var unit = new AnalysisDriverResolvedUnit.fromBuffer(bytes); | 827 var unit = new AnalysisDriverResolvedUnit.fromBuffer(bytes); |
| 785 List<AnalysisError> errors = withErrors | 828 List<AnalysisError> errors = withErrors |
| 786 ? _getErrorsFromSerialized(file, unit.errors) | 829 ? _getErrorsFromSerialized(file, unit.errors) |
| 787 : const <AnalysisError>[]; | 830 : const <AnalysisError>[]; |
| 788 return new AnalysisResult(this, sourceFactory, file.path, file.uri, content, | 831 return new AnalysisResult( |
| 789 file.contentHash, file.lineInfo, resolvedUnit, errors, unit.index); | 832 this, |
| 833 _sourceFactory, | |
| 834 file.path, | |
| 835 file.uri, | |
| 836 content, | |
| 837 file.contentHash, | |
| 838 file.lineInfo, | |
| 839 resolvedUnit, | |
| 840 errors, | |
| 841 unit.index); | |
| 790 } | 842 } |
| 791 | 843 |
| 792 /** | 844 /** |
| 793 * Return [AnalysisError]s for the given [serialized] errors. | 845 * Return [AnalysisError]s for the given [serialized] errors. |
| 794 */ | 846 */ |
| 795 List<AnalysisError> _getErrorsFromSerialized( | 847 List<AnalysisError> _getErrorsFromSerialized( |
| 796 FileState file, List<AnalysisDriverUnitError> serialized) { | 848 FileState file, List<AnalysisDriverUnitError> serialized) { |
| 797 return serialized.map((error) { | 849 return serialized.map((error) { |
| 798 String errorName = error.uniqueName; | 850 String errorName = error.uniqueName; |
| 799 ErrorCode errorCode = | 851 ErrorCode errorCode = |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 823 } | 875 } |
| 824 | 876 |
| 825 /** | 877 /** |
| 826 * Return the lint code with the given [errorName], or `null` if there is no | 878 * Return the lint code with the given [errorName], or `null` if there is no |
| 827 * lint registered with that name or the lint is not enabled in the analysis | 879 * lint registered with that name or the lint is not enabled in the analysis |
| 828 * options. | 880 * options. |
| 829 */ | 881 */ |
| 830 ErrorCode _lintCodeByUniqueName(String errorName) { | 882 ErrorCode _lintCodeByUniqueName(String errorName) { |
| 831 if (errorName.startsWith('_LintCode.')) { | 883 if (errorName.startsWith('_LintCode.')) { |
| 832 String lintName = errorName.substring(10); | 884 String lintName = errorName.substring(10); |
| 833 List<Linter> lintRules = analysisOptions.lintRules; | 885 List<Linter> lintRules = _analysisOptions.lintRules; |
| 834 for (Linter linter in lintRules) { | 886 for (Linter linter in lintRules) { |
| 835 if (linter.name == lintName) { | 887 if (linter.name == lintName) { |
| 836 return linter.lintCode; | 888 return linter.lintCode; |
| 837 } | 889 } |
| 838 } | 890 } |
| 839 } | 891 } |
| 840 return null; | 892 return null; |
| 841 } | 893 } |
| 842 | 894 |
| 843 /** | 895 /** |
| (...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1529 libraryDeclarations.add(new TopLevelDeclarationInSource( | 1581 libraryDeclarations.add(new TopLevelDeclarationInSource( |
| 1530 file.source, declaration, isExported)); | 1582 file.source, declaration, isExported)); |
| 1531 } | 1583 } |
| 1532 } | 1584 } |
| 1533 } | 1585 } |
| 1534 | 1586 |
| 1535 // We're not done yet. | 1587 // We're not done yet. |
| 1536 return false; | 1588 return false; |
| 1537 } | 1589 } |
| 1538 } | 1590 } |
| OLD | NEW |