From f552d89bf2f2d3930285f3c3841501ef449abb8d Mon Sep 17 00:00:00 2001 From: kasiaMarek Date: Thu, 12 Dec 2024 10:13:33 +0100 Subject: [PATCH 1/4] fix: workaround for synthetic tokens on multi declaraction (Scala 2) --- .../main/scala-2/scala/meta/internal/pc/PcCollector.scala | 6 +++++- .../src/test/scala/tests/tokens/SemanticTokensSuite.scala | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) 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/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 + ) + } From 574d599c0e74a9a4fec3dcc8cf2367aab5743e71 Mon Sep 17 00:00:00 2001 From: kasiaMarek Date: Thu, 12 Dec 2024 10:14:38 +0100 Subject: [PATCH 2/4] fix: workaround for hover for multi declaration (Scala 2) --- .../meta/internal/pc/HoverProvider.scala | 36 +++++++++++++------ .../scala/tests/hover/HoverTermSuite.scala | 11 ++++++ 2 files changed, 36 insertions(+), 11 deletions(-) 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..f3a1c90fd5b 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,12 +141,8 @@ 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 => - val symbol = (v.symbol.getter: Symbol) match { + case v: ValOrDefDef if correctPosDef(v) => + val symbol = v.symbol.getter 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 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/tests/cross/src/test/scala/tests/hover/HoverTermSuite.scala b/tests/cross/src/test/scala/tests/hover/HoverTermSuite.scala index 38e90114900..f1a0e38e096 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".tag(IgnoreScala3), + """|object O { + | val x@@x, yy, zz = 1 + |} + |""".stripMargin, + """| + |val xx: Int + |""".stripMargin.hover + ) + } From 976955c06921521f7c00d00edf0b1686dee88745 Mon Sep 17 00:00:00 2001 From: kasiaMarek Date: Thu, 12 Dec 2024 10:15:18 +0100 Subject: [PATCH 3/4] fix: workaround for hover for multi declaraction (Scala 3) --- .../scala/meta/internal/pc/MetalsInteractive.scala | 8 +++++++- .../cross/src/test/scala/tests/hover/HoverTermSuite.scala | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) 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 f1a0e38e096..f9d7ff2e20f 100644 --- a/tests/cross/src/test/scala/tests/hover/HoverTermSuite.scala +++ b/tests/cross/src/test/scala/tests/hover/HoverTermSuite.scala @@ -774,7 +774,7 @@ class HoverTermSuite extends BaseHoverSuite { ) check( - "i7012".tag(IgnoreScala3), + "i7012", """|object O { | val x@@x, yy, zz = 1 |} From 40ffc7cd3f1dc1734e329051b23fa1b456fa8208 Mon Sep 17 00:00:00 2001 From: kasiaMarek Date: Thu, 12 Dec 2024 10:21:10 +0100 Subject: [PATCH 4/4] fix compilation for earlier versions --- .../main/scala-2/scala/meta/internal/pc/HoverProvider.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 f3a1c90fd5b..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 @@ -142,7 +142,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 correctPosDef(v) => - val symbol = v.symbol.getter match { + val symbol = (v.symbol.getter: Symbol) match { case NoSymbol => v.symbol case getter => getter } @@ -194,7 +194,7 @@ class HoverProvider( case t @ Template(parents, self, body) => t.body.collectFirst { case v: ValDef if correctPosDef(v) => - val symbol = v.symbol.getter match { + val symbol = (v.symbol.getter: Symbol) match { case NoSymbol => v.symbol case getter => getter }