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

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: Change AnalysisDriver API to return declarations of a name. 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 of a name.
162 */
163 final _topLevelNameDeclarationsTasks = <_TopLevelNameDeclarationsTask>[];
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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 Stream<AnalysisStatus> get status => _statusSupport.stream; 302 Stream<AnalysisStatus> get status => _statusSupport.stream;
297 303
298 /** 304 /**
299 * Return the priority of work that the driver needs to perform. 305 * Return the priority of work that the driver needs to perform.
300 */ 306 */
301 AnalysisDriverPriority get _workPriority { 307 AnalysisDriverPriority get _workPriority {
302 if (_requestedFiles.isNotEmpty) { 308 if (_requestedFiles.isNotEmpty) {
303 return AnalysisDriverPriority.interactive; 309 return AnalysisDriverPriority.interactive;
304 } 310 }
305 if (_referencingNameTasks.isNotEmpty) { 311 if (_referencingNameTasks.isNotEmpty) {
306 return AnalysisDriverPriority.referencingName; 312 return AnalysisDriverPriority.interactive;
307 } 313 }
308 if (_indexRequestedFiles.isNotEmpty) { 314 if (_indexRequestedFiles.isNotEmpty) {
309 return AnalysisDriverPriority.getIndex; 315 return AnalysisDriverPriority.interactive;
316 }
317 if (_topLevelNameDeclarationsTasks.isNotEmpty) {
318 return AnalysisDriverPriority.interactive;
310 } 319 }
311 if (_priorityFiles.isNotEmpty) { 320 if (_priorityFiles.isNotEmpty) {
312 for (String path in _priorityFiles) { 321 for (String path in _priorityFiles) {
313 if (_filesToAnalyze.contains(path)) { 322 if (_filesToAnalyze.contains(path)) {
314 return AnalysisDriverPriority.priority; 323 return AnalysisDriverPriority.priority;
315 } 324 }
316 } 325 }
317 } 326 }
318 if (_filesToAnalyze.isNotEmpty) { 327 if (_filesToAnalyze.isNotEmpty) {
319 return AnalysisDriverPriority.general; 328 return AnalysisDriverPriority.general;
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 .putIfAbsent(path, () => <Completer<AnalysisResult>>[]) 440 .putIfAbsent(path, () => <Completer<AnalysisResult>>[])
432 .add(completer); 441 .add(completer);
433 _statusSupport.transitionToAnalyzing(); 442 _statusSupport.transitionToAnalyzing();
434 _scheduler._notify(this); 443 _scheduler._notify(this);
435 return completer.future; 444 return completer.future;
436 } 445 }
437 return new Future.value(); 446 return new Future.value();
438 } 447 }
439 448
440 /** 449 /**
450 * Return a [Future] that completes with top-level declarations with the
451 * given [name] in all known libraries.
452 */
453 Future<List<TopLevelDeclarationInSource>> getTopLevelNameDeclarations(
454 String name) {
455 var task = new _TopLevelNameDeclarationsTask(this, name);
456 _topLevelNameDeclarationsTasks.add(task);
457 _statusSupport.transitionToAnalyzing();
458 _scheduler._notify(this);
459 return task.completer.future;
460 }
461
462 /**
441 * Return a [Future] that completes with a [ParseResult] for the file 463 * Return a [Future] that completes with a [ParseResult] for the file
442 * with the given [path]. 464 * with the given [path].
443 * 465 *
444 * The [path] must be absolute and normalized. 466 * The [path] must be absolute and normalized.
445 * 467 *
446 * The [path] can be any file - explicitly or implicitly analyzed, or neither. 468 * The [path] can be any file - explicitly or implicitly analyzed, or neither.
447 * 469 *
448 * The parsing is performed in the method itself, and the result is not 470 * The parsing is performed in the method itself, and the result is not
449 * produced through the [results] stream (just because it is not a fully 471 * produced through the [results] stream (just because it is not a fully
450 * resolved unit). 472 * resolved unit).
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 // Compute files referencing a name. 828 // Compute files referencing a name.
807 if (_referencingNameTasks.isNotEmpty) { 829 if (_referencingNameTasks.isNotEmpty) {
808 _FilesReferencingNameTask task = _referencingNameTasks.first; 830 _FilesReferencingNameTask task = _referencingNameTasks.first;
809 bool isDone = await task.perform(); 831 bool isDone = await task.perform();
810 if (isDone) { 832 if (isDone) {
811 _referencingNameTasks.remove(task); 833 _referencingNameTasks.remove(task);
812 } 834 }
813 return; 835 return;
814 } 836 }
815 837
838 // Compute top-level declarations.
839 if (_topLevelNameDeclarationsTasks.isNotEmpty) {
840 _TopLevelNameDeclarationsTask task = _topLevelNameDeclarationsTasks.first;
841 bool isDone = await task.perform();
842 if (isDone) {
843 _topLevelNameDeclarationsTasks.remove(task);
844 }
845 return;
846 }
847
816 // Analyze a priority file. 848 // Analyze a priority file.
817 if (_priorityFiles.isNotEmpty) { 849 if (_priorityFiles.isNotEmpty) {
818 for (String path in _priorityFiles) { 850 for (String path in _priorityFiles) {
819 if (_filesToAnalyze.remove(path)) { 851 if (_filesToAnalyze.remove(path)) {
820 AnalysisResult result = _computeAnalysisResult(path, withUnit: true); 852 AnalysisResult result = _computeAnalysisResult(path, withUnit: true);
821 if (result == null) { 853 if (result == null) {
822 _partsToAnalyze.add(path); 854 _partsToAnalyze.add(path);
823 } else { 855 } else {
824 _resultController.add(result); 856 _resultController.add(result);
825 } 857 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 set.remove(element); 929 set.remove(element);
898 return element; 930 return element;
899 } 931 }
900 } 932 }
901 933
902 /** 934 /**
903 * Priorities of [AnalysisDriver] work. The farther a priority to the beginning 935 * Priorities of [AnalysisDriver] work. The farther a priority to the beginning
904 * of the list, the earlier the corresponding [AnalysisDriver] should be asked 936 * of the list, the earlier the corresponding [AnalysisDriver] should be asked
905 * to perform work. 937 * to perform work.
906 */ 938 */
907 enum AnalysisDriverPriority { 939 enum AnalysisDriverPriority { nothing, general, priority, interactive }
908 nothing,
909 general,
910 priority,
911 referencingName,
912 getIndex,
913 interactive
914 }
915 940
916 /** 941 /**
917 * Instances of this class schedule work in multiple [AnalysisDriver]s so that 942 * Instances of this class schedule work in multiple [AnalysisDriver]s so that
918 * work with the highest priority is performed first. 943 * work with the highest priority is performed first.
919 */ 944 */
920 class AnalysisDriverScheduler { 945 class AnalysisDriverScheduler {
921 /** 946 /**
922 * Time interval in milliseconds before pumping the event queue. 947 * Time interval in milliseconds before pumping the event queue.
923 * 948 *
924 * Relinquishing execution flow and running the event loop after every task 949 * Relinquishing execution flow and running the event loop after every task
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 } 1339 }
1315 1340
1316 /** 1341 /**
1317 * TODO(scheglov) document 1342 * TODO(scheglov) document
1318 */ 1343 */
1319 class _LibraryContext { 1344 class _LibraryContext {
1320 final FileState file; 1345 final FileState file;
1321 final SummaryDataStore store; 1346 final SummaryDataStore store;
1322 _LibraryContext(this.file, this.store); 1347 _LibraryContext(this.file, this.store);
1323 } 1348 }
1349
1350 /**
1351 * Task that computes top-level declarations in all known libraries.
Paul Berry 2016/12/02 17:56:37 Nit: Change to "Task that computes top-level decla
1352 */
1353 class _TopLevelNameDeclarationsTask {
1354 final AnalysisDriver driver;
1355 final String name;
1356 final Completer<List<TopLevelDeclarationInSource>> completer =
1357 new Completer<List<TopLevelDeclarationInSource>>();
1358
1359 final List<TopLevelDeclarationInSource> libraryDeclarations =
1360 <TopLevelDeclarationInSource>[];
1361 final Set<String> checkedFiles = new Set<String>();
1362 final List<String> filesToCheck = <String>[];
1363
1364 _TopLevelNameDeclarationsTask(this.driver, this.name);
1365
1366 /**
1367 * Perform a single piece of work, and either complete the [completer] and
1368 * return `true` to indicate that the task is done, return `false` to indicate
1369 * that the task should continue to be run.
1370 */
1371 Future<bool> perform() async {
1372 // Prepare files to check.
1373 if (filesToCheck.isEmpty) {
1374 filesToCheck.addAll(driver.addedFiles.difference(checkedFiles));
1375 filesToCheck.addAll(driver.knownFiles.difference(checkedFiles));
1376 }
1377
1378 // If no more files to check, complete and done.
1379 if (filesToCheck.isEmpty) {
1380 completer.complete(libraryDeclarations);
1381 return true;
1382 }
1383
1384 // Check the next file.
1385 String path = filesToCheck.removeLast();
1386 if (checkedFiles.add(path)) {
1387 FileState file = driver._fsState.getFileForPath(path);
1388 if (!file.isPart) {
1389 TopLevelDeclaration declaration =
1390 file.exportedTopLevelDeclarations[name];
1391 if (declaration != null) {
1392 libraryDeclarations
1393 .add(new TopLevelDeclarationInSource(file.source, declaration));
1394 }
1395 }
1396 }
1397
1398 // We're not done yet.
1399 return false;
1400 }
1401 }
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