| 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; |
| 11 import 'package:analyzer/error/error.dart'; | 11 import 'package:analyzer/error/error.dart'; |
| 12 import 'package:analyzer/error/listener.dart'; | 12 import 'package:analyzer/error/listener.dart'; |
| 13 import 'package:analyzer/exception/exception.dart'; |
| 13 import 'package:analyzer/file_system/file_system.dart'; | 14 import 'package:analyzer/file_system/file_system.dart'; |
| 14 import 'package:analyzer/src/context/context.dart'; | 15 import 'package:analyzer/src/context/context.dart'; |
| 15 import 'package:analyzer/src/dart/analysis/byte_store.dart'; | 16 import 'package:analyzer/src/dart/analysis/byte_store.dart'; |
| 16 import 'package:analyzer/src/dart/analysis/file_state.dart'; | 17 import 'package:analyzer/src/dart/analysis/file_state.dart'; |
| 17 import 'package:analyzer/src/dart/analysis/index.dart'; | 18 import 'package:analyzer/src/dart/analysis/index.dart'; |
| 18 import 'package:analyzer/src/dart/analysis/search.dart'; | 19 import 'package:analyzer/src/dart/analysis/search.dart'; |
| 19 import 'package:analyzer/src/dart/analysis/status.dart'; | 20 import 'package:analyzer/src/dart/analysis/status.dart'; |
| 20 import 'package:analyzer/src/dart/analysis/top_level_declaration.dart'; | 21 import 'package:analyzer/src/dart/analysis/top_level_declaration.dart'; |
| 21 import 'package:analyzer/src/generated/engine.dart' | 22 import 'package:analyzer/src/generated/engine.dart' |
| 22 show AnalysisContext, AnalysisEngine, AnalysisOptions, ChangeSet; | 23 show AnalysisContext, AnalysisEngine, AnalysisOptions, ChangeSet; |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 * The controller for the [results] stream. | 196 * The controller for the [results] stream. |
| 196 */ | 197 */ |
| 197 final _resultController = new StreamController<AnalysisResult>(); | 198 final _resultController = new StreamController<AnalysisResult>(); |
| 198 | 199 |
| 199 /** | 200 /** |
| 200 * The instance of the status helper. | 201 * The instance of the status helper. |
| 201 */ | 202 */ |
| 202 final StatusSupport _statusSupport = new StatusSupport(); | 203 final StatusSupport _statusSupport = new StatusSupport(); |
| 203 | 204 |
| 204 /** | 205 /** |
| 206 * The controller for the [exceptions] stream. |
| 207 */ |
| 208 final StreamController<ExceptionResult> _exceptionController = |
| 209 new StreamController<ExceptionResult>(); |
| 210 |
| 211 /** |
| 205 * The instance of the [Search] helper. | 212 * The instance of the [Search] helper. |
| 206 */ | 213 */ |
| 207 Search _search; | 214 Search _search; |
| 208 | 215 |
| 209 /** | 216 /** |
| 210 * Create a new instance of [AnalysisDriver]. | 217 * Create a new instance of [AnalysisDriver]. |
| 211 * | 218 * |
| 212 * The given [SourceFactory] is cloned to ensure that it does not contain a | 219 * The given [SourceFactory] is cloned to ensure that it does not contain a |
| 213 * reference to a [AnalysisContext] in which it could have been used. | 220 * reference to a [AnalysisContext] in which it could have been used. |
| 214 */ | 221 */ |
| (...skipping 20 matching lines...) Expand all Loading... |
| 235 _scheduler._add(this); | 242 _scheduler._add(this); |
| 236 _search = new Search(this); | 243 _search = new Search(this); |
| 237 } | 244 } |
| 238 | 245 |
| 239 /** | 246 /** |
| 240 * Return the set of files added to analysis using [addFile]. | 247 * Return the set of files added to analysis using [addFile]. |
| 241 */ | 248 */ |
| 242 Set<String> get addedFiles => _explicitFiles; | 249 Set<String> get addedFiles => _explicitFiles; |
| 243 | 250 |
| 244 /** | 251 /** |
| 252 * Return the stream that produces [ExceptionResult]s. |
| 253 */ |
| 254 Stream<ExceptionResult> get exceptions => _exceptionController.stream; |
| 255 |
| 256 /** |
| 245 * Return the set of files that are known, i.e. added or used implicitly. | 257 * Return the set of files that are known, i.e. added or used implicitly. |
| 246 */ | 258 */ |
| 247 Set<String> get knownFiles => _fsState.knownFiles; | 259 Set<String> get knownFiles => _fsState.knownFiles; |
| 248 | 260 |
| 249 /** | 261 /** |
| 250 * Return the list of files that the driver should try to analyze sooner. | 262 * Return the list of files that the driver should try to analyze sooner. |
| 251 */ | 263 */ |
| 252 List<String> get priorityFiles => _priorityFiles.toList(growable: false); | 264 List<String> get priorityFiles => _priorityFiles.toList(growable: false); |
| 253 | 265 |
| 254 /** | 266 /** |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 790 // Verify all changed files one at a time. | 802 // Verify all changed files one at a time. |
| 791 if (_changedFiles.isNotEmpty) { | 803 if (_changedFiles.isNotEmpty) { |
| 792 String path = _removeFirst(_changedFiles); | 804 String path = _removeFirst(_changedFiles); |
| 793 _verifyApiSignature(path); | 805 _verifyApiSignature(path); |
| 794 return; | 806 return; |
| 795 } | 807 } |
| 796 | 808 |
| 797 // Analyze a requested file. | 809 // Analyze a requested file. |
| 798 if (_requestedFiles.isNotEmpty) { | 810 if (_requestedFiles.isNotEmpty) { |
| 799 String path = _requestedFiles.keys.first; | 811 String path = _requestedFiles.keys.first; |
| 800 AnalysisResult result = _computeAnalysisResult(path, withUnit: true); | 812 try { |
| 801 // If a part without a library, delay its analysis. | 813 AnalysisResult result = _computeAnalysisResult(path, withUnit: true); |
| 802 if (result == null) { | 814 // If a part without a library, delay its analysis. |
| 803 _requestedParts | 815 if (result == null) { |
| 804 .putIfAbsent(path, () => []) | 816 _requestedParts |
| 805 .addAll(_requestedFiles.remove(path)); | 817 .putIfAbsent(path, () => []) |
| 806 return; | 818 .addAll(_requestedFiles.remove(path)); |
| 819 return; |
| 820 } |
| 821 // Notify the completers. |
| 822 _requestedFiles.remove(path).forEach((completer) { |
| 823 completer.complete(result); |
| 824 }); |
| 825 // Remove from to be analyzed and produce it now. |
| 826 _filesToAnalyze.remove(path); |
| 827 _resultController.add(result); |
| 828 } catch (exception, stackTrace) { |
| 829 _filesToAnalyze.remove(path); |
| 830 _requestedFiles.remove(path).forEach((completer) { |
| 831 completer.completeError(exception, stackTrace); |
| 832 }); |
| 807 } | 833 } |
| 808 // Notify the completers. | |
| 809 _requestedFiles.remove(path).forEach((completer) { | |
| 810 completer.complete(result); | |
| 811 }); | |
| 812 // Remove from to be analyzed and produce it now. | |
| 813 _filesToAnalyze.remove(path); | |
| 814 _resultController.add(result); | |
| 815 return; | 834 return; |
| 816 } | 835 } |
| 817 | 836 |
| 818 // Process an index request. | 837 // Process an index request. |
| 819 if (_indexRequestedFiles.isNotEmpty) { | 838 if (_indexRequestedFiles.isNotEmpty) { |
| 820 String path = _indexRequestedFiles.keys.first; | 839 String path = _indexRequestedFiles.keys.first; |
| 821 IndexResult result = _computeIndexResult(path); | 840 IndexResult result = _computeIndexResult(path); |
| 822 _indexRequestedFiles.remove(path).forEach((completer) { | 841 _indexRequestedFiles.remove(path).forEach((completer) { |
| 823 completer.complete(result); | 842 completer.complete(result); |
| 824 }); | 843 }); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 842 if (isDone) { | 861 if (isDone) { |
| 843 _topLevelNameDeclarationsTasks.remove(task); | 862 _topLevelNameDeclarationsTasks.remove(task); |
| 844 } | 863 } |
| 845 return; | 864 return; |
| 846 } | 865 } |
| 847 | 866 |
| 848 // Analyze a priority file. | 867 // Analyze a priority file. |
| 849 if (_priorityFiles.isNotEmpty) { | 868 if (_priorityFiles.isNotEmpty) { |
| 850 for (String path in _priorityFiles) { | 869 for (String path in _priorityFiles) { |
| 851 if (_filesToAnalyze.remove(path)) { | 870 if (_filesToAnalyze.remove(path)) { |
| 852 AnalysisResult result = _computeAnalysisResult(path, withUnit: true); | 871 try { |
| 853 if (result == null) { | 872 AnalysisResult result = |
| 854 _partsToAnalyze.add(path); | 873 _computeAnalysisResult(path, withUnit: true); |
| 855 } else { | 874 if (result == null) { |
| 856 _resultController.add(result); | 875 _partsToAnalyze.add(path); |
| 876 } else { |
| 877 _resultController.add(result); |
| 878 } |
| 879 } catch (exception, stackTrace) { |
| 880 _reportError(path, exception, stackTrace); |
| 857 } | 881 } |
| 858 return; | 882 return; |
| 859 } | 883 } |
| 860 } | 884 } |
| 861 } | 885 } |
| 862 | 886 |
| 863 // Analyze a general file. | 887 // Analyze a general file. |
| 864 if (_filesToAnalyze.isNotEmpty) { | 888 if (_filesToAnalyze.isNotEmpty) { |
| 865 String path = _removeFirst(_filesToAnalyze); | 889 String path = _removeFirst(_filesToAnalyze); |
| 866 AnalysisResult result = _computeAnalysisResult(path, withUnit: false); | 890 try { |
| 867 if (result == null) { | 891 AnalysisResult result = _computeAnalysisResult(path, withUnit: false); |
| 868 _partsToAnalyze.add(path); | 892 if (result == null) { |
| 869 } else { | 893 _partsToAnalyze.add(path); |
| 870 _resultController.add(result); | 894 } else { |
| 895 _resultController.add(result); |
| 896 } |
| 897 } catch (exception, stackTrace) { |
| 898 _reportError(path, exception, stackTrace); |
| 871 } | 899 } |
| 872 return; | 900 return; |
| 873 } | 901 } |
| 874 | 902 |
| 875 // Analyze a requested part file. | 903 // Analyze a requested part file. |
| 876 if (_requestedParts.isNotEmpty) { | 904 if (_requestedParts.isNotEmpty) { |
| 877 String path = _requestedParts.keys.first; | 905 String path = _requestedParts.keys.first; |
| 878 AnalysisResult result = _computeAnalysisResult(path, | 906 try { |
| 879 withUnit: true, asIsIfPartWithoutLibrary: true); | 907 AnalysisResult result = _computeAnalysisResult(path, |
| 880 // Notify the completers. | 908 withUnit: true, asIsIfPartWithoutLibrary: true); |
| 881 _requestedParts.remove(path).forEach((completer) { | 909 // Notify the completers. |
| 882 completer.complete(result); | 910 _requestedParts.remove(path).forEach((completer) { |
| 883 }); | 911 completer.complete(result); |
| 884 // Remove from to be analyzed and produce it now. | 912 }); |
| 885 _filesToAnalyze.remove(path); | 913 // Remove from to be analyzed and produce it now. |
| 886 _resultController.add(result); | 914 _partsToAnalyze.remove(path); |
| 915 _resultController.add(result); |
| 916 } catch (exception, stackTrace) { |
| 917 _partsToAnalyze.remove(path); |
| 918 _requestedParts.remove(path).forEach((completer) { |
| 919 completer.completeError(exception, stackTrace); |
| 920 }); |
| 921 } |
| 887 return; | 922 return; |
| 888 } | 923 } |
| 889 | 924 |
| 890 // Analyze a general part. | 925 // Analyze a general part. |
| 891 if (_partsToAnalyze.isNotEmpty) { | 926 if (_partsToAnalyze.isNotEmpty) { |
| 892 String path = _removeFirst(_partsToAnalyze); | 927 String path = _removeFirst(_partsToAnalyze); |
| 893 AnalysisResult result = _computeAnalysisResult(path, | 928 try { |
| 894 withUnit: _priorityFiles.contains(path), | 929 AnalysisResult result = _computeAnalysisResult(path, |
| 895 asIsIfPartWithoutLibrary: true); | 930 withUnit: _priorityFiles.contains(path), |
| 896 _resultController.add(result); | 931 asIsIfPartWithoutLibrary: true); |
| 932 _resultController.add(result); |
| 933 } catch (exception, stackTrace) { |
| 934 _reportError(path, exception, stackTrace); |
| 935 } |
| 897 return; | 936 return; |
| 898 } | 937 } |
| 899 } | 938 } |
| 900 | 939 |
| 940 void _reportError(String path, exception, StackTrace stackTrace) { |
| 941 CaughtException caught = new CaughtException(exception, stackTrace); |
| 942 _exceptionController.add(new ExceptionResult(path, caught)); |
| 943 } |
| 944 |
| 901 /** | 945 /** |
| 902 * Verify the API signature for the file with the given [path], and decide | 946 * Verify the API signature for the file with the given [path], and decide |
| 903 * which linked libraries should be invalidated, and files reanalyzed. | 947 * which linked libraries should be invalidated, and files reanalyzed. |
| 904 */ | 948 */ |
| 905 FileState _verifyApiSignature(String path) { | 949 FileState _verifyApiSignature(String path) { |
| 906 return _logger.run('Verify API signature of $path', () { | 950 return _logger.run('Verify API signature of $path', () { |
| 907 bool anyApiChanged = false; | 951 bool anyApiChanged = false; |
| 908 List<FileState> files = _fsState.getFilesForPath(path); | 952 List<FileState> files = _fsState.getFilesForPath(path); |
| 909 for (FileState file in files) { | 953 for (FileState file in files) { |
| 910 bool apiChanged = file.refresh(); | 954 bool apiChanged = file.refresh(); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1147 this.uri, | 1191 this.uri, |
| 1148 this.content, | 1192 this.content, |
| 1149 this.contentHash, | 1193 this.contentHash, |
| 1150 this.lineInfo, | 1194 this.lineInfo, |
| 1151 this.unit, | 1195 this.unit, |
| 1152 this.errors, | 1196 this.errors, |
| 1153 this._index); | 1197 this._index); |
| 1154 } | 1198 } |
| 1155 | 1199 |
| 1156 /** | 1200 /** |
| 1201 * Exception that happened during analysis. |
| 1202 */ |
| 1203 class ExceptionResult { |
| 1204 /** |
| 1205 * The path of the file being analyzed when the [exception] happened. |
| 1206 * |
| 1207 * Absolute and normalized. |
| 1208 */ |
| 1209 final String path; |
| 1210 |
| 1211 /** |
| 1212 * The exception during analysis of the file with the [path]. |
| 1213 */ |
| 1214 final CaughtException exception; |
| 1215 |
| 1216 ExceptionResult(this.path, this.exception); |
| 1217 } |
| 1218 |
| 1219 /** |
| 1157 * The result of indexing of a single file. | 1220 * The result of indexing of a single file. |
| 1158 */ | 1221 */ |
| 1159 class IndexResult { | 1222 class IndexResult { |
| 1160 /** | 1223 /** |
| 1161 * The element of the file. | 1224 * The element of the file. |
| 1162 */ | 1225 */ |
| 1163 final CompilationUnitElement unitElement; | 1226 final CompilationUnitElement unitElement; |
| 1164 | 1227 |
| 1165 /** | 1228 /** |
| 1166 * The index of the file. | 1229 * The index of the file. |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1393 libraryDeclarations | 1456 libraryDeclarations |
| 1394 .add(new TopLevelDeclarationInSource(file.source, declaration)); | 1457 .add(new TopLevelDeclarationInSource(file.source, declaration)); |
| 1395 } | 1458 } |
| 1396 } | 1459 } |
| 1397 } | 1460 } |
| 1398 | 1461 |
| 1399 // We're not done yet. | 1462 // We're not done yet. |
| 1400 return false; | 1463 return false; |
| 1401 } | 1464 } |
| 1402 } | 1465 } |
| OLD | NEW |