Skip to content

Commit

Permalink
bugfix: hover on nested selectable
Browse files Browse the repository at this point in the history
  • Loading branch information
kasiaMarek authored and tgodzik committed Jul 28, 2023
1 parent 90ee19b commit 983b9ac
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 8 deletions.
27 changes: 19 additions & 8 deletions mtags/src/main/scala-3/scala/meta/internal/pc/HoverProvider.scala
Original file line number Diff line number Diff line change
Expand Up @@ -158,23 +158,34 @@ object HoverProvider:
printer: MetalsPrinter,
)(using Context): ju.Optional[HoverSignature] = path match
case SelectDynamicExtractor(sel, n, name) =>
def findRefinement(tp: Type): ju.Optional[HoverSignature] =
def findRefinement(tp: Type): Option[HoverSignature] =
tp match
case RefinedType(info, refName, tpe) if name == refName.toString() =>
case RefinedType(_, refName, tpe) if name == refName.toString() =>
val tpeString =
if n == nme.selectDynamic then s": ${printer.tpe(tpe.resultType)}"
else printer.tpe(tpe)
ju.Optional.of(

val valOrDef =
if n == nme.selectDynamic && !tpe.isInstanceOf[ExprType]
then "val"
else "def"

Some(
new ScalaHover(
expressionType = Some(tpeString),
symbolSignature = Some(s"def $name$tpeString"),
symbolSignature = Some(s"$valOrDef $name$tpeString"),
)
)
case RefinedType(info, _, _) =>
findRefinement(info)
case _ => ju.Optional.empty()
case RefinedType(parent, _, _) =>
findRefinement(parent)
case _ => None

val refTpe = sel.tpe.metalsDealias match
case r: RefinedType => Some(r)
case t: (TermRef | TypeProxy) => Some(t.termSymbol.info.metalsDealias)
case _ => None

findRefinement(sel.tpe.termSymbol.info.dealias)
refTpe.flatMap(findRefinement).asJava
case _ =>
ju.Optional.empty()

Expand Down
39 changes: 39 additions & 0 deletions tests/cross/src/test/scala/tests/hover/HoverScala3TypeSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -325,4 +325,43 @@ class HoverScala3TypeSuite extends BaseHoverSuite {
"""|type Ident: Ident
|""".stripMargin.hover,
)

check(
"nested-selectable",
"""|trait Sel extends Selectable:
| def selectDynamic(name: String): Any = ???
|val sel = (new Sel {}).asInstanceOf[Sel { val foo: Sel { def bar: Int } }]
|val bar = sel.foo.ba@@r
|""".stripMargin,
"""|def bar: Int
|""".stripMargin.hover,
)

check(
"nested-selectable2",
"""|class SimpleSelectable(key : String, value: Any) extends Selectable:
| def selectDynamic(name: String): Any =
| if(name == key) value else ???
|
|type Node[T] = SimpleSelectable { val child: T }
|
|val leaf = SimpleSelectable("child", ()).asInstanceOf[Node[Unit]]
|val node = SimpleSelectable("child", leaf).asInstanceOf[Node[Node[Unit]]]
|
|val k = node.child.ch@@ild
|""".stripMargin,
"""|val child: Unit
|""".stripMargin.hover,
)

check(
"very-nested-selectable",
"""|trait Sel extends Selectable:
| def selectDynamic(name: String): Any = ???
|val sel = (new Sel {}).asInstanceOf[Sel { val foo: Sel { val bar: Sel { val ddd: Int } } }]
|val bar = sel.foo.bar.dd@@d
|""".stripMargin,
"""|val ddd: Int
|""".stripMargin.hover,
)
}

0 comments on commit 983b9ac

Please sign in to comment.