Skip to content

Commit 857c6c8

Browse files
committed
fix: show zero extent references when using pc
1 parent eda25ae commit 857c6c8

File tree

4 files changed

+111
-10
lines changed

4 files changed

+111
-10
lines changed

Diff for: presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala

+9-3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ trait PcCollector[T]:
3535
parent: Option[Tree]
3636
)(tree: Tree| EndMarker, pos: SourcePosition, symbol: Option[Symbol]): T
3737

38+
def allowZeroExtentImplicits: Boolean = false
39+
3840
def resultAllOccurences(): Set[T] =
3941
def noTreeFilter = (_: Tree) => true
4042
def noSoughtFilter = (_: Symbol => Boolean) => true
@@ -87,6 +89,10 @@ trait PcCollector[T]:
8789
def isCorrect =
8890
!span.isZeroExtent && span.exists && span.start < sourceText.size && span.end <= sourceText.size
8991

92+
extension (tree: Tree)
93+
def isCorrectSpan =
94+
tree.span.isCorrect || (allowZeroExtentImplicits && tree.symbol.is(Flags.Implicit))
95+
9096
def traverseSought(
9197
filter: Tree => Boolean,
9298
soughtFilter: (Symbol => Boolean) => Boolean
@@ -107,7 +113,7 @@ trait PcCollector[T]:
107113
* All indentifiers such as:
108114
* val a = <<b>>
109115
*/
110-
case ident: Ident if ident.span.isCorrect && filter(ident) =>
116+
case ident: Ident if ident.isCorrectSpan && filter(ident) =>
111117
// symbols will differ for params in different ext methods, but source pos will be the same
112118
if soughtFilter(_.sourcePos == ident.symbol.sourcePos)
113119
then
@@ -122,7 +128,7 @@ trait PcCollector[T]:
122128
* val x = new <<A>>(1)
123129
*/
124130
case sel @ Select(New(t), _)
125-
if sel.span.isCorrect &&
131+
if sel.isCorrectSpan &&
126132
sel.symbol.isConstructor &&
127133
t.symbol == NoSymbol =>
128134
if soughtFilter(_ == sel.symbol.owner) then
@@ -137,7 +143,7 @@ trait PcCollector[T]:
137143
* val a = hello.<<b>>
138144
*/
139145
case sel: Select
140-
if sel.span.isCorrect && filter(sel) &&
146+
if sel.isCorrectSpan && filter(sel) &&
141147
!sel.isForComprehensionMethod =>
142148
occurrences + collect(
143149
sel,

Diff for: presentation-compiler/src/main/dotty/tools/pc/PcReferencesProvider.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ class PcReferencesProvider(
2323
request: ReferencesRequest,
2424
) extends WithCompilationUnit(driver, request.file()) with PcCollector[Option[(String, Option[lsp4j.Range])]]:
2525

26+
override def allowZeroExtentImplicits: Boolean = true
27+
2628
private def soughtSymbols =
2729
if(request.offsetOrSymbol().isLeft()) {
2830
val offsetParams = CompilerOffsetParams(
@@ -64,4 +66,4 @@ class PcReferencesProvider(
6466
}
6567
.toList
6668
case _ => Nil
67-
end PcReferencesProvider
69+
end PcReferencesProvider
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package dotty.tools.pc.tests
2+
import dotty.tools.pc.base.BasePCSuite
3+
import dotty.tools.pc.utils.RangeReplace
4+
import scala.meta.internal.pc.PcReferencesRequest
5+
import scala.meta.internal.metals.CompilerVirtualFileParams
6+
import java.net.URI
7+
import scala.meta.internal.metals.EmptyCancelToken
8+
import org.eclipse.lsp4j.jsonrpc.messages.{Either => JEither}
9+
import scala.meta.internal.jdk.CollectionConverters.*
10+
11+
import org.junit.Test
12+
13+
class PcReferencesSuite extends BasePCSuite with RangeReplace {
14+
def check(
15+
original: String,
16+
): Unit =
17+
val edit = original.replaceAll("(<<|>>)", "")
18+
val expected = original.replaceAll("@@", "")
19+
val base = original.replaceAll("(<<|>>|@@)", "")
20+
21+
val (code, offset) = params(edit, "Highlight.scala")
22+
val ranges = presentationCompiler
23+
.references(
24+
PcReferencesRequest(
25+
CompilerVirtualFileParams(
26+
URI.create("file:/Highlight.scala"),
27+
code,
28+
EmptyCancelToken
29+
),
30+
includeDefinition = false,
31+
offsetOrSymbol = JEither.forLeft(offset)
32+
)
33+
)
34+
.get()
35+
.asScala
36+
.flatMap(_.locations().asScala.map(_.getRange()))
37+
.toList
38+
39+
assertEquals(
40+
renderRangesAsString(base, ranges),
41+
expected,
42+
"references should match"
43+
)
44+
45+
@Test def `implicit-args` =
46+
check(
47+
"""|package example
48+
|
49+
|class Bar(i: Int)
50+
|
51+
|object Hello {
52+
| def m(i: Int)(implicit b: Bar) = ???
53+
| val foo = {
54+
| implicit val ba@@rr: Bar = new Bar(1)
55+
| m(3)<<>>
56+
| }
57+
|}
58+
|""".stripMargin
59+
)
60+
61+
@Test def `implicit-args-2` =
62+
check(
63+
"""|package example
64+
|
65+
|class Bar(i: Int)
66+
|class Foo(implicit b: Bar)
67+
|
68+
|object Hello {
69+
| implicit val ba@@rr: Bar = new Bar(1)
70+
| val foo = new Foo<<>>
71+
|}
72+
|""".stripMargin
73+
)
74+
75+
@Test def `case-class` =
76+
check(
77+
"""|case class Ma@@in(i: Int)
78+
|""".stripMargin
79+
)
80+
81+
@Test def `case-class-with-implicit` =
82+
check(
83+
""""|case class A()(implicit val fo@@o: Int)
84+
|""".stripMargin
85+
)
86+
}

Diff for: presentation-compiler/test/dotty/tools/pc/utils/RangeReplace.scala

+13-6
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,21 @@ trait RangeReplace:
1212
def renderHighlightsAsString(
1313
code: String,
1414
highlights: List[DocumentHighlight]
15+
): String = renderRangesAsString(code, highlights.map(_.getRange()))
16+
17+
def renderRangesAsString(
18+
code: String,
19+
highlights: List[Range],
20+
alreadyAddedMarkings: List[(Int, Int)] = Nil,
21+
currentBase: Option[String] = None
1522
): String =
1623
highlights
17-
.foldLeft((code, immutable.List.empty[(Int, Int)])) {
18-
case ((base, alreadyAddedMarkings), location) =>
19-
replaceInRangeWithAdjustmens(
24+
.foldLeft((currentBase.getOrElse(code), alreadyAddedMarkings)) {
25+
case ((base, alreadyAddedMarkings), range) =>
26+
replaceInRangeWithAdjustments(
2027
code,
2128
base,
22-
location.getRange,
29+
range,
2330
alreadyAddedMarkings
2431
)
2532
}
@@ -31,9 +38,9 @@ trait RangeReplace:
3138
prefix: String = "<<",
3239
suffix: String = ">>"
3340
): String =
34-
replaceInRangeWithAdjustmens(base, base, range, List(), prefix, suffix)._1
41+
replaceInRangeWithAdjustments(base, base, range, List(), prefix, suffix)._1
3542

36-
protected def replaceInRangeWithAdjustmens(
43+
protected def replaceInRangeWithAdjustments(
3744
code: String,
3845
currentBase: String,
3946
range: Range,

0 commit comments

Comments
 (0)