| 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/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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |