Skip to content

Commit d307420

Browse files
rochalaKordyjan
authored andcommitted
Update presentation compiler to a829a6a (#18347)
[Cherry-picked 70be2df]
1 parent f55b40e commit d307420

File tree

6 files changed

+372
-12
lines changed

6 files changed

+372
-12
lines changed

presentation-compiler/src/main/dotty/tools/pc/HoverProvider.scala

+19-8
Original file line numberDiff line numberDiff line change
@@ -159,23 +159,34 @@ object HoverProvider:
159159
printer: ShortenedTypePrinter
160160
)(using Context): ju.Optional[HoverSignature] = path match
161161
case SelectDynamicExtractor(sel, n, name) =>
162-
def findRefinement(tp: Type): ju.Optional[HoverSignature] =
162+
def findRefinement(tp: Type): Option[HoverSignature] =
163163
tp match
164-
case RefinedType(info, refName, tpe) if name == refName.toString() =>
164+
case RefinedType(_, refName, tpe) if name == refName.toString() =>
165165
val tpeString =
166166
if n == nme.selectDynamic then s": ${printer.tpe(tpe.resultType)}"
167167
else printer.tpe(tpe)
168-
ju.Optional.of(
168+
169+
val valOrDef =
170+
if n == nme.selectDynamic && !tpe.isInstanceOf[ExprType]
171+
then "val"
172+
else "def"
173+
174+
Some(
169175
new ScalaHover(
170176
expressionType = Some(tpeString),
171-
symbolSignature = Some(s"def $name$tpeString")
177+
symbolSignature = Some(s"$valOrDef $name$tpeString"),
172178
)
173179
)
174-
case RefinedType(info, _, _) =>
175-
findRefinement(info)
176-
case _ => ju.Optional.empty()
180+
case RefinedType(parent, _, _) =>
181+
findRefinement(parent)
182+
case _ => None
183+
184+
val refTpe = sel.tpe.metalsDealias match
185+
case r: RefinedType => Some(r)
186+
case t: (TermRef | TypeProxy) => Some(t.termSymbol.info.metalsDealias)
187+
case _ => None
177188

178-
findRefinement(sel.tpe.termSymbol.info.dealias)
189+
refTpe.flatMap(findRefinement).asJava
179190
case _ =>
180191
ju.Optional.empty()
181192

presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala

+9-1
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,18 @@ class Completions(
7575
case Import
7676

7777
def include(sym: Symbol)(using Context): Boolean =
78+
def hasSyntheticCursorSuffix: Boolean =
79+
if !sym.name.endsWith(Cursor.value) then false
80+
else
81+
val realNameLength = sym.decodedName.length - Cursor.value.length
82+
sym.source == pos.source &&
83+
sym.span.start + realNameLength == pos.span.end
84+
7885
val generalExclude =
7986
isUninterestingSymbol(sym) ||
8087
!isNotLocalForwardReference(sym) ||
81-
sym.isPackageObject
88+
sym.isPackageObject ||
89+
hasSyntheticCursorSuffix
8290

8391
def isWildcardParam(sym: Symbol) =
8492
if sym.isTerm && sym.owner.isAnonymousFunction then

presentation-compiler/src/main/dotty/tools/pc/utils/MtagsEnrichments.scala

+8-1
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,16 @@ object MtagsEnrichments extends CommonMtagsEnrichments:
197197
else symbol
198198
)
199199
val sym = toSemanticdbSymbol(symbol)
200+
def parentSymbols =
201+
if symbol.name == nme.apply && symbol.maybeOwner.is(ModuleClass) then
202+
List(
203+
symbol.maybeOwner,
204+
symbol.maybeOwner.companion,
205+
).filter(_ != NoSymbol) ++ symbol.allOverriddenSymbols
206+
else symbol.allOverriddenSymbols
200207
val documentation = search.documentation(
201208
sym,
202-
() => symbol.allOverriddenSymbols.map(toSemanticdbSymbol).toList.asJava
209+
() => parentSymbols.iterator.map(toSemanticdbSymbol).toList.asJava,
203210
)
204211
if documentation.isPresent then Some(documentation.get())
205212
else None
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
package dotty.tools.pc.tests.hover
2+
3+
import dotty.tools.pc.base.BaseHoverSuite
4+
5+
import org.junit.Test
6+
import dotty.tools.pc.utils.MockEntries
7+
import scala.meta.pc.SymbolDocumentation
8+
9+
class HoverDocSuite extends BaseHoverSuite:
10+
11+
override protected def mockEntries: MockEntries = new MockEntries:
12+
override def documentations: Set[SymbolDocumentation] = Set(
13+
ScalaMockDocumentation("java/lang/String#substring().", "substring", List(MockParam("beginIndex"))),
14+
ScalaMockDocumentation("java/util/Collections#emptyList().", "emptyList"),
15+
ScalaMockDocumentation("_empty_/Alpha.apply().", "apply", List(MockParam("x"))),
16+
ScalaMockDocumentation("_empty_/Alpha#", "init", List(MockParam("x"))),
17+
ScalaMockDocumentation("scala/collection/LinearSeqOps#headOption().", "headOption"),
18+
)
19+
20+
@Test def `doc` =
21+
check(
22+
"""object a {
23+
| <<java.util.Collections.empty@@List[Int]>>
24+
|}
25+
|""".stripMargin,
26+
"""|**Expression type**:
27+
|```scala
28+
|java.util.List[Int]
29+
|```
30+
|**Symbol signature**:
31+
|```scala
32+
|final def emptyList[T](): java.util.List[T]
33+
|```
34+
|Found documentation for java/util/Collections#emptyList().
35+
|""".stripMargin,
36+
)
37+
38+
@Test def `doc-parent` =
39+
check(
40+
"""|object a {
41+
| <<List(12).hea@@dOption>>
42+
|}
43+
|""".stripMargin,
44+
// Assert that the docstring is extracted.
45+
"""|```scala
46+
|override def headOption: Option[Int]
47+
|```
48+
|Found documentation for scala/collection/LinearSeqOps#headOption().
49+
|""".stripMargin,
50+
51+
)
52+
53+
@Test def `java-method` =
54+
check(
55+
"""|object a {
56+
| <<"".substri@@ng(1)>>
57+
|}
58+
""".stripMargin,
59+
"""|```scala
60+
|def substring(beginIndex: Int): String
61+
|```
62+
|Found documentation for java/lang/String#substring().
63+
|""".stripMargin
64+
)
65+
66+
@Test def `object` =
67+
check(
68+
"""|
69+
|/**
70+
| * Doc about object
71+
| */
72+
|object Alpha {
73+
| def apply(x: Int) = x + 1
74+
|}
75+
|
76+
|object Main {
77+
| val x = <<Alp@@ha(2)>>
78+
|}
79+
|""".stripMargin,
80+
"""|```scala
81+
|def apply(x: Int): Int
82+
|```
83+
|Found documentation for _empty_/Alpha.apply().
84+
|""".stripMargin,
85+
)
86+
87+
@Test def `object1` =
88+
check(
89+
"""|
90+
|/**
91+
| * Doc about object
92+
| */
93+
|object Alpha {
94+
| /**
95+
| * Doc about method
96+
| */
97+
| def apply(x: Int) = x + 1
98+
|}
99+
|
100+
|object Main {
101+
| val x = <<Alp@@ha(2)>>
102+
|}
103+
|""".stripMargin,
104+
"""|```scala
105+
|def apply(x: Int): Int
106+
|```
107+
|Found documentation for _empty_/Alpha.apply().
108+
|""".stripMargin,
109+
)
110+
111+
@Test def `case-class` =
112+
check(
113+
"""|
114+
|/**
115+
| * Doc about case class
116+
| *
117+
| */
118+
|case class Alpha(x: Int)
119+
|
120+
|/**
121+
| * Doc about object
122+
| */
123+
|object Alpha {
124+
| /**
125+
| * Doc about method
126+
| */
127+
| def apply(x: Int) = x + 1
128+
|}
129+
|
130+
|object Main {
131+
| val x = <<Alp@@ha(2)>>
132+
|}
133+
|""".stripMargin,
134+
"""|```scala
135+
|def apply(x: Int): Int
136+
|```
137+
|Found documentation for _empty_/Alpha.apply().
138+
|""".stripMargin,
139+
)
140+
141+
@Test def `case-class1` =
142+
check(
143+
"""|
144+
|/**
145+
| * Doc about case class
146+
| *
147+
| */
148+
|case class Alpha(x: Int)
149+
|
150+
|/**
151+
| * Doc about object
152+
| */
153+
|object Alpha {
154+
| def apply(x: Int) = x + 1
155+
|}
156+
|
157+
|object Main {
158+
| val x = <<Alp@@ha(2)>>
159+
|}
160+
|""".stripMargin,
161+
"""|```scala
162+
|def apply(x: Int): Int
163+
|```
164+
|Found documentation for _empty_/Alpha.apply().
165+
|
166+
|""".stripMargin,
167+
)
168+
169+
@Test def `case-class2` =
170+
check(
171+
"""|
172+
|/**
173+
| * Doc about case class
174+
| *
175+
| */
176+
|case class Alpha(x: Int)
177+
|
178+
|object Alpha {
179+
| def apply(x: Int) = x + 1
180+
|}
181+
|
182+
|object Main {
183+
| val x = <<Alp@@ha(2)>>
184+
|}
185+
|""".stripMargin,
186+
"""|```scala
187+
|def apply(x: Int): Int
188+
|```
189+
|Found documentation for _empty_/Alpha.apply().
190+
|""".stripMargin,
191+
)
192+
193+
@Test def `case-class3` =
194+
check(
195+
"""|
196+
|/**
197+
| * Doc about case class
198+
| *
199+
| */
200+
|case class Alpha(x: Int)
201+
|
202+
|
203+
|object Main {
204+
| val x = <<Alp@@ha(2)>>
205+
|}
206+
|""".stripMargin,
207+
"""|```scala
208+
|def apply(x: Int): Alpha
209+
|```
210+
|Found documentation for _empty_/Alpha.apply().
211+
|""".stripMargin,
212+
)
213+
214+
@Test def `class` =
215+
check(
216+
"""|
217+
|/**
218+
| * Doc about class
219+
| *
220+
| */
221+
|class Alpha(x: Int)
222+
|
223+
|object Alpha {
224+
| def apply(x: Int) = x + 1
225+
|}
226+
|
227+
|object Main {
228+
| val x = <<Alp@@ha(2)>>
229+
|}
230+
|""".stripMargin,
231+
"""|```scala
232+
|def apply(x: Int): Int
233+
|```
234+
|Found documentation for _empty_/Alpha.apply().
235+
|""".stripMargin,
236+
)
237+
238+
@Test def `universal-apply` =
239+
check(
240+
"""|
241+
|/**
242+
| * Doc about class
243+
| *
244+
| */
245+
|class Alpha(x: Int)
246+
|
247+
|object Main {
248+
| val x = <<Alp@@ha(2)>>
249+
|}
250+
|""".stripMargin,
251+
"""|```scala
252+
|def this(x: Int): Alpha
253+
|```
254+
|Found documentation for _empty_/Alpha#
255+
|""".stripMargin,
256+
)

0 commit comments

Comments
 (0)