| 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'; |
| 11 import 'package:analyzer/dart/element/element.dart' show CompilationUnitElement; | 11 import 'package:analyzer/dart/element/element.dart' show CompilationUnitElement; |
| 12 import 'package:analyzer/error/error.dart'; | 12 import 'package:analyzer/error/error.dart'; |
| 13 import 'package:analyzer/error/listener.dart'; | 13 import 'package:analyzer/error/listener.dart'; |
| 14 import 'package:analyzer/exception/exception.dart'; | 14 import 'package:analyzer/exception/exception.dart'; |
| 15 import 'package:analyzer/file_system/file_system.dart'; | 15 import 'package:analyzer/file_system/file_system.dart'; |
| 16 import 'package:analyzer/src/context/context.dart'; | |
| 17 import 'package:analyzer/src/dart/analysis/byte_store.dart'; | 16 import 'package:analyzer/src/dart/analysis/byte_store.dart'; |
| 18 import 'package:analyzer/src/dart/analysis/file_state.dart'; | 17 import 'package:analyzer/src/dart/analysis/file_state.dart'; |
| 19 import 'package:analyzer/src/dart/analysis/index.dart'; | 18 import 'package:analyzer/src/dart/analysis/index.dart'; |
| 19 import 'package:analyzer/src/dart/analysis/library_context.dart'; |
| 20 import 'package:analyzer/src/dart/analysis/search.dart'; | 20 import 'package:analyzer/src/dart/analysis/search.dart'; |
| 21 import 'package:analyzer/src/dart/analysis/status.dart'; | 21 import 'package:analyzer/src/dart/analysis/status.dart'; |
| 22 import 'package:analyzer/src/dart/analysis/top_level_declaration.dart'; | 22 import 'package:analyzer/src/dart/analysis/top_level_declaration.dart'; |
| 23 import 'package:analyzer/src/generated/engine.dart' | 23 import 'package:analyzer/src/generated/engine.dart' |
| 24 show AnalysisContext, AnalysisEngine, AnalysisOptions; | 24 show AnalysisContext, AnalysisEngine, AnalysisOptions; |
| 25 import 'package:analyzer/src/generated/source.dart'; | 25 import 'package:analyzer/src/generated/source.dart'; |
| 26 import 'package:analyzer/src/services/lint.dart'; | 26 import 'package:analyzer/src/services/lint.dart'; |
| 27 import 'package:analyzer/src/summary/api_signature.dart'; | 27 import 'package:analyzer/src/summary/api_signature.dart'; |
| 28 import 'package:analyzer/src/summary/format.dart'; | 28 import 'package:analyzer/src/summary/format.dart'; |
| 29 import 'package:analyzer/src/summary/idl.dart'; | 29 import 'package:analyzer/src/summary/idl.dart'; |
| 30 import 'package:analyzer/src/summary/link.dart'; | |
| 31 import 'package:analyzer/src/summary/package_bundle_reader.dart'; | |
| 32 import 'package:analyzer/src/task/dart.dart' show COMPILATION_UNIT_ELEMENT; | |
| 33 import 'package:analyzer/task/dart.dart' show LibrarySpecificUnit; | |
| 34 import 'package:meta/meta.dart'; | 30 import 'package:meta/meta.dart'; |
| 35 | 31 |
| 36 /** | 32 /** |
| 37 * This class computes [AnalysisResult]s for Dart files. | 33 * This class computes [AnalysisResult]s for Dart files. |
| 38 * | 34 * |
| 39 * Let the set of "explicitly analyzed files" denote the set of paths that have | 35 * Let the set of "explicitly analyzed files" denote the set of paths that have |
| 40 * been passed to [addFile] but not subsequently passed to [removeFile]. Let | 36 * been passed to [addFile] but not subsequently passed to [removeFile]. Let |
| 41 * the "current analysis results" denote the map from the set of explicitly | 37 * the "current analysis results" denote the map from the set of explicitly |
| 42 * analyzed files to the most recent [AnalysisResult] delivered to [results] | 38 * analyzed files to the most recent [AnalysisResult] delivered to [results] |
| 43 * for each file. Let the "current file state" represent a map from file path | 39 * for each file. Let the "current file state" represent a map from file path |
| (...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 return _logger.run('Compute analysis result for $path', () { | 728 return _logger.run('Compute analysis result for $path', () { |
| 733 FileState file = _verifyApiSignature(path); | 729 FileState file = _verifyApiSignature(path); |
| 734 | 730 |
| 735 // Prepare the library file - the file itself, or the known library. | 731 // Prepare the library file - the file itself, or the known library. |
| 736 FileState libraryFile = getLibraryFile(file); | 732 FileState libraryFile = getLibraryFile(file); |
| 737 if (libraryFile == null) { | 733 if (libraryFile == null) { |
| 738 return null; | 734 return null; |
| 739 } | 735 } |
| 740 | 736 |
| 741 try { | 737 try { |
| 742 _LibraryContext libraryContext = _createLibraryContext(libraryFile); | 738 LibraryContext libraryContext = _createLibraryContext(libraryFile); |
| 743 AnalysisContext analysisContext = | |
| 744 _createAnalysisContext(libraryContext); | |
| 745 try { | 739 try { |
| 746 CompilationUnit resolvedUnit = analysisContext | 740 var resolutionResult = |
| 747 .resolveCompilationUnit2(file.source, libraryFile.source); | 741 libraryContext.resolveUnit(libraryFile.source, file.source); |
| 748 List<AnalysisError> errors = | 742 CompilationUnit resolvedUnit = resolutionResult.resolvedUnit; |
| 749 analysisContext.computeErrors(file.source); | 743 List<AnalysisError> errors = resolutionResult.errors; |
| 750 AnalysisDriverUnitIndexBuilder index = indexUnit(resolvedUnit); | 744 AnalysisDriverUnitIndexBuilder index = indexUnit(resolvedUnit); |
| 751 | 745 |
| 752 // Store the result into the cache. | 746 // Store the result into the cache. |
| 753 List<int> bytes; | 747 List<int> bytes; |
| 754 { | 748 { |
| 755 bytes = new AnalysisDriverResolvedUnitBuilder( | 749 bytes = new AnalysisDriverResolvedUnitBuilder( |
| 756 errors: errors | 750 errors: errors |
| 757 .map((error) => new AnalysisDriverUnitErrorBuilder( | 751 .map((error) => new AnalysisDriverUnitErrorBuilder( |
| 758 offset: error.offset, | 752 offset: error.offset, |
| 759 length: error.length, | 753 length: error.length, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 771 _logger.writeln('Computed new analysis result.'); | 765 _logger.writeln('Computed new analysis result.'); |
| 772 AnalysisResult result = _getAnalysisResultFromBytes(file, bytes, | 766 AnalysisResult result = _getAnalysisResultFromBytes(file, bytes, |
| 773 content: withUnit ? file.content : null, | 767 content: withUnit ? file.content : null, |
| 774 withErrors: _addedFiles.contains(path), | 768 withErrors: _addedFiles.contains(path), |
| 775 resolvedUnit: withUnit ? resolvedUnit : null); | 769 resolvedUnit: withUnit ? resolvedUnit : null); |
| 776 if (withUnit && _priorityFiles.contains(path)) { | 770 if (withUnit && _priorityFiles.contains(path)) { |
| 777 _priorityResults[path] = result; | 771 _priorityResults[path] = result; |
| 778 } | 772 } |
| 779 return result; | 773 return result; |
| 780 } finally { | 774 } finally { |
| 781 analysisContext.dispose(); | 775 libraryContext.dispose(); |
| 782 } | 776 } |
| 783 } catch (exception, stackTrace) { | 777 } catch (exception, stackTrace) { |
| 784 String contextKey = | 778 String contextKey = |
| 785 _storeExceptionContext(path, libraryFile, exception, stackTrace); | 779 _storeExceptionContext(path, libraryFile, exception, stackTrace); |
| 786 throw new _ExceptionState(exception, stackTrace, contextKey); | 780 throw new _ExceptionState(exception, stackTrace, contextKey); |
| 787 } | 781 } |
| 788 }); | 782 }); |
| 789 } | 783 } |
| 790 | 784 |
| 791 AnalysisDriverUnitIndex _computeIndex(String path) { | 785 AnalysisDriverUnitIndex _computeIndex(String path) { |
| 792 AnalysisResult analysisResult = _computeAnalysisResult(path, | 786 AnalysisResult analysisResult = _computeAnalysisResult(path, |
| 793 withUnit: false, asIsIfPartWithoutLibrary: true); | 787 withUnit: false, asIsIfPartWithoutLibrary: true); |
| 794 return analysisResult._index; | 788 return analysisResult._index; |
| 795 } | 789 } |
| 796 | 790 |
| 797 CompilationUnitElement _computeUnitElement(String path) { | 791 CompilationUnitElement _computeUnitElement(String path) { |
| 798 FileState file = _fsState.getFileForPath(path); | 792 FileState file = _fsState.getFileForPath(path); |
| 799 FileState libraryFile = file.library ?? file; | 793 FileState libraryFile = file.library ?? file; |
| 800 | 794 |
| 801 // Create the AnalysisContext to resynthesize elements in. | 795 // Create the AnalysisContext to resynthesize elements in. |
| 802 _LibraryContext libraryContext = _createLibraryContext(libraryFile); | 796 LibraryContext libraryContext = _createLibraryContext(libraryFile); |
| 803 AnalysisContext analysisContext = _createAnalysisContext(libraryContext); | |
| 804 | 797 |
| 805 // Resynthesize the CompilationUnitElement in the context. | 798 // Resynthesize the CompilationUnitElement in the context. |
| 806 try { | 799 try { |
| 807 return analysisContext.computeResult( | 800 return libraryContext.computeUnitElement(libraryFile.source, file.source); |
| 808 new LibrarySpecificUnit(libraryFile.source, file.source), | |
| 809 COMPILATION_UNIT_ELEMENT); | |
| 810 } finally { | 801 } finally { |
| 811 analysisContext.dispose(); | 802 libraryContext.dispose(); |
| 812 } | 803 } |
| 813 } | 804 } |
| 814 | 805 |
| 815 AnalysisContext _createAnalysisContext(_LibraryContext libraryContext) { | |
| 816 AnalysisContextImpl analysisContext = | |
| 817 AnalysisEngine.instance.createAnalysisContext(); | |
| 818 analysisContext.useSdkCachePartition = false; | |
| 819 analysisContext.analysisOptions = _analysisOptions; | |
| 820 analysisContext.declaredVariables.addAll(declaredVariables); | |
| 821 analysisContext.sourceFactory = _sourceFactory.clone(); | |
| 822 analysisContext.contentCache = new _ContentCacheWrapper(_fsState); | |
| 823 analysisContext.resultProvider = | |
| 824 new InputPackagesResultProvider(analysisContext, libraryContext.store); | |
| 825 return analysisContext; | |
| 826 } | |
| 827 | |
| 828 /** | 806 /** |
| 829 * Return the context in which the [library] should be analyzed it. | 807 * Return the context in which the [library] should be analyzed. |
| 830 */ | 808 */ |
| 831 _LibraryContext _createLibraryContext(FileState library) { | 809 LibraryContext _createLibraryContext(FileState library) => |
| 832 return _logger.run('Create library context', () { | 810 new LibraryContext.forSingleLibrary( |
| 833 Map<String, FileState> libraries = <String, FileState>{}; | 811 library, |
| 834 SummaryDataStore store = new SummaryDataStore(const <String>[]); | 812 _logger, |
| 835 | 813 _sdkBundle, |
| 836 if (_sdkBundle != null) { | 814 _byteStore, |
| 837 store.addBundle(null, _sdkBundle); | 815 _analysisOptions, |
| 838 } | 816 declaredVariables, |
| 839 | 817 _sourceFactory, |
| 840 void appendLibraryFiles(FileState library) { | 818 _fsState); |
| 841 if (!libraries.containsKey(library.uriStr)) { | |
| 842 // Serve 'dart:' URIs from the SDK bundle. | |
| 843 if (_sdkBundle != null && library.uri.scheme == 'dart') { | |
| 844 return; | |
| 845 } | |
| 846 | |
| 847 libraries[library.uriStr] = library; | |
| 848 | |
| 849 // Append the defining unit. | |
| 850 store.addUnlinkedUnit(library.uriStr, library.unlinked); | |
| 851 | |
| 852 // Append parts. | |
| 853 for (FileState part in library.partedFiles) { | |
| 854 store.addUnlinkedUnit(part.uriStr, part.unlinked); | |
| 855 } | |
| 856 | |
| 857 // Append referenced libraries. | |
| 858 library.importedFiles.forEach(appendLibraryFiles); | |
| 859 library.exportedFiles.forEach(appendLibraryFiles); | |
| 860 } | |
| 861 } | |
| 862 | |
| 863 _logger.run('Append library files', () { | |
| 864 return appendLibraryFiles(library); | |
| 865 }); | |
| 866 | |
| 867 Set<String> libraryUrisToLink = new Set<String>(); | |
| 868 _logger.run('Load linked bundles', () { | |
| 869 for (FileState library in libraries.values) { | |
| 870 if (library.exists) { | |
| 871 String key = '${library.transitiveSignature}.linked'; | |
| 872 List<int> bytes = _byteStore.get(key); | |
| 873 if (bytes != null) { | |
| 874 LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes); | |
| 875 store.addLinkedLibrary(library.uriStr, linked); | |
| 876 } else { | |
| 877 libraryUrisToLink.add(library.uriStr); | |
| 878 } | |
| 879 } | |
| 880 } | |
| 881 int numOfLoaded = libraries.length - libraryUrisToLink.length; | |
| 882 _logger.writeln('Loaded $numOfLoaded linked bundles.'); | |
| 883 }); | |
| 884 | |
| 885 Map<String, LinkedLibraryBuilder> linkedLibraries = {}; | |
| 886 _logger.run('Link bundles', () { | |
| 887 linkedLibraries = link(libraryUrisToLink, (String uri) { | |
| 888 LinkedLibrary linkedLibrary = store.linkedMap[uri]; | |
| 889 return linkedLibrary; | |
| 890 }, (String uri) { | |
| 891 UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri]; | |
| 892 return unlinkedUnit; | |
| 893 }, (_) => null, _analysisOptions.strongMode); | |
| 894 _logger.writeln('Linked ${linkedLibraries.length} bundles.'); | |
| 895 }); | |
| 896 | |
| 897 linkedLibraries.forEach((uri, linkedBuilder) { | |
| 898 FileState library = libraries[uri]; | |
| 899 String key = '${library.transitiveSignature}.linked'; | |
| 900 List<int> bytes = linkedBuilder.toBuffer(); | |
| 901 LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes); | |
| 902 store.addLinkedLibrary(uri, linked); | |
| 903 _byteStore.put(key, bytes); | |
| 904 }); | |
| 905 | |
| 906 return new _LibraryContext(library, store); | |
| 907 }); | |
| 908 } | |
| 909 | 819 |
| 910 /** | 820 /** |
| 911 * Fill [_salt] with data. | 821 * Fill [_salt] with data. |
| 912 */ | 822 */ |
| 913 void _fillSalt() { | 823 void _fillSalt() { |
| 914 _salt[0] = DATA_VERSION; | 824 _salt[0] = DATA_VERSION; |
| 915 List<int> crossContextOptions = _analysisOptions.signature; | 825 List<int> crossContextOptions = _analysisOptions.signature; |
| 916 assert(crossContextOptions.length == AnalysisOptions.signatureLength); | 826 assert(crossContextOptions.length == AnalysisOptions.signatureLength); |
| 917 for (int i = 0; i < crossContextOptions.length; i++) { | 827 for (int i = 0; i < crossContextOptions.length; i++) { |
| 918 _salt[i + 1] = crossContextOptions[i]; | 828 _salt[i + 1] = crossContextOptions[i]; |
| (...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1685 */ | 1595 */ |
| 1686 void exit() { | 1596 void exit() { |
| 1687 _timer.stop(); | 1597 _timer.stop(); |
| 1688 _logger._level--; | 1598 _logger._level--; |
| 1689 int ms = _timer.elapsedMilliseconds; | 1599 int ms = _timer.elapsedMilliseconds; |
| 1690 _logger.writeln('--- $_msg in $ms ms.'); | 1600 _logger.writeln('--- $_msg in $ms ms.'); |
| 1691 } | 1601 } |
| 1692 } | 1602 } |
| 1693 | 1603 |
| 1694 /** | 1604 /** |
| 1695 * [ContentCache] wrapper around [FileContentOverlay]. | |
| 1696 */ | |
| 1697 class _ContentCacheWrapper implements ContentCache { | |
| 1698 final FileSystemState fsState; | |
| 1699 | |
| 1700 _ContentCacheWrapper(this.fsState); | |
| 1701 | |
| 1702 @override | |
| 1703 void accept(ContentCacheVisitor visitor) { | |
| 1704 throw new UnimplementedError(); | |
| 1705 } | |
| 1706 | |
| 1707 @override | |
| 1708 String getContents(Source source) { | |
| 1709 return _getFileForSource(source).content; | |
| 1710 } | |
| 1711 | |
| 1712 @override | |
| 1713 bool getExists(Source source) { | |
| 1714 if (source.isInSystemLibrary) { | |
| 1715 return true; | |
| 1716 } | |
| 1717 return _getFileForSource(source).exists; | |
| 1718 } | |
| 1719 | |
| 1720 @override | |
| 1721 int getModificationStamp(Source source) { | |
| 1722 if (source.isInSystemLibrary) { | |
| 1723 return 0; | |
| 1724 } | |
| 1725 return _getFileForSource(source).exists ? 0 : -1; | |
| 1726 } | |
| 1727 | |
| 1728 @override | |
| 1729 String setContents(Source source, String contents) { | |
| 1730 throw new UnimplementedError(); | |
| 1731 } | |
| 1732 | |
| 1733 FileState _getFileForSource(Source source) { | |
| 1734 String path = source.fullName; | |
| 1735 return fsState.getFileForPath(path); | |
| 1736 } | |
| 1737 } | |
| 1738 | |
| 1739 /** | |
| 1740 * Information about an exception and its context. | 1605 * Information about an exception and its context. |
| 1741 */ | 1606 */ |
| 1742 class _ExceptionState { | 1607 class _ExceptionState { |
| 1743 final exception; | 1608 final exception; |
| 1744 final StackTrace stackTrace; | 1609 final StackTrace stackTrace; |
| 1745 | 1610 |
| 1746 /** | 1611 /** |
| 1747 * The key under which the context of the exception was stored, or `null` | 1612 * The key under which the context of the exception was stored, or `null` |
| 1748 * if unknown, the maximum number of context to store was reached, etc. | 1613 * if unknown, the maximum number of context to store was reached, etc. |
| 1749 */ | 1614 */ |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1803 } | 1668 } |
| 1804 checkedFiles.add(path); | 1669 checkedFiles.add(path); |
| 1805 } | 1670 } |
| 1806 | 1671 |
| 1807 // We're not done yet. | 1672 // We're not done yet. |
| 1808 return false; | 1673 return false; |
| 1809 } | 1674 } |
| 1810 } | 1675 } |
| 1811 | 1676 |
| 1812 /** | 1677 /** |
| 1813 * TODO(scheglov) document | |
| 1814 */ | |
| 1815 class _LibraryContext { | |
| 1816 final FileState file; | |
| 1817 final SummaryDataStore store; | |
| 1818 _LibraryContext(this.file, this.store); | |
| 1819 } | |
| 1820 | |
| 1821 /** | |
| 1822 * Task that computes top-level declarations for a certain name in all | 1678 * Task that computes top-level declarations for a certain name in all |
| 1823 * known libraries. | 1679 * known libraries. |
| 1824 */ | 1680 */ |
| 1825 class _TopLevelNameDeclarationsTask { | 1681 class _TopLevelNameDeclarationsTask { |
| 1826 final AnalysisDriver driver; | 1682 final AnalysisDriver driver; |
| 1827 final String name; | 1683 final String name; |
| 1828 final Completer<List<TopLevelDeclarationInSource>> completer = | 1684 final Completer<List<TopLevelDeclarationInSource>> completer = |
| 1829 new Completer<List<TopLevelDeclarationInSource>>(); | 1685 new Completer<List<TopLevelDeclarationInSource>>(); |
| 1830 | 1686 |
| 1831 final List<TopLevelDeclarationInSource> libraryDeclarations = | 1687 final List<TopLevelDeclarationInSource> libraryDeclarations = |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1871 libraryDeclarations.add(new TopLevelDeclarationInSource( | 1727 libraryDeclarations.add(new TopLevelDeclarationInSource( |
| 1872 file.source, declaration, isExported)); | 1728 file.source, declaration, isExported)); |
| 1873 } | 1729 } |
| 1874 } | 1730 } |
| 1875 } | 1731 } |
| 1876 | 1732 |
| 1877 // We're not done yet. | 1733 // We're not done yet. |
| 1878 return false; | 1734 return false; |
| 1879 } | 1735 } |
| 1880 } | 1736 } |
| OLD | NEW |