Skip to content

Commit 75bccdd

Browse files
authored
Polish: inlay hints and codelens performance (#634)
* polish: better performance for hints and codelens * update changelog * rename Cmt.fullFromPath to Cmt.loadFullCmtFromPath
1 parent 5506990 commit 75bccdd

File tree

8 files changed

+86
-112
lines changed

8 files changed

+86
-112
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
- Remove spacing between type definition in clients that do not support markdown links. https://github.com/rescript-lang/rescript-vscode/pull/619
1818
- Rename custom LSP methods names. https://github.com/rescript-lang/rescript-vscode/pull/611
19+
- Better performance for Inlay Hints and Codelens.
1920
- Accept both `@ns.doc` and the new `@res.doc` for the internal representation of doc comments. And both `@ns.optional` and `@res.optional` for the optional fields. https://github.com/rescript-lang/rescript-vscode/pull/642
2021

2122
#### :bug: Bug Fix

analysis/src/Cmt.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ let fullFromModule ~package ~moduleName =
3131
fullFromUri ~uri
3232
else None
3333

34-
let fullFromPath ~path =
34+
let loadFullCmtFromPath ~path =
3535
let uri = Uri.fromPath path in
3636
fullFromUri ~uri

analysis/src/Commands.ml

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ let getCompletions ~debug ~path ~pos ~currentFile ~forHover =
1313
Printf.printf "Completable: %s\n"
1414
(SharedTypes.Completable.toString completable);
1515
(* Only perform expensive ast operations if there are completables *)
16-
match Cmt.fullFromPath ~path with
16+
match Cmt.loadFullCmtFromPath ~path with
1717
| None -> []
1818
| Some {file; package} ->
1919
let env = SharedTypes.QueryEnv.fromFile file in
@@ -29,16 +29,24 @@ let completion ~debug ~path ~pos ~currentFile =
2929
|> Protocol.array)
3030

3131
let inlayhint ~path ~pos ~maxLength ~debug =
32-
let result = Hint.inlay ~path ~pos ~maxLength ~debug |> Protocol.array in
32+
let result =
33+
match Hint.inlay ~path ~pos ~maxLength ~debug with
34+
| Some hints -> hints |> Protocol.array
35+
| None -> Protocol.null
36+
in
3337
print_endline result
3438

3539
let codeLens ~path ~debug =
36-
let result = Hint.codeLens ~path ~debug |> Protocol.array in
40+
let result =
41+
match Hint.codeLens ~path ~debug with
42+
| Some lens -> lens |> Protocol.array
43+
| None -> Protocol.null
44+
in
3745
print_endline result
3846

