Skip to content

Commit a29a90a

Browse files
committed
sync with master
2 parents 77b0b55 + 35ac5f2 commit a29a90a

File tree

16 files changed

+414
-30
lines changed

16 files changed

+414
-30
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ jobs:
123123

124124
- name: Store short commit SHA for filename
125125
id: vars
126-
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
126+
env:
127+
COMMIT_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
128+
run: echo "::set-output name=sha_short::${COMMIT_SHA:0:7}"
127129

128130
- name: Package Extension
129131
run: npx vsce package -o rescript-vscode-${{ steps.vars.outputs.sha_short }}.vsix

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#### :rocket: New Feature
1616

1717
- Add workspace Symbols
18+
- Inlay Hints (experimetal). `rescript.settings.inlayHints.enable: true`
1819

1920
## v1.4.2
2021

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,18 @@ The extension will look for the existence of a `/node_modules/.bin/rescript` fil
106106

107107
To override this lookup process, the path can be configured explicitly using the setting `rescript.settings.binaryPath`.
108108

109+
### Inlay Hints (experimental)
110+
111+
This allows an editor to place annotations inline with text to display type hints.
112+
113+
```jsonc
114+
// Enable (experimental) inlay hints.
115+
rescript.settings.inlayHints.enable: true
116+
117+
// Maximum length of character for inlay hints. Set to null to have an unlimited length. Inlay hints that exceed the maximum length will not be shown
118+
rescript.settings.inlayHints.maxLength: 25
119+
```
120+
109121
### Hide generated files
110122

111123
You can configure VSCode to collapse the JavaScript files ReScript generates under its source ReScript file. This will "hide" the generated files in the VSCode file explorer, but still leaving them accessible by expanding the source ReScript file they belong to.

analysis/examples/larger-project/.merlin

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
####{BSB GENERATED: NO EDIT
2-
FLG -ppx '/Users/cristianocalcagno/GitHub/rescript-vscode/analysis/examples/larger-project/node_modules/rescript/darwin/bsc.exe -as-ppx -bs-jsx 3'
3-
S /Users/cristianocalcagno/GitHub/rescript-vscode/analysis/examples/larger-project/node_modules/rescript/lib/ocaml
4-
B /Users/cristianocalcagno/GitHub/rescript-vscode/analysis/examples/larger-project/node_modules/rescript/lib/ocaml
2+
FLG -ppx '/home/pedro/Desktop/Projects/rescript-vscode/analysis/examples/larger-project/node_modules/rescript/linux/bsc.exe -as-ppx -bs-jsx 3'
3+
S /home/pedro/Desktop/Projects/rescript-vscode/analysis/examples/larger-project/node_modules/rescript/lib/ocaml
4+
B /home/pedro/Desktop/Projects/rescript-vscode/analysis/examples/larger-project/node_modules/rescript/lib/ocaml
55
FLG -w +a-4-9-20-40-41-42-50-61-102
6-
S /Users/cristianocalcagno/GitHub/rescript-vscode/analysis/examples/larger-project/node_modules/@rescript/react/lib/ocaml
7-
B /Users/cristianocalcagno/GitHub/rescript-vscode/analysis/examples/larger-project/node_modules/@rescript/react/lib/ocaml
8-
S /Users/cristianocalcagno/GitHub/rescript-vscode/analysis/examples/larger-project/node_modules/@glennsl/bs-json/lib/ocaml
9-
B /Users/cristianocalcagno/GitHub/rescript-vscode/analysis/examples/larger-project/node_modules/@glennsl/bs-json/lib/ocaml
6+
S /home/pedro/Desktop/Projects/rescript-vscode/analysis/examples/larger-project/node_modules/@rescript/react/lib/ocaml
7+
B /home/pedro/Desktop/Projects/rescript-vscode/analysis/examples/larger-project/node_modules/@rescript/react/lib/ocaml
8+
S /home/pedro/Desktop/Projects/rescript-vscode/analysis/examples/larger-project/node_modules/@glennsl/bs-json/lib/ocaml
9+
B /home/pedro/Desktop/Projects/rescript-vscode/analysis/examples/larger-project/node_modules/@glennsl/bs-json/lib/ocaml
1010
S src
1111
B lib/bs/src
1212
S src/exception

