From c7e05ea1998c60a63c210dbbb2f2d854af01bffb Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Fri, 22 Dec 2023 05:09:01 +0900 Subject: [PATCH 1/3] GenType: support `@deriving(accessors)` outputs --- jscomp/frontend/ast_attributes.ml | 7 +++++++ jscomp/frontend/ast_attributes.mli | 4 ++++ jscomp/frontend/ast_comb.ml | 6 +++--- jscomp/frontend/ast_comb.mli | 10 ++++++++-- jscomp/frontend/ast_derive_projector.ml | 16 +++++++++++---- jscomp/frontend/ast_derive_util.ml | 4 ++-- .../src/Derivings.bs.js | 20 +++++++++++++++++++ .../src/Derivings.gen.tsx | 17 ++++++++++++++++ .../src/Derivings.res | 5 +++++ jscomp/runtime/release.ninja | 6 +++--- 10 files changed, 81 insertions(+), 14 deletions(-) create mode 100644 jscomp/gentype_tests/typescript-react-example/src/Derivings.bs.js create mode 100644 jscomp/gentype_tests/typescript-react-example/src/Derivings.gen.tsx create mode 100644 jscomp/gentype_tests/typescript-react-example/src/Derivings.res diff --git a/jscomp/frontend/ast_attributes.ml b/jscomp/frontend/ast_attributes.ml index 64863372c9..0cf882cbb2 100644 --- a/jscomp/frontend/ast_attributes.ml +++ b/jscomp/frontend/ast_attributes.ml @@ -373,3 +373,10 @@ let bs_return_undefined : attr = pstr_loc = locg; }; ] ) + +let is_gentype (attr : attr) = + match attr with + | {Location.txt = "genType" | "gentype"; _}, _ -> true + | _ -> false + +let gentype : attr = ({txt = "genType"; loc = locg}, Ast_payload.empty) diff --git a/jscomp/frontend/ast_attributes.mli b/jscomp/frontend/ast_attributes.mli index 97e14ec13e..ec31ccb547 100644 --- a/jscomp/frontend/ast_attributes.mli +++ b/jscomp/frontend/ast_attributes.mli @@ -90,3 +90,7 @@ val internal_expansive : attr val rs_externals : t -> string list -> bool val process_send_pipe : t -> (Parsetree.core_type * t) option + +val is_gentype : attr -> bool + +val gentype : attr diff --git a/jscomp/frontend/ast_comb.ml b/jscomp/frontend/ast_comb.ml index 24e8adc03f..0462a79968 100644 --- a/jscomp/frontend/ast_comb.ml +++ b/jscomp/frontend/ast_comb.ml @@ -62,7 +62,7 @@ let to_js_re_type loc = Typ.constr ~loc {txt = re_id; loc} [] let to_undefined_type loc x = Typ.constr ~loc {txt = Ast_literal.Lid.js_undefined; loc} [x] -let single_non_rec_value name exp = - Str.value Nonrecursive [Vb.mk (Pat.var name) exp] +let single_non_rec_value ?(attrs = []) name exp = + Str.value Nonrecursive [Vb.mk ~attrs (Pat.var name) exp] -let single_non_rec_val name ty = Sig.value (Val.mk name ty) +let single_non_rec_val ?(attrs = []) name ty = Sig.value (Val.mk ~attrs name ty) diff --git a/jscomp/frontend/ast_comb.mli b/jscomp/frontend/ast_comb.mli index 873b20f2d3..21dbfa989d 100644 --- a/jscomp/frontend/ast_comb.mli +++ b/jscomp/frontend/ast_comb.mli @@ -42,7 +42,13 @@ val to_undefined_type : Location.t -> Parsetree.core_type -> Parsetree.core_type val to_js_re_type : Location.t -> Parsetree.core_type val single_non_rec_value : - Ast_helper.str -> Parsetree.expression -> Parsetree.structure_item + ?attrs:Parsetree.attributes -> + Ast_helper.str -> + Parsetree.expression -> + Parsetree.structure_item val single_non_rec_val : - Ast_helper.str -> Parsetree.core_type -> Parsetree.signature_item + ?attrs:Parsetree.attributes -> + Ast_helper.str -> + Parsetree.core_type -> + Parsetree.signature_item diff --git a/jscomp/frontend/ast_derive_projector.ml b/jscomp/frontend/ast_derive_projector.ml index 707cb7c9ec..51955d80fc 100644 --- a/jscomp/frontend/ast_derive_projector.ml +++ b/jscomp/frontend/ast_derive_projector.ml @@ -18,6 +18,10 @@ let init () = let core_type = Ast_derive_util.core_type_of_type_declaration tdcl in + let gentype_attrs = + Ext_list.filter core_type.ptyp_attributes + Ast_attributes.is_gentype + in match tdcl.ptype_kind with | Ptype_record label_declarations -> Ext_list.map label_declarations @@ -26,7 +30,7 @@ let init () = Parsetree.label_declaration) -> let txt = "param" in - Ast_comb.single_non_rec_value pld_name + Ast_comb.single_non_rec_value ~attrs:gentype_attrs pld_name (Ast_compatible.fun_ (Pat.constraint_ (Pat.var {txt; loc}) core_type) (Exp.field @@ -57,7 +61,7 @@ let init () = | None -> core_type | Some x -> x in - Ast_comb.single_non_rec_value + Ast_comb.single_non_rec_value ~attrs:gentype_attrs {loc; txt = little_con_name} (if arity = 0 then (*TODO: add a prefix, better inter-op with FFI *) @@ -99,10 +103,14 @@ let init () = let core_type = Ast_derive_util.core_type_of_type_declaration tdcl in + let gentype_attrs = + Ext_list.filter core_type.ptyp_attributes + Ast_attributes.is_gentype + in match tdcl.ptype_kind with | Ptype_record label_declarations -> Ext_list.map label_declarations (fun {pld_name; pld_type} -> - Ast_comb.single_non_rec_val pld_name + Ast_comb.single_non_rec_val ~attrs:gentype_attrs pld_name (Ast_compatible.arrow core_type pld_type)) | Ptype_variant constructor_declarations -> Ext_list.map constructor_declarations @@ -124,7 +132,7 @@ let init () = | Some x -> x | None -> core_type in - Ast_comb.single_non_rec_val + Ast_comb.single_non_rec_val ~attrs:gentype_attrs {loc; txt = Ext_string.uncapitalize_ascii con_name} (Ext_list.fold_right pcd_args annotate_type (fun x acc -> Ast_compatible.arrow x acc))) diff --git a/jscomp/frontend/ast_derive_util.ml b/jscomp/frontend/ast_derive_util.ml index 779f82e82f..782c055d48 100644 --- a/jscomp/frontend/ast_derive_util.ml +++ b/jscomp/frontend/ast_derive_util.ml @@ -26,8 +26,8 @@ open Ast_helper let core_type_of_type_declaration (tdcl : Parsetree.type_declaration) = match tdcl with - | {ptype_name = {txt; loc}; ptype_params} -> - Typ.constr {txt = Lident txt; loc} (Ext_list.map ptype_params fst) + | {ptype_name = {txt; loc}; ptype_params; ptype_attributes = attrs} -> + Typ.constr ~attrs {txt = Lident txt; loc} (Ext_list.map ptype_params fst) let new_type_of_type_declaration (tdcl : Parsetree.type_declaration) newName = match tdcl with diff --git a/jscomp/gentype_tests/typescript-react-example/src/Derivings.bs.js b/jscomp/gentype_tests/typescript-react-example/src/Derivings.bs.js new file mode 100644 index 0000000000..5165501116 --- /dev/null +++ b/jscomp/gentype_tests/typescript-react-example/src/Derivings.bs.js @@ -0,0 +1,20 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function submit(param_0) { + return { + TAG: "Submit", + _0: param_0 + }; +} + +var click = "Click"; + +var cancel = "Cancel"; + +export { + click , + submit , + cancel , +} +/* No side effect */ diff --git a/jscomp/gentype_tests/typescript-react-example/src/Derivings.gen.tsx b/jscomp/gentype_tests/typescript-react-example/src/Derivings.gen.tsx new file mode 100644 index 0000000000..38d8b3291f --- /dev/null +++ b/jscomp/gentype_tests/typescript-react-example/src/Derivings.gen.tsx @@ -0,0 +1,17 @@ +/* TypeScript file generated from Derivings.res by genType. */ + +/* eslint-disable */ +/* tslint:disable */ + +import * as DerivingsBS from './Derivings.bs'; + +export type action = + "Click" + | "Cancel" + | { TAG: "Submit"; _0: string }; + +export const click: action = DerivingsBS.click as any; + +export const submit: (_1:string) => action = DerivingsBS.submit as any; + +export const cancel: action = DerivingsBS.cancel as any; diff --git a/jscomp/gentype_tests/typescript-react-example/src/Derivings.res b/jscomp/gentype_tests/typescript-react-example/src/Derivings.res new file mode 100644 index 0000000000..d55c189575 --- /dev/null +++ b/jscomp/gentype_tests/typescript-react-example/src/Derivings.res @@ -0,0 +1,5 @@ +@genType @deriving(accessors) +type action = + | Click + | Submit(string) + | Cancel diff --git a/jscomp/runtime/release.ninja b/jscomp/runtime/release.ninja index 181ca9fa81..b7b44625e4 100644 --- a/jscomp/runtime/release.ninja +++ b/jscomp/runtime/release.ninja @@ -21,7 +21,7 @@ o runtime/caml_bytes.cmj : cc_cmi runtime/caml_bytes.res | runtime/caml_bytes.cm o runtime/caml_bytes.cmi : cc runtime/caml_bytes.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj o runtime/caml_float.cmj : cc_cmi runtime/caml_float.res | runtime/caml_float.cmi runtime/caml_float_extern.cmj o runtime/caml_float.cmi : cc runtime/caml_float.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj -o runtime/caml_format.cmj : cc_cmi runtime/caml_format.ml | runtime/caml_float.cmj runtime/caml_float_extern.cmj runtime/caml_format.cmi runtime/caml_int64.cmj runtime/caml_int64_extern.cmj runtime/caml_nativeint_extern.cmj runtime/caml_string_extern.cmj +o runtime/caml_format.cmj : cc_cmi runtime/caml_format.ml | runtime/caml.cmj runtime/caml_float.cmj runtime/caml_float_extern.cmj runtime/caml_format.cmi runtime/caml_int64.cmj runtime/caml_int64_extern.cmj runtime/caml_nativeint_extern.cmj runtime/caml_string_extern.cmj o runtime/caml_format.cmi : cc runtime/caml_format.mli | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj o runtime/caml_hash.cmj : cc_cmi runtime/caml_hash.res | runtime/caml_hash.cmi runtime/caml_hash_primitive.cmj runtime/caml_nativeint_extern.cmj runtime/js.cmj o runtime/caml_hash.cmi : cc runtime/caml_hash.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj @@ -37,7 +37,7 @@ o runtime/caml_md5.cmj : cc_cmi runtime/caml_md5.res | runtime/caml_array_extern o runtime/caml_md5.cmi : cc runtime/caml_md5.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj o runtime/caml_module.cmj : cc_cmi runtime/caml_module.res | runtime/caml_array_extern.cmj runtime/caml_module.cmi runtime/caml_obj.cmj o runtime/caml_module.cmi : cc runtime/caml_module.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj -o runtime/caml_obj.cmj : cc_cmi runtime/caml_obj.res | runtime/caml_array_extern.cmj runtime/caml_obj.cmi runtime/caml_option.cmj runtime/js.cmj +o runtime/caml_obj.cmj : cc_cmi runtime/caml_obj.res | runtime/caml.cmj runtime/caml_array_extern.cmj runtime/caml_obj.cmi runtime/caml_option.cmj runtime/js.cmj o runtime/caml_obj.cmi : cc runtime/caml_obj.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj o runtime/caml_option.cmj : cc_cmi runtime/caml_option.res | runtime/caml_option.cmi runtime/caml_undefined_extern.cmj runtime/js.cmj o runtime/caml_option.cmi : cc runtime/caml_option.resi | runtime/bs_stdlib_mini.cmi runtime/caml_undefined_extern.cmj runtime/js.cmi runtime/js.cmj @@ -54,7 +54,7 @@ o runtime/caml_exceptions.cmi runtime/caml_exceptions.cmj : cc runtime/caml_exce o runtime/caml_external_polyfill.cmi runtime/caml_external_polyfill.cmj : cc runtime/caml_external_polyfill.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj o runtime/caml_float_extern.cmi runtime/caml_float_extern.cmj : cc runtime/caml_float_extern.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj o runtime/caml_int64_extern.cmi runtime/caml_int64_extern.cmj : cc runtime/caml_int64_extern.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj -o runtime/caml_js_exceptions.cmi runtime/caml_js_exceptions.cmj : cc runtime/caml_js_exceptions.res | runtime/bs_stdlib_mini.cmi runtime/caml_exceptions.cmj runtime/js.cmi runtime/js.cmj +o runtime/caml_js_exceptions.cmi runtime/caml_js_exceptions.cmj : cc runtime/caml_js_exceptions.res | runtime/bs_stdlib_mini.cmi runtime/caml_exceptions.cmj runtime/caml_option.cmj runtime/js.cmi runtime/js.cmj o runtime/caml_nativeint_extern.cmi runtime/caml_nativeint_extern.cmj : cc runtime/caml_nativeint_extern.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj o runtime/caml_string_extern.cmi runtime/caml_string_extern.cmj : cc runtime/caml_string_extern.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj o runtime/caml_undefined_extern.cmi runtime/caml_undefined_extern.cmj : cc runtime/caml_undefined_extern.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj From 409dbdb6807be987523fcafdbfd299c986805f39 Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Fri, 22 Dec 2023 05:22:49 +0900 Subject: [PATCH 2/3] [skip ci] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57e0b29e69..5f8af33ca5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ # 11.0.0-rc.9 (Unreleased) +#### :rocket: New Feature + +- GenType: support `@deriving(accessors)` outputs. https://github.com/rescript-lang/rescript-compiler/pull/6537 + # 11.0.0-rc.8 #### :rocket: New Feature From d84093982799b22ae7da5eb7afdb306096d8b756 Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Sat, 23 Dec 2023 00:08:46 +0900 Subject: [PATCH 3/3] changed to not recycle loc unintentinonlly --- jscomp/frontend/ast_derive_projector.ml | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/jscomp/frontend/ast_derive_projector.ml b/jscomp/frontend/ast_derive_projector.ml index 51955d80fc..ca63811c6f 100644 --- a/jscomp/frontend/ast_derive_projector.ml +++ b/jscomp/frontend/ast_derive_projector.ml @@ -19,8 +19,12 @@ let init () = Ast_derive_util.core_type_of_type_declaration tdcl in let gentype_attrs = - Ext_list.filter core_type.ptyp_attributes - Ast_attributes.is_gentype + match + Ext_list.exists core_type.ptyp_attributes + Ast_attributes.is_gentype + with + | true -> Some [Ast_attributes.gentype] + | false -> None in match tdcl.ptype_kind with | Ptype_record label_declarations -> @@ -30,7 +34,7 @@ let init () = Parsetree.label_declaration) -> let txt = "param" in - Ast_comb.single_non_rec_value ~attrs:gentype_attrs pld_name + Ast_comb.single_non_rec_value ?attrs:gentype_attrs pld_name (Ast_compatible.fun_ (Pat.constraint_ (Pat.var {txt; loc}) core_type) (Exp.field @@ -61,7 +65,7 @@ let init () = | None -> core_type | Some x -> x in - Ast_comb.single_non_rec_value ~attrs:gentype_attrs + Ast_comb.single_non_rec_value ?attrs:gentype_attrs {loc; txt = little_con_name} (if arity = 0 then (*TODO: add a prefix, better inter-op with FFI *) @@ -104,13 +108,17 @@ let init () = Ast_derive_util.core_type_of_type_declaration tdcl in let gentype_attrs = - Ext_list.filter core_type.ptyp_attributes - Ast_attributes.is_gentype + match + Ext_list.exists core_type.ptyp_attributes + Ast_attributes.is_gentype + with + | true -> Some [Ast_attributes.gentype] + | false -> None in match tdcl.ptype_kind with | Ptype_record label_declarations -> Ext_list.map label_declarations (fun {pld_name; pld_type} -> - Ast_comb.single_non_rec_val ~attrs:gentype_attrs pld_name + Ast_comb.single_non_rec_val ?attrs:gentype_attrs pld_name (Ast_compatible.arrow core_type pld_type)) | Ptype_variant constructor_declarations -> Ext_list.map constructor_declarations @@ -132,7 +140,7 @@ let init () = | Some x -> x | None -> core_type in - Ast_comb.single_non_rec_val ~attrs:gentype_attrs + Ast_comb.single_non_rec_val ?attrs:gentype_attrs {loc; txt = Ext_string.uncapitalize_ascii con_name} (Ext_list.fold_right pcd_args annotate_type (fun x acc -> Ast_compatible.arrow x acc)))