From 83ff1c6db3409da76ff7cb45579999500072ce53 Mon Sep 17 00:00:00 2001 From: Jakub Ciesluk <323892@uwr.edu.pl> Date: Thu, 26 Jan 2023 21:12:50 +0100 Subject: [PATCH] bugfix: Fix `select.nameSpan` for expressions in parentheses For expressions like (1 + 2).toString, span was incorrect, because they were treated as right associative infix operators. --- .../scala/meta/internal/pc/PcCollector.scala | 18 ++++++++++++++++-- .../highlight/DocumentHighlightSuite.scala | 13 +++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/mtags/src/main/scala-3/scala/meta/internal/pc/PcCollector.scala b/mtags/src/main/scala-3/scala/meta/internal/pc/PcCollector.scala index 8352b13f8b6..b521ea515f4 100644 --- a/mtags/src/main/scala-3/scala/meta/internal/pc/PcCollector.scala +++ b/mtags/src/main/scala-3/scala/meta/internal/pc/PcCollector.scala @@ -109,7 +109,7 @@ abstract class PcCollector[T](driver: InteractiveDriver, params: OffsetParams): /* simple selector: * object.val@@ue */ - case (sel: Select) :: _ if sel.nameSpan.contains(pos.span) => + case (sel: Select) :: _ if selectNameSpan(sel).contains(pos.span) => Some(symbolAlternatives(sel.symbol), pos.withSpan(sel.nameSpan)) /* named argument: * foo(nam@@e = "123") @@ -271,7 +271,7 @@ abstract class PcCollector[T](driver: InteractiveDriver, params: OffsetParams): if soughtOrOverride(sel.symbol) && !sel.span.isZeroExtent => occurences + collect( sel, - pos.withSpan(sel.nameSpan), + pos.withSpan(selectNameSpan(sel)), ) /* all definitions: * def <> = ??? @@ -383,6 +383,20 @@ abstract class PcCollector[T](driver: InteractiveDriver, params: OffsetParams): trees.collect { case t: Tree => t } + + // NOTE: Connected to https://github.com/lampepfl/dotty/issues/16771 + // `sel.nameSpan` is calculated incorrectly in (1 + 2).toString + // See test DocumentHighlightSuite.select-parentheses + private def selectNameSpan(sel: Select)(using Context): Span = + val span = sel.span + if span.exists then + val point = span.point + if sel.name.toTermName == nme.ERROR then Span(point) + else if sel.qualifier.span.start > span.point then // right associative + val realName = sel.name.stripModuleClassSuffix.lastPart + Span(span.start, span.start + realName.length, point) + else Span(point, span.end, point) + else span end PcCollector object PcCollector: diff --git a/tests/cross/src/test/scala/tests/highlight/DocumentHighlightSuite.scala b/tests/cross/src/test/scala/tests/highlight/DocumentHighlightSuite.scala index 51e09c2eae5..06177835359 100644 --- a/tests/cross/src/test/scala/tests/highlight/DocumentHighlightSuite.scala +++ b/tests/cross/src/test/scala/tests/highlight/DocumentHighlightSuite.scala @@ -699,4 +699,17 @@ class DocumentHighlightSuite extends BaseDocumentHighlightSuite { |}""".stripMargin, ) + check( + "select-parentheses", + """|object Main { + | val a = (1 + 2 + 3).<> + |}""".stripMargin, + ) + + check( + "select-parentheses2".tag(IgnoreScala2), + """|object Main { + | val a = (1 + 2 + 3) <<:@@:>> Nil + |}""".stripMargin, + ) }