Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- Remove runtime APIs that were deprecated for removal in ReScript 13, including the `Char` module, unsafe `Obj` operations, legacy `Pervasives` helpers, and `Array.unsafe_get`. https://github.com/rescript-lang/rescript/pull/8564
- Remove the deprecated `Js` namespace and its runtime modules. https://github.com/rescript-lang/rescript/pull/8531
- Move Belt into the separately installed `@rescript/belt` package. Projects using Belt must install the package and list it in their `rescript.json` dependencies. https://github.com/rescript-lang/rescript/pull/8554
- Correct the structured function details produced by `rescript-tools doc` and exposed by `RescriptTools.Docgen`: parameters now retain labels and optionality, nested functions, tuples, variables, and generic arguments retain their type structure, return types are identified correctly, and non-function values no longer receive fake function details. This changes the published docgen detail schema. https://github.com/rescript-lang/rescript/pull/8576

#### :eyeglasses: Spec Compliance

Expand Down
11 changes: 4 additions & 7 deletions compiler/ml/oprint.ml
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,10 @@ and print_out_type_1 ppf = function
pp_open_box ppf 0;
List.iter
(fun (lab, ty1) ->
if lab <> "" then (
pp_print_string ppf lab;
pp_print_char ppf ':');
(match lab with
| Asttypes.Noloc.Nolabel -> ()
| Asttypes.Noloc.Labelled label -> fprintf ppf "%s:" label
| Asttypes.Noloc.Optional label -> fprintf ppf "?%s:" label);
print_out_type_2 ppf ty1;
pp_print_string ppf " ->";
pp_print_space ppf ())
Expand Down Expand Up @@ -406,10 +407,6 @@ let rec print_out_class_type ppf = function
| tyl -> fprintf ppf "@[<1>[%a]@]@ " (print_typlist !out_type ",") tyl
in
fprintf ppf "@[%a%a@]" pr_tyl tyl print_ident id
| Octy_arrow (lab, ty, cty) ->
fprintf ppf "@[%s%a ->@ %a@]"
(if lab <> "" then lab ^ ":" else "")
print_out_type_2 ty print_out_class_type cty
| Octy_signature (self_ty, csil) ->
let pr_param ppf = function
| Some ty -> fprintf ppf "@ @[(%a)@]" !out_type ty
Expand Down
3 changes: 1 addition & 2 deletions compiler/ml/outcometree.ml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type out_type =
| Otyp_abstract
| Otyp_open
| Otyp_alias of out_type * string
| Otyp_arrow of (string * out_type) list * out_type
| Otyp_arrow of (Asttypes.Noloc.arg_label * out_type) list * out_type
| Otyp_class of bool * out_ident * out_type list
| Otyp_constr of out_ident * out_type list
| Otyp_manifest of out_type * out_type
Expand All @@ -74,7 +74,6 @@ and out_variant =

type out_class_type =
| Octy_constr of out_ident * out_type list
| Octy_arrow of string * out_type * out_class_type
| Octy_signature of out_type option * out_class_sig_item list
and out_class_sig_item =
| Ocsg_constraint of out_type * out_type
Expand Down
3 changes: 1 addition & 2 deletions compiler/ml/printtyp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,6 @@ let rec tree_of_typexp ?(printing_context : printing_context option) sch ty =
let args =
List.map
(fun (arg : Types.arg) ->
let lab = string_of_label arg.lbl in
let t1 =
if is_optional arg.lbl then
match (repr arg.typ).desc with
Expand All @@ -626,7 +625,7 @@ let rec tree_of_typexp ?(printing_context : printing_context option) sch ty =
| _ -> Otyp_stuff "<hidden>"
else tree_of_typexp ?printing_context sch arg.typ
in
(lab, t1))
(Asttypes.to_noloc arg.lbl, t1))
params
in
Otyp_arrow (args, tree_of_typexp ?printing_context sch ret)
Expand Down
35 changes: 16 additions & 19 deletions compiler/syntax/src/res_outcome_printer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -238,37 +238,34 @@ let rec print_out_type_doc (out_type : Outcometree.out_type) =

