Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pattern completion for unapply contexts #20274

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

natsukagami
Copy link
Contributor

Fixes #19972.

Add pattern completion for Unapply tree contexts.

A typical example would be

optionList match
    case List(S@@)

which should be prompted Some(value), due to List.unapplySeq expecting Option[T] patterns as arguments.

  • Add unapply pattern completion test
  • Add pattern completion based on the Unapply argument type

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.
Copy link
Contributor

@rochala rochala left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left 2 comments, and if you could also add test which checks deeper nesting levels. Other than that it looks fine to me

Will this also work for multiple nested levels ?

null match
  case Some(Some(Some(Som@@))))

case Ident(name) :: (unapp : UnApply) :: _ =>
(
CaseKeywordCompletion.contribute(
EmptyTree, // no selector
Copy link
Contributor

@rochala rochala Apr 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So will this work for this case (ideally add this case to tests):

object Test:
  case class NestedClass(x: Int)
object TestRun:
  null match
    case Some(Test.Neste@@)

|}
|""".stripMargin,
"""|Some(value) scala
|Some[A](value: A): Some[A]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure whether we should still show synthetic constructor / apply completions in this case. They are invalid here.

Completions for completions is a different story though, as we have no logic to detect whether it has nested members yet, so this is another improvement that could be made in the future.

If you want to remove Some[A](value: A): Some[A] I suppose it can be achieved by adding unapply cases here:

//file: Completions.scala
  private lazy val shouldAddSnippet =
    path match
      /* In case of `method@@()` we should not add snippets and the path
       * will contain apply as the parent of the current tree.
       */
      case (fun) :: (appl: GenericApply) :: _ if appl.fun == fun =>
        false
      case _ :: (withcursor @ Select(fun, name)) :: (appl: GenericApply) :: _
          if appl.fun == withcursor && name.decoded == Cursor.value =>
        false
      case (_: (Import | Export)) :: _ => false
      case _ :: (_: (Import | Export)) :: _ => false
      case _ => true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unapply completions should be completed in nested unapply context
2 participants