3947
let hover ~path ~pos ~currentFile ~debug ~supportsMarkdownLinks =
4048
let result =
41-
match Cmt.fullFromPath ~path with
49+
match Cmt.loadFullCmtFromPath ~path with
4250
| None -> Protocol.null
4351
| Some full -> (
4452
match References.getLocItem ~full ~pos ~debug with
@@ -94,7 +102,7 @@ let codeAction ~path ~pos ~currentFile ~debug =
94102

95103
let definition ~path ~pos ~debug =
96104
let locationOpt =
97-
match Cmt.fullFromPath ~path with
105+
match Cmt.loadFullCmtFromPath ~path with
98106
| None -> None
99107
| Some full -> (
100108
match References.getLocItem ~full ~pos ~debug with
@@ -130,7 +138,7 @@ let definition ~path ~pos ~debug =
130138

131139
let typeDefinition ~path ~pos ~debug =
132140
let maybeLocation =
133-
match Cmt.fullFromPath ~path with
141+
match Cmt.loadFullCmtFromPath ~path with
134142
| None -> None
135143
| Some full -> (
136144
match References.getLocItem ~full ~pos ~debug with
@@ -149,7 +157,7 @@ let typeDefinition ~path ~pos ~debug =
149157

150158
let references ~path ~pos ~debug =
151159
let allLocs =
152-
match Cmt.fullFromPath ~path with
160+
match Cmt.loadFullCmtFromPath ~path with
153161
| None -> []
154162
| Some full -> (
155163
match References.getLocItem ~full ~pos ~debug with
@@ -175,7 +183,7 @@ let references ~path ~pos ~debug =
175183

176184
let rename ~path ~pos ~newName ~debug =
177185
let result =
178-
match Cmt.fullFromPath ~path with
186+
match Cmt.loadFullCmtFromPath ~path with
179187
| None -> Protocol.null
180188
| Some full -> (
181189
match References.getLocItem ~full ~pos ~debug with

analysis/src/Hint.ml

Lines changed: 65 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,6 @@ let inlay ~path ~pos ~maxLength ~debug =
4141
if start_line <= range.end_.line && end_line >= range.start.line then
4242
hints := (range, kind) :: !hints
4343
in
44-
let rec processFunction (exp : Parsetree.expression) =
45-
match exp.pexp_desc with
46-
| Pexp_fun (_, _, pat_exp, e) -> (
47-
match pat_exp with
48-
| {ppat_desc = Ppat_var _} ->
49-
push pat_exp.ppat_loc Type;
50-
processFunction e
51-
| _ -> processFunction e)
52-
| _ -> ()
53-
in
5444
let rec processPattern (pat : Parsetree.pattern) =
5545
match pat.ppat_desc with
5646
| Ppat_tuple pl -> pl |> List.iter processPattern
@@ -77,14 +67,6 @@ let inlay ~path ~pos ~maxLength ~debug =
7767
push vb.pvb_pat.ppat_loc Type
7868
| {pvb_pat = {ppat_desc = Ppat_tuple _}} -> processPattern vb.pvb_pat
7969
| {pvb_pat = {ppat_desc = Ppat_record _}} -> processPattern vb.pvb_pat
80-
| {
81-
pvb_pat = {ppat_desc = Ppat_var _};
82-
pvb_expr = {pexp_desc = Pexp_fun (_, _, pat, e)};
83-
} ->
84-
(match pat with
85-
| {ppat_desc = Ppat_var _} -> push pat.ppat_loc Type
86-
| _ -> ());
87-
processFunction e
8870
| _ -> ());
8971
Ast_iterator.default_iterator.value_binding iterator vb
9072
in
@@ -95,38 +77,41 @@ let inlay ~path ~pos ~maxLength ~debug =
9577
in
9678
let {Res_driver.parsetree = structure} = parser ~filename:path in
9779
iterator.structure iterator structure |> ignore);
98-
!hints
99-
|> List.filter_map (fun ((range : Protocol.range), hintKind) ->
100-
match Cmt.fullFromPath ~path with
101-
| None -> None
102-
| Some full -> (
103-
match
104-
References.getLocItem ~full
105-
~pos:(range.start.line, range.start.character + 1)
106-
~debug
107-
with
108-
| None -> None
109-
| Some locItem -> (
110-
let position : Protocol.position =
111-
{line = range.start.line; character = range.end_.character}
112-
in
113-
match locItemToTypeHint locItem ~full with
114-
| Some label -> (
115-
let result =
116-
Protocol.stringifyHint
117-
{
118-
kind = inlayKindToNumber hintKind;
119-
position;
120-
paddingLeft = true;
121-
paddingRight = false;
122-
label = ": " ^ label;
123-
}
80+
match Cmt.loadFullCmtFromPath ~path with
81+
| None -> None
82+
| Some full ->
83+
let result =
84+
!hints
85+
|> List.filter_map (fun ((range : Protocol.range), hintKind) ->
86+
match
87+
References.getLocItem ~full
88+
~pos:(range.start.line, range.start.character + 1)
89+
~debug
90+
with
91+
| None -> None
92+
| Some locItem -> (
93+
let position : Protocol.position =
94+
{line = range.start.line; character = range.end_.character}
12495
in
125-
match maxlen with
126-
| Some value ->
127-
if String.length label > value then None else Some result
128-
| None -> Some result)
129-
| None -> None)))
96+
match locItemToTypeHint locItem ~full with
97+
| Some label -> (
98+
let result =
99+
Protocol.stringifyHint
100+
{
101+
kind = inlayKindToNumber hintKind;
102+
position;
103+
paddingLeft = true;
104+
paddingRight = false;
105+
label = ": " ^ label;
106+
}
107+
in
108+
match maxlen with
109+
| Some value ->
110+
if String.length label > value then None else Some result
111+
| None -> Some result)
112+
| None -> None))
113+
in
114+
Some result
130115

131116
let codeLens ~path ~debug =
132117
let lenses = ref [] in
@@ -156,30 +141,34 @@ let codeLens ~path ~debug =
156141
in
157142
let {Res_driver.parsetree = structure} = parser ~filename:path in
158143
iterator.structure iterator structure |> ignore);
159-
!lenses
160-
|> List.filter_map (fun (range : Protocol.range) ->
161-
match Cmt.fullFromPath ~path with
162-
| None -> None
163-
| Some full -> (
164-
match
165-
References.getLocItem ~full
166-
~pos:(range.start.line, range.start.character + 1)
167-
~debug
168-
with
169-
| Some {locType = Typed (_, typeExpr, _)} ->
170-
Some
171-
(Protocol.stringifyCodeLens
172-
{
173-
range;
174-
command =
175-
Some
176-
{
177-
(* Code lenses can run commands. An empty command string means we just want the editor
178-
to print the text, not link to running a command. *)
179-
command = "";
180-
(* Print the type with a huge line width, because the code lens always prints on a
181-
single line in the editor. *)
182-
title = typeExpr |> Shared.typeToString ~lineWidth:400;
183-
};
184-
})
185-
| _ -> None))
144+
match Cmt.loadFullCmtFromPath ~path with
145+
| None -> None
146+
| Some full ->
147+
let result =
148+
!lenses
149+
|> List.filter_map (fun (range : Protocol.range) ->
150+
match
151+
References.getLocItem ~full
152+
~pos:(range.start.line, range.start.character + 1)
153+
~debug
154+
with
155+
| Some {locType = Typed (_, typeExpr, _)} ->
156+
Some
157+
(Protocol.stringifyCodeLens
158+
{
159+
range;
160+
command =
161+
Some
162+
{
163+
(* Code lenses can run commands. An empty command string means we just want the editor
164+
to print the text, not link to running a command. *)
165+
command = "";
166+
(* Print the type with a huge line width, because the code lens always prints on a
167+
single line in the editor. *)
168+
title =
169+
typeExpr |> Shared.typeToString ~lineWidth:400;
170+
};
171+
})
172+
| _ -> None)
173+
in
174+
Some result

analysis/src/Hover.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ let getHoverViaCompletions ~debug ~path ~pos ~currentFile ~forHover
133133
Printf.printf "Completable: %s\n"
134134
(SharedTypes.Completable.toString completable);
135135
(* Only perform expensive ast operations if there are completables *)
136-
match Cmt.fullFromPath ~path with
136+
match Cmt.loadFullCmtFromPath ~path with
137137
| None -> None
138138
| Some {file; package} -> (
139139
let env = SharedTypes.QueryEnv.fromFile file in

analysis/src/SignatureHelp.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ let findFunctionType ~currentFile ~debug ~path ~pos =
1616
with
1717
| None -> None
1818
| Some (completable, scope) -> (
19-
match Cmt.fullFromPath ~path with
19+
match Cmt.loadFullCmtFromPath ~path with
2020
| None -> None
2121
| Some {file; package} ->
2222
let env = QueryEnv.fromFile file in

analysis/src/Xform.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ let parse ~filename =
301301
(structure, printExpr, printStructureItem)
302302

303303
let extractCodeActions ~path ~pos ~currentFile ~debug =
304-
match Cmt.fullFromPath ~path with
304+
match Cmt.loadFullCmtFromPath ~path with
305305
| Some full when Files.classifySourceFile currentFile = Res ->
306306
let structure, printExpr, printStructureItem =
307307
parse ~filename:currentFile

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

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,36 +35,12 @@ Inlay Hint src/InlayHint.res 1:34
3535
"kind": 1,
3636
"paddingLeft": true,
3737
"paddingRight": false
38-
}, {
39-
"position": {"line": 14, "character": 17},
40-
"label": ": string",
41-
"kind": 1,
42-
"paddingLeft": true,
43-
"paddingRight": false
44-
}, {
45-
"position": {"line": 10, "character": 24},
46-
"label": ": int",
47-
"kind": 1,
48-
"paddingLeft": true,
49-
"paddingRight": false
5038
}, {
5139
"position": {"line": 8, "character": 10},
5240
"label": ": int",
5341
"kind": 1,
5442
"paddingLeft": true,
5543
"paddingRight": false
56-
}, {
57-
"position": {"line": 6, "character": 15},
58-
"label": ": int",
59-
"kind": 1,
60-
"paddingLeft": true,
61-
"paddingRight": false
62-
}, {
63-
"position": {"line": 6, "character": 12},
64-
"label": ": int",
65-
"kind": 1,
66-
"paddingLeft": true,
67-
"paddingRight": false
6844
}, {
6945
"position": {"line": 4, "character": 8},
7046
"label": ": char",

0 commit comments

Comments
 (0)