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

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

Issue 987663002: Fix for subscribing for notifications for files in packages. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixes for review comments. Created 5 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/context_manager.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analysis_server/lib/src/analysis_server.dart
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 6c7aae92c48bdb42885e76999a4b328fa638ca6f..4b5529dbe73963050da59200c9751bb13915d436 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -367,26 +367,7 @@ class AnalysisServer {
* path.
*/
AnalysisContext getAnalysisContext(String path) {
- // try to find a containing context
- Folder containingFolder = null;
- for (Folder folder in folderMap.keys) {
- if (folder.path == path || folder.contains(path)) {
- if (containingFolder == null) {
- containingFolder = folder;
- } else if (containingFolder.path.length < folder.path.length) {
- containingFolder = folder;
- }
- }
- }
- if (containingFolder != null) {
- return folderMap[containingFolder];
- }
- Resource resource = resourceProvider.getResource(path);
- if (resource is Folder) {
- return null;
- }
- // check if there is a context that analyzed this source
- return getAnalysisContextForSource(_getSourceWithoutContext(path));
+ return getContextSourcePair(path).context;
}
/**
@@ -412,6 +393,67 @@ class AnalysisServer {
}
/**
+ * Return the primary [ContextSourcePair] representing the given [path].
+ *
+ * The [AnalysisContext] of this pair will be the context that explicitly
+ * contains the path, if any such context exists, otherwise it will be the
+ * first context that implicitly analyzes it.
+ *
+ * If the [path] is not analyzed by any context, a [ContextSourcePair] with
+ * `null` context and `file` [Source] is returned.
+ *
+ * If the [path] dosn't represent a file, `null` is returned as a [Source].
+ *
+ * Does not return `null`.
+ */
+ ContextSourcePair getContextSourcePair(String path) {
+ // try SDK
+ {
+ Uri uri = resourceProvider.pathContext.toUri(path);
+ Source sdkSource = defaultSdk.fromFileUri(uri);
+ if (sdkSource != null) {
+ AnalysisContext anyContext = folderMap.values.first;
+ return new ContextSourcePair(anyContext, sdkSource);
+ }
+ }
+ // try to find the deep-most containing context
+ Resource resource = resourceProvider.getResource(path);
+ File file = resource is File ? resource : null;
+ {
+ Folder containingFolder = null;
+ AnalysisContext containingContext = null;
+ folderMap.forEach((Folder folder, AnalysisContext context) {
+ if (folder.isOrContains(path)) {
+ if (containingFolder == null ||
+ containingFolder.path.length < folder.path.length) {
+ containingFolder = folder;
+ containingContext = context;
+ }
+ }
+ });
+ if (containingContext != null) {
+ Source source = file != null
+ ? ContextManager.createSourceInContext(containingContext, file)
+ : null;
+ return new ContextSourcePair(containingContext, source);
+ }
+ }
+ // try to find a context that analysed the file
+ for (AnalysisContext context in folderMap.values) {
+ Source source = file != null
+ ? ContextManager.createSourceInContext(context, file)
+ : null;
+ SourceKind kind = context.getKindOf(source);
+ if (kind != SourceKind.UNKNOWN) {
+ return new ContextSourcePair(context, source);
+ }
+ }
+ // file-based source
+ Source fileSource = file != null ? file.createSource() : null;
+ return new ContextSourcePair(null, fileSource);
+ }
+
+ /**
* Returns [Element]s at the given [offset] of the given [file].
*
* May be empty if cannot be resolved, but not `null`.
@@ -460,37 +502,18 @@ class AnalysisServer {
* the current state.
*/
AnalysisErrorInfo getErrors(String file) {
- // prepare AnalysisContext
- AnalysisContext context = getAnalysisContext(file);
+ ContextSourcePair contextSource = getContextSourcePair(file);
+ AnalysisContext context = contextSource.context;
+ Source source = contextSource.source;
if (context == null) {
return null;
}
- // prepare Source
- Source source = getSource(file);
- if (context.getKindOf(source) == SourceKind.UNKNOWN) {
+ if (!source.exists()) {
return null;
}
- // get errors for the file
return context.getErrors(source);
}
- /**
- * Returns resolved [AstNode]s at the given [offset] of the given [file].
- *
- * May be empty, but not `null`.
- */
- List<AstNode> getNodesAtOffset(String file, int offset) {
- List<CompilationUnit> units = getResolvedCompilationUnits(file);
- List<AstNode> nodes = <AstNode>[];
- for (CompilationUnit unit in units) {
- AstNode node = new NodeLocator.con1(offset).searchWithin(unit);
- if (node != null) {
- nodes.add(node);
- }
- }
- return nodes;
- }
-
// TODO(brianwilkerson) Add the following method after 'prioritySources' has
// been added to InternalAnalysisContext.
// /**
@@ -509,19 +532,37 @@ class AnalysisServer {
// }
/**
+ * Returns resolved [AstNode]s at the given [offset] of the given [file].
+ *
+ * May be empty, but not `null`.
+ */
+ List<AstNode> getNodesAtOffset(String file, int offset) {
+ List<CompilationUnit> units = getResolvedCompilationUnits(file);
+ List<AstNode> nodes = <AstNode>[];
+ for (CompilationUnit unit in units) {
+ AstNode node = new NodeLocator.con1(offset).searchWithin(unit);
+ if (node != null) {
+ nodes.add(node);
+ }
+ }
+ return nodes;
+ }
+
+ /**
* Returns resolved [CompilationUnit]s of the Dart file with the given [path].
*
* May be empty, but not `null`.
*/
List<CompilationUnit> getResolvedCompilationUnits(String path) {
List<CompilationUnit> units = <CompilationUnit>[];
+ ContextSourcePair contextSource = getContextSourcePair(path);
// prepare AnalysisContext
- AnalysisContext context = getAnalysisContext(path);
+ AnalysisContext context = contextSource.context;
if (context == null) {
return units;
}
// add a unit for each unit/library combination
- Source unitSource = getSource(path);
+ Source unitSource = contextSource.source;
List<Source> librarySources = context.getLibrariesContaining(unitSource);
for (Source librarySource in librarySources) {
CompilationUnit unit =
@@ -535,50 +576,6 @@ class AnalysisServer {
}
/**
- * Returns the [CompilationUnit] of the Dart file with the given [path] that
- * should be used to resend notifications for already resolved unit.
- * Returns `null` if the file is not a part of any context, library has not
- * been yet resolved, or any problem happened.
- */
- CompilationUnit getResolvedCompilationUnitToResendNotification(String path) {
- // prepare AnalysisContext
- AnalysisContext context = getAnalysisContext(path);
- if (context == null) {
- return null;
- }
- // prepare sources
- Source unitSource = getSource(path);
- List<Source> librarySources = context.getLibrariesContaining(unitSource);
- if (librarySources.isEmpty) {
- return null;
- }
- // if library has not been resolved yet, the unit will be resolved later
- Source librarySource = librarySources[0];
- if (context.getLibraryElement(librarySource) == null) {
- return null;
- }
- // if library has been already resolved, resolve unit
- return context.resolveCompilationUnit2(unitSource, librarySource);
- }
-
- /**
- * Return the [Source] of the Dart file with the given [path].
- */
- Source getSource(String path) {
- // try SDK
- {
- Uri uri = resourceProvider.pathContext.toUri(path);
- Source sdkSource = defaultSdk.fromFileUri(uri);
- if (sdkSource != null) {
- return sdkSource;
- }
- }
- // file-based source
- File file = resourceProvider.getResource(path);
- return ContextManager.createSourceInContext(getAnalysisContext(path), file);
- }
-
- /**
* Handle a [request] that was read from the communication channel.
*/
void handleRequest(Request request) {
@@ -852,16 +849,17 @@ class AnalysisServer {
Set<String> todoFiles =
oldFiles != null ? newFiles.difference(oldFiles) : newFiles;
for (String file in todoFiles) {
- Source source = getSource(file);
+ ContextSourcePair contextSource = getContextSourcePair(file);
// prepare context
- AnalysisContext context = getAnalysisContext(file);
+ AnalysisContext context = contextSource.context;
if (context == null) {
continue;
}
// Dart unit notifications.
if (AnalysisEngine.isDartFileName(file)) {
+ Source source = contextSource.source;
CompilationUnit dartUnit =
- getResolvedCompilationUnitToResendNotification(file);
+ _getResolvedCompilationUnitToResendNotification(context, source);
if (dartUnit != null) {
switch (service) {
case AnalysisService.HIGHLIGHTS:
@@ -875,6 +873,7 @@ class AnalysisServer {
sendAnalysisNotificationOccurrences(this, file, dartUnit);
break;
case AnalysisService.OUTLINE:
+ AnalysisContext context = dartUnit.element.context;
LineInfo lineInfo = context.getLineInfo(source);
sendAnalysisNotificationOutline(this, file, lineInfo, dartUnit);
break;
@@ -901,9 +900,11 @@ class AnalysisServer {
Map<AnalysisContext, List<Source>> sourceMap =
new HashMap<AnalysisContext, List<Source>>();
List<String> unanalyzed = new List<String>();
+ Source firstSource = null;
files.forEach((file) {
- AnalysisContext preferredContext = getAnalysisContext(file);
- Source source = getSource(file);
+ ContextSourcePair contextSource = getContextSourcePair(file);
+ AnalysisContext preferredContext = contextSource.context;
+ Source source = contextSource.source;
bool contextFound = false;
for (AnalysisContext context in folderMap.values) {
if (context == preferredContext ||
@@ -912,6 +913,9 @@ class AnalysisServer {
contextFound = true;
}
}
+ if (firstSource == null) {
+ firstSource = source;
+ }
if (!contextFound) {
unanalyzed.add(file);
}
@@ -933,7 +937,6 @@ class AnalysisServer {
schedulePerformAnalysisOperation(context);
});
operationQueue.reschedule();
- Source firstSource = files.length > 0 ? getSource(files[0]) : null;
_onPriorityChangeController.add(new PriorityChangeEvent(firstSource));
}
@@ -962,8 +965,9 @@ class AnalysisServer {
void test_flushResolvedUnit(String file) {
if (AnalysisEngine.isDartFileName(file)) {
- AnalysisContextImpl context = getAnalysisContext(file);
- Source source = getSource(file);
+ ContextSourcePair contextSource = getContextSourcePair(file);
+ AnalysisContextImpl context = contextSource.context;
+ Source source = contextSource.source;
DartEntry dartEntry = context.getReadableSourceEntryOrNull(source);
dartEntry.flushAstStructures();
}
@@ -989,7 +993,8 @@ class AnalysisServer {
*/
void updateContent(String id, Map<String, dynamic> changes) {
changes.forEach((file, change) {
- Source source = getSource(file);
+ ContextSourcePair contextSource = getContextSourcePair(file);
+ Source source = contextSource.source;
operationQueue.sourceAboutToChange(source);
// Prepare the new contents.
String oldContents = overlayState.getContents(source);
@@ -1073,21 +1078,24 @@ class AnalysisServer {
}
/**
- * Return the [Source] of the Dart file with the given [path], assuming that
- * we do not know the context in which the path should be interpreted.
+ * Returns the [CompilationUnit] of the Dart file with the given [source] that
+ * should be used to resend notifications for already resolved unit.
+ * Returns `null` if the file is not a part of any context, library has not
+ * been yet resolved, or any problem happened.
*/
- Source _getSourceWithoutContext(String path) {
- // try SDK
- {
- Uri uri = resourceProvider.pathContext.toUri(path);
- Source sdkSource = defaultSdk.fromFileUri(uri);
- if (sdkSource != null) {
- return sdkSource;
- }
+ CompilationUnit _getResolvedCompilationUnitToResendNotification(
+ AnalysisContext context, Source source) {
+ List<Source> librarySources = context.getLibrariesContaining(source);
+ if (librarySources.isEmpty) {
+ return null;
}
- // file-based source
- File file = resourceProvider.getResource(path);
- return file.createSource();
+ // if library has not been resolved yet, the unit will be resolved later
+ Source librarySource = librarySources[0];
+ if (context.getLibraryElement(librarySource) == null) {
+ return null;
+ }
+ // if library has been already resolved, resolve unit
+ return context.resolveCompilationUnit2(source, librarySource);
}
/**
@@ -1156,6 +1164,27 @@ class ContextsChangedEvent {
}
/**
+ * Information about a file - an [AnalysisContext] that analyses the file,
+ * and the [Source] representing the file in this context.
+ */
+class ContextSourcePair {
+ /**
+ * A context that analysis the file.
+ * May be `null` if the file is not analyzed by any context.
+ */
+ final AnalysisContext context;
+
+ /**
+ * The source that corresponds to the file.
+ * May be `null` if the file is not a regular file.
+ * If the file cannot be found in the [context], then it has a `file` uri.
+ */
+ final Source source;
+
+ ContextSourcePair(this.context, this.source);
+}
+
+/**
* A [PriorityChangeEvent] indicates the set the priority files has changed.
*/
class PriorityChangeEvent {
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/context_manager.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698