From 66905e798078ef719180444a7a6078fb3df67c4c Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Tue, 8 Feb 2022 19:36:42 +0100 Subject: [PATCH 1/2] 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. --- compiler/src/dotty/tools/dotc/ast/NavigateAST.scala | 6 +++--- .../dotty/tools/dotc/interactive/Interactive.scala | 12 ++++++------ .../test/dotty/tools/languageserver/HoverTest.scala | 9 +++++++++ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/ast/NavigateAST.scala b/compiler/src/dotty/tools/dotc/ast/NavigateAST.scala index 61561d5eaa24..7222fe87523a 100644 --- a/compiler/src/dotty/tools/dotc/ast/NavigateAST.scala +++ b/compiler/src/dotty/tools/dotc/ast/NavigateAST.scala @@ -60,7 +60,7 @@ object NavigateAST { * the given `span`. */ def untypedPath(span: Span)(using Context): List[Positioned] = - pathTo(span, ctx.compilationUnit.untpdTree) + pathTo(span, List(ctx.compilationUnit.untpdTree)) /** The reverse path from node `from` to the node that closest encloses `span`, @@ -72,7 +72,7 @@ object NavigateAST { * end point are the same, so this is useful when trying to reconcile * nodes with source code. */ - def pathTo(span: Span, from: Positioned, skipZeroExtent: Boolean = false)(using Context): List[Positioned] = { + def pathTo(span: Span, from: List[Positioned], skipZeroExtent: Boolean = false)(using Context): List[Positioned] = { def childPath(it: Iterator[Any], path: List[Positioned]): List[Positioned] = { var bestFit: List[Positioned] = path while (it.hasNext) { @@ -120,6 +120,6 @@ object NavigateAST { case _ => path } } - singlePath(from, Nil) + childPath(from.iterator, Nil) } } diff --git a/compiler/src/dotty/tools/dotc/interactive/Interactive.scala b/compiler/src/dotty/tools/dotc/interactive/Interactive.scala index 20a746ceb5ac..cb41650c0b57 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Interactive.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Interactive.scala @@ -252,14 +252,14 @@ object Interactive { * the tree closest enclosing `pos` and ends with an element of `trees`. */ def pathTo(trees: List[SourceTree], pos: SourcePosition)(using Context): List[Tree] = - trees.find(_.pos.contains(pos)) match { - case Some(tree) => pathTo(tree.tree, pos.span) - case None => Nil - } + pathTo(trees.map(_.tree), pos.span) def pathTo(tree: Tree, span: Span)(using Context): List[Tree] = - if (tree.span.contains(span)) - NavigateAST.pathTo(span, tree, skipZeroExtent = true) + pathTo(List(tree), span) + + private def pathTo(trees: List[Tree], span: Span)(using Context): List[Tree] = + if (trees.exists(_.span.contains(span))) + NavigateAST.pathTo(span, trees, skipZeroExtent = true) .collect { case t: untpd.Tree => t } .dropWhile(!_.hasType).asInstanceOf[List[tpd.Tree]] else Nil diff --git a/language-server/test/dotty/tools/languageserver/HoverTest.scala b/language-server/test/dotty/tools/languageserver/HoverTest.scala index 868134d6ea21..b396f1a15044 100644 --- a/language-server/test/dotty/tools/languageserver/HoverTest.scala +++ b/language-server/test/dotty/tools/languageserver/HoverTest.scala @@ -222,4 +222,13 @@ class HoverTest { |""".withSource .hover(m1 to m2, hoverContent("example.SimpleEnum.Color")) } + + @Test def enums: Unit = { + code"""|package example + |enum TestEnum3: + | case ${m1}A${m2} // no tooltip + | + |""".withSource + .hover(m1 to m2, hoverContent("example.TestEnum3")) + } } From f33fcb9b4e643d7bbcacc8d93fcc553eab058b86 Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Thu, 17 Feb 2022 14:31:57 +0100 Subject: [PATCH 2/2] Tweak `pathTo` comment in NavigateAST --- compiler/src/dotty/tools/dotc/ast/NavigateAST.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/ast/NavigateAST.scala b/compiler/src/dotty/tools/dotc/ast/NavigateAST.scala index 7222fe87523a..730149381487 100644 --- a/compiler/src/dotty/tools/dotc/ast/NavigateAST.scala +++ b/compiler/src/dotty/tools/dotc/ast/NavigateAST.scala @@ -63,9 +63,9 @@ object NavigateAST { pathTo(span, List(ctx.compilationUnit.untpdTree)) - /** The reverse path from node `from` to the node that closest encloses `span`, + /** The reverse path from any node in `from` to the node that closest encloses `span`, * or `Nil` if no such path exists. If a non-empty path is returned it starts with - * the node closest enclosing `span` and ends with `from`. + * the node closest enclosing `span` and ends with one of the nodes in `from`. * * @param skipZeroExtent If true, skip over zero-extent nodes in the search. These nodes * do not correspond to code the user wrote since their start and