analysis/src/Cli.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ API examples:
1212
./rescript-editor-analysis.exe references src/MyFile.res 10 2
1313
./rescript-editor-analysis.exe rename src/MyFile.res 10 2 foo
1414
./rescript-editor-analysis.exe diagnosticSyntax src/MyFile.res
15+
/rescript-editor-analysis.exe inlayHint src/MyFile.res 0 3 25
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 diagnosticSyntax src/MyFile.res
7273

74+
inlayHint: get all inlay Hint between line 0 and 3 declared in MyFile.res. Last argument is maximum of character length for inlay hints
75+
76+
./rescript-editor-analysis.exe inlayHint src/MyFile.res 0 3 25
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
@@ -95,6 +100,10 @@ let main () =
95100
Commands.hover ~path
96101
~pos:(int_of_string line, int_of_string col)
97102
~currentFile ~debug:false
103+
| [_; "inlayHint"; path; line_start; line_end; maxLength] ->
104+
Commands.inlayhint ~path
105+
~pos:(int_of_string line_start, int_of_string line_end)
106+
~maxLength ~debug:false
98107
| [_; "codeAction"; path; line; col; currentFile] ->
99108
Commands.codeAction ~path
100109
~pos:(int_of_string line, int_of_string col)

analysis/src/Commands.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ let completion ~debug ~path ~pos ~currentFile =
2828
|> List.map Protocol.stringifyCompletionItem
2929
|> Protocol.array)
3030

31+
let inlayhint ~path ~pos ~maxLength ~debug =
32+
let result = Hint.inlay ~path ~pos ~maxLength ~debug |> Protocol.array in
33+
print_endline result
34+
3135
let hover ~path ~pos ~currentFile ~debug =
3236
let result =
3337
match Cmt.fullFromPath ~path with
@@ -399,6 +403,11 @@ let test ~path =
399403
(Protocol.stringifyRange range)
400404
indent indent newText)))
401405
| "dia" -> diagnosticSyntax ~path
406+
| "hin" -> (
407+
let line_start = 0 in
408+
let line_end = 6 in
409+
print_endline ("Inlay Hint " ^ path ^ " " ^ string_of_int line_start ^ ":" ^ string_of_int line_end);
410+
inlayhint ~path ~pos:(line_start, line_end) ~maxLength:"25" ~debug:false)
402411
| _ -> ());
403412
print_newline ())
404413
in

analysis/src/FindFiles.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ let getNamespace config =
100100
if isNamespaced then
101101
let fromString = ns |> bind Json.string in
102102
let fromName = config |> Json.get "name" |> bind Json.string in
103-
either fromString fromName
103+
either fromString fromName |> Option.map nameSpaceToName
104104
else None
105105

106106
let collectFiles directory =

