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

Unified Diff: pkg/analysis_server/lib/src/context_manager.dart

Issue 1487903002: Issue 25048. Ignore inner analysis roots which are already managed by outer roots. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Additional test. Created 5 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analysis_server/test/context_manager_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analysis_server/lib/src/context_manager.dart
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 2032c899dbd93d13331ecb10f65e4bdbbff378fe..061cc23c2ace658ad2bdc58b004dd1f0b7c985ef 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -181,6 +181,31 @@ class ContextInfo {
void setDependencies(Iterable<String> newDependencies) {
_dependencies = newDependencies.toSet();
}
+
+ /**
+ * Return `true` if the given [path] is managed by this context or by
+ * any of its children.
+ */
+ bool _managesOrHasChildThatManages(String path) {
+ if (parent == null) {
+ for (ContextInfo child in children) {
+ if (child._managesOrHasChildThatManages(path)) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ if (!folder.isOrContains(path)) {
+ return false;
+ }
+ for (ContextInfo child in children) {
+ if (child._managesOrHasChildThatManages(path)) {
+ return true;
+ }
+ }
+ return !pathFilter.ignored(path);
+ }
+ }
}
/**
@@ -425,7 +450,7 @@ class ContextManagerImpl implements ContextManager {
* Virtual [ContextInfo] which acts as the ancestor of all other
* [ContextInfo]s.
*/
- final ContextInfo _rootInfo = new ContextInfo._root();
+ final ContextInfo rootInfo = new ContextInfo._root();
/**
* Stream subscription we are using to watch each analysis root directory for
@@ -481,7 +506,7 @@ class ContextManagerImpl implements ContextManager {
@override
bool isIgnored(String path) {
- ContextInfo info = _rootInfo;
+ ContextInfo info = rootInfo;
do {
info = info.findChildInfoFor(path);
if (info == null) {
@@ -500,7 +525,7 @@ class ContextManagerImpl implements ContextManager {
return false;
}
// check if in one of the roots
- for (ContextInfo info in _rootInfo.children) {
+ for (ContextInfo info in rootInfo.children) {
if (info.folder.contains(path)) {
return true;
}
@@ -575,7 +600,7 @@ class ContextManagerImpl implements ContextManager {
@override
void refresh(List<Resource> roots) {
// Destroy old contexts
- List<ContextInfo> contextInfos = _rootInfo.descendants.toList();
+ List<ContextInfo> contextInfos = rootInfo.descendants.toList();
if (roots == null) {
contextInfos.forEach(_destroyContext);
} else {
@@ -616,22 +641,31 @@ class ContextManagerImpl implements ContextManager {
}
});
- List<ContextInfo> contextInfos = _rootInfo.descendants.toList();
+ List<ContextInfo> contextInfos = rootInfo.descendants.toList();
// included
- Set<Folder> includedFolders = new HashSet<Folder>();
- for (int i = 0; i < includedPaths.length; i++) {
- String path = includedPaths[i];
- Resource resource = resourceProvider.getResource(path);
- if (resource is Folder) {
- includedFolders.add(resource);
- } else if (!resource.exists) {
- // Non-existent resources are ignored. TODO(paulberry): we should set
- // up a watcher to ensure that if the resource appears later, we will
- // begin analyzing it.
- } else {
- // TODO(scheglov) implemented separate files analysis
- throw new UnimplementedError('$path is not a folder. '
- 'Only support for folder analysis is implemented currently.');
+ List<Folder> includedFolders = <Folder>[];
+ {
+ // Sort paths to ensure that outer roots are handled before inner roots,
+ // so we can correctly ignore inner roots, which are already managed
+ // by outer roots.
+ LinkedHashSet<String> uniqueIncludedPaths =
+ new LinkedHashSet<String>.from(includedPaths);
+ List<String> sortedIncludedPaths = uniqueIncludedPaths.toList();
+ sortedIncludedPaths.sort((a, b) => a.length - b.length);
+ // Convert paths to folders.
+ for (String path in sortedIncludedPaths) {
+ Resource resource = resourceProvider.getResource(path);
+ if (resource is Folder) {
+ includedFolders.add(resource);
+ } else if (!resource.exists) {
+ // Non-existent resources are ignored. TODO(paulberry): we should set
+ // up a watcher to ensure that if the resource appears later, we will
+ // begin analyzing it.
+ } else {
+ // TODO(scheglov) implemented separate files analysis
+ throw new UnimplementedError('$path is not a folder. '
+ 'Only support for folder analysis is implemented currently.');
+ }
}
}
this.includedPaths = includedPaths;
@@ -648,7 +682,7 @@ class ContextManagerImpl implements ContextManager {
}
}
// Update package roots for existing contexts
- for (ContextInfo info in _rootInfo.descendants) {
+ for (ContextInfo info in rootInfo.descendants) {
String newPackageRoot = normalizedPackageRoots[info.folder.path];
if (info.packageRoot != newPackageRoot) {
info.packageRoot = newPackageRoot;
@@ -657,17 +691,17 @@ class ContextManagerImpl implements ContextManager {
}
// create new contexts
for (Folder includedFolder in includedFolders) {
- bool wasIncluded = contextInfos.any((info) {
- return info.folder.isOrContains(includedFolder.path);
- });
- if (!wasIncluded) {
+ String includedPath = includedFolder.path;
+ bool isManaged = rootInfo._managesOrHasChildThatManages(includedPath);
+ if (!isManaged) {
+ ContextInfo parent = _getParentForNewContext(includedPath);
changeSubscriptions[includedFolder] =
includedFolder.changes.listen(_handleWatchEvent);
- _createContexts(_rootInfo, includedFolder, false);
+ _createContexts(parent, includedFolder, false);
}
}
// remove newly excluded sources
- for (ContextInfo info in _rootInfo.descendants) {
+ for (ContextInfo info in rootInfo.descendants) {
// prepare excluded sources
Map<String, Source> excludedSources = new HashMap<String, Source>();
info.sources.forEach((String path, Source source) {
@@ -685,7 +719,7 @@ class ContextManagerImpl implements ContextManager {
callbacks.applyChangesToContext(info.folder, changeSet);
}
// add previously excluded sources
- for (ContextInfo info in _rootInfo.descendants) {
+ for (ContextInfo info in rootInfo.descendants) {
ChangeSet changeSet = new ChangeSet();
_addPreviouslyExcludedSources(
info, changeSet, info.folder, oldExcludedPaths);
@@ -822,7 +856,7 @@ class ContextManagerImpl implements ContextManager {
for (Source source in context.sources) {
flushedFiles.add(source.fullName);
}
- for (ContextInfo contextInfo in _rootInfo.descendants) {
+ for (ContextInfo contextInfo in rootInfo.descendants) {
AnalysisContext contextN = contextInfo.context;
if (context != contextN) {
for (Source source in contextN.sources) {
@@ -1082,7 +1116,7 @@ class ContextManagerImpl implements ContextManager {
* If no context contains the given path, `null` is returned.
*/
ContextInfo _getInnermostContextInfoFor(String path) {
- ContextInfo info = _rootInfo.findChildInfoFor(path);
+ ContextInfo info = rootInfo.findChildInfoFor(path);
if (info == null) {
return null;
}
@@ -1095,6 +1129,17 @@ class ContextManagerImpl implements ContextManager {
}
}
+ /**
+ * Return the parent for a new [ContextInfo] with the given [path] folder.
+ */
+ ContextInfo _getParentForNewContext(String path) {
+ ContextInfo parent = _getInnermostContextInfoFor(path);
+ if (parent != null) {
+ return parent;
+ }
+ return rootInfo;
+ }
+
void _handleWatchEvent(WatchEvent event) {
// Figure out which context this event applies to.
// TODO(brianwilkerson) If a file is explicitly included in one context
« no previous file with comments | « no previous file | pkg/analysis_server/test/context_manager_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698