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

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

Issue 2544883003: Implement 'topLevelLibraryDeclarations' getter to return all libraries with exported top-level decl… (Closed)
Patch Set: Created 4 years 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/lib/src/dart/analysis/top_level_declaration.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/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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/dart/analysis/top_level_declaration.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698