Skip to content

Commit 61822d2

Browse files
committed
add more tests, reduce Tree
1 parent 59d86d4 commit 61822d2

File tree

2 files changed

+93
-13
lines changed

2 files changed

+93
-13
lines changed

compiler/src/dotty/tools/dotc/interactive/Completion.scala

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -295,15 +295,22 @@ object Completion {
295295
resultMappings
296296
}
297297

298+
/** Replaces underlying type with reduced one, when it's MatchType */
299+
def reduceUnderlyingMatchType(qual: Tree)(using Context): Tree=
300+
qual.tpe.widen match
301+
case ctx.typer.MatchTypeInDisguise(mt) => qual.withType(mt)
302+
case _ => qual
303+
298304
/** Completions for selections from a term.
299305
* Direct members take priority over members from extensions
300306
* and so do members from extensions over members from implicit conversions
301307
*/
302308
def selectionCompletions(qual: Tree)(using Context): CompletionMap =
303-
implicitConversionMemberCompletions(qual) ++
304-
extensionCompletions(qual) ++
305-
matchTypeCompletions(qual) ++
306-
directMemberCompletions(qual)
309+
val reducedQual = reduceUnderlyingMatchType(qual)
310+
311+
implicitConversionMemberCompletions(reducedQual) ++
312+
extensionCompletions(reducedQual) ++
313+
directMemberCompletions(reducedQual)
307314

308315
/** Completions for members of `qual`'s type.
309316
* These include inherited definitions but not members added by extensions or implicit conversions
@@ -363,12 +370,6 @@ object Completion {
363370
implicitConversionTargets(qual)(using ctx.fresh.setExploreTyperState()).flatMap(accessibleMembers)
364371
membersFromConversion.toSeq.groupByName
365372

366-
/** Completions for derived members of `MatchType`'s type. */
367-
def matchTypeCompletions(qual: Tree)(using Context): CompletionMap =
368-
qual.tpe.widenDealias match
369-
case ctx.typer.MatchTypeInDisguise(mt) => accessibleMembers(mt.reduced).groupByName
370-
case _ => Map.empty
371-
372373
/** Completions from extension methods */
373374
private def extensionCompletions(qual: Tree)(using Context): CompletionMap =
374375
def asDefLikeType(tpe: Type): Type = tpe match

language-server/test/dotty/tools/languageserver/CompletionTest.scala

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class CompletionTest {
1717
@Test def completionFromScalaPredef: Unit = {
1818
code"class Foo { def foo: Unit = prin${m1} }".withSource
1919
.completion(m1, Set(
20-
("print", Method, "(x: Any): Unit"),
20+
("print", Method, "(x: Any): Unit"),
2121
("printf", Method, "(text: String, xs: Any*): Unit"),
2222
("println", Method, "(x: Any): Unit"),
2323
("println", Method, "(): Unit")
@@ -1122,19 +1122,98 @@ class CompletionTest {
11221122
.withSource.completion(m1, expected)
11231123
}
11241124

1125-
@Test def matchTypeCompletion: Unit = {
1125+
@Test def matchTypeCompletions: Unit = {
1126+
val expected = Set(
1127+
("fooTest", Method, "(y: Int): Int"),
1128+
)
1129+
code"""case class Foo(x: Int) {
1130+
| def fooTest(y: Int): Int = ???
1131+
|}
1132+
|type Elem[X] = X match {
1133+
| case Int => Foo
1134+
| case Any => X
1135+
|}
1136+
|def elem[X](x: X): Elem[X] = x match {
1137+
| case x: Int => Foo(x)
1138+
| case x: Any => x
1139+
|}
1140+
|object Test:
1141+
| elem(1).foo${m1}"""
1142+
.withSource.completion(m1, expected)
1143+
}
1144+
1145+
@Test def higherKindedMatchTypeDeclaredCompletion: Unit = {
11261146
val expected = Set(
11271147
("map", Method, "[B](f: Int => B): Foo[B]"),
11281148
)
11291149
code"""trait Foo[A] {
1130-
| def map[B](f: A => B): Foo[B]
1150+
| def map[B](f: A => B): Foo[B] = ???
1151+
|}
1152+
|case class Bar[F[_]](bar: F[Int])
1153+
|type M[T] = T match {
1154+
| case Int => Foo[Int]
1155+
|}
1156+
|object Test:
1157+
| val x = Bar[M](new Foo[Int]{})
1158+
| x.bar.m${m1}"""
1159+
.withSource.completion(m1, expected)
1160+
}
1161+
1162+
@Test def higherKindedMatchTypeLazyCompletion: Unit = {
1163+
val expected = Set(
1164+
("map", Method, "[B](f: Int => B): Foo[B]"),
1165+
)
1166+
code"""trait Foo[A] {
1167+
| def map[B](f: A => B): Foo[B] = ???
11311168
|}
11321169
|case class Bar[F[_]](bar: F[Int])
11331170
|type M[T] = T match {
11341171
| case Int => Foo[Int]
11351172
|}
11361173
|def foo(x: Bar[M]) = x.bar.m${m1}"""
11371174
.withSource.completion(m1, expected)
1175+
}
11381176

1177+
// This test is not passing due to https://github.com/lampepfl/dotty/issues/14687
1178+
// @Test def higherKindedMatchTypeImplicitConversionCompletion: Unit = {
1179+
// val expected = Set(
1180+
// ("mapBoo", Method, "[B](op: Int => B): Boo[B]"),
1181+
// ("mapFoo", Method, "[B](op: Int => B): Foo[B]"),
1182+
// )
1183+
// code"""import scala.language.implicitConversions
1184+
// |case class Foo[A](x: A) {
1185+
// | def mapFoo[B](op: A => B): Foo[B] = ???
1186+
// |}
1187+
// |case class Boo[A](x: A) {
1188+
// | def mapBoo[B](op: A => B): Boo[B] = ???
1189+
// |}
1190+
// |type M[A] = A match {
1191+
// | case Int => Foo[Int]
1192+
// |}
1193+
// |implicit def fooToBoo[A](x: Foo[A]): Boo[A] = Boo(x.x)
1194+
// |case class Bar[F[_]](bar: F[Int])
1195+
// |def foo(x: Bar[M]) = x.bar.m${m1}"""
1196+
// .withSource.completion(m1, expected)
1197+
// }
1198+
1199+
@Test def higherKindedMatchTypeExtensionMethodCompletion: Unit = {
1200+
val expected = Set(
1201+
("mapFoo", Method, "[B](f: Int => B): Foo[B]"),
1202+
("mapExtensionMethod", Method, "[B](f: Int => B): Foo[B]"),
1203+
)
1204+
code"""trait Foo[A] {
1205+
| def mapFoo[B](f: A => B): Foo[B] = ???
1206+
|}
1207+
|extension[A] (x: Foo[A]) {
1208+
| def mapExtensionMethod[B](f: A => B): Foo[B] = ???
1209+
|}
1210+
|case class Baz[F[_]](baz: F[Int])
1211+
|type M[T] = T match {
1212+
| case Int => Foo[Int]
1213+
|}
1214+
|case class Bar[F[_]](bar: F[Int])
1215+
|def foo(x: Bar[M]) = x.bar.ma${m1}"""
1216+
.withSource.completion(m1, expected)
11391217
}
1218+
11401219
}

0 commit comments

Comments
 (0)