Skip to content

Commit a893f7f

Browse files
authored
Fix inferredTypeEdits for symbols (#22485)
2 parents 6d9b0f1 + f6234e7 commit a893f7f

File tree

2 files changed

+101
-8
lines changed

2 files changed

+101
-8
lines changed

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

+14-8
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ final class InferredTypeProvider(
112112
def imports: List[TextEdit] =
113113
printer.imports(autoImportsGen)
114114

115-
def printType(tpe: Type): String =
116-
printer.tpe(tpe)
115+
def printTypeAscription(tpe: Type, spaceBefore: Boolean = false): String =
116+
(if spaceBefore then " : " else ": ") + printer.tpe(tpe)
117117

118118
path.headOption match
119119
/* `val a = 1` or `var b = 2`
@@ -124,7 +124,7 @@ final class InferredTypeProvider(
124124
* turns into
125125
* `.map((a: Int) => a + a)`
126126
*/
127-
case Some(vl @ ValDef(sym, tpt, rhs)) =>
127+
case Some(vl @ ValDef(name, tpt, rhs)) =>
128128
val isParam = path match
129129
case head :: next :: _ if next.symbol.isAnonymousFunction => true
130130
case head :: (b @ Block(stats, expr)) :: next :: _
@@ -136,9 +136,11 @@ final class InferredTypeProvider(
136136
val endPos =
137137
findNamePos(sourceText, vl, keywordOffset).endPos.toLsp
138138
adjustOpt.foreach(adjust => endPos.setEnd(adjust.adjustedEndPos))
139+
val spaceBefore = name.isOperatorName
140+
139141
new TextEdit(
140142
endPos,
141-
": " + printType(optDealias(tpt.typeOpt)) + {
143+
printTypeAscription(optDealias(tpt.typeOpt), spaceBefore) + {
142144
if withParens then ")" else ""
143145
}
144146
)
@@ -197,7 +199,7 @@ final class InferredTypeProvider(
197199
* turns into
198200
* `def a[T](param : Int): Int = param`
199201
*/
200-
case Some(df @ DefDef(name, _, tpt, rhs)) =>
202+
case Some(df @ DefDef(name, paramss, tpt, rhs)) =>
201203
def typeNameEdit =
202204
/* NOTE: In Scala 3.1.3, `List((1,2)).map((<<a>>,b) => ...)`
203205
* turns into `List((1,2)).map((:Inta,b) => ...)`,
@@ -208,10 +210,12 @@ final class InferredTypeProvider(
208210
if tpt.endPos.end > df.namePos.end then tpt.endPos.toLsp
209211
else df.namePos.endPos.toLsp
210212

213+
val spaceBefore = name.isOperatorName && paramss.isEmpty
214+
211215
adjustOpt.foreach(adjust => end.setEnd(adjust.adjustedEndPos))
212216
new TextEdit(
213217
end,
214-
": " + printType(optDealias(tpt.typeOpt))
218+
printTypeAscription(optDealias(tpt.typeOpt), spaceBefore)
215219
)
216220
end typeNameEdit
217221

@@ -239,9 +243,10 @@ final class InferredTypeProvider(
239243
*/
240244
case Some(bind @ Bind(name, body)) =>
241245
def baseEdit(withParens: Boolean) =
246+
val spaceBefore = name.isOperatorName
242247
new TextEdit(
243248
bind.endPos.toLsp,
244-
": " + printType(optDealias(body.typeOpt)) + {
249+
printTypeAscription(optDealias(body.typeOpt), spaceBefore) + {
245250
if withParens then ")" else ""
246251
}
247252
)
@@ -272,9 +277,10 @@ final class InferredTypeProvider(
272277
* `for(t: Int <- 0 to 10)`
273278
*/
274279
case Some(i @ Ident(name)) =>
280+
val spaceBefore = name.isOperatorName
275281
val typeNameEdit = new TextEdit(
276282
i.endPos.toLsp,
277-
": " + printType(optDealias(i.typeOpt.widen))
283+
printTypeAscription(optDealias(i.typeOpt.widen), spaceBefore)
278284
)
279285
typeNameEdit :: imports
280286

Diff for: presentation-compiler/test/dotty/tools/pc/tests/edit/InsertInferredTypeSuite.scala

+87
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,93 @@ class InsertInferredTypeSuite extends BaseCodeActionSuite:
883883
|""".stripMargin
884884
)
885885

886+
@Test def `operator-val` =
887+
checkEdit(
888+
"""|object A {
889+
| val <<!>> = 1
890+
|}
891+
|""".stripMargin,
892+
"""|object A {
893+
| val ! : Int = 1
894+
|}
895+
|""".stripMargin
896+
)
897+
898+
@Test def `operator-def` =
899+
checkEdit(
900+
"""|object A {
901+
| def <<!>> = 1
902+
|}
903+
|""".stripMargin,
904+
"""|object A {
905+
| def ! : Int = 1
906+
|}
907+
|""".stripMargin
908+
)
909+
910+
@Test def `operator-def-param` =
911+
checkEdit(
912+
"""|object A {
913+
| def <<!>>[T] = 1
914+
|}
915+
|""".stripMargin,
916+
"""|object A {
917+
| def ![T]: Int = 1
918+
|}
919+
|""".stripMargin
920+
)
921+
922+
@Test def `operator-def-type-param` =
923+
checkEdit(
924+
"""|object A {
925+
| def <<!>>(x: Int) = 1
926+
|}
927+
|""".stripMargin,
928+
"""|object A {
929+
| def !(x: Int): Int = 1
930+
|}
931+
|""".stripMargin
932+
)
933+
934+
@Test def `operator-for` =
935+
checkEdit(
936+
"""|object A {
937+
| def foo = for(<<!>> <- List(1)) yield !
938+
|}
939+
|""".stripMargin,
940+
"""|object A {
941+
| def foo = for(! : Int <- List(1)) yield !
942+
|}
943+
|""".stripMargin
944+
)
945+
@Test def `operator-lambda` =
946+
checkEdit(
947+
"""|object A {
948+
| val foo: Int => Int = (<<!>>) => ! + 1
949+
|}
950+
|""".stripMargin,
951+
"""|object A {
952+
| val foo: Int => Int = (! : Int) => ! + 1
953+
|}
954+
|""".stripMargin
955+
)
956+
957+
@Test def `operator-ident` =
958+
checkEdit(
959+
"""|object A {
960+
| def foo =
961+
| val ! = 1
962+
| <<!>>
963+
|}
964+
|""".stripMargin,
965+
"""|object A {
966+
| def foo =
967+
| val ! = 1
968+
| ! : Int
969+
|}
970+
|""".stripMargin
971+
)
972+
886973
def checkEdit(
887974
original: String,
888975
expected: String

0 commit comments

Comments
 (0)