analysis/src/Hint.ml

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
open SharedTypes
2+
3+
type inlayHintKind = Type | Parameter
4+
let inlayKindToNumber = function
5+
| Type -> 1
6+
| Parameter -> 2
7+
8+
let locItemToTypeHint ~full:{file; package} locItem =
9+
match locItem.locType with
10+
| Constant t ->
11+
Some
12+
(match t with
13+
| Const_int _ -> "int"
14+
| Const_char _ -> "char"
15+
| Const_string _ -> "string"
16+
| Const_float _ -> "float"
17+
| Const_int32 _ -> "int32"
18+
| Const_int64 _ -> "int64"
19+
| Const_nativeint _ -> "int")
20+
| Typed (_, t, locKind) ->
21+
let fromType typ =
22+
typ |> Shared.typeToString
23+
|> Str.global_replace (Str.regexp "[\r\n\t]") ""
24+
in
25+
Some
26+
(match References.definedForLoc ~file ~package locKind with
27+
| None -> fromType t
28+
| Some (_, res) -> (
29+
match res with
30+
| `Declared -> fromType t
31+
| `Constructor _ -> fromType t
32+
| `Field -> fromType t))
33+
| _ -> None
34+
35+
let inlay ~path ~pos ~maxLength ~debug =
36+
let maxlen = try Some (int_of_string maxLength) with Failure _ -> None in
37+
let hints = ref [] in
38+
let start_line, end_line = pos in
39+
let push loc kind =
40+
let range = Utils.cmtLocToRange loc in
41+
if start_line <= range.end_.line && end_line >= range.start.line then
42+
hints := (range, kind) :: !hints
43+
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
54+
let value_binding (iterator : Ast_iterator.iterator)
55+
(vb : Parsetree.value_binding) =
56+
(match vb with
57+
| {
58+
pvb_pat = {ppat_desc = Ppat_var _};
59+
pvb_expr =
60+
{
61+
pexp_desc =
62+
( Pexp_constant _ | Pexp_tuple _ | Pexp_record _ | Pexp_variant _
63+
| Pexp_apply _ | Pexp_match _ | Pexp_construct _ | Pexp_ifthenelse _
64+
| Pexp_array _ | Pexp_ident _ | Pexp_try _ | Pexp_lazy _
65+
| Pexp_send _ | Pexp_field _ | Pexp_open _ );
66+
};
67+
} ->
68+
push vb.pvb_pat.ppat_loc Type
69+
| {pvb_pat = {ppat_desc = Ppat_tuple tuples}} ->
70+
List.iter
71+
(fun (tuple : Parsetree.pattern) -> push tuple.ppat_loc Type)
72+
tuples
73+
| {
74+
pvb_pat = {ppat_desc = Ppat_var _};
75+
pvb_expr = {pexp_desc = Pexp_fun (_, _, pat, e)};
76+
} ->
77+
(match pat with
78+
| {ppat_desc = Ppat_var _} -> push pat.ppat_loc Type
79+
| _ -> ());
80+
processFunction e
81+
| _ -> ());
82+
Ast_iterator.default_iterator.value_binding iterator vb
83+
in
84+
let iterator = {Ast_iterator.default_iterator with value_binding} in
85+
(if Filename.check_suffix path ".res" then
86+
let parser =
87+
Res_driver.parsingEngine.parseImplementation ~forPrinter:false
88+
in
89+
let {Res_driver.parsetree = structure} = parser ~filename:path in
90+
iterator.structure iterator structure |> ignore);
91+
!hints
92+
|> List.filter_map (fun ((range : Protocol.range), hintKind) ->
93+
match Cmt.fullFromPath ~path with
94+
| None -> None
95+
| Some full -> (
96+
match
97+
References.getLocItem ~full
98+
~pos:(range.start.line, range.start.character + 1)
99+
~debug
100+
with
101+
| None -> None
102+
| Some locItem -> (
103+
let position : Protocol.position =
104+
{line = range.start.line; character = range.end_.character}
105+
in
106+
match locItemToTypeHint locItem ~full with
107+
| Some label -> (
108+
let result =
109+
Protocol.stringifyHint
110+
{
111+
kind = inlayKindToNumber hintKind;
112+
position;
113+
paddingLeft = true;
114+
paddingRight = false;
115+
label = ": " ^ label;
116+
}
117+
in
118+
match maxlen with
119+
| Some value ->
120+
if String.length label > value then None else Some result
121+
| None -> Some result)
122+
| None -> None)))

analysis/src/Protocol.ml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
type position = {line: int; character: int}
22
type range = {start: position; end_: position}
33
type markupContent = {kind: string; value: string}
4+
type inlayHint = {
5+
position: position;
6+
label: string;
7+
kind: int;
8+
paddingLeft: bool;
9+
paddingRight: bool;
10+
}
411

512
type completionItem = {
613
label: string;
@@ -128,6 +135,18 @@ let stringifyCodeAction ca =
128135
(codeActionKindToString ca.codeActionKind)
129136
(ca.edit |> stringifyCodeActionEdit)
130137

138+
let stringifyHint hint =
139+
Printf.sprintf
140+
{|{
141+
"position": %s,
142+
"label": "%s",
143+
"kind": %i,
144+
"paddingLeft": %b,
145+
"paddingRight": %b
146+
}|}
147+
(stringifyPosition hint.position)
148+
(Json.escape hint.label) hint.kind hint.paddingLeft hint.paddingRight
149+
131150
(* https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic *)
132151
let stringifyDiagnostic d =
133152
Printf.sprintf
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
let string = "ReScript"
2+
let number = 1
3+
let float = 1.1
4+
let char = 'c'
5+
6+
let add = (x, y) => x + y
7+
8+
let my_sum = 3->add(1)->add(1)->add(1)->add(8)
9+
10+
let withAs = (~xx as yyy) => yyy + 1
11+
12+
13+
@react.component
14+
let make = (~name) => React.string(name)
15+
16+
let tuple = ("ReScript", "lol")
17+
18+
let (lang, _) = tuple
19+
20+
//^hin

0 commit comments

Comments
 (0)