| Index: pkg/analyzer/lib/src/dart/analysis/driver.dart
|
| diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
|
| index 517f582e2ca79af502ea5b7a4e9dd9d3ec3f2979..de38ebf1fe65199c97f2717d881fff8ebe8f199a 100644
|
| --- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
|
| +++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
|
| @@ -150,6 +150,11 @@ class AnalysisDriver {
|
| final _requestedFiles = <String, List<Completer<AnalysisResult>>>{};
|
|
|
| /**
|
| + * The list of tasks to compute files referencing a name.
|
| + */
|
| + final _referencingNameTasks = <_FilesReferencingNameTask>[];
|
| +
|
| + /**
|
| * The set of files were reported as changed through [changeFile] and not
|
| * checked for actual changes yet.
|
| */
|
| @@ -284,6 +289,9 @@ class AnalysisDriver {
|
| if (_requestedFiles.isNotEmpty) {
|
| return AnalysisDriverPriority.interactive;
|
| }
|
| + if (_referencingNameTasks.isNotEmpty) {
|
| + return AnalysisDriverPriority.referencingName;
|
| + }
|
| if (_priorityFiles.isNotEmpty) {
|
| for (String path in _priorityFiles) {
|
| if (_filesToAnalyze.contains(path)) {
|
| @@ -357,6 +365,18 @@ class AnalysisDriver {
|
| }
|
|
|
| /**
|
| + * Return a [Future] that completes with the list of added files that
|
| + * reference the given external [name].
|
| + */
|
| + Future<List<String>> getFilesReferencingName(String name) {
|
| + var task = new _FilesReferencingNameTask(this, name);
|
| + _referencingNameTasks.add(task);
|
| + _statusSupport.transitionToAnalyzing();
|
| + _scheduler._notify(this);
|
| + return task.completer.future;
|
| + }
|
| +
|
| + /**
|
| * Return a [Future] that completes with a [AnalysisResult] for the Dart
|
| * file with the given [path]. If the file is not a Dart file, the [Future]
|
| * completes with `null`.
|
| @@ -732,6 +752,16 @@ class AnalysisDriver {
|
| return;
|
| }
|
|
|
| + // Compute files referencing a name.
|
| + if (_referencingNameTasks.isNotEmpty) {
|
| + _FilesReferencingNameTask task = _referencingNameTasks.first;
|
| + bool isDone = await task.perform();
|
| + if (isDone) {
|
| + _referencingNameTasks.remove(task);
|
| + }
|
| + return;
|
| + }
|
| +
|
| // Analyze a priority file.
|
| if (_priorityFiles.isNotEmpty) {
|
| for (String path in _priorityFiles) {
|
| @@ -823,7 +853,13 @@ class AnalysisDriver {
|
| * of the list, the earlier the corresponding [AnalysisDriver] should be asked
|
| * to perform work.
|
| */
|
| -enum AnalysisDriverPriority { nothing, general, priority, interactive }
|
| +enum AnalysisDriverPriority {
|
| + nothing,
|
| + general,
|
| + priority,
|
| + referencingName,
|
| + interactive
|
| +}
|
|
|
| /**
|
| * Instances of this class schedule work in multiple [AnalysisDriver]s so that
|
| @@ -1132,6 +1168,53 @@ class PerformanceLogSection {
|
| }
|
|
|
| /**
|
| + * Task that computes the list of files that were added to the driver and
|
| + * have at least one reference to an identifier [name] defined outside of the
|
| + * file.
|
| + */
|
| +class _FilesReferencingNameTask {
|
| + final AnalysisDriver driver;
|
| + final String name;
|
| + final Completer<List<String>> completer = new Completer<List<String>>();
|
| +
|
| + final List<String> referencingFiles = <String>[];
|
| + final Set<String> checkedFiles = new Set<String>();
|
| + final List<String> filesToCheck = <String>[];
|
| +
|
| + _FilesReferencingNameTask(this.driver, this.name);
|
| +
|
| + /**
|
| + * Perform a single chunk of work, and either complete the [completer] and
|
| + * return `true` to indicate that the task is done, return `false` to
|
| + * indicate that the task should continue to be run.
|
| + */
|
| + Future<bool> perform() async {
|
| + // Prepare files to check.
|
| + if (filesToCheck.isEmpty) {
|
| + Set<String> newFiles = driver.addedFiles.difference(checkedFiles);
|
| + filesToCheck.addAll(newFiles);
|
| + }
|
| +
|
| + // If no more files to check, complete and done.
|
| + if (filesToCheck.isEmpty) {
|
| + completer.complete(referencingFiles);
|
| + return true;
|
| + }
|
| +
|
| + // Check the next file.
|
| + String path = filesToCheck.removeLast();
|
| + FileState file = driver._fsState.getFileForPath(path);
|
| + if (file.referencedNames.contains(name)) {
|
| + referencingFiles.add(path);
|
| + }
|
| + checkedFiles.add(path);
|
| +
|
| + // We're not done yet.
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +/**
|
| * TODO(scheglov) document
|
| */
|
| class _LibraryContext {
|
|
|