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

Improve signature help by more stable position calculation + better named arg support #19214

Merged
merged 14 commits into from
Jan 19, 2024

Conversation

rochala
Copy link
Contributor

@rochala rochala commented Dec 6, 2023

Previously, signature help had unstable way of calculating active parameter inside the signature help. It is now changed to work better with erroneous trees such as unclosed openings.

It also adds a new feature for signature help, which will help user navigate inside named arguments. Furthermore, it will now find reordered named arguments, and display in the same way, by also marking the remaining parameters that they are now required to be named.

Example:

Screen.Recording.2023-12-06.at.15.55.02.mov

For the reviewers: I recommend testing it locally.

Copy link
Contributor

@kasiaMarek kasiaMarek left a comment

Choose a reason for hiding this comment

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

Also the unclosed opening works for params but not type params.

Copy link
Contributor

@jkciesluk jkciesluk left a comment

Choose a reason for hiding this comment

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

Great job! It fixes a lot of things, but I'm unsure if handling unclosed openings is needed, especially because it really complicates finding enclosing apply.

Could you add these tests:

def test[T, F](aaa: Int, bbb: T, ccc: F): T = ???
val x = test(1, ccc = 2, b@@)
def test2(aaa: Int, bbb: Int, ccc: Int): Int = ???
val x = test2(
    1, 
    @@
  )
def test2(aaa: Int, bbb: Int, ccc: Int): Int = ???
val x = test2(aaa = 2@@, ccc = 1)
def test2(aaa: Int, bbb: Int, ccc: Int): Int = ???
val x = test2(aaa = 2, @@  ccc = 1, bbb = 3)

Also, would it be possible to show in the case below that arguments in the first parameter list are reordered?

def test3(aaa: Int, bbb: Int, ccc: Int)(ddd: Int): Int = ???
val x = test3(bbb = 1, aaa = 2, ccc = 3)(d@@)

@rochala
Copy link
Contributor Author

rochala commented Dec 28, 2023

The following changes have been made:

  • we will stop supporting Signature Helps for unclosed openings. It is too hard to recover from such errors reliably and to track where we are with the cursor. All modern editors will close opening on input. It simplified the code, and is the best way forward.
  • if there is an error within a definition return type parameter, we will now fall back to source, instead of print error,
  • tuples and functions are now supported when they are returned from methods.
  • this rewrite made me change a few things, and I took the chance and made it support clause interleaving. There is now a proper test suite for that. It required changing the way we represent Signatures.
  • argument reordering now works for all parameter lists, not only the currently applied one,
  • type parameters now also correctly display documentation

@rochala
Copy link
Contributor Author

rochala commented Jan 9, 2024

I've changed the PR to use ShortenedTypePrinter and fixed some other minor issues like correctly marking reordered argumentss or hiding synthetic parameter names.

In the future, Signature help should be changed to return symbols from the compiler instead of already printed values, and only print them later using shared API of ShortenedTypePrinter in the Presentation Compiler. Ideally we'd want a shared implementation for label printing with completions, hovers and other features.

Copy link
Contributor

@jkciesluk jkciesluk left a comment

Choose a reason for hiding this comment

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

LGTM! Great work!

Copy link
Contributor

@kasiaMarek kasiaMarek left a comment

Choose a reason for hiding this comment

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

Looks really good. 🚀 I feel like you improved naming of different variables/methods, thanks for that, I think it made things more readable.

@@ -202,23 +202,6 @@ class SignatureHelpPatternSuite extends BaseSignatureHelpSuite:
|""".stripMargin
)

@Test def `pat4` =
Copy link
Contributor

Choose a reason for hiding this comment

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

Why did you delete this test?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A. It is not working any more due to changes to range.
B. It was a bit useless as it would not be automatically opened and triggered, also the information is not that helpful, especially if you have more than single Apply like
a :: b :: c :: Nil

@@ -323,9 +323,9 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite:
| } yield k
|}
""".stripMargin,
"""|to(end: Int): scala.collection.immutable.Range.Inclusive
"""|to(end: Int): Inclusive
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it supposed to shorten the name this much?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, it should only shorten packages. I'll change it in separate PR as this is not caused by these changes.

compiler/src/dotty/tools/dotc/util/Signatures.scala Outdated Show resolved Hide resolved
}
.mkString("(", ")(", ")")
val tparamsLabel = if (signature.tparams.isEmpty) "" else signature.tparams.mkString("[", ", ", "]")
signature.paramss
Copy link
Contributor

Choose a reason for hiding this comment

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

I assume this whole duplication is because there is no good place for it, such that it could be used by both modules.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Dotty language server should actually be removed from the repository as it is no longer necessary. It is not so easy tho as the test coverage is different. This change was only made to make the tests pass

@rochala rochala enabled auto-merge (squash) January 19, 2024 13:24
@rochala rochala disabled auto-merge January 19, 2024 13:48
@rochala rochala merged commit 01171de into scala:main Jan 19, 2024
19 checks passed
@Kordyjan Kordyjan added this to the 3.4.1 milestone Feb 14, 2024
@tgodzik tgodzik added the area:presentation-compiler Related to the presentation compiler module used by Metals and possibly other tools label May 8, 2024
WojciechMazur pushed a commit that referenced this pull request Jun 27, 2024
…amed arg support (#19214)

Previously, signature help had unstable way of calculating active
parameter inside the signature help. It is now changed to work better
with erroneous trees such as unclosed openings.

It also adds a new feature for signature help, which will help user
navigate inside named arguments. Furthermore, it will now find reordered
named arguments, and display in the same way, by also marking the
remaining parameters that they are now required to be named.

Example:


https://github.com/lampepfl/dotty/assets/48657087/b181d2d5-60f0-46a5-b2df-a58aa5f07454

The following changes have been made:

    - we will stop supporting Signature Helps for unclosed openings. It is too hard to recover from such errors reliably and to track where we are with the cursor. All modern editors will close opening on input. It simplified the code, and is the best way forward.
    - if there is an error within a definition return type parameter, we will now fall back to source, instead of print error,
    - tuples and functions are now supported when they are returned from methods.
    - this rewrite made me change a few things, and I took the chance and made it support clause interleaving. There is now a proper test suite for that. It required changing the way we represent Signatures.
    - argument reordering now works for all parameter lists, not only the currently applied one,
    - type parameters now also correctly display documentation

I've changed the PR to use ShortenedTypePrinter and fixed some other minor issues like correctly marking reordered argumentss or hiding synthetic parameter names.

In the future, Signature help should be changed to return symbols from the compiler instead of already printed values, and only print them later using shared API of ShortenedTypePrinter in the Presentation Compiler. Ideally we'd want a shared implementation for label printing with completions, hovers and other features.
[Cherry-picked 01171de]
WojciechMazur added a commit that referenced this pull request Jun 28, 2024
…+ better named arg support" to LTS (#20845)

Backports #19214 to the LTS branch.

PR submitted by the release tooling.
[skip ci]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:presentation-compiler Related to the presentation compiler module used by Metals and possibly other tools
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants