From 0a7fb4eacd351d6462550502b5e95ce8e0575a1b Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 14 Mar 2024 10:48:05 +0100 Subject: [PATCH 1/3] make sure doc strings are always on top in hovers --- CHANGELOG.md | 4 ++++ analysis/src/Hover.ml | 13 +++++++------ analysis/tests/src/Hover.res | 5 ++++- .../tests/src/expected/Definition.res.txt | 2 +- .../tests/src/expected/DocComments.res.txt | 10 +++++----- analysis/tests/src/expected/Hover.res.txt | 19 +++++++++++-------- analysis/tests/src/expected/JsxV4.res.txt | 2 +- 7 files changed, 33 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eebb8eccc..f3146d26e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ ## master +#### :nail_care: Polish + +- Make sure doc strings are always on top in hovers. + ## 1.50.0 #### :rocket: New Feature diff --git a/analysis/src/Hover.ml b/analysis/src/Hover.ml index f26881b5c..6fb6661fa 100644 --- a/analysis/src/Hover.ml +++ b/analysis/src/Hover.ml @@ -133,9 +133,10 @@ let getHoverViaCompletions ~debug ~path ~pos ~currentFile ~forHover match completions with | {kind = Label typString; docstring} :: _ -> let parts = - (if typString = "" then [] else [Markdown.codeBlock typString]) - @ docstring + docstring + @ if typString = "" then [] else [Markdown.codeBlock typString] in + Some (Protocol.stringifyHover (String.concat "\n\n" parts)) | {kind = Field _; env; docstring} :: _ -> ( let opens = CompletionBackEnd.getOpens ~debug ~rawOpens ~package ~env in @@ -147,7 +148,7 @@ let getHoverViaCompletions ~debug ~path ~pos ~currentFile ~forHover let typeString = hoverWithExpandedTypes ~file ~package ~supportsMarkdownLinks typ in - let parts = typeString :: docstring in + let parts = docstring @ [typeString] in Some (Protocol.stringifyHover (String.concat "\n\n" parts)) | None -> None) | {env} :: _ -> ( @@ -236,12 +237,12 @@ let newHover ~full:{file; package} ~supportsMarkdownLinks locItem = match References.definedForLoc ~file ~package locKind with | None -> let typeString, docstring = t |> fromType ~docstring:[] in - typeString :: docstring + docstring @ [typeString] | Some (docstring, res) -> ( match res with | `Declared -> let typeString, docstring = t |> fromType ~docstring in - typeString :: docstring + docstring @ [typeString] | `Constructor {cname = {txt}; args; docstring} -> let typeString, docstring = t |> fromType ~docstring in let argsString = @@ -255,6 +256,6 @@ let newHover ~full:{file; package} ~supportsMarkdownLinks locItem = (Markdown.codeBlock (txt ^ argsString) :: docstring) @ [typeString] | `Field -> let typeString, docstring = t |> fromType ~docstring in - typeString :: docstring) + docstring @ [typeString]) in Some (String.concat "\n\n" parts) diff --git a/analysis/tests/src/Hover.res b/analysis/tests/src/Hover.res index 704946272..3d7555dd2 100644 --- a/analysis/tests/src/Hover.res +++ b/analysis/tests/src/Hover.res @@ -265,4 +265,7 @@ module Arr = Belt.Array // ^hov type aliased = variant -// ^hov \ No newline at end of file +// ^hov + +let _xx = Belt.Array.slice([1], ~offset=0, ~len=2) +// ^hov \ No newline at end of file diff --git a/analysis/tests/src/expected/Definition.res.txt b/analysis/tests/src/expected/Definition.res.txt index 4d8ab2721..83b89b121 100644 --- a/analysis/tests/src/expected/Definition.res.txt +++ b/analysis/tests/src/expected/Definition.res.txt @@ -5,7 +5,7 @@ Definition src/Definition.res 10:23 {"uri": "Definition.res", "range": {"start": {"line": 6, "character": 7}, "end": {"line": 6, "character": 13}}} Hover src/Definition.res 14:14 -{"contents": {"kind": "markdown", "value": "```rescript\n('a => 'b, list<'a>) => list<'b>\n```\n\n [List.map f [a1; ...; an]] applies function [f] to [a1, ..., an],\n and builds the list [[f a1; ...; f an]]\n with the results returned by [f]. Not tail-recursive. "}} +{"contents": {"kind": "markdown", "value": " [List.map f [a1; ...; an]] applies function [f] to [a1, ..., an],\n and builds the list [[f a1; ...; f an]]\n with the results returned by [f]. Not tail-recursive. \n\n```rescript\n('a => 'b, list<'a>) => list<'b>\n```"}} Hover src/Definition.res 18:14 {"contents": {"kind": "markdown", "value": "```rescript\n(list<'a>, 'a => 'b) => list<'b>\n```"}} diff --git a/analysis/tests/src/expected/DocComments.res.txt b/analysis/tests/src/expected/DocComments.res.txt index 2342210b2..434f340ff 100644 --- a/analysis/tests/src/expected/DocComments.res.txt +++ b/analysis/tests/src/expected/DocComments.res.txt @@ -1,15 +1,15 @@ Hover src/DocComments.res 9:9 -{"contents": {"kind": "markdown", "value": "```rescript\nint\n```\n\n Doc comment with a triple-backquote example\\n \\n ```res example\\n let a = 10\\n /*\\n * stuff\\n */\\n ```\\n"}} +{"contents": {"kind": "markdown", "value": " Doc comment with a triple-backquote example\\n \\n ```res example\\n let a = 10\\n /*\\n * stuff\\n */\\n ```\\n\n\n```rescript\nint\n```"}} Hover src/DocComments.res 22:6 -{"contents": {"kind": "markdown", "value": "```rescript\nint\n```\n\n\n Doc comment with a triple-backquote example\n \n ```res example\n let a = 10\n /*\n * stuff\n */\n ```\n"}} +{"contents": {"kind": "markdown", "value": "\n Doc comment with a triple-backquote example\n \n ```res example\n let a = 10\n /*\n * stuff\n */\n ```\n\n\n```rescript\nint\n```"}} Hover src/DocComments.res 33:9 -{"contents": {"kind": "markdown", "value": "```rescript\nint\n```\n\n Doc comment with a triple-backquote example\\n \\n ```res example\\n let a = 10\\n let b = 20\\n ```\\n"}} +{"contents": {"kind": "markdown", "value": " Doc comment with a triple-backquote example\\n \\n ```res example\\n let a = 10\\n let b = 20\\n ```\\n\n\n```rescript\nint\n```"}} Hover src/DocComments.res 44:6 -{"contents": {"kind": "markdown", "value": "```rescript\nint\n```\n\n\n Doc comment with a triple-backquote example\n \n ```res example\n let a = 10\n let b = 20\n ```\n"}} +{"contents": {"kind": "markdown", "value": "\n Doc comment with a triple-backquote example\n \n ```res example\n let a = 10\n let b = 20\n ```\n\n\n```rescript\nint\n```"}} Hover src/DocComments.res 48:5 -{"contents": {"kind": "markdown", "value": "```rescript\nint\n```\n\nNew doc comment format"}} +{"contents": {"kind": "markdown", "value": "New doc comment format\n\n```rescript\nint\n```"}} diff --git a/analysis/tests/src/expected/Hover.res.txt b/analysis/tests/src/expected/Hover.res.txt index 5f3fbcd02..7989229db 100644 --- a/analysis/tests/src/expected/Hover.res.txt +++ b/analysis/tests/src/expected/Hover.res.txt @@ -11,7 +11,7 @@ Hover src/Hover.res 19:11 {"contents": {"kind": "markdown", "value": "\nThis module is commented\n```rescript\nmodule Dep: {\n let customDouble: int => int\n}\n```"}} Hover src/Hover.res 22:11 -{"contents": {"kind": "markdown", "value": "```rescript\nint => int\n```\n\nSome doc comment"}} +{"contents": {"kind": "markdown", "value": "Some doc comment\n\n```rescript\nint => int\n```"}} Hover src/Hover.res 26:6 getLocItem #8: heuristic for JSX with at most one child @@ -19,7 +19,7 @@ heuristic for: [makeProps, make, createElement], give the loc of `make` {"contents": {"kind": "markdown", "value": "```rescript\nint\n```"}} Hover src/Hover.res 33:4 -{"contents": {"kind": "markdown", "value": "```rescript\nunit => int\n```\n\nDoc comment for functionWithTypeAnnotation"}} +{"contents": {"kind": "markdown", "value": "Doc comment for functionWithTypeAnnotation\n\n```rescript\nunit => int\n```"}} Hover src/Hover.res 37:13 getLocItem #5: heuristic for JSX and compiler combined: @@ -103,10 +103,10 @@ Hover src/Hover.res 137:5 {"contents": {"kind": "markdown", "value": "```rescript\nunit => unit => int\n```"}} Hover src/Hover.res 144:9 -{"contents": {"kind": "markdown", "value": "```rescript\nint\n```\n\ndoc comment 1"}} +{"contents": {"kind": "markdown", "value": "doc comment 1\n\n```rescript\nint\n```"}} Hover src/Hover.res 148:6 -{"contents": {"kind": "markdown", "value": "```rescript\nint\n```\n\n doc comment 2 "}} +{"contents": {"kind": "markdown", "value": " doc comment 2 \n\n```rescript\nint\n```"}} Hover src/Hover.res 165:23 {"contents": {"kind": "markdown", "value": "```rescript\nfoo\n```\n\n---\n\n```\n \n```\n```rescript\ntype foo<'a> = {content: 'a, zzz: string}\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22Hover.res%22%2C161%2C2%5D)\n\n\n---\n\n```\n \n```\n```rescript\ntype bar = {age: int}\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22Hover.res%22%2C162%2C2%5D)\n"}} @@ -206,10 +206,10 @@ Resolved opens 1 pervasives {"contents": {"kind": "markdown", "value": "```rescript\nuseR\n```\n\n---\n\n```\n \n```\n```rescript\ntype useR = {x: int, y: list>>}\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22Hover.res%22%2C200%2C0%5D)\n\n\n---\n\n```\n \n```\n```rescript\ntype r<'a> = {i: 'a, f: float}\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22Hover.res%22%2C101%2C0%5D)\n"}} Hover src/Hover.res 230:20 -{"contents": {"kind": "markdown", "value": "```rescript\nint\n```\n\n More Stuff "}} +{"contents": {"kind": "markdown", "value": " More Stuff \n\n```rescript\nint\n```"}} Hover src/Hover.res 233:17 -{"contents": {"kind": "markdown", "value": "```rescript\nint\n```\n\n More Stuff "}} +{"contents": {"kind": "markdown", "value": " More Stuff \n\n```rescript\nint\n```"}} Hover src/Hover.res 245:6 Nothing at that position. Now trying to use completion. @@ -223,10 +223,10 @@ ContextPath Value[x] Path x Package opens Pervasives.JsxModules.place holder Resolved opens 1 pervasives -{"contents": {"kind": "markdown", "value": "```rescript\nbool\n```\n\n Mighty fine field here. "}} +{"contents": {"kind": "markdown", "value": " Mighty fine field here. \n\n```rescript\nbool\n```"}} Hover src/Hover.res 248:19 -{"contents": {"kind": "markdown", "value": "```rescript\nbool\n```\n\n Mighty fine field here. "}} +{"contents": {"kind": "markdown", "value": " Mighty fine field here. \n\n```rescript\nbool\n```"}} Hover src/Hover.res 253:20 {"contents": {"kind": "markdown", "value": "```rescript\nCoolVariant\n```\n\n Cool variant! \n\n```rescript\nvariant\n```\n\n---\n\n```\n \n```\n```rescript\ntype variant = CoolVariant | OtherCoolVariant\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22Hover.res%22%2C251%2C0%5D)\n"}} @@ -267,3 +267,6 @@ Hover src/Hover.res 263:8 Hover src/Hover.res 266:6 {"contents": {"kind": "markdown", "value": "```rescript\ntype aliased = variant\n```\n\n---\n\n```\n \n```\n```rescript\ntype variant = CoolVariant | OtherCoolVariant\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22Hover.res%22%2C251%2C0%5D)\n"}} +Hover src/Hover.res 269:22 +{"contents": {"kind": "markdown", "value": "\n`slice(xs, offset, len)` creates a new array with the len elements of `xs`\nstarting at `offset` for `offset` can be negative;and is evaluated as\n`length(xs) - offset(slice, xs) - 1(1)` means get the last element as a\nsingleton array `slice(xs, ~-len, len)` will return a copy of the array if the\narray does not have enough data; `slice` extracts through the end of sequence.\n\nif `len` is negative; returns the empty array.\n\n## Examples\n\n```rescript\nBelt.Array.slice([10, 11, 12, 13, 14, 15, 16], ~offset=2, ~len=3) == [12, 13, 14]\n\nBelt.Array.slice([10, 11, 12, 13, 14, 15, 16], ~offset=-4, ~len=3) == [13, 14, 15]\n\nBelt.Array.slice([10, 11, 12, 13, 14, 15, 16], ~offset=4, ~len=9) == [14, 15, 16]\n```\n\n\n```rescript\n(\n Belt.Array.t,\n ~offset: int,\n ~len: int,\n) => Belt.Array.t\n```\n\n---\n\n```\n \n```\n```rescript\ntype Belt.Array.t<'a> = array<'a>\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22belt_Array.resi%22%2C27%2C0%5D)\n"}} + diff --git a/analysis/tests/src/expected/JsxV4.res.txt b/analysis/tests/src/expected/JsxV4.res.txt index 9c9bb9d37..ce2c9ffba 100644 --- a/analysis/tests/src/expected/JsxV4.res.txt +++ b/analysis/tests/src/expected/JsxV4.res.txt @@ -17,7 +17,7 @@ Path M4.make }] Hover src/JsxV4.res 14:9 -{"contents": {"kind": "markdown", "value": "```rescript\nReact.component>\n```\n\n---\n\n```\n \n```\n```rescript\ntype React.component<'props> = Jsx.component<'props>\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22React.res%22%2C12%2C0%5D)\n\n\n---\n\n```\n \n```\n```rescript\ntype M4.props<'first, 'fun, 'second> = {\n first: 'first,\n fun?: 'fun,\n second?: 'second,\n}\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22JsxV4.res%22%2C3%2C2%5D)\n\n\n Doc Comment For M4 "}} +{"contents": {"kind": "markdown", "value": " Doc Comment For M4 \n\n```rescript\nReact.component>\n```\n\n---\n\n```\n \n```\n```rescript\ntype React.component<'props> = Jsx.component<'props>\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22React.res%22%2C12%2C0%5D)\n\n\n---\n\n```\n \n```\n```rescript\ntype M4.props<'first, 'fun, 'second> = {\n first: 'first,\n fun?: 'fun,\n second?: 'second,\n}\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22JsxV4.res%22%2C3%2C2%5D)\n"}} Create Interface src/JsxV4.res module M4: { From 9e13e31eb2437f6a44e79e27ea6fc9cf9694159b Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 14 Mar 2024 10:48:52 +0100 Subject: [PATCH 2/3] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3146d26e..7fd7a16b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ #### :nail_care: Polish -- Make sure doc strings are always on top in hovers. +- Make sure doc strings are always on top in hovers. https://github.com/rescript-lang/rescript-vscode/pull/956 ## 1.50.0 From fefccdb3e5cfd9cf80af4cee93131f97cfb4bafb Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 14 Mar 2024 10:55:19 +0100 Subject: [PATCH 3/3] remove flaky test --- analysis/tests/src/Hover.res | 3 --- analysis/tests/src/expected/Hover.res.txt | 3 --- 2 files changed, 6 deletions(-) diff --git a/analysis/tests/src/Hover.res b/analysis/tests/src/Hover.res index 3d7555dd2..e038a2490 100644 --- a/analysis/tests/src/Hover.res +++ b/analysis/tests/src/Hover.res @@ -266,6 +266,3 @@ module Arr = Belt.Array type aliased = variant // ^hov - -let _xx = Belt.Array.slice([1], ~offset=0, ~len=2) -// ^hov \ No newline at end of file diff --git a/analysis/tests/src/expected/Hover.res.txt b/analysis/tests/src/expected/Hover.res.txt index 7989229db..db72b3799 100644 --- a/analysis/tests/src/expected/Hover.res.txt +++ b/analysis/tests/src/expected/Hover.res.txt @@ -267,6 +267,3 @@ Hover src/Hover.res 263:8 Hover src/Hover.res 266:6 {"contents": {"kind": "markdown", "value": "```rescript\ntype aliased = variant\n```\n\n---\n\n```\n \n```\n```rescript\ntype variant = CoolVariant | OtherCoolVariant\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22Hover.res%22%2C251%2C0%5D)\n"}} -Hover src/Hover.res 269:22 -{"contents": {"kind": "markdown", "value": "\n`slice(xs, offset, len)` creates a new array with the len elements of `xs`\nstarting at `offset` for `offset` can be negative;and is evaluated as\n`length(xs) - offset(slice, xs) - 1(1)` means get the last element as a\nsingleton array `slice(xs, ~-len, len)` will return a copy of the array if the\narray does not have enough data; `slice` extracts through the end of sequence.\n\nif `len` is negative; returns the empty array.\n\n## Examples\n\n```rescript\nBelt.Array.slice([10, 11, 12, 13, 14, 15, 16], ~offset=2, ~len=3) == [12, 13, 14]\n\nBelt.Array.slice([10, 11, 12, 13, 14, 15, 16], ~offset=-4, ~len=3) == [13, 14, 15]\n\nBelt.Array.slice([10, 11, 12, 13, 14, 15, 16], ~offset=4, ~len=9) == [14, 15, 16]\n```\n\n\n```rescript\n(\n Belt.Array.t,\n ~offset: int,\n ~len: int,\n) => Belt.Array.t\n```\n\n---\n\n```\n \n```\n```rescript\ntype Belt.Array.t<'a> = array<'a>\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22belt_Array.resi%22%2C27%2C0%5D)\n"}} -