Skip to content

Fix nested signature help #687

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

Merged
merged 3 commits into from
Jan 11, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -30,6 +30,7 @@
#### :bug: Bug Fix

- Highlight `catch` like a keyword https://github.com/rescript-lang/rescript-vscode/pull/677
- Make signature help work in calls nested inside of other calls. https://github.com/rescript-lang/rescript-vscode/pull/687

## v1.10.0

25 changes: 20 additions & 5 deletions analysis/src/SignatureHelp.ml
Original file line number Diff line number Diff line change
@@ -179,10 +179,19 @@ let signatureHelp ~path ~pos ~currentFile ~debug =
let supportsMarkdownLinks = true in
let foundFunctionApplicationExpr = ref None in
let setFound r =
if !foundFunctionApplicationExpr = None then
(* Because we want to handle both piped and regular function calls, and in
the case of piped calls the iterator will process both the pipe and the
regular call (even though it's piped), we need to ensure that we don't
re-save the same expression (but unpiped, even though it's actually piped). *)
match (!foundFunctionApplicationExpr, r) with
| Some (_, alreadyFoundExp, _), (_, newExp, _)
when alreadyFoundExp.Parsetree.pexp_loc <> newExp.Parsetree.pexp_loc
->
foundFunctionApplicationExpr := Some r
| None, _ -> foundFunctionApplicationExpr := Some r
| Some _, _ -> ()
in
let searchForArgWithCursor ~isPipeExpr ~args ~exp =
let searchForArgWithCursor ~isPipeExpr ~args =
let extractedArgs = extractExpApplyArgs ~args in
let argAtCursor =
let firstArgIndex = if isPipeExpr then 1 else 0 in
@@ -246,7 +255,7 @@ let signatureHelp ~path ~pos ~currentFile ~debug =
else 0))
| v -> v
in
setFound (argAtCursor, exp, extractedArgs)
(argAtCursor, extractedArgs)
in
let expr (iterator : Ast_iterator.iterator) (expr : Parsetree.expression)
=
@@ -269,7 +278,10 @@ let signatureHelp ~path ~pos ~currentFile ~debug =
when pexp_loc
|> CursorPosition.classifyLoc ~pos:posBeforeCursor
== HasCursor ->
searchForArgWithCursor ~isPipeExpr:true ~args ~exp
let argAtCursor, extractedArgs =
searchForArgWithCursor ~isPipeExpr:true ~args
in
setFound (argAtCursor, exp, extractedArgs)
(* Look for applying idents, like someIdent(...) *)
| {
pexp_desc = Pexp_apply (({pexp_desc = Pexp_ident _} as exp), args);
@@ -278,7 +290,10 @@ let signatureHelp ~path ~pos ~currentFile ~debug =
when pexp_loc
|> CursorPosition.classifyLoc ~pos:posBeforeCursor
== HasCursor ->
searchForArgWithCursor ~isPipeExpr:false ~args ~exp
let argAtCursor, extractedArgs =
searchForArgWithCursor ~isPipeExpr:false ~args
in
setFound (argAtCursor, exp, extractedArgs)
| _ -> ());
Ast_iterator.default_iterator.expr iterator expr
in
6 changes: 6 additions & 0 deletions analysis/tests/src/SignatureHelp.res
Original file line number Diff line number Diff line change
@@ -68,3 +68,9 @@ let fn = (age: int, name: string, year: int) => {

// let _ = fn(12, "hello", )
// ^she

// let _ = fn({ iAmSoSpecial() })
// ^she

// let _ = fn({ iAmSoSpecial({ someFunc() }) })
// ^she
42 changes: 42 additions & 0 deletions analysis/tests/src/expected/SignatureHelp.res.txt
Original file line number Diff line number Diff line change
@@ -266,3 +266,45 @@ extracted params:
"activeParameter": 2
}

Signature help src/SignatureHelp.res 71:29
posCursor:[71:28] posNoWhite:[71:27] Found expr:[71:11->71:33]
Pexp_apply ...[71:11->71:13] (...[71:16->71:30])
posCursor:[71:28] posNoWhite:[71:27] Found expr:[71:16->71:30]
Pexp_apply ...[71:16->71:28] (...[71:29->71:30])
posCursor:[71:28] posNoWhite:[71:27] Found expr:[71:16->71:28]
Pexp_ident iAmSoSpecial:[71:16->71:28]
argAtCursor: unlabelled<0>
extracted params:
[string]
{
"signatures": [{
"label": "string => unit",
"parameters": [{"label": [0, 6], "documentation": {"kind": "markdown", "value": "```rescript\nstring\n```"}}]
}],
"activeSignature": 0,
"activeParameter": 0
}

Signature help src/SignatureHelp.res 74:40
posCursor:[74:39] posNoWhite:[74:38] Found expr:[74:11->74:47]
Pexp_apply ...[74:11->74:13] (...[74:16->74:44])
posCursor:[74:39] posNoWhite:[74:38] Found expr:[74:16->74:44]
Pexp_apply ...[74:16->74:28] (...[74:31->74:41])
posCursor:[74:39] posNoWhite:[74:38] Found expr:[74:31->74:41]
Pexp_apply ...[74:31->74:39] (...[74:40->74:41])
posCursor:[74:39] posNoWhite:[74:38] Found expr:[74:31->74:39]
Pexp_ident someFunc:[74:31->74:39]
argAtCursor: unlabelled<0>
extracted params:
[(
int, ~two: string=?, ~three: unit => unit, ~four: someVariant, unit]
{
"signatures": [{
"label": "(\n int,\n ~two: string=?,\n ~three: unit => unit,\n ~four: someVariant,\n unit,\n) => unit",
"parameters": [{"label": [0, 7], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}, {"label": [11, 25], "documentation": {"kind": "markdown", "value": "```rescript\noption<string>\n```"}}, {"label": [29, 49], "documentation": {"kind": "markdown", "value": ""}}, {"label": [53, 71], "documentation": {"kind": "markdown", "value": "```rescript\nsomeVariant\n```\n```rescript\ntype someVariant = One | Two | Three\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22SignatureHelp.res%22%2C0%2C0%5D)"}}, {"label": [75, 79], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}],
"documentation": {"kind": "markdown", "value": " Does stuff. "}
}],
"activeSignature": 0,
"activeParameter": 0
}