Skip to content

Commit

Permalink
Add additional signature information to doc json (#1043)
Browse files Browse the repository at this point in the history
* Add signature to details

* Include Tsubst and Tpoly

* Update processing of Tpoly
  • Loading branch information
nojaf authored Oct 22, 2024
1 parent f173347 commit 3b1014e
Show file tree
Hide file tree
Showing 9 changed files with 300 additions and 2 deletions.
2 changes: 1 addition & 1 deletion tools/bin/main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Usage: rescript-tools [command]

Commands:

doc Generate documentation
doc <file> Generate documentation
reanalyze Reanalyze
-v, --version Print version
-h, --help Print help|}
Expand Down
13 changes: 13 additions & 0 deletions tools/npm/Tools_Docgen.res
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,21 @@ type constructor = {
payload?: constructorPayload,
}

type rec typeInSignature = {
path: string,
genericTypeParameters: array<typeInSignature>,
}

type signatureDetais = {
parameters: array<typeInSignature>,
returnType: typeInSignature,
}

@tag("kind")
type detail =
| @as("record") Record({items: array<field>})
| @as("variant") Variant({items: array<constructor>})
| @as("alias") Signature(signatureDetais)

type source = {
filepath: string,
Expand All @@ -38,6 +49,8 @@ type rec item =
name: string,
deprecated?: string,
source: source,
/** Additional documentation of signature, if available. */
detail?: detail,
})
| @as("type")
Type({
Expand Down
14 changes: 14 additions & 0 deletions tools/npm/Tools_Docgen.resi
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,22 @@ type constructor = {
deprecated?: string,
payload?: constructorPayload,
}

type rec typeInSignature = {
path: string,
genericTypeParameters: array<typeInSignature>,
}

type signatureDetais = {
parameters: array<typeInSignature>,
returnType: typeInSignature,
}

@tag("kind")
type detail =
| @as("record") Record({items: array<field>})
| @as("variant") Variant({items: array<constructor>})
| @as("signature") Signature(signatureDetais)

type source = {
filepath: string,
Expand All @@ -37,6 +49,8 @@ type rec item =
name: string,
deprecated?: string,
source: source,
/** Additional documentation of signature, if available. */
detail?: detail,
})
| @as("type")
Type({
Expand Down
99 changes: 98 additions & 1 deletion tools/src/tools.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@ type constructorDoc = {
items: constructorPayload option;
}

type typeDoc = {path: string; genericParameters: typeDoc list}
type valueSignature = {parameters: typeDoc list; returnType: typeDoc}

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

type docItemDetail =
| Record of {fieldDocs: fieldDoc list}
| Variant of {constructorDocs: constructorDoc list}
| Signature of valueSignature

type docItem =
| Value of {
Expand All @@ -31,6 +35,7 @@ type docItem =
signature: string;
name: string;
deprecated: string option;
detail: docItemDetail option;
source: source;
}
| Type of {
Expand Down Expand Up @@ -104,6 +109,19 @@ let stringifyConstructorPayload ~indentation
|> array) );
]

let rec stringifyTypeDoc ~indentation (td : typeDoc) : string =
let open Protocol in
let ps =
match td.genericParameters with
| [] -> None
| ts ->
ts |> List.map (stringifyTypeDoc ~indentation:(indentation + 1))
|> fun ts -> Some (array ts)
in

stringifyObject ~indentation:(indentation + 1)
[("path", Some (wrapInQuotes td.path)); ("genericTypeParameters", ps)]

let stringifyDetail ?(indentation = 0) (detail : docItemDetail) =
let open Protocol in
match detail with
Expand Down Expand Up @@ -147,6 +165,25 @@ let stringifyDetail ?(indentation = 0) (detail : docItemDetail) =
])
|> array) );
]
| Signature {parameters; returnType} ->
let ps =
match parameters with
| [] -> None
| ps ->
ps |> List.map (stringifyTypeDoc ~indentation:(indentation + 1))
|> fun ps -> Some (array ps)
in
stringifyObject ~startOnNewline:true ~indentation
[
("kind", Some (wrapInQuotes "signature"));
( "items",
Some
(stringifyObject ~startOnNewline:false ~indentation
[
("parameters", ps);
("returnType", Some (stringifyTypeDoc ~indentation returnType));
]) );
]

