diff --git a/mtags/src/main/scala-2/scala/meta/internal/pc/HoverProvider.scala b/mtags/src/main/scala-2/scala/meta/internal/pc/HoverProvider.scala index 9de237c87fb..b7bddfce335 100644 --- a/mtags/src/main/scala-2/scala/meta/internal/pc/HoverProvider.scala +++ b/mtags/src/main/scala-2/scala/meta/internal/pc/HoverProvider.scala @@ -82,6 +82,11 @@ class HoverProvider( ) } + def correctPosDef(df: MemberDef): Boolean = + (df.namePosition.includes(pos) || pos.includes( + df.namePosition + )) && df.symbol != null + tree match { case i @ Import(_, _) => for { @@ -136,11 +141,7 @@ class HoverProvider( ) // Def, val or val definition, example `val x: Int = 1` // Matches only if the cursor is over the definition name. - case v: ValOrDefDef - if (v.namePosition - .includes(pos) || pos.includes( - v.namePosition - )) && v.symbol != null => + case v: ValOrDefDef if correctPosDef(v) => val symbol = (v.symbol.getter: Symbol) match { case NoSymbol => v.symbol case getter => getter @@ -178,11 +179,7 @@ class HoverProvider( Some(report) ) // Class, object, type definitions, matches only if the cursor is over the definition name. - case t: MemberDef - if (t.namePosition - .includes(pos) || pos.includes( - t.namePosition - )) && t.symbol != null => + case t: MemberDef if correctPosDef(t) => val symbol = tree.symbol val tpe = seenFromType(tree, symbol) toHover( @@ -194,6 +191,23 @@ class HoverProvider( range = t.namePosition, Some(report) ) + case t @ Template(parents, self, body) => + t.body.collectFirst { + case v: ValDef if correctPosDef(v) => + val symbol = (v.symbol.getter: Symbol) match { + case NoSymbol => v.symbol + case getter => getter + } + toHover( + symbol, + v.symbol.keyString, + symbol.info, + symbol.info, + pos, + v.pos, + Some(report) + ) + }.flatten case _ => // Don't show hover for non-identifiers. None diff --git a/mtags/src/main/scala-2/scala/meta/internal/pc/PcCollector.scala b/mtags/src/main/scala-2/scala/meta/internal/pc/PcCollector.scala index 4c267dca49a..581063d594b 100644 --- a/mtags/src/main/scala-2/scala/meta/internal/pc/PcCollector.scala +++ b/mtags/src/main/scala-2/scala/meta/internal/pc/PcCollector.scala @@ -92,6 +92,9 @@ trait PcCollector[T] { self: WithCompilationUnit => def isCorrectPos(t: Tree): Boolean = t.pos.isRange || (t.pos.isDefined && allowZeroExtentImplicits && t.symbol != null && t.symbol.isImplicit) + def correctNamePos(t: MemberDef): Boolean = + t.pos.isDefined && t.namePosition.isRange + def traverseSought( filter: Tree => Boolean, soughtFilter: (Symbol => Boolean) => Boolean @@ -172,7 +175,8 @@ trait PcCollector[T] { self: WithCompilationUnit => * class <> = ??? * etc. */ - case df: MemberDef if isCorrectPos(df) && filter(df) => + case df: MemberDef + if (isCorrectPos(df) || correctNamePos(df)) && filter(df) => (annotationChildren(df) ++ df.children).foldLeft({ val t = collect( df, diff --git a/mtags/src/main/scala-3/scala/meta/internal/pc/MetalsInteractive.scala b/mtags/src/main/scala-3/scala/meta/internal/pc/MetalsInteractive.scala index c5b04ab9efb..29af349da11 100644 --- a/mtags/src/main/scala-3/scala/meta/internal/pc/MetalsInteractive.scala +++ b/mtags/src/main/scala-3/scala/meta/internal/pc/MetalsInteractive.scala @@ -241,7 +241,13 @@ object MetalsInteractive: */ else if head.isInstanceOf[TypeTree] then enclosingSymbolsWithExpressionType(tail, pos, indexed) - else Nil + else + path match + case (_: ValDef) :: (t : Template) :: _ => + t.body.collectFirst { + case d: ValDef if d.nameSpan.contains(pos.span) => List((d.symbol, d.symbol.info)) + }.getOrElse(Nil) + case _ => Nil else val recovered = recoverError(head, indexed) if recovered.isEmpty then diff --git a/tests/cross/src/test/scala/tests/hover/HoverTermSuite.scala b/tests/cross/src/test/scala/tests/hover/HoverTermSuite.scala index 38e90114900..f9d7ff2e20f 100644 --- a/tests/cross/src/test/scala/tests/hover/HoverTermSuite.scala +++ b/tests/cross/src/test/scala/tests/hover/HoverTermSuite.scala @@ -773,4 +773,15 @@ class HoverTermSuite extends BaseHoverSuite { ) ) + check( + "i7012", + """|object O { + | val x@@x, yy, zz = 1 + |} + |""".stripMargin, + """| + |val xx: Int + |""".stripMargin.hover + ) + } diff --git a/tests/cross/src/test/scala/tests/tokens/SemanticTokensSuite.scala b/tests/cross/src/test/scala/tests/tokens/SemanticTokensSuite.scala index e7f68679838..8c08f3160f2 100644 --- a/tests/cross/src/test/scala/tests/tokens/SemanticTokensSuite.scala +++ b/tests/cross/src/test/scala/tests/tokens/SemanticTokensSuite.scala @@ -406,4 +406,12 @@ class SemanticTokensSuite extends BaseSemanticTokensSuite { ) ) + check( + "i7012", + """|object <>/*class*/ { + | val <>/*variable,definition,readonly*/, <>/*variable,definition,readonly*/, <>/*variable,definition,readonly*/ = 1 + |} + |""".stripMargin + ) + }