diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ecb4dc38..f4ea7469f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - Enhance variant constructor payload completion. https://github.com/rescript-lang/rescript-vscode/pull/946 - Clean occasional dots from "insert missing fields" code action. https://github.com/rescript-lang/rescript-vscode/pull/948 - Pick up code actions in incremental compilation. https://github.com/rescript-lang/rescript-vscode/pull/948 +- Various improvements to the signature help functionality. https://github.com/rescript-lang/rescript-vscode/pull/950 ## 1.48.0 diff --git a/analysis/src/SignatureHelp.ml b/analysis/src/SignatureHelp.ml index 881c4f6f7..b717a5192 100644 --- a/analysis/src/SignatureHelp.ml +++ b/analysis/src/SignatureHelp.ml @@ -1,39 +1,105 @@ open SharedTypes type cursorAtArg = Unlabelled of int | Labelled of string -let findFunctionType ~currentFile ~debug ~path ~pos = - let completables = - let textOpt = Files.readFile currentFile in - match textOpt with - | None | Some "" -> None - | Some text -> ( - (* Leverage the completion functionality to pull out the type of the identifier doing the function application. - This lets us leverage all of the smart work done in completions to find the correct type in many cases even - for files not saved yet. *) - match - CompletionFrontEnd.completionWithParser ~debug ~path ~posCursor:pos - ~currentFile ~text - with - | None -> None - | Some (completable, scope) -> ( - match Cmt.loadFullCmtFromPath ~path with - | None -> None - | Some full -> - let {file; package} = full in - let env = QueryEnv.fromFile file in - Some - ( completable - |> CompletionBackEnd.processCompletable ~debug ~full ~pos ~scope - ~env ~forHover:true, - env, - package, - file ))) +(* Produces the doc string shown below the signature help for each parameter. *) +let docsForLabel typeExpr ~file ~package ~supportsMarkdownLinks = + let types = Hover.findRelevantTypesFromType ~file ~package typeExpr in + let typeNames = types |> List.map (fun {Hover.name} -> name) in + let typeDefinitions = + types + |> List.map (fun {Hover.decl; name; env; loc; path} -> + let linkToTypeDefinitionStr = + if supportsMarkdownLinks then + Markdown.goToDefinitionText ~env ~pos:loc.Warnings.loc_start + else "" + in + (* Since printing the whole name via its path can get quite long, and + we're short on space for the signature help, we'll only print the + fully "qualified" type name if we must (ie if several types we're + displaying have the same name). *) + let multipleTypesHaveThisName = + typeNames + |> List.filter (fun typeName -> typeName = name) + |> List.length > 1 + in + let typeName = + if multipleTypesHaveThisName then + path |> SharedTypes.pathIdentToString + else name + in + Markdown.codeBlock + (Shared.declToString ~printNameAsIs:true typeName decl) + ^ linkToTypeDefinitionStr) in - match completables with - | Some ({kind = Value type_expr; docstring} :: _, env, package, file) -> - let args, _ = TypeUtils.extractFunctionType type_expr ~env ~package in - Some (args, docstring, type_expr, package, env, file) - | _ -> None + typeDefinitions |> String.concat "\n" + +let findFunctionType ~currentFile ~debug ~path ~pos = + (* Start by looking at the typed info at the loc of the fn *) + match Cmt.loadFullCmtFromPath ~path with + | None -> None + | Some full -> ( + let {file; package} = full in + let env = QueryEnv.fromFile file in + let fnFromLocItem = + match References.getLocItem ~full ~pos ~debug:false with + | Some {locType = Typed (_, typeExpr, locKind)} -> ( + let docstring = + match References.definedForLoc ~file ~package locKind with + | None -> [] + | Some (docstring, _) -> docstring + in + if Debug.verbose () then + Printf.printf "[sig_help_fn] Found loc item: %s.\n" + (Shared.typeToString typeExpr); + match + TypeUtils.extractFunctionType2 ~env ~package:full.package typeExpr + with + | args, _tRet, _ when args <> [] -> + Some (args, docstring, typeExpr, package, env, file) + | _ -> None) + | None -> + if Debug.verbose () then + Printf.printf "[sig_help_fn] Found no loc item.\n"; + None + | Some _ -> + if Debug.verbose () then + Printf.printf + "[sig_help_fn] Found loc item, but not what was expected.\n"; + None + in + match fnFromLocItem with + | Some fnFromLocItem -> Some fnFromLocItem + | None -> ( + (* If nothing was found there, try using the unsaved completion engine *) + let completables = + let textOpt = Files.readFile currentFile in + match textOpt with + | None | Some "" -> None + | Some text -> ( + (* Leverage the completion functionality to pull out the type of the identifier doing the function application. + This lets us leverage all of the smart work done in completions to find the correct type in many cases even + for files not saved yet. *) + match + CompletionFrontEnd.completionWithParser ~debug ~path ~posCursor:pos + ~currentFile ~text + with + | None -> None + | Some (completable, scope) -> + Some + ( completable + |> CompletionBackEnd.processCompletable ~debug ~full ~pos ~scope + ~env ~forHover:true, + env, + package, + file )) + in + match completables with + | Some ({kind = Value type_expr; docstring} :: _, env, package, file) -> + let args, _, _ = + TypeUtils.extractFunctionType2 type_expr ~env ~package + in + Some (args, docstring, type_expr, package, env, file) + | _ -> None)) (* Extracts all parameters from a parsed function signature *) let extractParameters ~signature ~typeStrForParser ~labelPrefixLen = @@ -126,52 +192,6 @@ let findActiveParameter ~argAtCursor ~args = index := !index + 1; None) -let shouldPrintMainTypeStr typ ~env ~package = - match typ |> Shared.digConstructor with - | Some path -> ( - match References.digConstructor ~env ~package path with - | Some (_, {item = {kind = Record _}}) -> false - | _ -> true) - | _ -> false - -(* Produces the doc string shown below the signature help for each parameter. *) -let docsForLabel typeExpr ~file ~package ~supportsMarkdownLinks = - let env = QueryEnv.fromFile file in - let types = Hover.findRelevantTypesFromType ~file ~package typeExpr in - let typeString = - if shouldPrintMainTypeStr typeExpr ~env ~package then - Markdown.codeBlock (typeExpr |> Shared.typeToString) - else "" - in - let typeNames = types |> List.map (fun {Hover.name} -> name) in - let typeDefinitions = - types - |> List.map (fun {Hover.decl; name; env; loc; path} -> - let linkToTypeDefinitionStr = - if supportsMarkdownLinks then - Markdown.goToDefinitionText ~env ~pos:loc.Warnings.loc_start - else "" - in - (* Since printing the whole name via its path can get quite long, and - we're short on space for the signature help, we'll only print the - fully "qualified" type name if we must (ie if several types we're - displaying have the same name). *) - let multipleTypesHaveThisName = - typeNames - |> List.filter (fun typeName -> typeName = name) - |> List.length > 1 - in - let typeName = - if multipleTypesHaveThisName then - path |> SharedTypes.pathIdentToString - else name - in - Markdown.codeBlock - (Shared.declToString ~printNameAsIs:true typeName decl) - ^ linkToTypeDefinitionStr) - in - typeString :: typeDefinitions |> String.concat "\n" - let findConstructorArgs ~full ~env ~constructorName loc = match References.getLocItem ~debug:false ~full @@ -206,26 +226,37 @@ let signatureHelp ~path ~pos ~currentFile ~debug ~allowForConstructorPayloads = loc |> CursorPosition.locHasCursor ~pos:posBeforeCursor in let supportsMarkdownLinks = true in - let foundFunctionApplicationExpr = ref None in - let foundConstructorExpr = ref None in - let setFoundConstructor r = - if allowForConstructorPayloads then - match !foundConstructorExpr with - | None -> foundConstructorExpr := Some r - | Some _ -> () + let result = ref None in + let printThing thg = + match thg with + | `Constructor _ -> "Constructor" + | `FunctionCall _ -> "FunctionCall" in - let setFound r = - (* 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 _, _ -> () + let setResult (loc, thing) = + match (thing, allowForConstructorPayloads) with + | `Constructor _, false -> () + | _ -> ( + match !result with + | None -> + if Debug.verbose () then + Printf.printf "[sig_help_result] Setting because had none\n"; + result := Some (loc, thing) + | Some (currentLoc, currentThing) + when Pos.ofLexing loc.Location.loc_start + > Pos.ofLexing currentLoc.Location.loc_start -> + result := Some (loc, thing); + + if Debug.verbose () then + Printf.printf + "[sig_help_result] Setting because loc of %s > then existing \ + of %s\n" + (printThing thing) (printThing currentThing) + | Some (_, currentThing) -> + if Debug.verbose () then + Printf.printf + "[sig_help_result] Doing nothing because loc of %s < then \ + existing of %s\n" + (printThing thing) (printThing currentThing)) in let searchForArgWithCursor ~isPipeExpr ~args = let extractedArgs = extractExpApplyArgs ~args in @@ -315,7 +346,8 @@ let signatureHelp ~path ~pos ~currentFile ~debug ~allowForConstructorPayloads = let argAtCursor, extractedArgs = searchForArgWithCursor ~isPipeExpr:true ~args in - setFound (argAtCursor, exp, extractedArgs) + setResult + (exp.pexp_loc, `FunctionCall (argAtCursor, exp, extractedArgs)) (* Look for applying idents, like someIdent(...) *) | { pexp_desc = Pexp_apply (({pexp_desc = Pexp_ident _} as exp), args); @@ -325,13 +357,14 @@ let signatureHelp ~path ~pos ~currentFile ~debug ~allowForConstructorPayloads = let argAtCursor, extractedArgs = searchForArgWithCursor ~isPipeExpr:false ~args in - setFound (argAtCursor, exp, extractedArgs) + setResult + (exp.pexp_loc, `FunctionCall (argAtCursor, exp, extractedArgs)) | {pexp_desc = Pexp_construct (lid, Some payloadExp); pexp_loc} when locHasCursor payloadExp.pexp_loc || CompletionExpressions.isExprHole payloadExp && locHasCursor pexp_loc -> (* Constructor payloads *) - setFoundConstructor (lid, payloadExp) + setResult (lid.loc, `Constructor (lid, payloadExp)) | _ -> ()); Ast_iterator.default_iterator.expr iterator expr in @@ -342,8 +375,8 @@ let signatureHelp ~path ~pos ~currentFile ~debug ~allowForConstructorPayloads = let {Res_driver.parsetree = structure} = parser ~filename:currentFile in iterator.structure iterator structure |> ignore; (* Handle function application, if found *) - match !foundFunctionApplicationExpr with - | Some (argAtCursor, exp, _extractedArgs) -> ( + match !result with + | Some (_, `FunctionCall (argAtCursor, exp, _extractedArgs)) -> ( (* Not looking for the cursor position after this, but rather the target function expression's loc. *) let pos = exp.pexp_loc |> Loc.end_ in match findFunctionType ~currentFile ~debug ~path ~pos with @@ -382,6 +415,8 @@ let signatureHelp ~path ~pos ~currentFile ~debug ~allowForConstructorPayloads = (* Figure out the active parameter *) let activeParameter = findActiveParameter ~argAtCursor ~args in + + let paramUnlabelledArgCount = ref 0 in Some { Protocol.signatures = @@ -391,16 +426,32 @@ let signatureHelp ~path ~pos ~currentFile ~debug ~allowForConstructorPayloads = parameters = parameters |> List.map (fun (argLabel, start, end_) -> + let paramArgCount = !paramUnlabelledArgCount in + paramUnlabelledArgCount := paramArgCount + 1; + let unlabelledArgCount = ref 0 in { Protocol.label = (start, end_); documentation = (match args |> List.find_opt (fun (lbl, _) -> - lbl = argLabel) + let argCount = !unlabelledArgCount in + unlabelledArgCount := argCount + 1; + match (lbl, argLabel) with + | ( Asttypes.Optional l1, + Asttypes.Optional l2 ) + when l1 = l2 -> + true + | Labelled l1, Labelled l2 + when l1 = l2 -> + true + | Nolabel, Nolabel + when paramArgCount = argCount -> + true + | _ -> false) with | None -> - {Protocol.kind = "markdown"; value = "Nope"} + {Protocol.kind = "markdown"; value = ""} | Some (_, labelTypExpr) -> { Protocol.kind = "markdown"; @@ -423,200 +474,195 @@ let signatureHelp ~path ~pos ~currentFile ~debug ~allowForConstructorPayloads = | activeParameter -> activeParameter); } | _ -> None) - | None -> ( - (* Handle constructor payload if we had no function application *) - match !foundConstructorExpr with - | Some (lid, expr) -> ( + | Some (_, `Constructor (lid, expr)) -> ( + if Debug.verbose () then + Printf.printf "[signature_help] Found constructor expr!\n"; + match Cmt.loadFullCmtFromPath ~path with + | None -> if Debug.verbose () then - Printf.printf "[signature_help] Found constructor expr!\n"; - match Cmt.loadFullCmtFromPath ~path with + Printf.printf "[signature_help] Could not load cmt\n"; + None + | Some full -> ( + let {file} = full in + let env = QueryEnv.fromFile file in + let constructorName = Longident.last lid.txt in + match + findConstructorArgs ~full ~env ~constructorName + {lid.loc with loc_start = lid.loc.loc_end} + with | None -> if Debug.verbose () then - Printf.printf "[signature_help] Could not load cmt\n"; + Printf.printf "[signature_help] Did not find constructor '%s'\n" + constructorName; None - | Some full -> ( - let {file} = full in - let env = QueryEnv.fromFile file in - let constructorName = Longident.last lid.txt in - match - findConstructorArgs ~full ~env ~constructorName - {lid.loc with loc_start = lid.loc.loc_end} - with - | None -> - if Debug.verbose () then - Printf.printf "[signature_help] Did not find constructor '%s'\n" - constructorName; - None - | Some constructor -> - let argParts = - match constructor.args with - | Args [] -> None - | InlineRecord fields -> - let offset = ref 0 in - Some - (`InlineRecord - (fields - |> List.map (fun (field : field) -> - let startOffset = !offset in - let argText = - Printf.sprintf "%s%s: %s" field.fname.txt - (if field.optional then "?" else "") - (Shared.typeToString - (if field.optional then - Utils.unwrapIfOption field.typ - else field.typ)) - in - let endOffset = - startOffset + String.length argText - in - offset := endOffset + String.length ", "; - (argText, field, (startOffset, endOffset))))) - | Args [(typ, _)] -> - Some - (`SingleArg - ( typ |> Shared.typeToString, - docsForLabel ~file:full.file ~package:full.package - ~supportsMarkdownLinks typ )) - | Args args -> - let offset = ref 0 in - Some - (`TupleArg - (args - |> List.map (fun (typ, _) -> - let startOffset = !offset in - let argText = typ |> Shared.typeToString in - let endOffset = - startOffset + String.length argText - in - offset := endOffset + String.length ", "; - ( argText, - docsForLabel ~file:full.file - ~package:full.package ~supportsMarkdownLinks - typ, - (startOffset, endOffset) )))) - in - let label = - constructor.cname.txt ^ "(" - ^ (match argParts with - | None -> "" - | Some (`InlineRecord fields) -> - "{" - ^ (fields - |> List.map (fun (argText, _, _) -> argText) - |> String.concat ", ") - ^ "}" - | Some (`SingleArg (arg, _)) -> arg - | Some (`TupleArg items) -> - items + | Some constructor -> + let argParts = + match constructor.args with + | Args [] -> None + | InlineRecord fields -> + let offset = ref 0 in + Some + (`InlineRecord + (fields + |> List.map (fun (field : field) -> + let startOffset = !offset in + let argText = + Printf.sprintf "%s%s: %s" field.fname.txt + (if field.optional then "?" else "") + (Shared.typeToString + (if field.optional then + Utils.unwrapIfOption field.typ + else field.typ)) + in + let endOffset = + startOffset + String.length argText + in + offset := endOffset + String.length ", "; + (argText, field, (startOffset, endOffset))))) + | Args [(typ, _)] -> + Some + (`SingleArg + ( typ |> Shared.typeToString, + docsForLabel ~file:full.file ~package:full.package + ~supportsMarkdownLinks typ )) + | Args args -> + let offset = ref 0 in + Some + (`TupleArg + (args + |> List.map (fun (typ, _) -> + let startOffset = !offset in + let argText = typ |> Shared.typeToString in + let endOffset = + startOffset + String.length argText + in + offset := endOffset + String.length ", "; + ( argText, + docsForLabel ~file:full.file ~package:full.package + ~supportsMarkdownLinks typ, + (startOffset, endOffset) )))) + in + let label = + constructor.cname.txt ^ "(" + ^ (match argParts with + | None -> "" + | Some (`InlineRecord fields) -> + "{" + ^ (fields |> List.map (fun (argText, _, _) -> argText) |> String.concat ", ") - ^ ")" - in - let activeParameter = - match expr with - | {pexp_desc = Pexp_tuple items} -> ( + ^ "}" + | Some (`SingleArg (arg, _)) -> arg + | Some (`TupleArg items) -> + items + |> List.map (fun (argText, _, _) -> argText) + |> String.concat ", ") + ^ ")" + in + let activeParameter = + match expr with + | {pexp_desc = Pexp_tuple items} -> ( + let idx = ref 0 in + let tupleItemWithCursor = + items + |> List.find_map (fun (item : Parsetree.expression) -> + let currentIndex = !idx in + idx := currentIndex + 1; + if locHasCursor item.pexp_loc then Some currentIndex + else None) + in + match tupleItemWithCursor with + | None -> -1 + | Some i -> i) + | {pexp_desc = Pexp_record (fields, _)} -> ( + let fieldNameWithCursor = + fields + |> List.find_map + (fun + (({loc; txt}, expr) : + Longident.t Location.loc * Parsetree.expression) + -> + if + posBeforeCursor >= Pos.ofLexing loc.loc_start + && posBeforeCursor + <= Pos.ofLexing expr.pexp_loc.loc_end + then Some (Longident.last txt) + else None) + in + match (fieldNameWithCursor, argParts) with + | Some fieldName, Some (`InlineRecord fields) -> let idx = ref 0 in - let tupleItemWithCursor = - items - |> List.find_map (fun (item : Parsetree.expression) -> - let currentIndex = !idx in - idx := currentIndex + 1; - if locHasCursor item.pexp_loc then Some currentIndex - else None) - in - match tupleItemWithCursor with - | None -> -1 - | Some i -> i) - | {pexp_desc = Pexp_record (fields, _)} -> ( - let fieldNameWithCursor = - fields - |> List.find_map - (fun - (({loc; txt}, expr) : - Longident.t Location.loc * Parsetree.expression) - -> - if - posBeforeCursor >= Pos.ofLexing loc.loc_start - && posBeforeCursor - <= Pos.ofLexing expr.pexp_loc.loc_end - then Some (Longident.last txt) - else None) - in - match (fieldNameWithCursor, argParts) with - | Some fieldName, Some (`InlineRecord fields) -> - let idx = ref 0 in - let fieldIndex = ref (-1) in - fields - |> List.iter (fun (_, field, _) -> - idx := !idx + 1; - let currentIndex = !idx in - if fieldName = field.fname.txt then - fieldIndex := currentIndex - else ()); - !fieldIndex - | _ -> -1) - | _ when locHasCursor expr.pexp_loc -> 0 - | _ -> -1 - in + let fieldIndex = ref (-1) in + fields + |> List.iter (fun (_, field, _) -> + idx := !idx + 1; + let currentIndex = !idx in + if fieldName = field.fname.txt then + fieldIndex := currentIndex + else ()); + !fieldIndex + | _ -> -1) + | _ when locHasCursor expr.pexp_loc -> 0 + | _ -> -1 + in - let constructorNameLength = String.length constructor.cname.txt in - let params = - match argParts with - | None -> [] - | Some (`SingleArg (_, docstring)) -> + let constructorNameLength = String.length constructor.cname.txt in + let params = + match argParts with + | None -> [] + | Some (`SingleArg (_, docstring)) -> + [ + { + Protocol.label = + (constructorNameLength + 1, String.length label - 1); + documentation = + {Protocol.kind = "markdown"; value = docstring}; + }; + ] + | Some (`InlineRecord fields) -> + (* Account for leading '({' *) + let baseOffset = constructorNameLength + 2 in + { + Protocol.label = (0, 0); + documentation = {Protocol.kind = "markdown"; value = ""}; + } + :: (fields + |> List.map (fun (_, (field : field), (start, end_)) -> + { + Protocol.label = + (baseOffset + start, baseOffset + end_); + documentation = + { + Protocol.kind = "markdown"; + value = field.docstring |> String.concat "\n"; + }; + })) + | Some (`TupleArg items) -> + (* Account for leading '(' *) + let baseOffset = constructorNameLength + 1 in + items + |> List.map (fun (_, docstring, (start, end_)) -> + { + Protocol.label = (baseOffset + start, baseOffset + end_); + documentation = + {Protocol.kind = "markdown"; value = docstring}; + }) + in + Some + { + Protocol.signatures = [ { - Protocol.label = - (constructorNameLength + 1, String.length label - 1); + label; + parameters = params; documentation = - {Protocol.kind = "markdown"; value = docstring}; + (match List.nth_opt constructor.docstring 0 with + | None -> None + | Some docs -> + Some {Protocol.kind = "markdown"; value = docs}); }; - ] - | Some (`InlineRecord fields) -> - (* Account for leading '({' *) - let baseOffset = constructorNameLength + 2 in - { - Protocol.label = (0, 0); - documentation = {Protocol.kind = "markdown"; value = ""}; - } - :: (fields - |> List.map (fun (_, field, (start, end_)) -> - { - Protocol.label = - (baseOffset + start, baseOffset + end_); - documentation = - { - Protocol.kind = "markdown"; - value = field.docstring |> String.concat "\n"; - }; - })) - | Some (`TupleArg items) -> - (* Account for leading '(' *) - let baseOffset = constructorNameLength + 1 in - items - |> List.map (fun (_, docstring, (start, end_)) -> - { - Protocol.label = - (baseOffset + start, baseOffset + end_); - documentation = - {Protocol.kind = "markdown"; value = docstring}; - }) - in - Some - { - Protocol.signatures = - [ - { - label; - parameters = params; - documentation = - (match List.nth_opt constructor.docstring 0 with - | None -> None - | Some docs -> - Some {Protocol.kind = "markdown"; value = docs}); - }; - ]; - activeSignature = Some 0; - activeParameter = Some activeParameter; - })) - | None -> None))) + ]; + activeSignature = Some 0; + activeParameter = Some activeParameter; + })) + | _ -> None)) diff --git a/analysis/tests/src/SignatureHelp.res b/analysis/tests/src/SignatureHelp.res index f7cf8bedd..fadc198bd 100644 --- a/analysis/tests/src/SignatureHelp.res +++ b/analysis/tests/src/SignatureHelp.res @@ -100,3 +100,42 @@ let three = Three("", []) let three2 = Three("", []) // ^she + +let _deepestTakesPrecedence = [12]->Js.Array2.map(v => + if v > 0 { + One({}) + // ^she + } else { + Two("") + } +) + +/** Main docstring here. */ +let map = (arr, mapper) => { + Array.map(mapper, arr) +} + +let _usesCorrectTypeInfo = [12]->map(v => v) +// ^she + +/** Type x... */ +type x = { + age?: int, + name?: string, +} + +/** Type tt! */ +type tt = One + +/** Some stuff */ +let stuffers = (x: x, y: tt) => { + ignore(x) + ignore(y) + "hello" +} + +let _ = stuffers({}, One) +// ^she + +let _ = stuffers({}, One) +// ^she diff --git a/analysis/tests/src/expected/SignatureHelp.res.txt b/analysis/tests/src/expected/SignatureHelp.res.txt index 664affdcb..6d7ea98db 100644 --- a/analysis/tests/src/expected/SignatureHelp.res.txt +++ b/analysis/tests/src/expected/SignatureHelp.res.txt @@ -14,7 +14,7 @@ extracted params: { "signatures": [{ "label": "(\n int,\n ~two: string=?,\n ~three: unit => unit,\n ~four: someVariant,\n unit,\n) => unit", - "parameters": [{"label": [4, 7], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}, {"label": [11, 25], "documentation": {"kind": "markdown", "value": "```rescript\noption\n```"}}, {"label": [29, 49], "documentation": {"kind": "markdown", "value": "```rescript\nunit => unit\n```"}}, {"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```"}}], + "parameters": [{"label": [4, 7], "documentation": {"kind": "markdown", "value": ""}}, {"label": [11, 25], "documentation": {"kind": "markdown", "value": ""}}, {"label": [29, 49], "documentation": {"kind": "markdown", "value": ""}}, {"label": [53, 71], "documentation": {"kind": "markdown", "value": "```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": ""}}], "documentation": {"kind": "markdown", "value": " Does stuff. "} }], "activeSignature": 0, @@ -37,7 +37,7 @@ extracted params: { "signatures": [{ "label": "(\n int,\n ~two: string=?,\n ~three: unit => unit,\n ~four: someVariant,\n unit,\n) => unit", - "parameters": [{"label": [4, 7], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}, {"label": [11, 25], "documentation": {"kind": "markdown", "value": "```rescript\noption\n```"}}, {"label": [29, 49], "documentation": {"kind": "markdown", "value": "```rescript\nunit => unit\n```"}}, {"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```"}}], + "parameters": [{"label": [4, 7], "documentation": {"kind": "markdown", "value": ""}}, {"label": [11, 25], "documentation": {"kind": "markdown", "value": ""}}, {"label": [29, 49], "documentation": {"kind": "markdown", "value": ""}}, {"label": [53, 71], "documentation": {"kind": "markdown", "value": "```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": ""}}], "documentation": {"kind": "markdown", "value": " Does stuff. "} }], "activeSignature": 0, @@ -60,7 +60,7 @@ extracted params: { "signatures": [{ "label": "(\n int,\n ~two: string=?,\n ~three: unit => unit,\n ~four: someVariant,\n unit,\n) => unit", - "parameters": [{"label": [4, 7], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}, {"label": [11, 25], "documentation": {"kind": "markdown", "value": "```rescript\noption\n```"}}, {"label": [29, 49], "documentation": {"kind": "markdown", "value": "```rescript\nunit => unit\n```"}}, {"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```"}}], + "parameters": [{"label": [4, 7], "documentation": {"kind": "markdown", "value": ""}}, {"label": [11, 25], "documentation": {"kind": "markdown", "value": ""}}, {"label": [29, 49], "documentation": {"kind": "markdown", "value": ""}}, {"label": [53, 71], "documentation": {"kind": "markdown", "value": "```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": ""}}], "documentation": {"kind": "markdown", "value": " Does stuff. "} }], "activeSignature": 0, @@ -83,7 +83,7 @@ extracted params: { "signatures": [{ "label": "(\n int,\n ~two: string=?,\n ~three: unit => unit,\n ~four: someVariant,\n unit,\n) => unit", - "parameters": [{"label": [4, 7], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}, {"label": [11, 25], "documentation": {"kind": "markdown", "value": "```rescript\noption\n```"}}, {"label": [29, 49], "documentation": {"kind": "markdown", "value": "```rescript\nunit => unit\n```"}}, {"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```"}}], + "parameters": [{"label": [4, 7], "documentation": {"kind": "markdown", "value": ""}}, {"label": [11, 25], "documentation": {"kind": "markdown", "value": ""}}, {"label": [29, 49], "documentation": {"kind": "markdown", "value": ""}}, {"label": [53, 71], "documentation": {"kind": "markdown", "value": "```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": ""}}], "documentation": {"kind": "markdown", "value": " Does stuff. "} }], "activeSignature": 0, @@ -106,7 +106,7 @@ extracted params: { "signatures": [{ "label": "(\n int,\n ~two: string=?,\n ~three: unit => unit,\n ~four: someVariant,\n unit,\n) => unit", - "parameters": [{"label": [4, 7], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}, {"label": [11, 25], "documentation": {"kind": "markdown", "value": "```rescript\noption\n```"}}, {"label": [29, 49], "documentation": {"kind": "markdown", "value": "```rescript\nunit => unit\n```"}}, {"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```"}}], + "parameters": [{"label": [4, 7], "documentation": {"kind": "markdown", "value": ""}}, {"label": [11, 25], "documentation": {"kind": "markdown", "value": ""}}, {"label": [29, 49], "documentation": {"kind": "markdown", "value": ""}}, {"label": [53, 71], "documentation": {"kind": "markdown", "value": "```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": ""}}], "documentation": {"kind": "markdown", "value": " Does stuff. "} }], "activeSignature": 0, @@ -129,7 +129,7 @@ extracted params: { "signatures": [{ "label": "(\n int,\n ~two: string=?,\n ~three: unit => unit,\n ~four: someVariant,\n unit,\n) => unit", - "parameters": [{"label": [4, 7], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}, {"label": [11, 25], "documentation": {"kind": "markdown", "value": "```rescript\noption\n```"}}, {"label": [29, 49], "documentation": {"kind": "markdown", "value": "```rescript\nunit => unit\n```"}}, {"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```"}}], + "parameters": [{"label": [4, 7], "documentation": {"kind": "markdown", "value": ""}}, {"label": [11, 25], "documentation": {"kind": "markdown", "value": ""}}, {"label": [29, 49], "documentation": {"kind": "markdown", "value": ""}}, {"label": [53, 71], "documentation": {"kind": "markdown", "value": "```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": ""}}], "documentation": {"kind": "markdown", "value": " Does stuff. "} }], "activeSignature": 0, @@ -152,7 +152,7 @@ extracted params: { "signatures": [{ "label": "(string, int, float) => unit", - "parameters": [{"label": [1, 7], "documentation": {"kind": "markdown", "value": "```rescript\nstring\n```"}}, {"label": [9, 12], "documentation": {"kind": "markdown", "value": "```rescript\nstring\n```"}}, {"label": [14, 19], "documentation": {"kind": "markdown", "value": "```rescript\nstring\n```"}}] + "parameters": [{"label": [1, 7], "documentation": {"kind": "markdown", "value": ""}}, {"label": [9, 12], "documentation": {"kind": "markdown", "value": ""}}, {"label": [14, 19], "documentation": {"kind": "markdown", "value": ""}}] }], "activeSignature": 0, "activeParameter": 0 @@ -174,7 +174,7 @@ extracted params: { "signatures": [{ "label": "(string, int, float) => unit", - "parameters": [{"label": [1, 7], "documentation": {"kind": "markdown", "value": "```rescript\nstring\n```"}}, {"label": [9, 12], "documentation": {"kind": "markdown", "value": "```rescript\nstring\n```"}}, {"label": [14, 19], "documentation": {"kind": "markdown", "value": "```rescript\nstring\n```"}}] + "parameters": [{"label": [1, 7], "documentation": {"kind": "markdown", "value": ""}}, {"label": [9, 12], "documentation": {"kind": "markdown", "value": ""}}, {"label": [14, 19], "documentation": {"kind": "markdown", "value": ""}}] }], "activeSignature": 0, "activeParameter": 0 @@ -196,7 +196,7 @@ extracted params: { "signatures": [{ "label": "(string, int, float) => unit", - "parameters": [{"label": [1, 7], "documentation": {"kind": "markdown", "value": "```rescript\nstring\n```"}}, {"label": [9, 12], "documentation": {"kind": "markdown", "value": "```rescript\nstring\n```"}}, {"label": [14, 19], "documentation": {"kind": "markdown", "value": "```rescript\nstring\n```"}}] + "parameters": [{"label": [1, 7], "documentation": {"kind": "markdown", "value": ""}}, {"label": [9, 12], "documentation": {"kind": "markdown", "value": ""}}, {"label": [14, 19], "documentation": {"kind": "markdown", "value": ""}}] }], "activeSignature": 0, "activeParameter": 2 @@ -218,7 +218,7 @@ extracted params: { "signatures": [{ "label": "(~age: int, ~name: string) => string", - "parameters": [{"label": [1, 10], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}, {"label": [12, 25], "documentation": {"kind": "markdown", "value": "```rescript\nstring\n```"}}] + "parameters": [{"label": [1, 10], "documentation": {"kind": "markdown", "value": ""}}, {"label": [12, 25], "documentation": {"kind": "markdown", "value": ""}}] }], "activeSignature": 0, "activeParameter": 0 @@ -240,7 +240,7 @@ extracted params: { "signatures": [{ "label": "string => unit", - "parameters": [{"label": [0, 6], "documentation": {"kind": "markdown", "value": "```rescript\nstring\n```"}}] + "parameters": [{"label": [0, 6], "documentation": {"kind": "markdown", "value": ""}}] }], "activeSignature": 0, "activeParameter": 0 @@ -263,7 +263,7 @@ extracted params: { "signatures": [{ "label": "(string, int, float) => unit", - "parameters": [{"label": [1, 7], "documentation": {"kind": "markdown", "value": "```rescript\nstring\n```"}}, {"label": [9, 12], "documentation": {"kind": "markdown", "value": "```rescript\nstring\n```"}}, {"label": [14, 19], "documentation": {"kind": "markdown", "value": "```rescript\nstring\n```"}}] + "parameters": [{"label": [1, 7], "documentation": {"kind": "markdown", "value": ""}}, {"label": [9, 12], "documentation": {"kind": "markdown", "value": ""}}, {"label": [14, 19], "documentation": {"kind": "markdown", "value": ""}}] }], "activeSignature": 0, "activeParameter": 1 @@ -285,7 +285,7 @@ extracted params: { "signatures": [{ "label": "(int, string, int) => unit", - "parameters": [{"label": [1, 4], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}, {"label": [6, 12], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}, {"label": [14, 17], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}] + "parameters": [{"label": [1, 4], "documentation": {"kind": "markdown", "value": ""}}, {"label": [6, 12], "documentation": {"kind": "markdown", "value": ""}}, {"label": [14, 17], "documentation": {"kind": "markdown", "value": ""}}] }], "activeSignature": 0, "activeParameter": 1 @@ -307,7 +307,7 @@ extracted params: { "signatures": [{ "label": "(int, string, int) => unit", - "parameters": [{"label": [1, 4], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}, {"label": [6, 12], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}, {"label": [14, 17], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}] + "parameters": [{"label": [1, 4], "documentation": {"kind": "markdown", "value": ""}}, {"label": [6, 12], "documentation": {"kind": "markdown", "value": ""}}, {"label": [14, 17], "documentation": {"kind": "markdown", "value": ""}}] }], "activeSignature": 0, "activeParameter": 1 @@ -329,7 +329,7 @@ extracted params: { "signatures": [{ "label": "(int, string, int) => unit", - "parameters": [{"label": [1, 4], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}, {"label": [6, 12], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}, {"label": [14, 17], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}] + "parameters": [{"label": [1, 4], "documentation": {"kind": "markdown", "value": ""}}, {"label": [6, 12], "documentation": {"kind": "markdown", "value": ""}}, {"label": [14, 17], "documentation": {"kind": "markdown", "value": ""}}] }], "activeSignature": 0, "activeParameter": 2 @@ -353,7 +353,7 @@ extracted params: { "signatures": [{ "label": "string => unit", - "parameters": [{"label": [0, 6], "documentation": {"kind": "markdown", "value": "```rescript\nstring\n```"}}] + "parameters": [{"label": [0, 6], "documentation": {"kind": "markdown", "value": ""}}] }], "activeSignature": 0, "activeParameter": 0 @@ -379,7 +379,7 @@ extracted params: { "signatures": [{ "label": "(\n int,\n ~two: string=?,\n ~three: unit => unit,\n ~four: someVariant,\n unit,\n) => unit", - "parameters": [{"label": [4, 7], "documentation": {"kind": "markdown", "value": "```rescript\nint\n```"}}, {"label": [11, 25], "documentation": {"kind": "markdown", "value": "```rescript\noption\n```"}}, {"label": [29, 49], "documentation": {"kind": "markdown", "value": "```rescript\nunit => unit\n```"}}, {"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```"}}], + "parameters": [{"label": [4, 7], "documentation": {"kind": "markdown", "value": ""}}, {"label": [11, 25], "documentation": {"kind": "markdown", "value": ""}}, {"label": [29, 49], "documentation": {"kind": "markdown", "value": ""}}, {"label": [53, 71], "documentation": {"kind": "markdown", "value": "```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": ""}}], "documentation": {"kind": "markdown", "value": " Does stuff. "} }], "activeSignature": 0, @@ -423,7 +423,7 @@ Signature help src/SignatureHelp.res 94:15 { "signatures": [{ "label": "Two(mySpecialThing)", - "parameters": [{"label": [4, 18], "documentation": {"kind": "markdown", "value": "```rescript\nmySpecialThing\n```\n```rescript\ntype mySpecialThing = string\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22SignatureHelp.res%22%2C78%2C0%5D)"}}], + "parameters": [{"label": [4, 18], "documentation": {"kind": "markdown", "value": "```rescript\ntype mySpecialThing = string\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22SignatureHelp.res%22%2C78%2C0%5D)"}}], "documentation": {"kind": "markdown", "value": " Two is fun! "} }], "activeSignature": 0, @@ -434,7 +434,7 @@ Signature help src/SignatureHelp.res 97:19 { "signatures": [{ "label": "Three(mySpecialThing, array>)", - "parameters": [{"label": [6, 20], "documentation": {"kind": "markdown", "value": "```rescript\nmySpecialThing\n```\n```rescript\ntype mySpecialThing = string\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22SignatureHelp.res%22%2C78%2C0%5D)"}}, {"label": [22, 43], "documentation": {"kind": "markdown", "value": "```rescript\narray>\n```"}}], + "parameters": [{"label": [6, 20], "documentation": {"kind": "markdown", "value": "```rescript\ntype mySpecialThing = string\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22SignatureHelp.res%22%2C78%2C0%5D)"}}, {"label": [22, 43], "documentation": {"kind": "markdown", "value": ""}}], "documentation": {"kind": "markdown", "value": " Three is... three "} }], "activeSignature": 0, @@ -445,10 +445,63 @@ Signature help src/SignatureHelp.res 100:24 { "signatures": [{ "label": "Three(mySpecialThing, array>)", - "parameters": [{"label": [6, 20], "documentation": {"kind": "markdown", "value": "```rescript\nmySpecialThing\n```\n```rescript\ntype mySpecialThing = string\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22SignatureHelp.res%22%2C78%2C0%5D)"}}, {"label": [22, 43], "documentation": {"kind": "markdown", "value": "```rescript\narray>\n```"}}], + "parameters": [{"label": [6, 20], "documentation": {"kind": "markdown", "value": "```rescript\ntype mySpecialThing = string\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22SignatureHelp.res%22%2C78%2C0%5D)"}}, {"label": [22, 43], "documentation": {"kind": "markdown", "value": ""}}], "documentation": {"kind": "markdown", "value": " Three is... three "} }], "activeSignature": 0, "activeParameter": 1 } +Signature help src/SignatureHelp.res 105:9 +{ + "signatures": [{ + "label": "One({miss?: bool, hit?: bool, stuff?: string})", + "parameters": [{"label": [0, 0], "documentation": {"kind": "markdown", "value": ""}}, {"label": [5, 16], "documentation": {"kind": "markdown", "value": ""}}, {"label": [18, 28], "documentation": {"kind": "markdown", "value": ""}}, {"label": [30, 44], "documentation": {"kind": "markdown", "value": ""}}], + "documentation": {"kind": "markdown", "value": " One is cool. "} + }], + "activeSignature": 0, + "activeParameter": -1 +} + +Signature help src/SignatureHelp.res 117:42 +argAtCursor: unlabelled<1> +extracted params: +[array, int => int] +{ + "signatures": [{ + "label": "(array, int => int) => array", + "parameters": [{"label": [1, 11], "documentation": {"kind": "markdown", "value": ""}}, {"label": [13, 23], "documentation": {"kind": "markdown", "value": ""}}], + "documentation": {"kind": "markdown", "value": " Main docstring here. "} + }], + "activeSignature": 0, + "activeParameter": 1 +} + +Signature help src/SignatureHelp.res 136:18 +argAtCursor: unlabelled<0> +extracted params: +[x, tt] +{ + "signatures": [{ + "label": "(x, tt) => string", + "parameters": [{"label": [1, 2], "documentation": {"kind": "markdown", "value": "```rescript\ntype x = {age?: int, name?: string}\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22SignatureHelp.res%22%2C121%2C0%5D)"}}, {"label": [4, 6], "documentation": {"kind": "markdown", "value": "```rescript\ntype tt = One\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22SignatureHelp.res%22%2C127%2C0%5D)"}}], + "documentation": {"kind": "markdown", "value": " Some stuff "} + }], + "activeSignature": 0, + "activeParameter": 0 +} + +Signature help src/SignatureHelp.res 139:22 +argAtCursor: unlabelled<1> +extracted params: +[x, tt] +{ + "signatures": [{ + "label": "(x, tt) => string", + "parameters": [{"label": [1, 2], "documentation": {"kind": "markdown", "value": "```rescript\ntype x = {age?: int, name?: string}\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22SignatureHelp.res%22%2C121%2C0%5D)"}}, {"label": [4, 6], "documentation": {"kind": "markdown", "value": "```rescript\ntype tt = One\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22SignatureHelp.res%22%2C127%2C0%5D)"}}], + "documentation": {"kind": "markdown", "value": " Some stuff "} + }], + "activeSignature": 0, + "activeParameter": 1 +} +