Skip to content

Commit 9bf69a3

Browse files
natsukagamiWojciechMazur
authored andcommitted
Fix pattern matching for get matches
1 parent 10a4662 commit 9bf69a3

File tree

3 files changed

+95
-2
lines changed

3 files changed

+95
-2
lines changed

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ class Completions(
7070
false
7171
case (_: (Import | Export)) :: _ => false
7272
case _ :: (_: (Import | Export)) :: _ => false
73+
// UnApply has patterns included in MatchCaseCompletions
74+
case _ :: (_: UnApply) :: _ => false
7375
case _ => true
7476

7577
private lazy val isNew: Boolean = Completion.isInNewContext(adjustedPath)
@@ -407,6 +409,36 @@ class Completions(
407409
true,
408410
)
409411

412+
// unapply pattern
413+
case Ident(name) :: (unapp : UnApply) :: _ =>
414+
(
415+
CaseKeywordCompletion.contribute(
416+
EmptyTree, // no selector
417+
completionPos,
418+
indexedContext,
419+
config,
420+
search,
421+
parent = unapp,
422+
autoImports,
423+
patternOnly = Some(name.decoded)
424+
),
425+
false,
426+
)
427+
case Select(_, name) :: (unapp : UnApply) :: _ =>
428+
(
429+
CaseKeywordCompletion.contribute(
430+
EmptyTree, // no selector
431+
completionPos,
432+
indexedContext,
433+
config,
434+
search,
435+
parent = unapp,
436+
autoImports,
437+
patternOnly = Some(name.decoded)
438+
),
439+
false,
440+
)
441+
410442
// class FooImpl extends Foo:
411443
// def x|
412444
case OverrideExtractor(td, completing, start, exhaustive, fallbackName) =>

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import dotty.tools.dotc.core.Types.NoType
2727
import dotty.tools.dotc.core.Types.OrType
2828
import dotty.tools.dotc.core.Types.Type
2929
import dotty.tools.dotc.core.Types.TypeRef
30+
import dotty.tools.dotc.core.Types.AppliedType
31+
import dotty.tools.dotc.typer.Applications.unapplyArgs
3032
import dotty.tools.dotc.util.SourcePosition
3133
import dotty.tools.pc.AutoImports.AutoImportsGenerator
3234
import dotty.tools.pc.AutoImports.SymbolImport
@@ -75,10 +77,24 @@ object CaseKeywordCompletion:
7577
patternOnly,
7678
hasBind
7779
)
80+
7881
val printer = ShortenedTypePrinter(search, IncludeDefaultParam.Never)(using indexedContext)
7982
val selTpe = selector match
8083
case EmptyTree =>
8184
parent match
85+
/* Parent is an unapply pattern */
86+
case UnApply(fn, implicits, patterns) if !fn.tpe.isErroneous =>
87+
patternOnly match
88+
case None => None
89+
case Some(value) =>
90+
val argPts = unapplyArgs(fn.tpe.widen.finalResultType, fn, patterns, parent.srcPos)
91+
patterns.zipWithIndex
92+
.find:
93+
case (Ident(v), tpe) => v.decoded == value
94+
case (Select(_, v), tpe) => v.decoded == value
95+
case t => false
96+
.map((_, id) => argPts(id).widen.deepDealias)
97+
/* Parent is a function expecting a case match expression */
8298
case TreeApply(fun, _) if !fun.tpe.isErroneous =>
8399
fun.tpe.paramInfoss match
84100
case (head :: Nil) :: _
@@ -105,7 +121,8 @@ object CaseKeywordCompletion:
105121
if patternOnly.isEmpty then
106122
val selectorTpe = selTpe.show
107123
val tpeLabel =
108-
if !selectorTpe.contains("x$1") then selectorTpe
124+
if !selectorTpe.contains("x$1") /* selector of a function type? */ then
125+
selectorTpe
109126
else selector.symbol.info.show
110127
val label = s"case ${tpeLabel} =>"
111128
List(

presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,14 +634,58 @@ class CompletionSuite extends BaseCompletionSuite:
634634
|""".stripMargin
635635
)
636636

637+
@Test def patRecursive =
638+
check(
639+
s"""|object Main {
640+
| Option(List(Option(1))) match {
641+
| case Some(List(None, Som@@))
642+
|}
643+
|""".stripMargin,
644+
"""|Some(value) scala
645+
|Some scala
646+
|""".stripMargin
647+
)
648+
check(
649+
s"""|object Main {
650+
| (null: Option[Option[Option[Option[Int]]]]) match
651+
| case Some(Some(Some(Som@@))))
652+
|}
653+
|""".stripMargin,
654+
"""|Some(value) scala
655+
|Some scala
656+
|""".stripMargin
657+
)
658+
check(
659+
s"""|object Main {
660+
| Option(Option(1)) match {
661+
| case Some(Som@@)
662+
|}
663+
|""".stripMargin,
664+
"""|Some(value) scala
665+
|Some scala
666+
|""".stripMargin
667+
)
668+
check(
669+
s"""|object Test:
670+
| case class NestedClass(x: Int)
671+
|object TestRun:
672+
| Option(Test.NestedClass(5)) match
673+
| case Some(Test.Neste@@)
674+
|""".stripMargin,
675+
"""|NestedClass(x) test.Test
676+
|NestedClass test.Test
677+
|""".stripMargin
678+
)
679+
637680
@Test def pat1 =
638681
check(
639682
s"""|object Main {
640683
| Option(1) match {
641684
| case List(Som@@)
642685
|}
643686
|""".stripMargin,
644-
"""|Some[A](value: A): Some[A]
687+
"""|Some(value) scala
688+
|Some scala
645689
|Some scala
646690
|""".stripMargin
647691
)

0 commit comments

Comments
 (0)