Skip to content

Commit b7cdbc6

Browse files
committed
Initial signature dump
1 parent f351f02 commit b7cdbc6

File tree

3 files changed

+81
-94
lines changed

3 files changed

+81
-94
lines changed

tools/bin/main.ml

-5
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,6 @@ let version = Version.version
3131

3232
let main () =
3333
match Sys.argv |> Array.to_list |> List.tl with
34-
| "temp" :: rest -> (
35-
match rest with
36-
| ["-h"] | ["--help"] -> logAndExit (Ok docHelp)
37-
| [path] -> logAndExit (Tools.dump ~entryPointFile:path ~debug:false)
38-
| _ -> logAndExit (Error docHelp))
3934
| "doc" :: rest -> (
4035
match rest with
4136
| ["-h"] | ["--help"] -> logAndExit (Ok docHelp)

tools/src/print_tast.ml

+11-24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
(* *)
2-
31
(** Transform the AST types to the more generic Oak format *)
42
module Oak = struct
53
type application = {name: string; argument: oak}
@@ -20,7 +18,10 @@ module Oak = struct
2018

2119
let rec mk_type_desc (desc : Types.type_desc) : oak =
2220
match desc with
23-
| Tvar _ -> Ident "type_desc.Tvar"
21+
| Tvar var -> (
22+
match var with
23+
| None -> Application {name = "type_desc.Tvar"; argument = Ident "None"}
24+
| Some s -> Application {name = "type_desc.Tvar"; argument = Ident s})
2425
| Tarrow (_, t1, t2, _) ->
2526
Application
2627
{
@@ -113,6 +114,13 @@ end
113114

114115
(** Transform the Oak types to string *)
115116
module CodePrinter = struct
117+
(**
118+
The idea is that we capture events in a context type.
119+
Doing this allows us to reason about the current state of the writer
120+
and whether the next expression fits on the current line or not.
121+
122+
*)
123+
116124
type writerEvents =
117125
| Write of string
118126
| WriteLine
@@ -310,24 +318,3 @@ end
310318
let print_type_expr (typ : Types.type_expr) : string =
311319
CodePrinter.genOak (Oak.mk_type_desc typ.desc) CodePrinter.emptyContext
312320
|> CodePrinter.dump
313-
314-
(* let oak =
315-
Oak.Application
316-
{
317-
Oak.name = "foo";
318-
argument =
319-
Oak.Tuple [{Oak.name = "foo"; value = Oak.Ident "baaaaaaaaaaaaaaaaar"}];
320-
} *)
321-
(* Oak.Record
322-
[
323-
{Oak.name = "foo"; value = Oak.Ident "baaaaaaaaaaaaaaaaar"};
324-
{Oak.name = "member"; value = Oak.Ident "Zigbar"};
325-
] *)
326-
327-
(* let _ =
328-
CodePrinter.genOak oak CodePrinter.emptyContext
329-
|> CodePrinter.dump |> Format.printf "%s\n" *)
330-
331-
(*
332-
Interpret using ocaml /home/nojaf/projects/rescript-vscode/tools/src/print_tast.ml
333-
*)

tools/src/tools.ml

+70-65
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ type constructorDoc = {
1818
items: constructorPayload option;
1919
}
2020

21-
type valueSignature = {parameters: string list; returnType: string}
21+
type typeDoc = {path: string; genericParameters: typeDoc list}
22+
type valueSignature = {parameters: typeDoc list; returnType: typeDoc}
2223

2324
type source = {filepath: string; line: int; col: int}
2425

@@ -108,6 +109,19 @@ let stringifyConstructorPayload ~indentation
108109
|> array) );
109110
]
110111

112+
let rec stringifyTypeDoc ~indentation (td : typeDoc) : string =
113+
let open Protocol in
114+
let ps =
115+
match td.genericParameters with
116+
| [] -> None
117+
| ts ->
118+
ts |> List.map (stringifyTypeDoc ~indentation:(indentation + 1))
119+
|> fun ts -> Some (array ts)
120+
in
121+
122+
stringifyObject ~indentation:(indentation + 1)
123+
[("path", Some (wrapInQuotes td.path)); ("genericTypeParameters", ps)]
124+
111125
let stringifyDetail ?(indentation = 0) (detail : docItemDetail) =
112126
let open Protocol in
113127
match detail with
@@ -151,7 +165,19 @@ let stringifyDetail ?(indentation = 0) (detail : docItemDetail) =
151165
])
152166
|> array) );
153167
]
154-
| Signature {parameters; returnType} -> returnType
168+
| Signature {parameters; returnType} ->
169+
let ps =
170+
match parameters with
171+
| [] -> None
172+
| ps ->
173+
ps |> List.map (stringifyTypeDoc ~indentation:(indentation + 1))
174+
|> fun ps -> Some (array ps)
175+
in
176+
stringifyObject ~startOnNewline:false ~indentation
177+
[
178+
("parameters", ps);
179+
("returnType", Some (stringifyTypeDoc ~indentation returnType));
180+
]
155181

