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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
529 */ | 540 */ |
530 Future<ParseResult> parseFile(String path) async { | 541 Future<ParseResult> parseFile(String path) async { |
531 FileState file = _verifyApiSignature(path); | 542 FileState file = _verifyApiSignature(path); |
532 RecordingErrorListener listener = new RecordingErrorListener(); | 543 RecordingErrorListener listener = new RecordingErrorListener(); |
533 CompilationUnit unit = file.parse(listener); | 544 CompilationUnit unit = file.parse(listener); |
534 return new ParseResult(file.path, file.uri, file.content, file.contentHash, | 545 return new ParseResult(file.path, file.uri, file.content, file.contentHash, |
535 unit.lineInfo, unit, listener.errors); | 546 unit.lineInfo, unit, listener.errors); |
536 } | 547 } |
537 | 548 |
538 /** | 549 /** |
550 * Some state on which analysis depends has changed, so everything needs to be | |
551 * re-analyzed. | |
552 * | |
553 * At least one of the optional parameters should be provided, but only those | |
554 * that represent state that has changed need be provided. | |
555 */ | |
556 void reanalyze( | |
scheglov
2016/12/12 18:42:04
Maybe call this "configure" and don't actually spe
| |
557 {AnalysisOptions analysisOptions, SourceFactory sourceFactory}) { | |
558 if (analysisOptions != null) { | |
559 _analysisOptions = analysisOptions; | |
560 } | |
561 if (sourceFactory != null) { | |
562 _sourceFactory = sourceFactory; | |
563 } | |
564 _filesToAnalyze.addAll(_addedFiles); | |
565 _statusSupport.transitionToAnalyzing(); | |
566 _scheduler._notify(this); | |
567 } | |
568 | |
569 /** | |
539 * Remove the file with the given [path] from the list of files to analyze. | 570 * Remove the file with the given [path] from the list of files to analyze. |
540 * | 571 * |
541 * The [path] must be absolute and normalized. | 572 * The [path] must be absolute and normalized. |
542 * | 573 * |
543 * The results of analysis of the file might still be produced by the | 574 * The results of analysis of the file might still be produced by the |
544 * [results] stream. The driver will try to stop producing these results, | 575 * [results] stream. The driver will try to stop producing these results, |
545 * but does not guarantee this. | 576 * but does not guarantee this. |
546 */ | 577 */ |
547 void removeFile(String path) { | 578 void removeFile(String path) { |
548 _addedFiles.remove(path); | 579 _addedFiles.remove(path); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
666 new LibrarySpecificUnit(libraryFile.source, file.source), | 697 new LibrarySpecificUnit(libraryFile.source, file.source), |
667 COMPILATION_UNIT_ELEMENT); | 698 COMPILATION_UNIT_ELEMENT); |
668 } finally { | 699 } finally { |
669 analysisContext.dispose(); | 700 analysisContext.dispose(); |
670 } | 701 } |
671 } | 702 } |
672 | 703 |
673 AnalysisContext _createAnalysisContext(_LibraryContext libraryContext) { | 704 AnalysisContext _createAnalysisContext(_LibraryContext libraryContext) { |
674 AnalysisContextImpl analysisContext = | 705 AnalysisContextImpl analysisContext = |
675 AnalysisEngine.instance.createAnalysisContext(); | 706 AnalysisEngine.instance.createAnalysisContext(); |
676 analysisContext.analysisOptions = analysisOptions; | 707 analysisContext.analysisOptions = _analysisOptions; |
677 | 708 |
678 analysisContext.sourceFactory = sourceFactory.clone(); | 709 analysisContext.sourceFactory = _sourceFactory.clone(); |
679 analysisContext.resultProvider = | 710 analysisContext.resultProvider = |
680 new InputPackagesResultProvider(analysisContext, libraryContext.store); | 711 new InputPackagesResultProvider(analysisContext, libraryContext.store); |
681 analysisContext | 712 analysisContext |
682 .applyChanges(new ChangeSet()..addedSource(libraryContext.file.source)); | 713 .applyChanges(new ChangeSet()..addedSource(libraryContext.file.source)); |
683 return analysisContext; | 714 return analysisContext; |
684 } | 715 } |
685 | 716 |
686 /** | 717 /** |
687 * Return the context in which the [library] should be analyzed it. | 718 * Return the context in which the [library] should be analyzed it. |
688 */ | 719 */ |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
738 }); | 769 }); |
739 | 770 |
740 Map<String, LinkedLibraryBuilder> linkedLibraries = {}; | 771 Map<String, LinkedLibraryBuilder> linkedLibraries = {}; |
741 _logger.run('Link bundles', () { | 772 _logger.run('Link bundles', () { |
742 linkedLibraries = link(libraryUrisToLink, (String uri) { | 773 linkedLibraries = link(libraryUrisToLink, (String uri) { |
743 LinkedLibrary linkedLibrary = store.linkedMap[uri]; | 774 LinkedLibrary linkedLibrary = store.linkedMap[uri]; |
744 return linkedLibrary; | 775 return linkedLibrary; |
745 }, (String uri) { | 776 }, (String uri) { |
746 UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri]; | 777 UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri]; |
747 return unlinkedUnit; | 778 return unlinkedUnit; |
748 }, (_) => null, analysisOptions.strongMode); | 779 }, (_) => null, _analysisOptions.strongMode); |
749 _logger.writeln('Linked ${linkedLibraries.length} bundles.'); | 780 _logger.writeln('Linked ${linkedLibraries.length} bundles.'); |
750 }); | 781 }); |
751 | 782 |
752 linkedLibraries.forEach((uri, linkedBuilder) { | 783 linkedLibraries.forEach((uri, linkedBuilder) { |
753 FileState library = libraries[uri]; | 784 FileState library = libraries[uri]; |
754 String key = '${library.transitiveSignature}.linked'; | 785 String key = '${library.transitiveSignature}.linked'; |
755 List<int> bytes = linkedBuilder.toBuffer(); | 786 List<int> bytes = linkedBuilder.toBuffer(); |
756 LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes); | 787 LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes); |
757 store.addLinkedLibrary(uri, linked); | 788 store.addLinkedLibrary(uri, linked); |
758 _byteStore.put(key, bytes); | 789 _byteStore.put(key, bytes); |
759 }); | 790 }); |
760 | 791 |
761 return new _LibraryContext(library, store); | 792 return new _LibraryContext(library, store); |
762 }); | 793 }); |
763 } | 794 } |
764 | 795 |
765 /** | 796 /** |
766 * Fill [_salt] with data. | 797 * Fill [_salt] with data. |
767 */ | 798 */ |
768 void _fillSalt() { | 799 void _fillSalt() { |
769 _salt[0] = DATA_VERSION; | 800 _salt[0] = DATA_VERSION; |
770 List<int> crossContextOptions = analysisOptions.encodeCrossContextOptions(); | 801 List<int> crossContextOptions = |
802 _analysisOptions.encodeCrossContextOptions(); | |
771 assert(crossContextOptions.length == | 803 assert(crossContextOptions.length == |
772 AnalysisOptions.crossContextOptionsLength); | 804 AnalysisOptions.crossContextOptionsLength); |
773 for (int i = 0; i < crossContextOptions.length; i++) { | 805 for (int i = 0; i < crossContextOptions.length; i++) { |
774 _salt[i + 1] = crossContextOptions[i]; | 806 _salt[i + 1] = crossContextOptions[i]; |
775 } | 807 } |
776 } | 808 } |
777 | 809 |
778 /** | 810 /** |
779 * Load the [AnalysisResult] for the given [file] from the [bytes]. Set | 811 * Load the [AnalysisResult] for the given [file] from the [bytes]. Set |
780 * optional [content] and [resolvedUnit]. | 812 * optional [content] and [resolvedUnit]. |
781 */ | 813 */ |
782 AnalysisResult _getAnalysisResultFromBytes(FileState file, List<int> bytes, | 814 AnalysisResult _getAnalysisResultFromBytes(FileState file, List<int> bytes, |
783 {String content, bool withErrors: true, CompilationUnit resolvedUnit}) { | 815 {String content, bool withErrors: true, CompilationUnit resolvedUnit}) { |
784 var unit = new AnalysisDriverResolvedUnit.fromBuffer(bytes); | 816 var unit = new AnalysisDriverResolvedUnit.fromBuffer(bytes); |
785 List<AnalysisError> errors = withErrors | 817 List<AnalysisError> errors = withErrors |
786 ? _getErrorsFromSerialized(file, unit.errors) | 818 ? _getErrorsFromSerialized(file, unit.errors) |
787 : const <AnalysisError>[]; | 819 : const <AnalysisError>[]; |
788 return new AnalysisResult(this, sourceFactory, file.path, file.uri, content, | 820 return new AnalysisResult( |
789 file.contentHash, file.lineInfo, resolvedUnit, errors, unit.index); | 821 this, |
822 _sourceFactory, | |
823 file.path, | |
824 file.uri, | |
825 content, | |
826 file.contentHash, | |
827 file.lineInfo, | |
828 resolvedUnit, | |
829 errors, | |
830 unit.index); | |
790 } | 831 } |
791 | 832 |
792 /** | 833 /** |
793 * Return [AnalysisError]s for the given [serialized] errors. | 834 * Return [AnalysisError]s for the given [serialized] errors. |
794 */ | 835 */ |
795 List<AnalysisError> _getErrorsFromSerialized( | 836 List<AnalysisError> _getErrorsFromSerialized( |
796 FileState file, List<AnalysisDriverUnitError> serialized) { | 837 FileState file, List<AnalysisDriverUnitError> serialized) { |
797 return serialized.map((error) { | 838 return serialized.map((error) { |
798 String errorName = error.uniqueName; | 839 String errorName = error.uniqueName; |
799 ErrorCode errorCode = | 840 ErrorCode errorCode = |
(...skipping 23 matching lines...) Expand all Loading... | |
823 } | 864 } |
824 | 865 |
825 /** | 866 /** |
826 * Return the lint code with the given [errorName], or `null` if there is no | 867 * 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 | 868 * lint registered with that name or the lint is not enabled in the analysis |
828 * options. | 869 * options. |
829 */ | 870 */ |
830 ErrorCode _lintCodeByUniqueName(String errorName) { | 871 ErrorCode _lintCodeByUniqueName(String errorName) { |
831 if (errorName.startsWith('_LintCode.')) { | 872 if (errorName.startsWith('_LintCode.')) { |
832 String lintName = errorName.substring(10); | 873 String lintName = errorName.substring(10); |
833 List<Linter> lintRules = analysisOptions.lintRules; | 874 List<Linter> lintRules = _analysisOptions.lintRules; |
834 for (Linter linter in lintRules) { | 875 for (Linter linter in lintRules) { |
835 if (linter.name == lintName) { | 876 if (linter.name == lintName) { |
836 return linter.lintCode; | 877 return linter.lintCode; |
837 } | 878 } |
838 } | 879 } |
839 } | 880 } |
840 return null; | 881 return null; |
841 } | 882 } |
842 | 883 |
843 /** | 884 /** |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1529 libraryDeclarations.add(new TopLevelDeclarationInSource( | 1570 libraryDeclarations.add(new TopLevelDeclarationInSource( |
1530 file.source, declaration, isExported)); | 1571 file.source, declaration, isExported)); |
1531 } | 1572 } |
1532 } | 1573 } |
1533 } | 1574 } |
1534 | 1575 |
1535 // We're not done yet. | 1576 // We're not done yet. |
1536 return false; | 1577 return false; |
1537 } | 1578 } |
1538 } | 1579 } |
OLD | NEW |