Skip to content

Commit 66905e7

Browse files
committed
Search all source trees for a given span
When we create a synthetic companion object, for exmaple for enums, all the value definitions are put into it and the there are actually multiple trees that contain the position we are itnerested in. Now, NavigateAST.pathTo takes in multiple trees since the method is already able to find the best fit.
1 parent d09dd2a commit 66905e7

File tree

3 files changed

+18
-9
lines changed

3 files changed

+18
-9
lines changed

compiler/src/dotty/tools/dotc/ast/NavigateAST.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ object NavigateAST {
6060
* the given `span`.
6161
*/
6262
def untypedPath(span: Span)(using Context): List[Positioned] =
63-
pathTo(span, ctx.compilationUnit.untpdTree)
63+
pathTo(span, List(ctx.compilationUnit.untpdTree))
6464

6565

6666
/** The reverse path from node `from` to the node that closest encloses `span`,
@@ -72,7 +72,7 @@ object NavigateAST {
7272
* end point are the same, so this is useful when trying to reconcile
7373
* nodes with source code.
7474
*/
75-
def pathTo(span: Span, from: Positioned, skipZeroExtent: Boolean = false)(using Context): List[Positioned] = {
75+
def pathTo(span: Span, from: List[Positioned], skipZeroExtent: Boolean = false)(using Context): List[Positioned] = {
7676
def childPath(it: Iterator[Any], path: List[Positioned]): List[Positioned] = {
7777
var bestFit: List[Positioned] = path
7878
while (it.hasNext) {
@@ -120,6 +120,6 @@ object NavigateAST {
120120
case _ => path
121121
}
122122
}
123-
singlePath(from, Nil)
123+
childPath(from.iterator, Nil)
124124
}
125125
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -252,14 +252,14 @@ object Interactive {
252252
* the tree closest enclosing `pos` and ends with an element of `trees`.
253253
*/
254254
def pathTo(trees: List[SourceTree], pos: SourcePosition)(using Context): List[Tree] =
255-
trees.find(_.pos.contains(pos)) match {
256-
case Some(tree) => pathTo(tree.tree, pos.span)
257-
case None => Nil
258-
}
255+
pathTo(trees.map(_.tree), pos.span)
259256

260257
def pathTo(tree: Tree, span: Span)(using Context): List[Tree] =
261-
if (tree.span.contains(span))
262-
NavigateAST.pathTo(span, tree, skipZeroExtent = true)
258+
pathTo(List(tree), span)
259+
260+
private def pathTo(trees: List[Tree], span: Span)(using Context): List[Tree] =
261+
if (trees.exists(_.span.contains(span)))
262+
NavigateAST.pathTo(span, trees, skipZeroExtent = true)
263263
.collect { case t: untpd.Tree => t }
264264
.dropWhile(!_.hasType).asInstanceOf[List[tpd.Tree]]
265265
else Nil

language-server/test/dotty/tools/languageserver/HoverTest.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,13 @@ class HoverTest {
222222
|""".withSource
223223
.hover(m1 to m2, hoverContent("example.SimpleEnum.Color"))
224224
}
225+
226+
@Test def enums: Unit = {
227+
code"""|package example
228+
|enum TestEnum3:
229+
| case ${m1}A${m2} // no tooltip
230+
|
231+
|""".withSource
232+
.hover(m1 to m2, hoverContent("example.TestEnum3"))
233+
}
225234
}

0 commit comments

Comments
 (0)