156182
let stringifySource ~indentation source =
157183
let open Protocol in
@@ -320,9 +346,47 @@ let typeDetail typ ~env ~full =
320346
})
321347
| _ -> None
322348

323-
let valueDetail (item : SharedTypes.Module.item) (typ : Types.type_expr) =
324-
let s = Print_tast.print_type_expr typ in
325-
Some (Signature {parameters = []; returnType = s})
349+
(* split a list into two parts all the items except the last one and the last item *)
350+
let splitLast l =
351+
let rec splitLast' acc = function
352+
| [] -> failwith "splitLast: empty list"
353+
| [x] -> (List.rev acc, x)
354+
| x :: xs -> splitLast' (x :: acc) xs
355+
in
356+
splitLast' [] l
357+
358+
let isFunction = function
359+
| Path.Pident {name = "function$"} -> true
360+
| _ -> false
361+
362+
let valueDetail (typ : Types.type_expr) =
363+
Printf.printf "%s\n" (Print_tast.print_type_expr typ);
364+
let rec collectSignatureTypes (typ_desc : Types.type_desc) =
365+
match typ_desc with
366+
| Tlink t -> collectSignatureTypes t.desc
367+
| Tconstr (path, [t; _], _) when isFunction path ->
368+
collectSignatureTypes t.desc
369+
| Tconstr (path, ts, _) -> (
370+
let p = Print_tast.Oak.path_to_string path in
371+
match ts with
372+
| [] -> [{path = p; genericParameters = []}]
373+
| ts ->
374+
let ts =
375+
ts
376+
|> List.concat_map (fun (t : Types.type_expr) ->
377+
collectSignatureTypes t.desc)
378+
in
379+
[{path = p; genericParameters = ts}])
380+
| Tarrow (_, t1, t2, _) ->
381+
collectSignatureTypes t1.desc @ collectSignatureTypes t2.desc
382+
| Tvar None -> [{path = "_"; genericParameters = []}]
383+
| _ -> []
384+
in
385+
match collectSignatureTypes typ.desc with
386+
| [] -> None
387+
| ts ->
388+
let parameters, returnType = splitLast ts in
389+
Some (Signature {parameters; returnType})
326390

327391
let makeId modulePath ~identifier =
328392
identifier :: modulePath |> List.rev |> SharedTypes.ident
@@ -336,65 +400,6 @@ let getSource ~rootPath ({loc_start} : Location.t) =
336400
in
337401
{filepath; line = line + 1; col = col + 1}
338402

339-
let dump ~entryPointFile ~debug =
340-
let path =
341-
match Filename.is_relative entryPointFile with
342-
| true -> Unix.realpath entryPointFile
343-
| false -> entryPointFile
344-
in
345-
if debug then Printf.printf "extracting docs for %s\n" path;
346-
let result =
347-
match
348-
FindFiles.isImplementation path = false
349-
&& FindFiles.isInterface path = false
350-
with
351-
| false -> (
352-
let path =
353-
if FindFiles.isImplementation path then
354-
let pathAsResi =
355-
(path |> Filename.dirname) ^ "/"
356-
^ (path |> Filename.basename |> Filename.chop_extension)
357-
^ ".resi"
358-
in
359-
if Sys.file_exists pathAsResi then (
360-
if debug then
361-
Printf.printf "preferring found resi file for impl: %s\n"
362-
pathAsResi;
363-
pathAsResi)
364-
else path
365-
else path
366-
in
367-
match Cmt.loadFullCmtFromPath ~path with
368-
| None ->
369-
Error
370-
(Printf.sprintf
371-
"error: failed to generate doc for %s, try to build the project"
372-
path)
373-
| Some full ->
374-
let file = full.file in
375-
let structure = file.structure in
376-
let open SharedTypes in
377-
let extractDocsForModule (structure : Module.structure) =
378-
structure.items
379-
|> List.filter_map (fun (item : Module.item) ->
380-
match item.kind with
381-
| Value typ -> (
382-
match valueDetail item typ with
383-
| Some (Signature {returnType = rt}) -> Some rt
384-
| _ -> None)
385-
| _ -> None)
386-
|> String.concat "\n"
387-
in
388-
let docs = extractDocsForModule structure in
389-
Ok docs)
390-
| true ->
391-
Error
392-
(Printf.sprintf
393-
"error: failed to read %s, expected an .res or .resi file" path)
394-
in
395-
396-
result
397-
398403
let extractDocs ~entryPointFile ~debug =
399404
let path =
400405
match Filename.is_relative entryPointFile with
@@ -471,7 +476,7 @@ let extractDocs ~entryPointFile ~debug =
471476
^ Shared.typeToString typ;
472477
name = item.name;
473478
deprecated = item.deprecated;
474-
detail = valueDetail item typ;
479+
detail = valueDetail typ;
475480
source;
476481
})
477482
| Type (typ, _) ->

0 commit comments

Comments
 (0)