Skip to content

Commit

Permalink
Add pattern completion based on the Unapply argument type
Browse files Browse the repository at this point in the history
The idea was to collect patterns given the Unapply tree as the parent.
We need to deconstruct the UnApply type tree and get the type of the placeholder ident.
  • Loading branch information
natsukagami committed Apr 27, 2024
1 parent a918d61 commit 240ac68
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,22 @@ class Completions(
true,
)

// unapply pattern
case Ident(name) :: (unapp : UnApply) :: _ =>
(
CaseKeywordCompletion.contribute(
EmptyTree, // no selector
completionPos,
indexedContext,
config,
search,
parent = unapp,
autoImports,
patternOnly = Some(name.decoded)
),
false,
)

// class FooImpl extends Foo:
// def x|
case OverrideExtractor(td, completing, start, exhaustive, fallbackName) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import dotty.tools.dotc.core.Types.NoType
import dotty.tools.dotc.core.Types.OrType
import dotty.tools.dotc.core.Types.Type
import dotty.tools.dotc.core.Types.TypeRef
import dotty.tools.dotc.core.Types.AppliedType
import dotty.tools.dotc.typer.Applications.unapplyArgs
import dotty.tools.dotc.util.SourcePosition
import dotty.tools.pc.AutoImports.AutoImportsGenerator
import dotty.tools.pc.AutoImports.SymbolImport
Expand Down Expand Up @@ -76,10 +78,23 @@ object CaseKeywordCompletion:
patternOnly,
hasBind
)

val printer = ShortenedTypePrinter(search, IncludeDefaultParam.Never)(using indexedContext)
val selTpe = selector match
case EmptyTree =>
parent match
/* Parent is an unapply pattern */
case UnApply(fn, implicits, patterns) if !fn.tpe.isErroneous =>
patternOnly match
case None => None
case Some(value) =>
val argPts = unapplyArgs(fn.tpe.widen.finalResultType, fn, patterns, parent.srcPos)
patterns.zipWithIndex
.find:
case (id@Ident(v), tpe) => v.decoded == value
case _ => false
.map((_, id) => argPts(id).widen.metalsDealias)
/* Parent is a function expecting a case match expression */
case TreeApply(fun, _) if !fun.tpe.isErroneous =>
fun.tpe.paramInfoss match
case (head :: Nil) :: _
Expand All @@ -106,7 +121,8 @@ object CaseKeywordCompletion:
if patternOnly.isEmpty then
val selectorTpe = selTpe.show
val tpeLabel =
if !selectorTpe.contains("x$1") then selectorTpe
if !selectorTpe.contains("x$1") /* selector of a function type? */ then
selectorTpe
else selector.symbol.info.show
val label = s"case ${tpeLabel} =>"
List(
Expand Down

0 comments on commit 240ac68

Please sign in to comment.