diff --git a/presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala b/presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala index 89bfd05a7386..310edd60d87e 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala @@ -144,6 +144,22 @@ abstract class PcCollector[T]( if id.symbol .is(Flags.Param) && id.symbol.owner.is(Flags.ExtensionMethod) => Some(findAllExtensionParamSymbols(id.sourcePos, id.name, id.symbol)) + /** + * Workaround for missing symbol in: + * class A[T](a: T) + * val x = new <>(1) + */ + case t :: (n: New) :: (sel: Select) :: _ + if t.symbol == NoSymbol && sel.symbol.isConstructor => + Some(symbolAlternatives(sel.symbol.owner), namePos(t)) + /** + * Workaround for missing symbol in: + * class A[T](a: T) + * val x = <>[Int](1) + */ + case (sel @ Select(New(t), _)) :: (_: TypeApply) :: _ + if sel.symbol.isConstructor => + Some(symbolAlternatives(sel.symbol.owner), namePos(t)) /* simple identifier: * val a = val@@ue + value */ @@ -403,6 +419,22 @@ abstract class PcCollector[T]( ident.sourcePos ) else occurrences + /** + * Workaround for missing symbol in: + * class A[T](a: T) + * val x = new <>(1) + */ + case sel @ Select(New(t), _) + if sel.span.isCorrect && + sel.symbol.isConstructor && + t.symbol == NoSymbol => + if soughtFilter(_ == sel.symbol.owner) then + occurrences + collect( + sel, + namePos(t), + Some(sel.symbol.owner), + ) + else occurrences /** * All select statements such as: * val a = hello.<> @@ -564,6 +596,11 @@ abstract class PcCollector[T]( Span(span.start, span.start + realName.length, point) else Span(point, span.end, point) else span + + private def namePos(tree: Tree): SourcePosition = + tree match + case sel: Select => sel.sourcePos.withSpan(selectNameSpan(sel)) + case _ => tree.sourcePos end PcCollector object PcCollector: diff --git a/presentation-compiler/test/dotty/tools/pc/tests/highlight/DocumentHighlightSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/highlight/DocumentHighlightSuite.scala index 80451fc67562..1dc2a7b156db 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/highlight/DocumentHighlightSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/highlight/DocumentHighlightSuite.scala @@ -1185,3 +1185,97 @@ class DocumentHighlightSuite extends BaseDocumentHighlightSuite: |val a = MyIntOut(1) <<+@@+>> 3 |""".stripMargin, ) + + @Test def `constructor` = + check( + """ + |object Main { + | class <>[T](abc: T) + | val x = new <>(123) + |}""".stripMargin + ) + + @Test def `constructor1` = + check( + """ + |object Main { + | case class <>[T](abc: T) + | val x = <>(123) + |}""".stripMargin + ) + + @Test def `constructor2` = + check( + """ + |object Main { + | class <>[T](abc: T) + | object <> + | val x = new <>(123) + |}""".stripMargin + ) + + @Test def `constructor3` = + check( + """ + |object Main { + | class <>[T](abc: T) + | object <> + | val x = new <>(123) + |}""".stripMargin + ) + + @Test def `constructor4` = + check( + """ + |object Main { + | class <>[T](abc: T) + | object <> + | val x = new <>(123) + |}""".stripMargin + ) + + @Test def `constructor5` = + check( + """ + |object Main { + | class <>[T](abc: T) + | object <> { + | def apply(abc: Int, bde: Int) = new <>(abc + bde) + | } + | val x = <>(123, 456) + |}""".stripMargin + ) + + @Test def `constructor6` = + check( + """ + |class <>[T](a: T) + |object O { + | def foo(a: Int) = new <>[Int](a) + | val x = <>[Int](2) + |}""".stripMargin + ) + + @Test def `constructor7` = + check( + """ + |object Bar { + |class <>[T](a: T) + |} + | + |object O { + | val x = new Bar.<>(2) + |}""".stripMargin + ) + + @Test def `constructor8` = + check( + """ + |object Bar { + |class <>[T](a: T) + |} + | + |object O { + | val x = Bar.<>[Int](2) + |}""".stripMargin + ) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/tokens/SemanticTokensSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/tokens/SemanticTokensSuite.scala index d4ddefcc11d0..c8cfac044732 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/tokens/SemanticTokensSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/tokens/SemanticTokensSuite.scala @@ -375,3 +375,40 @@ class SemanticTokensSuite extends BaseSemanticTokensSuite: |end <>/*method,definition*/ |""".stripMargin, ) + + @Test def `constructor` = + check( + """ + |object <>/*class*/ { + | class <>/*class*/[<>/*typeParameter,definition,abstract*/](<>/*variable,declaration,readonly*/: <>/*typeParameter,abstract*/) + |} + | + |object <>/*class*/ { + | val <>/*variable,definition,readonly*/ = new <>/*class*/.<>/*class*/(2) + | val <>/*variable,definition,readonly*/ = new <>/*class*/.<>/*class*/[<>/*class,abstract*/](2) + | val <>/*variable,definition,readonly*/ = <>/*class*/.<>/*class*/(2) + | val <>/*variable,definition,readonly*/ = <>/*class*/.<>/*class*/[<>/*class,abstract*/](2) + |}""".stripMargin + ) + + @Test def `constructor1` = + check( + """ + |object <
>/*class*/ { + | class <>/*class*/[<>/*typeParameter,definition,abstract*/](<>/*variable,declaration,readonly*/: <>/*typeParameter,abstract*/) + | object <>/*class*/ + | val <>/*variable,definition,readonly*/ = new <>/*class*/(123) + |}""".stripMargin + ) + + @Test def `constructor2` = + check( + """ + |object <
>/*class*/ { + | class <>/*class*/[<>/*typeParameter,definition,abstract*/](<>/*variable,declaration,readonly*/: <>/*typeParameter,abstract*/) + | object <>/*class*/ { + | def <>/*method,definition*/[<>/*typeParameter,definition,abstract*/](<>/*parameter,declaration,readonly*/: <>/*typeParameter,abstract*/, <>/*parameter,declaration,readonly*/: <>/*typeParameter,abstract*/) = new <>/*class*/(<>/*parameter,readonly*/) + | } + | val <>/*variable,definition,readonly*/ = <>/*class*/(123, 456) + |}""".stripMargin + ) \ No newline at end of file