Skip to content

Commit d64ed9a

Browse files
committed
Implement emitting code lenses for functions.
1 parent 564f905 commit d64ed9a

File tree

3 files changed

+69
-2
lines changed

3 files changed

+69
-2
lines changed

analysis/src/Cli.ml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ API examples:
1111
./rescript-editor-analysis.exe references src/MyFile.res 10 2
1212
./rescript-editor-analysis.exe rename src/MyFile.res 10 2 foo
1313
./rescript-editor-analysis.exe diagnosticSyntax src/MyFile.res
14-
/rescript-editor-analysis.exe inlayHint src/MyFile.res 0 3 25
14+
./rescript-editor-analysis.exe inlayHint src/MyFile.res 0 3 25
15+
./rescript-editor-analysis.exe codeLens src/MyFile.res
1516

1617
Dev-time examples:
1718
./rescript-editor-analysis.exe dump src/MyFile.res src/MyFile2.res
@@ -70,6 +71,10 @@ Options:
7071

7172
./rescript-editor-analysis.exe inlayHint src/MyFile.res 0 3 25
7273

74+
codeLens: get all code lens entries for file src/MyFile.res
75+
76+
./rescript-editor-analysis.exe codeLens src/MyFile.res
77+
7378
test: run tests specified by special comments in file src/MyFile.res
7479

7580
./rescript-editor-analysis.exe test src/src/MyFile.res
@@ -98,6 +103,7 @@ let main () =
98103
Commands.inlayhint ~path
99104
~pos:(int_of_string line_start, int_of_string line_end)
100105
~maxLength ~debug:false
106+
| [_; "codeLens"; path] -> Commands.codeLens ~path ~debug:false
101107
| [_; "codeAction"; path; line; col; currentFile] ->
102108
Commands.codeAction ~path
103109
~pos:(int_of_string line, int_of_string col)

analysis/src/Commands.ml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ let inlayhint ~path ~pos ~maxLength ~debug =
3232
let result = Hint.inlay ~path ~pos ~maxLength ~debug |> Protocol.array in
3333
print_endline result
3434

35+
let codeLens ~path ~debug =
36+
let result = Hint.codeLens ~path ~debug |> Protocol.array in
37+
print_endline result
38+
3539
let hover ~path ~pos ~currentFile ~debug =
3640
let result =
3741
match Cmt.fullFromPath ~path with
@@ -391,6 +395,9 @@ let test ~path =
391395
let line_end = 6 in
392396
print_endline ("Inlay Hint " ^ path ^ " " ^ string_of_int line_start ^ ":" ^ string_of_int line_end);
393397
inlayhint ~path ~pos:(line_start, line_end) ~maxLength:"25" ~debug:false)
398+
| "clens" ->
399+
print_endline ("Code Lens " ^ path);
400+
codeLens ~path ~debug:false
394401
| _ -> ());
395402
print_newline ())
396403
in

analysis/src/Hint.ml

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,58 @@ let inlay ~path ~pos ~maxLength ~debug =
119119
| Some value ->
120120
if String.length label > value then None else Some result
121121
| None -> Some result)
122-
| None -> None)))
122+
| None -> None)))
123+
124+
let codeLens ~path ~debug =
125+
let lenses = ref [] in
126+
let push loc =
127+
let range = Utils.cmtLocToRange loc in
128+
lenses := range :: !lenses
129+
in
130+
(* Code lenses are only emitted for functions right now. So look for value bindings that are functions,
131+
and use the loc of the value binding itself so we can look up the full function type for our code lens. *)
132+
let value_binding (iterator : Ast_iterator.iterator)
133+
(vb : Parsetree.value_binding) =
134+
(match vb with
135+
| {
136+
pvb_pat = {ppat_desc = Ppat_var _; ppat_loc};
137+
pvb_expr = {pexp_desc = Pexp_fun _};
138+
} ->
139+
push ppat_loc
140+
| _ -> ());
141+
Ast_iterator.default_iterator.value_binding iterator vb
142+
in
143+
let iterator = {Ast_iterator.default_iterator with value_binding} in
144+
(if Filename.check_suffix path ".res" then
145+
let parser =
146+
Res_driver.parsingEngine.parseImplementation ~forPrinter:false
147+
in
148+
let {Res_driver.parsetree = structure} = parser ~filename:path in
149+
iterator.structure iterator structure |> ignore);
150+
!lenses
151+
|> List.filter_map (fun (range : Protocol.range) ->
152+
match Cmt.fullFromPath ~path with
153+
| None -> None
154+
| Some full -> (
155+
match
156+
References.getLocItem ~full
157+
~pos:(range.start.line, range.start.character + 1)
158+
~debug
159+
with
160+
| Some {locType = Typed (_, typeExpr, _)} ->
161+
Some
162+
(Protocol.stringifyCodeLens
163+
{
164+
range;
165+
command =
166+
Some
167+
{
168+
(* Code lenses can run commands. An empty command string means we just want the editor
169+
to print the text, not link to running a command. *)
170+
command = "";
171+
(* Print the type with a huge line width, because the code lens always prints on a
172+
single line in the editor. *)
173+
title = typeExpr |> Shared.typeToString ~lineWidth:400;
174+
};
175+
})
176+
| _ -> None))

0 commit comments

Comments
 (0)