and print_out_arrow_type typ =
let typ_args, typ = collect_arrow_args typ in
let print_labeled_arg label optional_indicator typ =
Doc.group
(Doc.concat
[
Doc.text ("~" ^ label ^ ": ");
print_out_type_doc typ;
optional_indicator;
])
in
let args =
Doc.join
~sep:(Doc.concat [Doc.comma; Doc.line])
(List.map
(fun (lbl, typ) ->
let lbl_len = String.length lbl in
if lbl_len = 0 then print_out_type_doc typ
else
let lbl, optional_indicator =
(* the ocaml compiler hardcodes the optional label inside the string of the label in printtyp.ml *)
match String.unsafe_get lbl 0 with
| '?' ->
( (String.sub [@doesNotRaise]) lbl 1 (lbl_len - 1),
Doc.text "=?" )
| _ -> (lbl, Doc.nil)
in
Doc.group
(Doc.concat
[
Doc.text ("~" ^ lbl ^ ": ");
print_out_type_doc typ;
optional_indicator;
]))
match lbl with
| Asttypes.Noloc.Nolabel -> print_out_type_doc typ
| Asttypes.Noloc.Labelled label ->
print_labeled_arg label Doc.nil typ
| Asttypes.Noloc.Optional label ->
print_labeled_arg label (Doc.text "=?") typ)
typ_args)
in
let args_doc =
let needs_parens =
match typ_args with
| [(_, (Otyp_tuple _ | Otyp_arrow _))] -> true
(* single argument should not be wrapped *)
| [("", _)] -> false
| [(Asttypes.Noloc.Nolabel, _)] -> false
| _ -> true
in
if needs_parens then
Expand Down
18 changes: 13 additions & 5 deletions packages/@rescript/runtime/RescriptTools_Docgen.res
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,29 @@ type constructor = {
payload?: constructorPayload,
}

