diff options
-rwxr-xr-x | src/compiler/scala/tools/nsc/interactive/ContextTrees.scala | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala b/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala index 30fcccbb56..570958825b 100755 --- a/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala +++ b/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala @@ -28,12 +28,27 @@ trait ContextTrees { self: Global => /** Optionally returns the smallest context that contains given `pos`, or None if none exists. */ def locateContext(contexts: Contexts, pos: Position): Option[Context] = { + def locateNearestContextTree(contexts: Contexts, pos: Position, recent: Array[ContextTree]): Option[ContextTree] = { + locateContextTree(contexts, pos) match { + case Some(x) => + recent(0) = x + locateNearestContextTree(x.children, pos, recent) + case None => recent(0) match { + case null => None + case x => Some(x) + } + } + } + locateNearestContextTree(contexts, pos, new Array[ContextTree](1)) map (_.context) + } + + def locateContextTree(contexts: Contexts, pos: Position): Option[ContextTree] = { if (contexts.isEmpty) None else { val hi = contexts.length - 1 if ((contexts(hi).pos precedes pos) || (pos precedes contexts(0).pos)) None else { - def loop(lo: Int, hi: Int): Option[Context] = { + def loop(lo: Int, hi: Int): Option[ContextTree] = { val mid = (lo + hi) / 2 val midpos = contexts(mid).pos if ((pos precedes midpos) && (mid < hi)) @@ -41,9 +56,9 @@ trait ContextTrees { self: Global => else if ((midpos precedes pos) && (lo < mid)) loop(mid, hi) else if (midpos includes pos) - Some(contexts(mid).context) + Some(contexts(mid)) else if (contexts(mid+1).pos includes pos) - Some(contexts(mid+1).context) + Some(contexts(mid+1)) else None } loop(0, hi) @@ -73,11 +88,11 @@ trait ContextTrees { self: Global => else if (contexts.isEmpty) contexts += new ContextTree(cpos, context) else { val hi = contexts.length - 1 - if (contexts(hi).pos properlyPrecedes cpos) + if (contexts(hi).pos precedes cpos) contexts += new ContextTree(cpos, context) else if (contexts(hi).pos properlyIncludes cpos) // fast path w/o search addContext(contexts(hi).children, context, cpos) - else if (cpos properlyPrecedes contexts(0).pos) + else if (cpos precedes contexts(0).pos) new ContextTree(cpos, context) +: contexts else { def insertAt(idx: Int): Boolean = { |