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

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

Issue 2673653003: Add AnalysisDriver.getFilesDefiningClassMemberName(). (Closed)
Patch Set: Created 3 years, 10 months 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/test/src/dart/analysis/driver_test.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/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';
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 */ 153 */
154 final _priorityFiles = new LinkedHashSet<String>(); 154 final _priorityFiles = new LinkedHashSet<String>();
155 155
156 /** 156 /**
157 * The mapping from the files for which analysis was requested using 157 * The mapping from the files for which analysis was requested using
158 * [getResult] to the [Completer]s to report the result. 158 * [getResult] to the [Completer]s to report the result.
159 */ 159 */
160 final _requestedFiles = <String, List<Completer<AnalysisResult>>>{}; 160 final _requestedFiles = <String, List<Completer<AnalysisResult>>>{};
161 161
162 /** 162 /**
163 * The list of tasks to compute files defining a class member name.
164 */
165 final _definingClassMemberNameTasks = <_FilesDefiningClassMemberNameTask>[];
166
167 /**
163 * The list of tasks to compute files referencing a name. 168 * The list of tasks to compute files referencing a name.
164 */ 169 */
165 final _referencingNameTasks = <_FilesReferencingNameTask>[]; 170 final _referencingNameTasks = <_FilesReferencingNameTask>[];
166 171
167 /** 172 /**
168 * The list of tasks to compute top-level declarations of a name. 173 * The list of tasks to compute top-level declarations of a name.
169 */ 174 */
170 final _topLevelNameDeclarationsTasks = <_TopLevelNameDeclarationsTask>[]; 175 final _topLevelNameDeclarationsTasks = <_TopLevelNameDeclarationsTask>[];
171 176
172 /** 177 /**
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 @visibleForTesting 365 @visibleForTesting
361 AnalysisDriverTestView get test => _testView; 366 AnalysisDriverTestView get test => _testView;
362 367
363 /** 368 /**
364 * Return the priority of work that the driver needs to perform. 369 * Return the priority of work that the driver needs to perform.
365 */ 370 */
366 AnalysisDriverPriority get _workPriority { 371 AnalysisDriverPriority get _workPriority {
367 if (_requestedFiles.isNotEmpty) { 372 if (_requestedFiles.isNotEmpty) {
368 return AnalysisDriverPriority.interactive; 373 return AnalysisDriverPriority.interactive;
369 } 374 }
370 if (_referencingNameTasks.isNotEmpty) { 375 if (_definingClassMemberNameTasks.isNotEmpty ||
376 _referencingNameTasks.isNotEmpty) {
371 return AnalysisDriverPriority.interactive; 377 return AnalysisDriverPriority.interactive;
372 } 378 }
373 if (_indexRequestedFiles.isNotEmpty) { 379 if (_indexRequestedFiles.isNotEmpty) {
374 return AnalysisDriverPriority.interactive; 380 return AnalysisDriverPriority.interactive;
375 } 381 }
376 if (_unitElementRequestedFiles.isNotEmpty) { 382 if (_unitElementRequestedFiles.isNotEmpty) {
377 return AnalysisDriverPriority.interactive; 383 return AnalysisDriverPriority.interactive;
378 } 384 }
379 if (_topLevelNameDeclarationsTasks.isNotEmpty) { 385 if (_topLevelNameDeclarationsTasks.isNotEmpty) {
380 return AnalysisDriverPriority.interactive; 386 return AnalysisDriverPriority.interactive;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 return new ErrorsResult( 504 return new ErrorsResult(
499 path, 505 path,
500 analysisResult.uri, 506 analysisResult.uri,
501 analysisResult.contentHash, 507 analysisResult.contentHash,
502 analysisResult.lineInfo, 508 analysisResult.lineInfo,
503 analysisResult.errors); 509 analysisResult.errors);
504 } 510 }
505 511
506 /** 512 /**
507 * Return a [Future] that completes with the list of added files that 513 * Return a [Future] that completes with the list of added files that
514 * define a class member with the given [name].
515 */
516 Future<List<String>> getFilesDefiningClassMemberName(String name) {
517 var task = new _FilesDefiningClassMemberNameTask(this, name);
518 _definingClassMemberNameTasks.add(task);
519 _scheduler._notify(this);
520 return task.completer.future;
521 }
522
523 /**
524 * Return a [Future] that completes with the list of added files that
508 * reference the given external [name]. 525 * reference the given external [name].
509 */ 526 */
510 Future<List<String>> getFilesReferencingName(String name) { 527 Future<List<String>> getFilesReferencingName(String name) {
511 var task = new _FilesReferencingNameTask(this, name); 528 var task = new _FilesReferencingNameTask(this, name);
512 _referencingNameTasks.add(task); 529 _referencingNameTasks.add(task);
513 _scheduler._notify(this); 530 _scheduler._notify(this);
514 return task.completer.future; 531 return task.completer.future;
515 } 532 }
516 533
517 /** 534 /**
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
931 // Process a unit request. 948 // Process a unit request.
932 if (_unitElementRequestedFiles.isNotEmpty) { 949 if (_unitElementRequestedFiles.isNotEmpty) {
933 String path = _unitElementRequestedFiles.keys.first; 950 String path = _unitElementRequestedFiles.keys.first;
934 CompilationUnitElement unitElement = _computeUnitElement(path); 951 CompilationUnitElement unitElement = _computeUnitElement(path);
935 _unitElementRequestedFiles.remove(path).forEach((completer) { 952 _unitElementRequestedFiles.remove(path).forEach((completer) {
936 completer.complete(unitElement); 953 completer.complete(unitElement);
937 }); 954 });
938 return; 955 return;
939 } 956 }
940 957
958 // Compute files defining a name.
959 if (_definingClassMemberNameTasks.isNotEmpty) {
960 _FilesDefiningClassMemberNameTask task =
961 _definingClassMemberNameTasks.first;
962 bool isDone = await task.perform();
963 if (isDone) {
964 _definingClassMemberNameTasks.remove(task);
965 }
966 return;
967 }
968
941 // Compute files referencing a name. 969 // Compute files referencing a name.
942 if (_referencingNameTasks.isNotEmpty) { 970 if (_referencingNameTasks.isNotEmpty) {
943 _FilesReferencingNameTask task = _referencingNameTasks.first; 971 _FilesReferencingNameTask task = _referencingNameTasks.first;
944 bool isDone = await task.perform(); 972 bool isDone = await task.perform();
945 if (isDone) { 973 if (isDone) {
946 _referencingNameTasks.remove(task); 974 _referencingNameTasks.remove(task);
947 } 975 }
948 return; 976 return;
949 } 977 }
950 978
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after
1595 final String contextKey; 1623 final String contextKey;
1596 1624
1597 _ExceptionState(this.exception, this.stackTrace, this.contextKey); 1625 _ExceptionState(this.exception, this.stackTrace, this.contextKey);
1598 1626
1599 @override 1627 @override
1600 String toString() => '$exception\n$stackTrace'; 1628 String toString() => '$exception\n$stackTrace';
1601 } 1629 }
1602 1630
1603 /** 1631 /**
1604 * Task that computes the list of files that were added to the driver and 1632 * Task that computes the list of files that were added to the driver and
1633 * declare a class member with the given [name].
1634 */
1635 class _FilesDefiningClassMemberNameTask {
1636 static const int _MS_WORK_INTERVAL = 5;
1637
1638 final AnalysisDriver driver;
1639 final String name;
1640 final Completer<List<String>> completer = new Completer<List<String>>();
1641
1642 final List<String> definingFiles = <String>[];
1643 final Set<String> checkedFiles = new Set<String>();
1644 final List<String> filesToCheck = <String>[];
1645
1646 _FilesDefiningClassMemberNameTask(this.driver, this.name);
1647
1648 /**
1649 * Perform work for a fixed length of time, and complete the [completer] to
1650 * either return `true` to indicate that the task is done, or return `false`
1651 * to indicate that the task should continue to be run.
1652 *
1653 * Each invocation of an asynchronous method has overhead, which looks as
1654 * `_SyncCompleter.complete` invocation, we see as much as 62% in some
1655 * scenarios. Instead we use a fixed length of time, so we can spend less time
1656 * overall and keep quick enough response time.
1657 */
1658 Future<bool> perform() async {
1659 Stopwatch timer = new Stopwatch()..start();
1660 while (timer.elapsedMilliseconds < _MS_WORK_INTERVAL) {
1661 // Prepare files to check.
1662 if (filesToCheck.isEmpty) {
1663 Set<String> newFiles = driver.addedFiles.difference(checkedFiles);
1664 filesToCheck.addAll(newFiles);
1665 }
1666
1667 // If no more files to check, complete and done.
1668 if (filesToCheck.isEmpty) {
1669 completer.complete(definingFiles);
1670 return true;
1671 }
1672
1673 // Check the next file.
1674 String path = filesToCheck.removeLast();
1675 FileState file = driver._fsState.getFileForPath(path);
1676 if (file.definedClassMemberNames.contains(name)) {
1677 definingFiles.add(path);
1678 }
1679 checkedFiles.add(path);
1680 }
1681
1682 // We're not done yet.
1683 return false;
1684 }
1685 }
1686
1687 /**
1688 * Task that computes the list of files that were added to the driver and
1605 * have at least one reference to an identifier [name] defined outside of the 1689 * have at least one reference to an identifier [name] defined outside of the
1606 * file. 1690 * file.
1607 */ 1691 */
1608 class _FilesReferencingNameTask { 1692 class _FilesReferencingNameTask {
1609 static const int _MS_WORK_INTERVAL = 5; 1693 static const int _MS_WORK_INTERVAL = 5;
1610 1694
1611 final AnalysisDriver driver; 1695 final AnalysisDriver driver;
1612 final String name; 1696 final String name;
1613 final Completer<List<String>> completer = new Completer<List<String>>(); 1697 final Completer<List<String>> completer = new Completer<List<String>>();
1614 1698
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 libraryDeclarations.add(new TopLevelDeclarationInSource( 1794 libraryDeclarations.add(new TopLevelDeclarationInSource(
1711 file.source, declaration, isExported)); 1795 file.source, declaration, isExported));
1712 } 1796 }
1713 } 1797 }
1714 } 1798 }
1715 1799
1716 // We're not done yet. 1800 // We're not done yet.
1717 return false; 1801 return false;
1718 } 1802 }
1719 } 1803 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/dart/analysis/driver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698