Index: pkg/analysis_server/lib/src/domain_analysis.dart |
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart |
index 42afae33f24f5cbedb1eab496bb5c2e0799b89a4..2a6fec7e05d16927af691381ff2d036772547a6a 100644 |
--- a/pkg/analysis_server/lib/src/domain_analysis.dart |
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart |
@@ -112,13 +112,12 @@ class AnalysisDomainHandler implements RequestHandler { |
Response getNavigation(Request request) { |
var params = new AnalysisGetNavigationParams.fromRequest(request); |
String file = params.file; |
- int offset = params.offset; |
- Future<AnalysisDoneReason> completionFuture = |
+ Future<AnalysisDoneReason> analysisFuture = |
server.onFileAnalysisComplete(file); |
- if (completionFuture == null) { |
+ if (analysisFuture == null) { |
return new Response.getNavigationInvalidFile(request); |
} |
- completionFuture.then((AnalysisDoneReason reason) { |
+ analysisFuture.then((AnalysisDoneReason reason) { |
switch (reason) { |
case AnalysisDoneReason.COMPLETE: |
List<CompilationUnit> units = |
@@ -128,11 +127,10 @@ class AnalysisDomainHandler implements RequestHandler { |
} else { |
DartUnitNavigationComputer computer = |
new DartUnitNavigationComputer(); |
+ _GetNavigationAstVisitor visitor = new _GetNavigationAstVisitor( |
+ params.offset, params.offset + params.length, computer); |
for (CompilationUnit unit in units) { |
- AstNode node = new NodeLocator(offset).searchWithin(unit); |
- if (node != null) { |
- computer.compute(node); |
- } |
+ unit.accept(visitor); |
} |
server.sendResponse(new AnalysisGetNavigationResult( |
computer.files, computer.targets, computer.regions) |
@@ -292,3 +290,36 @@ class AnalysisDomainHandler implements RequestHandler { |
return new AnalysisUpdateOptionsResult().toResponse(request.id); |
} |
} |
+ |
+/** |
+ * An AST visitor that computer navigation regions in the givne region. |
+ */ |
+class _GetNavigationAstVisitor extends UnifyingAstVisitor { |
+ final int rangeStart; |
+ final int rangeEnd; |
+ final DartUnitNavigationComputer computer; |
+ |
+ _GetNavigationAstVisitor(this.rangeStart, this.rangeEnd, this.computer); |
+ |
+ bool isInRange(int offset) { |
+ return rangeStart <= offset && offset <= rangeEnd; |
+ } |
+ |
+ @override |
+ visitNode(AstNode node) { |
+ // The node ends before the range starts. |
+ if (node.end < rangeStart) { |
+ return; |
+ } |
+ // The node starts after the range ends. |
+ if (node.offset > rangeEnd) { |
+ return; |
+ } |
+ // The node starts or ends in the range. |
+ if (isInRange(node.offset) || isInRange(node.end)) { |
+ computer.compute(node); |
+ return; |
+ } |
+ super.visitNode(node); |
+ } |
+} |