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/file_system/file_system.dart'; | 13 import 'package:analyzer/file_system/file_system.dart'; |
14 import 'package:analyzer/src/context/context.dart'; | 14 import 'package:analyzer/src/context/context.dart'; |
15 import 'package:analyzer/src/dart/analysis/byte_store.dart'; | 15 import 'package:analyzer/src/dart/analysis/byte_store.dart'; |
16 import 'package:analyzer/src/dart/analysis/file_state.dart'; | 16 import 'package:analyzer/src/dart/analysis/file_state.dart'; |
17 import 'package:analyzer/src/dart/analysis/index.dart'; | 17 import 'package:analyzer/src/dart/analysis/index.dart'; |
18 import 'package:analyzer/src/dart/analysis/search.dart'; | 18 import 'package:analyzer/src/dart/analysis/search.dart'; |
19 import 'package:analyzer/src/dart/analysis/status.dart'; | 19 import 'package:analyzer/src/dart/analysis/status.dart'; |
20 import 'package:analyzer/src/dart/analysis/top_level_declaration.dart'; | |
20 import 'package:analyzer/src/generated/engine.dart' | 21 import 'package:analyzer/src/generated/engine.dart' |
21 show AnalysisContext, AnalysisEngine, AnalysisOptions, ChangeSet; | 22 show AnalysisContext, AnalysisEngine, AnalysisOptions, ChangeSet; |
22 import 'package:analyzer/src/generated/source.dart'; | 23 import 'package:analyzer/src/generated/source.dart'; |
23 import 'package:analyzer/src/summary/api_signature.dart'; | 24 import 'package:analyzer/src/summary/api_signature.dart'; |
24 import 'package:analyzer/src/summary/format.dart'; | 25 import 'package:analyzer/src/summary/format.dart'; |
25 import 'package:analyzer/src/summary/idl.dart'; | 26 import 'package:analyzer/src/summary/idl.dart'; |
26 import 'package:analyzer/src/summary/link.dart'; | 27 import 'package:analyzer/src/summary/link.dart'; |
27 import 'package:analyzer/src/summary/package_bundle_reader.dart'; | 28 import 'package:analyzer/src/summary/package_bundle_reader.dart'; |
28 import 'package:analyzer/src/task/dart.dart' show COMPILATION_UNIT_ELEMENT; | 29 import 'package:analyzer/src/task/dart.dart' show COMPILATION_UNIT_ELEMENT; |
29 import 'package:analyzer/task/dart.dart' show LibrarySpecificUnit; | 30 import 'package:analyzer/task/dart.dart' show LibrarySpecificUnit; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
150 * [getResult] to the [Completer]s to report the result. | 151 * [getResult] to the [Completer]s to report the result. |
151 */ | 152 */ |
152 final _requestedFiles = <String, List<Completer<AnalysisResult>>>{}; | 153 final _requestedFiles = <String, List<Completer<AnalysisResult>>>{}; |
153 | 154 |
154 /** | 155 /** |
155 * The list of tasks to compute files referencing a name. | 156 * The list of tasks to compute files referencing a name. |
156 */ | 157 */ |
157 final _referencingNameTasks = <_FilesReferencingNameTask>[]; | 158 final _referencingNameTasks = <_FilesReferencingNameTask>[]; |
158 | 159 |
159 /** | 160 /** |
161 * The list of tasks to compute top-level declarations. | |
162 */ | |
163 final _topLevelDeclarationsTasks = <_TopLevelLibraryDeclarationsTask>[]; | |
164 | |
165 /** | |
160 * The mapping from the files for which the index was requested using | 166 * The mapping from the files for which the index was requested using |
161 * [getIndex] to the [Completer]s to report the result. | 167 * [getIndex] to the [Completer]s to report the result. |
162 */ | 168 */ |
163 final _indexRequestedFiles = <String, List<Completer<IndexResult>>>{}; | 169 final _indexRequestedFiles = <String, List<Completer<IndexResult>>>{}; |
164 | 170 |
165 /** | 171 /** |
166 * The set of files were reported as changed through [changeFile] and not | 172 * The set of files were reported as changed through [changeFile] and not |
167 * checked for actual changes yet. | 173 * checked for actual changes yet. |
168 */ | 174 */ |
169 final _changedFiles = new LinkedHashSet<String>(); | 175 final _changedFiles = new LinkedHashSet<String>(); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
289 * Return the search support for the driver. | 295 * Return the search support for the driver. |
290 */ | 296 */ |
291 Search get search => _search; | 297 Search get search => _search; |
292 | 298 |
293 /** | 299 /** |
294 * Return the stream that produces [AnalysisStatus] events. | 300 * Return the stream that produces [AnalysisStatus] events. |
295 */ | 301 */ |
296 Stream<AnalysisStatus> get status => _statusSupport.stream; | 302 Stream<AnalysisStatus> get status => _statusSupport.stream; |
297 | 303 |
298 /** | 304 /** |
305 * Return a [Future] that completes with top-level declaration in all known | |
306 * libraries. | |
307 */ | |
308 Future<List<TopLevelLibraryDeclarations>> get topLevelLibraryDeclarations { | |
Paul Berry
2016/12/01 22:28:15
I'm concerned that this API forces the driver to c
scheglov
2016/12/02 17:19:12
That's a good idea.
Thank you.
We need to know ki
| |
309 var task = new _TopLevelLibraryDeclarationsTask(this); | |
310 _topLevelDeclarationsTasks.add(task); | |
311 _statusSupport.transitionToAnalyzing(); | |
312 _scheduler._notify(this); | |
313 return task.completer.future; | |
314 } | |
315 | |
316 /** | |
299 * Return the priority of work that the driver needs to perform. | 317 * Return the priority of work that the driver needs to perform. |
300 */ | 318 */ |
301 AnalysisDriverPriority get _workPriority { | 319 AnalysisDriverPriority get _workPriority { |
302 if (_requestedFiles.isNotEmpty) { | 320 if (_requestedFiles.isNotEmpty) { |
303 return AnalysisDriverPriority.interactive; | 321 return AnalysisDriverPriority.interactive; |
304 } | 322 } |
305 if (_referencingNameTasks.isNotEmpty) { | 323 if (_referencingNameTasks.isNotEmpty) { |
306 return AnalysisDriverPriority.referencingName; | 324 return AnalysisDriverPriority.interactive; |
307 } | 325 } |
308 if (_indexRequestedFiles.isNotEmpty) { | 326 if (_indexRequestedFiles.isNotEmpty) { |
309 return AnalysisDriverPriority.getIndex; | 327 return AnalysisDriverPriority.interactive; |
328 } | |
329 if (_topLevelDeclarationsTasks.isNotEmpty) { | |
330 return AnalysisDriverPriority.interactive; | |
310 } | 331 } |
311 if (_priorityFiles.isNotEmpty) { | 332 if (_priorityFiles.isNotEmpty) { |
312 for (String path in _priorityFiles) { | 333 for (String path in _priorityFiles) { |
313 if (_filesToAnalyze.contains(path)) { | 334 if (_filesToAnalyze.contains(path)) { |
314 return AnalysisDriverPriority.priority; | 335 return AnalysisDriverPriority.priority; |
315 } | 336 } |
316 } | 337 } |
317 } | 338 } |
318 if (_filesToAnalyze.isNotEmpty) { | 339 if (_filesToAnalyze.isNotEmpty) { |
319 return AnalysisDriverPriority.general; | 340 return AnalysisDriverPriority.general; |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
806 // Compute files referencing a name. | 827 // Compute files referencing a name. |
807 if (_referencingNameTasks.isNotEmpty) { | 828 if (_referencingNameTasks.isNotEmpty) { |
808 _FilesReferencingNameTask task = _referencingNameTasks.first; | 829 _FilesReferencingNameTask task = _referencingNameTasks.first; |
809 bool isDone = await task.perform(); | 830 bool isDone = await task.perform(); |
810 if (isDone) { | 831 if (isDone) { |
811 _referencingNameTasks.remove(task); | 832 _referencingNameTasks.remove(task); |
812 } | 833 } |
813 return; | 834 return; |
814 } | 835 } |
815 | 836 |
837 // Compute top-level declarations. | |
838 if (_topLevelDeclarationsTasks.isNotEmpty) { | |
839 _TopLevelLibraryDeclarationsTask task = _topLevelDeclarationsTasks.first; | |
840 bool isDone = await task.perform(); | |
841 if (isDone) { | |
842 _topLevelDeclarationsTasks.remove(task); | |
843 } | |
844 return; | |
845 } | |
846 | |
816 // Analyze a priority file. | 847 // Analyze a priority file. |
817 if (_priorityFiles.isNotEmpty) { | 848 if (_priorityFiles.isNotEmpty) { |
818 for (String path in _priorityFiles) { | 849 for (String path in _priorityFiles) { |
819 if (_filesToAnalyze.remove(path)) { | 850 if (_filesToAnalyze.remove(path)) { |
820 AnalysisResult result = _computeAnalysisResult(path, withUnit: true); | 851 AnalysisResult result = _computeAnalysisResult(path, withUnit: true); |
821 if (result == null) { | 852 if (result == null) { |
822 _partsToAnalyze.add(path); | 853 _partsToAnalyze.add(path); |
823 } else { | 854 } else { |
824 _resultController.add(result); | 855 _resultController.add(result); |
825 } | 856 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
897 set.remove(element); | 928 set.remove(element); |
898 return element; | 929 return element; |
899 } | 930 } |
900 } | 931 } |
901 | 932 |
902 /** | 933 /** |
903 * Priorities of [AnalysisDriver] work. The farther a priority to the beginning | 934 * Priorities of [AnalysisDriver] work. The farther a priority to the beginning |
904 * of the list, the earlier the corresponding [AnalysisDriver] should be asked | 935 * of the list, the earlier the corresponding [AnalysisDriver] should be asked |
905 * to perform work. | 936 * to perform work. |
906 */ | 937 */ |
907 enum AnalysisDriverPriority { | 938 enum AnalysisDriverPriority { nothing, general, priority, interactive } |
908 nothing, | |
909 general, | |
910 priority, | |
911 referencingName, | |
912 getIndex, | |
913 interactive | |
914 } | |
915 | 939 |
916 /** | 940 /** |
917 * Instances of this class schedule work in multiple [AnalysisDriver]s so that | 941 * Instances of this class schedule work in multiple [AnalysisDriver]s so that |
918 * work with the highest priority is performed first. | 942 * work with the highest priority is performed first. |
919 */ | 943 */ |
920 class AnalysisDriverScheduler { | 944 class AnalysisDriverScheduler { |
921 /** | 945 /** |
922 * Time interval in milliseconds before pumping the event queue. | 946 * Time interval in milliseconds before pumping the event queue. |
923 * | 947 * |
924 * Relinquishing execution flow and running the event loop after every task | 948 * Relinquishing execution flow and running the event loop after every task |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1314 } | 1338 } |
1315 | 1339 |
1316 /** | 1340 /** |
1317 * TODO(scheglov) document | 1341 * TODO(scheglov) document |
1318 */ | 1342 */ |
1319 class _LibraryContext { | 1343 class _LibraryContext { |
1320 final FileState file; | 1344 final FileState file; |
1321 final SummaryDataStore store; | 1345 final SummaryDataStore store; |
1322 _LibraryContext(this.file, this.store); | 1346 _LibraryContext(this.file, this.store); |
1323 } | 1347 } |
1348 | |
1349 /** | |
1350 * Task that computes top-level declarations in all known libraries. | |
1351 */ | |
1352 class _TopLevelLibraryDeclarationsTask { | |
1353 final AnalysisDriver driver; | |
1354 final Completer<List<TopLevelLibraryDeclarations>> completer = | |
1355 new Completer<List<TopLevelLibraryDeclarations>>(); | |
1356 | |
1357 final List<TopLevelLibraryDeclarations> libraryDeclarations = | |
1358 <TopLevelLibraryDeclarations>[]; | |
1359 final Set<String> checkedFiles = new Set<String>(); | |
1360 final List<String> filesToCheck = <String>[]; | |
1361 | |
1362 _TopLevelLibraryDeclarationsTask(this.driver); | |
1363 | |
1364 /** | |
1365 * Perform a single piece of work, and either complete the [completer] and | |
1366 * return `true` to indicate that the task is done, return `false` to indicate | |
1367 * that the task should continue to be run. | |
1368 */ | |
1369 Future<bool> perform() async { | |
1370 // Prepare files to check. | |
1371 if (filesToCheck.isEmpty) { | |
1372 filesToCheck.addAll(driver.addedFiles.difference(checkedFiles)); | |
1373 filesToCheck.addAll(driver.knownFiles.difference(checkedFiles)); | |
1374 } | |
1375 | |
1376 // If no more files to check, complete and done. | |
1377 if (filesToCheck.isEmpty) { | |
1378 completer.complete(libraryDeclarations); | |
1379 return true; | |
1380 } | |
1381 | |
1382 // Check the next file. | |
1383 String path = filesToCheck.removeLast(); | |
1384 FileState file = driver._fsState.getFileForPath(path); | |
1385 if (!file.isPart) { | |
1386 libraryDeclarations.add(new TopLevelLibraryDeclarations( | |
1387 file.source, file.exportedTopLevelDeclarations)); | |
1388 } | |
1389 checkedFiles.add(path); | |
1390 | |
1391 // We're not done yet. | |
1392 return false; | |
1393 } | |
1394 } | |
OLD | NEW |