| Index: pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
|
| diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
|
| index 9e998e07fbd026c700ddeb186fd9b700f805ea66..3fde4ac6c6605851259f62a4cb70c76f71fdd517 100644
|
| --- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
|
| +++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
|
| @@ -137,16 +137,20 @@ class CompletionTarget {
|
| /**
|
| * Compute the appropriate [CompletionTarget] for the given [offset] within
|
| * the [compilationUnit].
|
| + *
|
| + * Optionally, start the search from within [entryPoint] instead of using
|
| + * the [compilationUnit], which is useful for analyzing ASTs that have no
|
| + * [compilationUnit] such as dart expressions within angular templates.
|
| */
|
| factory CompletionTarget.forOffset(
|
| - CompilationUnit compilationUnit, int offset) {
|
| + CompilationUnit compilationUnit, int offset, {AstNode entryPoint}) {
|
| // The precise algorithm is as follows. We perform a depth-first search of
|
| // all edges in the parse tree (both those that point to AST nodes and
|
| // those that point to tokens), visiting parents before children. The
|
| // first edge which points to an entity satisfying either _isCandidateToken
|
| // or _isCandidateNode is the completion target. If no edge is found that
|
| // satisfies these two predicates, then we set the completion target entity
|
| - // to null and the containingNode to the compilationUnit.
|
| + // to null and the containingNode to the entryPoint.
|
| //
|
| // Note that if a token is not a candidate target, then none of the tokens
|
| // that precede it are candidate targets either. Therefore any entity
|
| @@ -154,7 +158,8 @@ class CompletionTarget {
|
| // prune the search to the point where no recursion is necessary; at each
|
| // step in the process we know exactly which child node we need to proceed
|
| // to.
|
| - AstNode containingNode = compilationUnit;
|
| + entryPoint ??= compilationUnit;
|
| + AstNode containingNode = entryPoint;
|
| outerLoop: while (true) {
|
| if (containingNode is Comment) {
|
| // Comments are handled specially: we descend into any CommentReference
|
| @@ -232,13 +237,13 @@ class CompletionTarget {
|
| // the first time through the outer loop (since we only jump to the start
|
| // of the outer loop after determining that the completion target is
|
| // inside an entity). We can check that assumption by verifying that
|
| - // containingNode is still the compilationUnit.
|
| - assert(identical(containingNode, compilationUnit));
|
| + // containingNode is still the entryPoint.
|
| + assert(identical(containingNode, entryPoint));
|
|
|
| // Since no completion target was found, we set the completion target
|
| - // entity to null and use the compilationUnit as the parent.
|
| + // entity to null and use the entryPoint as the parent.
|
| return new CompletionTarget._(
|
| - compilationUnit, offset, compilationUnit, null, false);
|
| + compilationUnit, offset, entryPoint, null, false);
|
| }
|
| }
|
|
|
|
|