Skip to content

Commit 018033f

Browse files
committed
print link to type definition inline next to expanded type
1 parent 7c8b745 commit 018033f

File tree

15 files changed

+89
-81
lines changed

15 files changed

+89
-81
lines changed

analysis/src/Hover.ml

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ let encodeURIComponent text =
2222
loop 0;
2323
Buffer.contents buf
2424

25-
type link = {range: Protocol.range; file: string; label: string}
25+
type link = {startPos: Protocol.position; file: string; label: string}
2626

2727
let linkToCommandArgs link =
28-
Printf.sprintf "[\"%s\",%i,%i,%i,%i]" link.file link.range.start.character
29-
link.range.start.line link.range.end_.character link.range.end_.line
28+
Printf.sprintf "[\"%s\",%i,%i]" link.file link.startPos.line
29+
link.startPos.character
3030

3131
let makeGotoCommand link =
3232
Printf.sprintf "[%s](command:rescript-vscode.go_to_location?%s)" link.label
@@ -131,9 +131,15 @@ let newHover ~full:{file; package} locItem =
131131
let fromConstructorPath ~env path =
132132
match References.digConstructor ~env ~package path with
133133
| None -> None
134-
| Some (_env, {name = {txt}; item = {decl}}) ->
134+
| Some (env, {extentLoc; item = {decl}}) ->
135135
if Utils.isUncurriedInternal path then None
136-
else Some (decl |> Shared.declToString txt |> codeBlock)
136+
else
137+
Some
138+
( decl
139+
|> Shared.declToString ~printNameAsIs:true
140+
(SharedTypes.pathIdentToString path),
141+
extentLoc,
142+
env )
137143
in
138144
let fromType ~docstring typ =
139145
let typeString = codeBlock (typ |> Shared.typeToString) in
@@ -172,40 +178,40 @@ let newHover ~full:{file; package} locItem =
172178
| None -> (env, [typ])
173179
in
174180
let constructors = Shared.findTypeConstructors typesToSearch in
175-
constructors |> List.filter_map (fromConstructorPath ~env:envToSearch)
181+
constructors
182+
|> List.filter_map (fun constructorPath ->
183+
match
184+
constructorPath |> fromConstructorPath ~env:envToSearch
185+
with
186+
| None -> None
187+
| Some (typString, extentLoc, env) ->
188+
let startLine, startCol = Pos.ofLexing extentLoc.loc_start in
189+
Some
190+
(Shared.markdownSpacing ^ codeBlock typString ^ "\n"
191+
^ "Go to: "
192+
^ makeGotoCommand
193+
{
194+
label = "Type definition";
195+
file = Uri.toString env.file.uri;
196+
startPos = {line = startLine; character = startCol};
197+
}
198+
^ "\n\n---\n"))
176199
in
177200
let typeString = typeString :: typeDefinitions |> String.concat "\n\n" in
178-
let links =
179-
"\n---\nGo to: "
180-
^ ([
181-
makeGotoCommand
182-
{
183-
label = "SomeModule";
184-
file =
185-
"file:///Users/zth/git/rescript-vscode-official/analysis/examples/example-project/src/Json.res";
186-
range =
187-
{
188-
start = {character = 0; line = 34};
189-
end_ = {character = 0; line = 42};
190-
};
191-
};
192-
]
193-
|> String.concat " | ")
194-
in
195-
(typeString, docstring, links)
201+
(typeString, docstring)
196202
in
197203
let parts =
198204
match References.definedForLoc ~file ~package locKind with
199205
| None ->
200-
let typeString, docstring, links = t |> fromType ~docstring:[] in
201-
List.concat [[typeString]; docstring; [links]]
206+
let typeString, docstring = t |> fromType ~docstring:[] in
207+
typeString :: docstring
202208
| Some (docstring, res) -> (
203209
match res with
204210
| `Declared ->
205-
let typeString, docstring, links = t |> fromType ~docstring in
206-
List.concat [[typeString]; docstring; [links]]
211+
let typeString, docstring = t |> fromType ~docstring in
212+
typeString :: docstring
207213
| `Constructor {cname = {txt}; args} ->
208-
let typeString, docstring, links = t |> fromType ~docstring in
214+
let typeString, docstring = t |> fromType ~docstring in
209215
let argsString =
210216
match args with
211217
| [] -> ""
@@ -214,10 +220,9 @@ let newHover ~full:{file; package} locItem =
214220
|> List.map (fun (t, _) -> Shared.typeToString t)
215221
|> String.concat ", " |> Printf.sprintf "(%s)"
216222
in
217-
List.concat
218-
[[typeString; codeBlock (txt ^ argsString)]; docstring; [links]]
223+
typeString :: codeBlock (txt ^ argsString) :: docstring
219224
| `Field ->
220-
let typeString, docstring, links = t |> fromType ~docstring in
221-
List.concat [[typeString]; docstring; [links]])
225+
let typeString, docstring = t |> fromType ~docstring in
226+
typeString :: docstring)
222227
in
223228
Some (String.concat "\n\n" parts)

analysis/src/PrintType.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ let printExpr ?(lineWidth = 60) typ =
33
Res_doc.toString ~width:lineWidth
44
(Res_outcome_printer.printOutTypeDoc (Printtyp.tree_of_typexp false typ))
55

6-
let printDecl ~recStatus name decl =
6+
let printDecl ?printNameAsIs ~recStatus name decl =
77
Printtyp.reset_names ();
88
Res_doc.toString ~width:60
9-
(Res_outcome_printer.printOutSigItemDoc
9+
(Res_outcome_printer.printOutSigItemDoc ?printNameAsIs
1010
(Printtyp.tree_of_type_declaration (Ident.create name) decl recStatus))

analysis/src/Shared.ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ let findTypeConstructors (tel : Types.type_expr list) =
6363
tel |> List.iter loop;
6464
!paths |> List.rev
6565

66-
let declToString ?(recStatus = Types.Trec_not) name t =
67-
PrintType.printDecl ~recStatus name t
66+
let declToString ?printNameAsIs ?(recStatus = Types.Trec_not) name t =
67+
PrintType.printDecl ?printNameAsIs ~recStatus name t
6868

6969
let cacheTypeToString = ref false
7070
let typeTbl = Hashtbl.create 1
@@ -78,3 +78,5 @@ let typeToString ?lineWidth (t : Types.type_expr) =
7878
Hashtbl.replace typeTbl (t.id, t) s;
7979
s
8080
| Some s -> s
81+
82+
let markdownSpacing = "\n```\n \n```\n"

analysis/src/SharedTypes.ml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,13 @@ type path = string list
315315

316316
let pathToString (path : path) = path |> String.concat "."
317317

318+
let rec pathIdentToString (p : Path.t) =
319+
match p with
320+
| Pident {name} -> name
321+
| Pdot (nextPath, id, _) ->
322+
Printf.sprintf "%s.%s" (pathIdentToString nextPath) id
323+
| Papply _ -> ""
324+
318325
type locKind =
319326
| LocalReference of int * Tip.t
320327
| GlobalReference of string * string list * Tip.t
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
Hover src/Auto.res 2:13
2-
{"contents": "```rescript\n(Belt.List.t<'a>, 'a => 'b) => Belt.List.t<'b>\n```\n\n```rescript\ntype t<'a> = list<'a>\n```\n\n\n Returns a new list with `f` applied to each element of `someList`.\n\n ```res example\n list{1, 2}->Belt.List.map(x => x + 1) // list{3, 4}\n ```\n\n\n[SomeModule](command:rescript-vscode.go_to_location?%5B%22file%3A%2F%2Fwhatever%2Ffolder%2FSomeModule.res%22%2C0%2C0%2C0%2C0%5D)"}
2+
{"contents": "```rescript\n(Belt.List.t<'a>, 'a => 'b) => Belt.List.t<'b>\n```\n\n\n```\n \n```\n```rescript\ntype Belt.List.t<'a> = list<'a>\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22belt_List.mli%22%2C34%2C0%5D)\n\n---\n\n\n\n Returns a new list with `f` applied to each element of `someList`.\n\n ```res example\n list{1, 2}->Belt.List.map(x => x + 1) // list{3, 4}\n ```\n"}
33

analysis/tests/src/expected/Definition.res.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ Definition src/Definition.res 10:23
55
{"uri": "Definition.res", "range": {"start": {"line": 6, "character": 7}, "end": {"line": 6, "character": 13}}}
66

77
Hover src/Definition.res 14:14
8-
{"contents": "```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. \n\n[SomeModule](command:rescript-vscode.go_to_location?%5B%22file%3A%2F%2Fwhatever%2Ffolder%2FSomeModule.res%22%2C0%2C0%2C0%2C0%5D)"}
8+
{"contents": "```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. "}
99

1010
Hover src/Definition.res 18:14
11-
{"contents": "```rescript\n(Belt.List.t<'a>, 'a => 'b) => Belt.List.t<'b>\n```\n\n```rescript\ntype t<'a> = list<'a>\n```\n\n\n Returns a new list with `f` applied to each element of `someList`.\n\n ```res example\n list{1, 2}->Belt.List.map(x => x + 1) // list{3, 4}\n ```\n\n\n[SomeModule](command:rescript-vscode.go_to_location?%5B%22file%3A%2F%2Fwhatever%2Ffolder%2FSomeModule.res%22%2C0%2C0%2C0%2C0%5D)"}
11+
{"contents": "```rescript\n(Belt.List.t<'a>, 'a => 'b) => Belt.List.t<'b>\n```\n\n\n```\n \n```\n```rescript\ntype Belt.List.t<'a> = list<'a>\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22belt_List.mli%22%2C34%2C0%5D)\n\n---\n\n\n\n Returns a new list with `f` applied to each element of `someList`.\n\n ```res example\n list{1, 2}->Belt.List.map(x => x + 1) // list{3, 4}\n ```\n"}
1212

1313
Hover src/Definition.res 23:3
14-
{"contents": "```rescript\n(. int, int) => int\n```\n\n[SomeModule](command:rescript-vscode.go_to_location?%5B%22file%3A%2F%2Fwhatever%2Ffolder%2FSomeModule.res%22%2C0%2C0%2C0%2C0%5D)"}
14+
{"contents": "```rescript\n(. int, int) => int\n```"}
1515

1616
Definition src/Definition.res 26:3
1717
{"uri": "Definition.res", "range": {"start": {"line": 21, "character": 4}, "end": {"line": 21, "character": 13}}}

analysis/tests/src/expected/Div.res.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Hover src/Div.res 0:10
22
getLocItem #3: heuristic for <div>
3-
{"contents": "```rescript\n(\n string,\n ~props: ReactDOMRe.domProps=?,\n array<React.element>,\n) => React.element\n```\n\n```rescript\ntype domProps = ReactDOM.Props.domProps\n```\n\n```rescript\ntype element\n```\n\n[SomeModule](command:rescript-vscode.go_to_location?%5B%22file%3A%2F%2Fwhatever%2Ffolder%2FSomeModule.res%22%2C0%2C0%2C0%2C0%5D)"}
3+
{"contents": "```rescript\n(\n string,\n ~props: ReactDOMRe.domProps=?,\n array<React.element>,\n) => React.element\n```\n\n\n```\n \n```\n```rescript\ntype ReactDOMRe.domProps = ReactDOM.Props.domProps\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22ReactDOMRe.res%22%2C57%2C2%5D)\n\n---\n\n\n\n```\n \n```\n```rescript\ntype React.element\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22React.res%22%2C0%2C0%5D)\n\n---\n"}
44

55
Complete src/Div.res 3:17
66
posCursor:[3:17] posNoWhite:[3:16] Found expr:[3:4->3:17]
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
Hover src/DocComments.res 9:9
2-
{"contents": "```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\n\n[SomeModule](command:rescript-vscode.go_to_location?%5B%22file%3A%2F%2Fwhatever%2Ffolder%2FSomeModule.res%22%2C0%2C0%2C0%2C0%5D)"}
2+
{"contents": "```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"}
33

44
Hover src/DocComments.res 22:6
5-
{"contents": "```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\n\n[SomeModule](command:rescript-vscode.go_to_location?%5B%22file%3A%2F%2Fwhatever%2Ffolder%2FSomeModule.res%22%2C0%2C0%2C0%2C0%5D)"}
5+
{"contents": "```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"}
66

77
Hover src/DocComments.res 33:9
8-
{"contents": "```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\n\n[SomeModule](command:rescript-vscode.go_to_location?%5B%22file%3A%2F%2Fwhatever%2Ffolder%2FSomeModule.res%22%2C0%2C0%2C0%2C0%5D)"}
8+
{"contents": "```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"}
99

1010
Hover src/DocComments.res 44:6
11-
{"contents": "```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\n\n[SomeModule](command:rescript-vscode.go_to_location?%5B%22file%3A%2F%2Fwhatever%2Ffolder%2FSomeModule.res%22%2C0%2C0%2C0%2C0%5D)"}
11+
{"contents": "```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"}
1212

analysis/tests/src/expected/Fragment.res.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Hover src/Fragment.res 6:19
22
getLocItem #4: heuristic for </Comp> within fragments: take make as makeProps does not work
33
the type is not great but jump to definition works
4-
{"contents": "```rescript\nReact.component<{\"children\": React.element}>\n```\n\n```rescript\ntype component<'props> = componentLike<'props, element>\n```\n\n[SomeModule](command:rescript-vscode.go_to_location?%5B%22file%3A%2F%2Fwhatever%2Ffolder%2FSomeModule.res%22%2C0%2C0%2C0%2C0%5D)"}
4+
{"contents": "```rescript\nReact.component<{\"children\": React.element}>\n```\n\n\n```\n \n```\n```rescript\ntype React.component<'props> = componentLike<\n 'props,\n element,\n>\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22React.res%22%2C12%2C0%5D)\n\n---\n"}
55

66
Hover src/Fragment.res 9:56
77
Nothing at that position. Now trying to use completion.

0 commit comments

Comments
 (0)