let stringifySource ~indentation source =
let open Protocol in
Expand All @@ -160,7 +197,7 @@ let stringifySource ~indentation source =
let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) =
let open Protocol in
match item with
| Value {id; docstring; signature; name; deprecated; source} ->
| Value {id; docstring; signature; name; deprecated; source; detail} ->
stringifyObject ~startOnNewline:true ~indentation
[
("id", Some (wrapInQuotes id));
Expand All @@ -173,6 +210,11 @@ let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) =
("signature", Some (signature |> String.trim |> wrapInQuotes));
("docstrings", Some (stringifyDocstrings docstring));
("source", Some (stringifySource ~indentation:(indentation + 1) source));
( "detail",
match detail with
| None -> None
| Some detail ->
Some (stringifyDetail ~indentation:(indentation + 1) detail) );
]
| Type {id; docstring; signature; name; deprecated; detail; source} ->
stringifyObject ~startOnNewline:true ~indentation
Expand Down Expand Up @@ -310,6 +352,60 @@ let typeDetail typ ~env ~full =
})
| _ -> None

(* split a list into two parts all the items except the last one and the last item *)
let splitLast l =
let rec splitLast' acc = function
| [] -> failwith "splitLast: empty list"
| [x] -> (List.rev acc, x)
| x :: xs -> splitLast' (x :: acc) xs
in
splitLast' [] l

let path_to_string path =
let buf = Buffer.create 64 in
let rec aux = function
| Path.Pident id -> Buffer.add_string buf (Ident.name id)
| Path.Pdot (p, s, _) ->
aux p;
Buffer.add_char buf '.';
Buffer.add_string buf s
| Path.Papply (p1, p2) ->
aux p1;
Buffer.add_char buf '(';
aux p2;
Buffer.add_char buf ')'
in
aux path;
Buffer.contents buf

let valueDetail (typ : Types.type_expr) =
let rec collectSignatureTypes (typ_desc : Types.type_desc) =
match typ_desc with
| Tlink t | Tsubst t | Tpoly (t, []) -> collectSignatureTypes t.desc
| Tconstr (Path.Pident {name = "function$"}, [t; _], _) ->
collectSignatureTypes t.desc
| Tconstr (path, ts, _) -> (
let p = path_to_string path in
match ts with
| [] -> [{path = p; genericParameters = []}]
| ts ->
let ts =
ts
|> List.concat_map (fun (t : Types.type_expr) ->
collectSignatureTypes t.desc)
in
[{path = p; genericParameters = ts}])
| Tarrow (_, t1, t2, _) ->
collectSignatureTypes t1.desc @ collectSignatureTypes t2.desc
| Tvar None -> [{path = "_"; genericParameters = []}]
| _ -> []
in
match collectSignatureTypes typ.desc with
| [] -> None
| ts ->
let parameters, returnType = splitLast ts in
Some (Signature {parameters; returnType})

let makeId modulePath ~identifier =
identifier :: modulePath |> List.rev |> SharedTypes.ident

Expand Down Expand Up @@ -398,6 +494,7 @@ let extractDocs ~entryPointFile ~debug =
^ Shared.typeToString typ;
name = item.name;
deprecated = item.deprecated;
detail = valueDetail typ;
source;
})
| Type (typ, _) ->
Expand Down
24 changes: 24 additions & 0 deletions tools/tests/src/expected/DocExtraction2.res.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@
"filepath": "src/DocExtraction2.resi",
"line": 7,
"col": 1
},
"detail":
{
"kind": "signature",
"items": {
"parameters": [{
"path": "unit"
}],
"returnType": {
"path": "t"
}
}
}
},
{
Expand Down Expand Up @@ -65,6 +77,18 @@
"filepath": "src/DocExtraction2.resi",
"line": 15,
"col": 3
},
"detail":
{
"kind": "signature",
"items": {
"parameters": [{
"path": "unit"
}],
"returnType": {
"path": "t"
}
}
}
}]
}]
Expand Down
24 changes: 24 additions & 0 deletions tools/tests/src/expected/DocExtraction2.resi.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@
"filepath": "src/DocExtraction2.resi",
"line": 7,
"col": 1
},
"detail":
{
"kind": "signature",
"items": {
"parameters": [{
"path": "unit"
}],
"returnType": {
"path": "t"
}
}
}
},
{
Expand Down Expand Up @@ -65,6 +77,18 @@
"filepath": "src/DocExtraction2.resi",
"line": 15,
"col": 3
},
"detail":
{
"kind": "signature",
"items": {
"parameters": [{
"path": "unit"
}],
"returnType": {
"path": "t"
}
}
}
}]
}]
Expand Down
Loading

0 comments on commit 3b1014e

Please sign in to comment.