type rec typeInSignature = {
path: string,
genericTypeParameters: array<typeInSignature>,
@tag("kind")
type rec typeInSignature =
| @as("constructor") Constructor({path: string, genericTypeParameters: array<typeInSignature>})
| @as("variable") Variable({name: string, weak: bool})
| @as("tuple") Tuple({elements: array<typeInSignature>})
| @as("function") Function({parameters: array<signatureParameter>, returnType: typeInSignature})
| @as("rendered") Rendered({signature: string})
and signatureParameter = {
label?: string,
optional: bool,
@as("type") type_: typeInSignature,
}

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

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

type source = {
filepath: string,
Expand Down
16 changes: 12 additions & 4 deletions packages/@rescript/runtime/RescriptTools_Docgen.resi
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,21 @@ type constructor = {
payload?: constructorPayload,
}

type rec typeInSignature = {
path: string,
genericTypeParameters: array<typeInSignature>,
@tag("kind")
type rec typeInSignature =
| @as("constructor") Constructor({path: string, genericTypeParameters: array<typeInSignature>})
| @as("variable") Variable({name: string, weak: bool})
| @as("tuple") Tuple({elements: array<typeInSignature>})
| @as("function") Function({parameters: array<signatureParameter>, returnType: typeInSignature})
| @as("rendered") Rendered({signature: string})
and signatureParameter = {
label?: string,
optional: bool,
@as("type") type_: typeInSignature,
}

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

Expand Down
17 changes: 17 additions & 0 deletions tests/tools_tests/src/DocgenSignatureDetails.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
let labeledOptional: (~required: 'a, ~optional: array<'a>=?) => result<'a, string> = (
~required,
~optional=?,
) => {
ignore(optional)
Ok(required)
}

let takesCallback: ('a => string) => bool = _callback => true

let returnsTuple: int => (string, int) = value => ("value", value)

let returnsFunction: int => string => bool = _value => _text => true

let takesVariant: [#enabled | #count(int)] => unit = _variant => ()

let constant = 42
17 changes: 17 additions & 0 deletions tests/tools_tests/src/DocgenSignatureDetails.resi
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/** Labeled and optional parameters keep their parameter metadata. */
let labeledOptional: (~required: 'a, ~optional: array<'a>=?) => result<'a, string>

/** A callback remains one parameter instead of becoming outer parameters. */
let takesCallback: ('a => string) => bool

/** A tuple remains one return-type node. */
let returnsTuple: int => (string, int)

/** A returned function remains nested in the return type. */
let returnsFunction: int => string => bool

/** Less common type forms remain visible through an explicit fallback. */
let takesVariant: [#enabled | #count(int)] => unit

/** Non-functions do not receive function signature details. */
let constant: int
45 changes: 39 additions & 6 deletions tests/tools_tests/src/expected/DocExtraction2.res.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,21 @@
"detail": {
"kind": "signature",
"details": {
"parameters": [ { "path": "unit", "genericTypeParameters": [] } ],
"returnType": { "path": "t", "genericTypeParameters": [] }
"parameters": [
{
"optional": false,
"type": {
"kind": "constructor",
"path": "unit",
"genericTypeParameters": []
}
}
],
"returnType": {
"kind": "constructor",
"path": "t",
"genericTypeParameters": []
}
}
}
},
Expand Down Expand Up @@ -72,9 +85,20 @@
"kind": "signature",
"details": {
"parameters": [
{ "path": "unit", "genericTypeParameters": [] }
{
"optional": false,
"type": {
"kind": "constructor",
"path": "unit",
"genericTypeParameters": []
}
}
],
"returnType": { "path": "t", "genericTypeParameters": [] }
"returnType": {
"kind": "constructor",
"path": "t",
"genericTypeParameters": []
}
}
}
}
Expand All @@ -95,8 +119,17 @@
"detail": {
"kind": "signature",
"details": {
"parameters": [],
"returnType": { "path": "unit", "genericTypeParameters": [] }
"parameters": [
{
"optional": false,
"type": { "kind": "variable", "name": "a", "weak": false }
}
],
"returnType": {
"kind": "constructor",
"path": "unit",
"genericTypeParameters": []
}
}
}
}
Expand Down
45 changes: 39 additions & 6 deletions tests/tools_tests/src/expected/DocExtraction2.resi.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,21 @@
"detail": {
"kind": "signature",
"details": {
"parameters": [ { "path": "unit", "genericTypeParameters": [] } ],
"returnType": { "path": "t", "genericTypeParameters": [] }
"parameters": [
{
"optional": false,
"type": {
"kind": "constructor",
"path": "unit",
"genericTypeParameters": []
}
}
],
"returnType": {
"kind": "constructor",
"path": "t",
"genericTypeParameters": []
}
}
}
},
Expand Down Expand Up @@ -72,9 +85,20 @@
"kind": "signature",
"details": {
"parameters": [
{ "path": "unit", "genericTypeParameters": [] }
{
"optional": false,
"type": {
"kind": "constructor",
"path": "unit",
"genericTypeParameters": []
}
}
],
"returnType": { "path": "t", "genericTypeParameters": [] }
"returnType": {
"kind": "constructor",
"path": "t",
"genericTypeParameters": []
}
}
}
}
Expand All @@ -95,8 +119,17 @@
"detail": {
"kind": "signature",
"details": {
"parameters": [],
"returnType": { "path": "unit", "genericTypeParameters": [] }
"parameters": [
{
"optional": false,
"type": { "kind": "variable", "name": "a", "weak": false }
}
],
"returnType": {
"kind": "constructor",
"path": "unit",
"genericTypeParameters": []
}
}
}
}
Expand Down
Loading
Loading