Skip to content

Commit 9947cb3

Browse files
authored
Merge pull request #150 from rescript-lang/tst
Complete Outline
2 parents 505ba07 + 4664ff5 commit 9947cb3

File tree

12 files changed

+527
-348
lines changed

12 files changed

+527
-348
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Fixes:
55
- `->` autocomplete overruled `.`.
66

77
Features:
8+
- Show Outline
89
- Show References!
910
- Hover now supports markdown docs!
1011
- Hover on labels in component functions with compiler version 9.1, and labels with type annotation.

analysis/src/Cli.ml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,12 @@ Options:
3030

3131
references: get references to item in Foo.res at line 10 column 2:
3232

33-
./run.exe references src/Foo.res 10 2|}
33+
./run.exe references src/Foo.res 10 2
34+
35+
documentSymbol: get all symbols in Foo.res:
36+
37+
./run.exe documentSymbol src/Foo.res
38+
|}
3439

3540
let main () =
3641
match Array.to_list Sys.argv with
@@ -45,6 +50,7 @@ let main () =
4550
| [_; "references"; path; line; col] ->
4651
Commands.references ~path ~line:(int_of_string line)
4752
~col:(int_of_string col)
53+
| [_; "documentSymbol"; path] -> Commands.documentSymbol ~path
4854
| _ :: "dump" :: files -> Commands.dump files
4955
| [_; "test"; path] -> Commands.test ~path
5056
| args when List.mem "-h" args || List.mem "--help" args -> prerr_endline help

analysis/src/Commands.ml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,40 @@ let references ~path ~line ~col =
170170
in
171171
print_endline result
172172

