Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(665)

Side by Side Diff: pkg/analyzer/lib/src/dart/analysis/driver.dart

Issue 2692073002: Add AnalysisDriver.getUnitElementSignature() for checking without resynthesizing. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/analyzer/test/src/dart/analysis/driver_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/declared_variables.dart'; 9 import 'package:analyzer/context/declared_variables.dart';
10 import 'package:analyzer/dart/ast/ast.dart'; 10 import 'package:analyzer/dart/ast/ast.dart';
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 final _topLevelNameDeclarationsTasks = <_TopLevelNameDeclarationsTask>[]; 172 final _topLevelNameDeclarationsTasks = <_TopLevelNameDeclarationsTask>[];
173 173
174 /** 174 /**
175 * The mapping from the files for which the index was requested using 175 * The mapping from the files for which the index was requested using
176 * [getIndex] to the [Completer]s to report the result. 176 * [getIndex] to the [Completer]s to report the result.
177 */ 177 */
178 final _indexRequestedFiles = 178 final _indexRequestedFiles =
179 <String, List<Completer<AnalysisDriverUnitIndex>>>{}; 179 <String, List<Completer<AnalysisDriverUnitIndex>>>{};
180 180
181 /** 181 /**
182 * The mapping from the files for which the unit element key was requested
183 * using [getUnitElementSignature] to the [Completer]s to report the result.
184 */
185 final _unitElementSignatureRequests = <String, List<Completer<String>>>{};
186
187 /**
182 * The mapping from the files for which the unit element was requested using 188 * The mapping from the files for which the unit element was requested using
183 * [getUnitElement] to the [Completer]s to report the result. 189 * [getUnitElement] to the [Completer]s to report the result.
184 */ 190 */
185 final _unitElementRequestedFiles = 191 final _unitElementRequestedFiles =
186 <String, List<Completer<UnitElementResult>>>{}; 192 <String, List<Completer<UnitElementResult>>>{};
187 193
188 /** 194 /**
189 * The mapping from the files for which analysis was requested using 195 * The mapping from the files for which analysis was requested using
190 * [getResult], and which were found to be parts without known libraries, 196 * [getResult], and which were found to be parts without known libraries,
191 * to the [Completer]s to report the result. 197 * to the [Completer]s to report the result.
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 if (_requestedFiles.isNotEmpty) { 369 if (_requestedFiles.isNotEmpty) {
364 return AnalysisDriverPriority.interactive; 370 return AnalysisDriverPriority.interactive;
365 } 371 }
366 if (_definingClassMemberNameTasks.isNotEmpty || 372 if (_definingClassMemberNameTasks.isNotEmpty ||
367 _referencingNameTasks.isNotEmpty) { 373 _referencingNameTasks.isNotEmpty) {
368 return AnalysisDriverPriority.interactive; 374 return AnalysisDriverPriority.interactive;
369 } 375 }
370 if (_indexRequestedFiles.isNotEmpty) { 376 if (_indexRequestedFiles.isNotEmpty) {
371 return AnalysisDriverPriority.interactive; 377 return AnalysisDriverPriority.interactive;
372 } 378 }
379 if (_unitElementSignatureRequests.isNotEmpty) {
380 return AnalysisDriverPriority.interactive;
381 }
373 if (_unitElementRequestedFiles.isNotEmpty) { 382 if (_unitElementRequestedFiles.isNotEmpty) {
374 return AnalysisDriverPriority.interactive; 383 return AnalysisDriverPriority.interactive;
375 } 384 }
376 if (_topLevelNameDeclarationsTasks.isNotEmpty) { 385 if (_topLevelNameDeclarationsTasks.isNotEmpty) {
377 return AnalysisDriverPriority.interactive; 386 return AnalysisDriverPriority.interactive;
378 } 387 }
379 if (_priorityFiles.isNotEmpty) { 388 if (_priorityFiles.isNotEmpty) {
380 for (String path in _priorityFiles) { 389 for (String path in _priorityFiles) {
381 if (_fileTracker.isFilePending(path)) { 390 if (_fileTracker.isFilePending(path)) {
382 return AnalysisDriverPriority.priority; 391 return AnalysisDriverPriority.priority;
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 } 615 }
607 var completer = new Completer<UnitElementResult>(); 616 var completer = new Completer<UnitElementResult>();
608 _unitElementRequestedFiles 617 _unitElementRequestedFiles
609 .putIfAbsent(path, () => <Completer<UnitElementResult>>[]) 618 .putIfAbsent(path, () => <Completer<UnitElementResult>>[])
610 .add(completer); 619 .add(completer);
611 _scheduler.notify(this); 620 _scheduler.notify(this);
612 return completer.future; 621 return completer.future;
613 } 622 }
614 623
615 /** 624 /**
625 * Return a [Future] that completes with the signature for the
626 * [UnitElementResult] for the file with the given [path], or with `null` if
627 * the file cannot be analyzed.
628 *
629 * The signature is based on the content of the file, and the transitive
630 * closure of files imported and exported by the the library of the requested
631 * file.
632 */
633 Future<String> getUnitElementSignature(String path) {
634 if (!_fileTracker.fsState.hasUri(path)) {
635 return new Future.value();
636 }
637 var completer = new Completer<String>();
638 _unitElementSignatureRequests
639 .putIfAbsent(path, () => <Completer<String>>[])
640 .add(completer);
641 _scheduler.notify(this);
642 return completer.future;
643 }
644
645 /**
616 * Return a [Future] that completes with a [ParseResult] for the file 646 * Return a [Future] that completes with a [ParseResult] for the file
617 * with the given [path]. 647 * with the given [path].
618 * 648 *
619 * The [path] must be absolute and normalized. 649 * The [path] must be absolute and normalized.
620 * 650 *
621 * The [path] can be any file - explicitly or implicitly analyzed, or neither. 651 * The [path] can be any file - explicitly or implicitly analyzed, or neither.
622 * 652 *
623 * The parsing is performed in the method itself, and the result is not 653 * The parsing is performed in the method itself, and the result is not
624 * produced through the [results] stream (just because it is not a fully 654 * produced through the [results] stream (just because it is not a fully
625 * resolved unit). 655 * resolved unit).
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 FileState file = _fileTracker.fsState.getFileForPath(path); 782 FileState file = _fileTracker.fsState.getFileForPath(path);
753 FileState library = file.library ?? file; 783 FileState library = file.library ?? file;
754 784
755 // Create the AnalysisContext to resynthesize elements in. 785 // Create the AnalysisContext to resynthesize elements in.
756 LibraryContext libraryContext = _createLibraryContext(library); 786 LibraryContext libraryContext = _createLibraryContext(library);
757 787
758 // Resynthesize the CompilationUnitElement in the context. 788 // Resynthesize the CompilationUnitElement in the context.
759 try { 789 try {
760 CompilationUnitElement element = 790 CompilationUnitElement element =
761 libraryContext.computeUnitElement(library.source, file.source); 791 libraryContext.computeUnitElement(library.source, file.source);
762 String key = _getResolvedUnitKey(library, file); 792 String signature = _getResolvedUnitSignature(library, file);
763 return new UnitElementResult(path, file.contentHash, key, element); 793 return new UnitElementResult(path, file.contentHash, signature, element);
764 } finally { 794 } finally {
765 libraryContext.dispose(); 795 libraryContext.dispose();
766 } 796 }
767 } 797 }
768 798
799 String _computeUnitElementSignature(String path) {
800 FileState file = _fileTracker.fsState.getFileForPath(path);
801 FileState library = file.library ?? file;
802 return _getResolvedUnitSignature(library, file);
803 }
804
769 /** 805 /**
770 * Creates a new [FileTracker] object and stores it in [_fileTracker]. 806 * Creates a new [FileTracker] object and stores it in [_fileTracker].
771 * 807 *
772 * This is used both on initial construction and whenever the configuration 808 * This is used both on initial construction and whenever the configuration
773 * changes. 809 * changes.
774 */ 810 */
775 void _createFileTracker(PerformanceLog logger) { 811 void _createFileTracker(PerformanceLog logger) {
776 _fillSalt(); 812 _fillSalt();
777 _fileTracker = new FileTracker(logger, _byteStore, _contentOverlay, 813 _fileTracker = new FileTracker(logger, _byteStore, _contentOverlay,
778 _resourceProvider, sourceFactory, _analysisOptions, _salt, _changeHook); 814 _resourceProvider, sourceFactory, _analysisOptions, _salt, _changeHook);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 // errors were written. 879 // errors were written.
844 throw new StateError('No ErrorCode for $errorName in $file'); 880 throw new StateError('No ErrorCode for $errorName in $file');
845 } 881 }
846 return new AnalysisError.forValues(file.source, error.offset, 882 return new AnalysisError.forValues(file.source, error.offset,
847 error.length, errorCode, error.message, error.correction); 883 error.length, errorCode, error.message, error.correction);
848 }).toList(); 884 }).toList();
849 } 885 }
850 886
851 /** 887 /**
852 * Return the key to store fully resolved results for the [file] in the 888 * Return the key to store fully resolved results for the [file] in the
853 * [library] into the cache. Return `null` if the dependency signature is 889 * [library] into the cache.
854 * not known yet.
855 */ 890 */
856 String _getResolvedUnitKey(FileState library, FileState file) { 891 String _getResolvedUnitKey(FileState library, FileState file) {
892 String signature = _getResolvedUnitSignature(library, file);
893 return '$signature.resolved';
894 }
895
896 /**
897 * Return the signature that identifies fully resolved results for the [file]
898 * in the [library], e.g. element model, errors, index, etc.
899 */
900 String _getResolvedUnitSignature(FileState library, FileState file) {
857 ApiSignature signature = new ApiSignature(); 901 ApiSignature signature = new ApiSignature();
858 signature.addUint32List(_salt); 902 signature.addUint32List(_salt);
859 signature.addString(library.transitiveSignature); 903 signature.addString(library.transitiveSignature);
860 signature.addString(file.contentHash); 904 signature.addString(file.contentHash);
861 return '${signature.toHex()}.resolved'; 905 return signature.toHex();
862 } 906 }
863 907
864 /** 908 /**
865 * Return the lint code with the given [errorName], or `null` if there is no 909 * Return the lint code with the given [errorName], or `null` if there is no
866 * lint registered with that name or the lint is not enabled in the analysis 910 * lint registered with that name or the lint is not enabled in the analysis
867 * options. 911 * options.
868 */ 912 */
869 ErrorCode _lintCodeByUniqueName(String errorName) { 913 ErrorCode _lintCodeByUniqueName(String errorName) {
870 if (errorName.startsWith('_LintCode.')) { 914 if (errorName.startsWith('_LintCode.')) {
871 String lintName = errorName.substring(10); 915 String lintName = errorName.substring(10);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
918 // Process an index request. 962 // Process an index request.
919 if (_indexRequestedFiles.isNotEmpty) { 963 if (_indexRequestedFiles.isNotEmpty) {
920 String path = _indexRequestedFiles.keys.first; 964 String path = _indexRequestedFiles.keys.first;
921 AnalysisDriverUnitIndex index = _computeIndex(path); 965 AnalysisDriverUnitIndex index = _computeIndex(path);
922 _indexRequestedFiles.remove(path).forEach((completer) { 966 _indexRequestedFiles.remove(path).forEach((completer) {
923 completer.complete(index); 967 completer.complete(index);
924 }); 968 });
925 return; 969 return;
926 } 970 }
927 971
928 // Process a unit request. 972 // Process a unit element key request.
973 if (_unitElementSignatureRequests.isNotEmpty) {
974 String path = _unitElementSignatureRequests.keys.first;
975 String signature = _computeUnitElementSignature(path);
976 _unitElementSignatureRequests.remove(path).forEach((completer) {
977 completer.complete(signature);
978 });
979 return;
980 }
981
982 // Process a unit element request.
929 if (_unitElementRequestedFiles.isNotEmpty) { 983 if (_unitElementRequestedFiles.isNotEmpty) {
930 String path = _unitElementRequestedFiles.keys.first; 984 String path = _unitElementRequestedFiles.keys.first;
931 UnitElementResult result = _computeUnitElement(path); 985 UnitElementResult result = _computeUnitElement(path);
932 _unitElementRequestedFiles.remove(path).forEach((completer) { 986 _unitElementRequestedFiles.remove(path).forEach((completer) {
933 completer.complete(result); 987 completer.complete(result);
934 }); 988 });
935 return; 989 return;
936 } 990 }
937 991
938 // Compute files defining a name. 992 // Compute files defining a name.
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 * The path of the file, absolute and normalized. 1656 * The path of the file, absolute and normalized.
1603 */ 1657 */
1604 final String path; 1658 final String path;
1605 1659
1606 /** 1660 /**
1607 * The MD5 hash of the file content. 1661 * The MD5 hash of the file content.
1608 */ 1662 */
1609 final String contentHash; 1663 final String contentHash;
1610 1664
1611 /** 1665 /**
1612 * The key of the [element] based on the transitive closure of files imported 1666 * The signature of the [element] based on the content of the file, and the
1613 * and exported by the requested file. 1667 * transitive closure of files imported and exported by the the library of
1668 * the requested file.
1614 */ 1669 */
1615 final String key; 1670 final String signature;
1616 1671
1617 /** 1672 /**
1618 * The element of the file. 1673 * The element of the file.
1619 */ 1674 */
1620 final CompilationUnitElement element; 1675 final CompilationUnitElement element;
1621 1676
1622 UnitElementResult(this.path, this.contentHash, this.key, this.element); 1677 UnitElementResult(this.path, this.contentHash, this.signature, this.element);
1623 } 1678 }
1624 1679
1625 /** 1680 /**
1626 * Information about an exception and its context. 1681 * Information about an exception and its context.
1627 */ 1682 */
1628 class _ExceptionState { 1683 class _ExceptionState {
1629 final exception; 1684 final exception;
1630 final StackTrace stackTrace; 1685 final StackTrace stackTrace;
1631 1686
1632 /** 1687 /**
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1807 libraryDeclarations.add(new TopLevelDeclarationInSource( 1862 libraryDeclarations.add(new TopLevelDeclarationInSource(
1808 file.source, declaration, isExported)); 1863 file.source, declaration, isExported));
1809 } 1864 }
1810 } 1865 }
1811 } 1866 }
1812 1867
1813 // We're not done yet. 1868 // We're not done yet.
1814 return false; 1869 return false;
1815 } 1870 }
1816 } 1871 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/dart/analysis/driver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698