Skip to content

Commit 4879e6b

Browse files
committed
Support jump to definition in top-level imports
This is done by recording the top level imports that appear in every source file.
1 parent b62abfe commit 4879e6b

File tree

4 files changed

+17
-13
lines changed

4 files changed

+17
-13
lines changed

compiler/src/dotty/tools/dotc/interactive/Interactive.scala

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ object Interactive {
304304
(implicit ctx: Context): List[SourceTree] = safely {
305305
val buf = new mutable.ListBuffer[SourceTree]
306306

307-
trees foreach { case SourceTree(topTree, source) =>
307+
trees foreach { case SourceTree(_, topTree, source) =>
308308
new untpd.TreeTraverser {
309309
override def traverse(tree: untpd.Tree)(implicit ctx: Context) = {
310310
tree match {
@@ -316,7 +316,7 @@ object Interactive {
316316
&& !tree.pos.isZeroExtent
317317
&& (includeReferences || isDefinition(tree))
318318
&& treePredicate(tree))
319-
buf += SourceTree(tree, source)
319+
buf += SourceTree(Nil, tree, source)
320320
traverseChildren(tree)
321321
case tree: untpd.Inlined =>
322322
traverse(tree.call)
@@ -334,11 +334,13 @@ object Interactive {
334334
* or `Nil` if no such path exists. If a non-empty path is returned it starts with
335335
* the tree closest enclosing `pos` and ends with an element of `trees`.
336336
*/
337-
def pathTo(trees: List[SourceTree], pos: SourcePosition)(implicit ctx: Context): List[Tree] =
338-
trees.find(_.pos.contains(pos)) match {
339-
case Some(tree) => pathTo(tree.tree, pos.pos)
337+
def pathTo(trees: List[SourceTree], pos: SourcePosition)(implicit ctx: Context): List[Tree] = {
338+
val allTrees = trees.flatMap(t => t.tree :: t.topLevelImports)
339+
allTrees.find(t => t.pos.contains(pos.pos)) match {
340+
case Some(tree) => pathTo(tree, pos.pos)
340341
case None => Nil
341342
}
343+
}
342344

343345
def pathTo(tree: Tree, pos: Position)(implicit ctx: Context): List[Tree] =
344346
if (tree.pos.contains(pos))

compiler/src/dotty/tools/dotc/interactive/InteractiveDriver.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,15 @@ class InteractiveDriver(val settings: List[String]) extends Driver {
173173
private def topLevelClassTrees(topTree: Tree, source: SourceFile): List[SourceTree] = {
174174
val trees = new mutable.ListBuffer[SourceTree]
175175

176-
def addTrees(tree: Tree): Unit = tree match {
176+
def addTrees(topLevelImports: List[Import], tree: Tree): Unit = tree match {
177177
case PackageDef(_, stats) =>
178-
stats.foreach(addTrees)
178+
val imports = stats.collect { case imp: Import => imp }
179+
stats.foreach(addTrees(imports, _))
179180
case tree: TypeDef =>
180-
trees += SourceTree(tree, source)
181+
trees += SourceTree(topLevelImports, tree, source)
181182
case _ =>
182183
}
183-
addTrees(topTree)
184+
addTrees(Nil, topTree)
184185

185186
trees.toList
186187
}

compiler/src/dotty/tools/dotc/interactive/SourceTree.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Contexts._, NameOps._, Symbols._
1010
import util._, util.Positions._
1111

1212
/** A typechecked named `tree` coming from `source` */
13-
case class SourceTree(tree: tpd.NameTree, source: SourceFile) {
13+
case class SourceTree(topLevelImports: List[tpd.Import], tree: tpd.NameTree, source: SourceFile) {
1414
/** The position of `tree` */
1515
def pos(implicit ctx: Context): SourcePosition = source.atPos(tree.pos)
1616

@@ -47,10 +47,11 @@ object SourceTree {
4747
import ast.Trees._
4848
def sourceTreeOfClass(tree: tpd.Tree): Option[SourceTree] = tree match {
4949
case PackageDef(_, stats) =>
50-
stats.flatMap(sourceTreeOfClass).headOption
50+
val imports = stats.collect { case imp: tpd.Import => imp }
51+
stats.flatMap(sourceTreeOfClass(_).map(_.copy(topLevelImports = imports))).headOption
5152
case tree: tpd.TypeDef if tree.symbol == sym =>
5253
val sourceFile = new SourceFile(sym.sourceFile, Codec.UTF8)
53-
Some(SourceTree(tree, sourceFile))
54+
Some(SourceTree(Nil, tree, sourceFile))
5455
case _ => None
5556
}
5657
sourceTreeOfClass(sym.treeContaining(id))

compiler/src/dotty/tools/repl/ReplDriver.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ class ReplDriver(settings: Array[String],
172172
implicit val ctx: Context = state.run.runContext
173173
val file = new dotc.util.SourceFile("compl", expr)
174174
val srcPos = dotc.util.SourcePosition(file, Position(cursor))
175-
val (startOffset, completions) = Interactive.completions(SourceTree(tree, file) :: Nil, srcPos)(ctx)
175+
val (startOffset, completions) = Interactive.completions(SourceTree(Nil, tree, file) :: Nil, srcPos)(ctx)
176176
val query =
177177
if (startOffset < cursor) expr.substring(startOffset, cursor) else ""
178178

0 commit comments

Comments
 (0)