173+
let documentSymbol ~path =
174+
let uri = Uri2.fromLocalPath path in
175+
match ProcessCmt.fileForUri uri with
176+
| Error _ -> print_endline Protocol.null
177+
| Ok (file, _extra) ->
178+
let open SharedTypes in
179+
let rec getItems {topLevel} =
180+
let fn {name = {txt}; extentLoc; item} =
181+
let item, siblings =
182+
match item with
183+
| MValue v -> (v |> SharedTypes.variableKind, [])
184+
| MType (t, _) -> (t.decl |> SharedTypes.declarationKind, [])
185+
| Module (Structure contents) -> (Module, getItems contents)
186+
| Module (Ident _) -> (Module, [])
187+
in
188+
if extentLoc.loc_ghost then siblings
189+
else (txt, extentLoc, item) :: siblings
190+
in
191+
let x = topLevel |> List.map fn |> List.concat in
192+
x
193+
in
194+
let allSymbols =
195+
getItems file.contents
196+
|> List.map (fun (name, loc, kind) ->
197+
Protocol.stringifyDocumentSymbolItem
198+
{
199+
name;
200+
location =
201+
{uri = Uri2.toString uri; range = Utils.cmtLocToRange loc};
202+
kind = SharedTypes.symbolKind kind;
203+
})
204+
in
205+
print_endline ("[\n" ^ (allSymbols |> String.concat ",\n") ^ "\n]")
206+
173207
let test ~path =
174208
Uri2.stripPath := true;
175209
match Files.readFile path with
@@ -202,6 +236,9 @@ let test ~path =
202236
("References " ^ path ^ " " ^ string_of_int line ^ ":"
203237
^ string_of_int col);
204238
references ~path ~line ~col
239+
| "doc" ->
240+
print_endline ("DocumentSymbol " ^ path);
241+
documentSymbol ~path
205242
| "com" ->
206243
print_endline
207244
("Complete " ^ path ^ " " ^ string_of_int line ^ ":"

analysis/src/Protocol.ml

Lines changed: 38 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,67 @@
1-
type position = {
2-
line: int;
3-
character: int;
4-
}
1+
type position = {line : int; character : int}
52

6-
type range = {
7-
start: position;
8-
end_: position;
9-
}
3+
type range = {start : position; end_ : position}
104

11-
type markupContent = {
12-
kind: string;
13-
value: string;
14-
}
5+
type markupContent = {kind : string; value : string}
156

167
type completionItem = {
17-
label: string;
18-
kind: int;
19-
tags: int list;
20-
detail: string;
21-
documentation: markupContent option;
8+
label : string;
9+
kind : int;
10+
tags : int list;
11+
detail : string;
12+
documentation : markupContent option;
2213
}
2314

24-
type hover = {
25-
contents: string;
26-
}
15+
type hover = {contents : string}
2716

28-
type location = {
29-
uri: string;
30-
range: range;
31-
}
17+
type location = {uri : string; range : range}
18+
19+
type documentSymbolItem = {name : string; kind : int; location : location}
3220

3321
let null = "null"
3422

35-
let array l = "[" ^ (String.concat ", " l) ^ "]"
23+
let array l = "[" ^ String.concat ", " l ^ "]"
3624

3725
let stringifyPosition p =
38-
Printf.sprintf {|{"line": %i, "character": %i}|} p.line p.character
26+
Printf.sprintf {|{"line": %i, "character": %i}|} p.line p.character
3927

4028
let stringifyRange r =
41-
Printf.sprintf {|{"start": %s, "end": %s}|}
29+
Printf.sprintf {|{"start": %s, "end": %s}|}
4230
(stringifyPosition r.start)
4331
(stringifyPosition r.end_)
4432

45-
let stringifyMarkupContent (m: markupContent) =
46-
Printf.sprintf {|{"kind": "%s", "value": "%s"}|}
47-
m.kind (Json.escape m.value)
33+
let stringifyMarkupContent (m : markupContent) =
34+
Printf.sprintf {|{"kind": "%s", "value": "%s"}|} m.kind (Json.escape m.value)
4835

4936
let stringifyCompletionItem c =
50-
Printf.sprintf {|{
37+
Printf.sprintf
38+
{|{
5139
"label": "%s",
5240
"kind": %i,
5341
"tags": %s,
5442
"detail": "%s",
5543
"documentation": %s
5644
}|}
57-
(Json.escape c.label)
58-
c.kind
59-
(c.tags |> List.map string_of_int |> array)
60-
(Json.escape c.detail)
61-
(match c.documentation with
62-
| None -> null
63-
| Some doc -> stringifyMarkupContent doc)
45+
(Json.escape c.label) c.kind
46+
(c.tags |> List.map string_of_int |> array)
47+
(Json.escape c.detail)
48+
(match c.documentation with
49+
| None -> null
50+
| Some doc -> stringifyMarkupContent doc)
6451

6552
let stringifyHover h =
66-
Printf.sprintf {|{"contents": "%s"}|}
67-
(Json.escape h.contents)
53+
Printf.sprintf {|{"contents": "%s"}|} (Json.escape h.contents)
6854

6955
let stringifyLocation h =
70-
Printf.sprintf {|{"uri": "%s", "range": %s}|}
71-
(Json.escape h.uri)
72-
(stringifyRange h.range)
56+
Printf.sprintf {|{"uri": "%s", "range": %s}|} (Json.escape h.uri)
57+
(stringifyRange h.range)
58+
59+
let stringifyDocumentSymbolItem i =
60+
Printf.sprintf
61+
{|{
62+
"name": "%s",
63+
"kind": %i,
64+
"location": %s
65+
}|}
66+
(Json.escape i.name) i.kind
67+
(stringifyLocation i.location)

analysis/src/SharedTypes.ml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,5 +233,49 @@ let locationToString ({Location.loc_start; loc_end}, loc) =
233233
Printf.sprintf "%d:%d-%d:%d %s" pos1.line pos1.character pos2.line
234234
pos2.character (locToString loc)
235235

236+
type kinds =
237+
| Module
238+
| Enum
239+
| Interface
240+
| Function
241+
| Variable
242+
| Array
243+
| Object
244+
| Null
245+
| EnumMember
246+
| TypeParameter
247+
248+
let rec variableKind t =
249+
match t.Types.desc with
250+
| Tlink t -> variableKind t
251+
| Tsubst t -> variableKind t
252+
| Tarrow _ -> Function
253+
| Ttuple _ -> Array
254+
| Tconstr _ -> Variable
255+
| Tobject _ -> Object
256+
| Tnil -> Null
257+
| Tvariant _ -> EnumMember
258+
| Tpoly _ -> EnumMember
259+
| Tpackage _ -> Module
260+
| _ -> Variable
261+
262+
let symbolKind = function
263+
| Module -> 2
264+
| Enum -> 10
265+
| Interface -> 11
266+
| Function -> 12
267+
| Variable -> 13
268+
| Array -> 18
269+
| Object -> 19
270+
| Null -> 21
271+
| EnumMember -> 22
272+
| TypeParameter -> 26
273+
274+
let declarationKind t =
275+
match t.Types.type_kind with
276+
| Type_open | Type_abstract -> TypeParameter
277+
| Type_record _ -> Interface
278+
| Type_variant _ -> Enum
279+
236280
(* for debugging *)
237281
let _ = locationToString

analysis/tests/src/Complete.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,4 @@ let zzz = 11
5454
//^com let comp = <O.Comp z
5555

5656

57-
57+
//^doc

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

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,3 +454,87 @@ Complete tests/src/Complete.res 52:2
454454
"documentation": null
455455
}]
456456

457+
DocumentSymbol tests/src/Complete.res
458+
[
459+
{
460+
"name": "MyList",
461+
"kind": 2,
462+
"location": {"uri": "Complete.res", "range": {"start": {"line": 0, "character": 7}, "end": {"line": 0, "character": 25}}}
463+
},
464+
{
465+
"name": "Dep",
466+
"kind": 2,
467+
"location": {"uri": "Complete.res", "range": {"start": {"line": 6, "character": 7}, "end": {"line": 11, "character": 1}}}
468+
},
469+
{
470+
"name": "customDouble",
471+
"kind": 12,
472+
"location": {"uri": "Complete.res", "range": {"start": {"line": 7, "character": 2}, "end": {"line": 8, "character": 30}}}
473+
},
474+
{
475+
"name": "Lib",
476+
"kind": 2,
477+
"location": {"uri": "Complete.res", "range": {"start": {"line": 15, "character": 7}, "end": {"line": 18, "character": 1}}}
478+
},
479+
{
480+
"name": "foo",
481+
"kind": 12,
482+
"location": {"uri": "Complete.res", "range": {"start": {"line": 16, "character": 2}, "end": {"line": 16, "character": 55}}}
483+
},
484+
{
485+
"name": "next",
486+
"kind": 12,
487+
"location": {"uri": "Complete.res", "range": {"start": {"line": 17, "character": 2}, "end": {"line": 17, "character": 48}}}
488+
},
489+
{
490+
"name": "op",
491+
"kind": 13,
492+
"location": {"uri": "Complete.res", "range": {"start": {"line": 26, "character": 0}, "end": {"line": 26, "character": 16}}}
493+
},
494+
{
495+
"name": "ForAuto",
496+
"kind": 2,
497+
"location": {"uri": "Complete.res", "range": {"start": {"line": 30, "character": 7}, "end": {"line": 34, "character": 1}}}
498+
},
499+
{
500+
"name": "t",
501+
"kind": 26,
502+
"location": {"uri": "Complete.res", "range": {"start": {"line": 31, "character": 2}, "end": {"line": 31, "character": 14}}}
503+
},
504+
{
505+
"name": "abc",
506+
"kind": 12,
507+
"location": {"uri": "Complete.res", "range": {"start": {"line": 32, "character": 2}, "end": {"line": 32, "character": 30}}}
508+
},
509+
{
510+
"name": "abd",
511+
"kind": 12,
512+
"location": {"uri": "Complete.res", "range": {"start": {"line": 33, "character": 2}, "end": {"line": 33, "character": 30}}}
513+
},
514+
{
515+
"name": "fa",
516+
"kind": 13,
517+
"location": {"uri": "Complete.res", "range": {"start": {"line": 36, "character": 0}, "end": {"line": 36, "character": 21}}}
518+
},
519+
{
520+
"name": "O",
521+
"kind": 2,
522+
"location": {"uri": "Complete.res", "range": {"start": {"line": 41, "character": 7}, "end": {"line": 47, "character": 1}}}
523+
},
524+
{
525+
"name": "Comp",
526+
"kind": 2,
527+
"location": {"uri": "Complete.res", "range": {"start": {"line": 42, "character": 9}, "end": {"line": 46, "character": 3}}}
528+
},
529+
{
530+
"name": "make",
531+
"kind": 12,
532+
"location": {"uri": "Complete.res", "range": {"start": {"line": 44, "character": 4}, "end": {"line": 45, "character": 57}}}
533+
},
534+
{
535+
"name": "zzz",
536+
"kind": 13,
537+
"location": {"uri": "Complete.res", "range": {"start": {"line": 49, "character": 0}, "end": {"line": 49, "character": 12}}}
538+
}
539+
]
540+

0 commit comments

Comments
 (0)