diff --git a/compiler/frontend/ast_core_type_class_type.ml b/compiler/frontend/ast_core_type_class_type.ml index fccd2f0f55..e8bfcb4cdd 100644 --- a/compiler/frontend/ast_core_type_class_type.ml +++ b/compiler/frontend/ast_core_type_class_type.ml @@ -56,7 +56,7 @@ let process_getter_setter ~not_getter_setter pctf_attributes :: get_acc -let default_typ_mapper = Bs_ast_mapper.default_mapper.typ +let default_typ_mapper = Ast_mapper.default_mapper.typ (* Attributes are very hard to attribute (since ptyp_attributes could happen in so many places), @@ -64,7 +64,19 @@ let default_typ_mapper = Bs_ast_mapper.default_mapper.typ we can only use it locally *) -let typ_mapper (self : Bs_ast_mapper.mapper) (ty : Parsetree.core_type) = +(* Turns [(t1, .., tn) => ret] with a method-callback attribute into + [Js.MethodCallback.arityN]. *) +let to_method_callback_type loc (mapper : Ast_mapper.mapper) ~arity + (meth_type : Parsetree.core_type) = + let meth_type = Ast_mapper.default_mapper.typ mapper meth_type in + Ast_helper.Typ.constr + { + txt = Ldot (Ast_literal.Lid.method_callback, "arity" ^ string_of_int arity); + loc; + } + [meth_type] + +let typ_mapper (self : Ast_mapper.mapper) (ty : Parsetree.core_type) = let loc = ty.ptyp_loc in match ty.ptyp_desc with | Ptyp_arrow {params = _} @@ -76,10 +88,9 @@ let typ_mapper (self : Bs_ast_mapper.mapper) (ty : Parsetree.core_type) = | Meth_callback _ -> ( match ty.ptyp_desc with | Ptyp_arrow {params} -> - Ast_typ_uncurry.to_method_callback_type loc self - ~arity:(List.length params) ty + to_method_callback_type loc self ~arity:(List.length params) ty | _ -> assert false) - | Nothing -> Bs_ast_mapper.default_mapper.typ self ty) + | Nothing -> Ast_mapper.default_mapper.typ self ty) | Ptyp_object (methods, closed_flag) -> let ( +> ) attr (typ : Parsetree.core_type) = {typ with ptyp_attributes = attr :: typ.ptyp_attributes} diff --git a/compiler/frontend/ast_core_type_class_type.mli b/compiler/frontend/ast_core_type_class_type.mli index 088d300b3c..6592b20602 100644 --- a/compiler/frontend/ast_core_type_class_type.mli +++ b/compiler/frontend/ast_core_type_class_type.mli @@ -22,5 +22,4 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -val typ_mapper : - Bs_ast_mapper.mapper -> Parsetree.core_type -> Parsetree.core_type +val typ_mapper : Ast_mapper.mapper -> Parsetree.core_type -> Parsetree.core_type diff --git a/compiler/frontend/ast_exp_apply.ml b/compiler/frontend/ast_exp_apply.ml index 44d751a764..5775835fa0 100644 --- a/compiler/frontend/ast_exp_apply.ml +++ b/compiler/frontend/ast_exp_apply.ml @@ -42,7 +42,7 @@ let bound (e : exp) (cb : exp -> _) = [Vb.mk ~loc (Pat.var ~loc {txt = tuple_obj_id; loc}) e] (cb (Exp.ident ~loc {txt = Lident tuple_obj_id; loc})) -let default_expr_mapper = Bs_ast_mapper.default_mapper.expr +let default_expr_mapper = Ast_mapper.default_mapper.expr let check_and_discard (args : (Asttypes.arg_label * Parsetree.expression) list) = @@ -72,7 +72,7 @@ let view_as_app (fn : exp) (s : string list) : app_pattern option = let infix_ops = ["->"; "#="; "##"] -let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) : exp = +let app_exp_mapper (e : exp) (self : Ast_mapper.mapper) : exp = match view_as_app e infix_ops with | Some {op = "->"; args = [a_; f_]; loc} -> ( (* diff --git a/compiler/frontend/ast_exp_apply.mli b/compiler/frontend/ast_exp_apply.mli index 0fa498a681..65ba42f4c5 100644 --- a/compiler/frontend/ast_exp_apply.mli +++ b/compiler/frontend/ast_exp_apply.mli @@ -23,4 +23,4 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) val app_exp_mapper : - Parsetree.expression -> Bs_ast_mapper.mapper -> Parsetree.expression + Parsetree.expression -> Ast_mapper.mapper -> Parsetree.expression diff --git a/compiler/frontend/ast_exp_extension.ml b/compiler/frontend/ast_exp_extension.ml index adde841096..8b45cadc1d 100644 --- a/compiler/frontend/ast_exp_extension.ml +++ b/compiler/frontend/ast_exp_extension.ml @@ -23,7 +23,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) open Ast_helper -let handle_extension e (self : Bs_ast_mapper.mapper) +let handle_extension e (self : Ast_mapper.mapper) (({txt; loc}, payload) : Parsetree.extension) = match txt with | "todo" -> @@ -81,4 +81,4 @@ let handle_extension e (self : Bs_ast_mapper.mapper) (* For an unknown extension, we don't really need to process further*) (* Exp.extension ~loc ~attrs:e.pexp_attributes ( self.extension self extension) *) -(* Bs_ast_mapper.default_mapper.expr self e *) +(* Ast_mapper.default_mapper.expr self e *) diff --git a/compiler/frontend/ast_exp_extension.mli b/compiler/frontend/ast_exp_extension.mli index fbb449d0ac..778f8b0425 100644 --- a/compiler/frontend/ast_exp_extension.mli +++ b/compiler/frontend/ast_exp_extension.mli @@ -24,6 +24,6 @@ val handle_extension : Parsetree.expression -> - Bs_ast_mapper.mapper -> + Ast_mapper.mapper -> Parsetree.extension -> Parsetree.expression diff --git a/compiler/frontend/ast_external.ml b/compiler/frontend/ast_external.ml index f145999f25..91109173c2 100644 --- a/compiler/frontend/ast_external.ml +++ b/compiler/frontend/ast_external.ml @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -let handle_external_in_sig (self : Bs_ast_mapper.mapper) +let handle_external_in_sig (self : Ast_mapper.mapper) (prim : Parsetree.value_description) (sigi : Parsetree.signature_item) : Parsetree.signature_item = let loc = prim.pval_loc in @@ -51,7 +51,7 @@ let handle_external_in_sig (self : Bs_ast_mapper.mapper) }; }) -let handle_external_in_stru (self : Bs_ast_mapper.mapper) +let handle_external_in_stru (self : Ast_mapper.mapper) (prim : Parsetree.value_description) (str : Parsetree.structure_item) : Parsetree.structure_item = let loc = prim.pval_loc in diff --git a/compiler/frontend/ast_external.mli b/compiler/frontend/ast_external.mli index 8e53466962..140c453037 100644 --- a/compiler/frontend/ast_external.mli +++ b/compiler/frontend/ast_external.mli @@ -23,13 +23,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) val handle_external_in_sig : - Bs_ast_mapper.mapper -> + Ast_mapper.mapper -> Parsetree.value_description -> Parsetree.signature_item -> Parsetree.signature_item val handle_external_in_stru : - Bs_ast_mapper.mapper -> + Ast_mapper.mapper -> Parsetree.value_description -> Parsetree.structure_item -> Parsetree.structure_item diff --git a/compiler/frontend/ast_external_mk.ml b/compiler/frontend/ast_external_mk.ml index da95884d45..c1df71e494 100644 --- a/compiler/frontend/ast_external_mk.ml +++ b/compiler/frontend/ast_external_mk.ml @@ -28,35 +28,20 @@ let local_external_apply loc ?(pval_attributes = []) ~(pval_prim : string list) Parsetree.expression_desc = Pexp_letmodule ( {txt = local_module_name; loc}, - { - pmod_desc = - Pmod_structure - [ - { - pstr_desc = - Pstr_primitive - { - pval_name = {txt = local_fun_name; loc}; - pval_type; - pval_loc = loc; - pval_prim; - pval_attributes; - }; - pstr_loc = loc; - }; - ]; - pmod_loc = loc; - pmod_attributes = []; - }, + Ast_helper.Mod.structure ~loc + [ + Ast_helper.Str.primitive ~loc + { + pval_name = {txt = local_fun_name; loc}; + pval_type; + pval_loc = loc; + pval_prim; + pval_attributes; + }; + ], Ast_helper.Exp.apply ~loc - ({ - pexp_desc = - Pexp_ident - {txt = Ldot (Lident local_module_name, local_fun_name); loc}; - pexp_attributes = []; - pexp_loc = loc; - } - : Parsetree.expression) + (Ast_helper.Exp.ident ~loc + {txt = Ldot (Lident local_module_name, local_fun_name); loc}) (Ext_list.map args (fun x -> (Asttypes.Nolabel, x))) ) let local_external_obj loc ?(pval_attributes = []) ~pval_prim ~pval_type @@ -64,34 +49,19 @@ let local_external_obj loc ?(pval_attributes = []) ~pval_prim ~pval_type Parsetree.expression_desc = Pexp_letmodule ( {txt = local_module_name; loc}, - { - pmod_desc = - Pmod_structure - [ - { - pstr_desc = - Pstr_primitive - { - pval_name = {txt = local_fun_name; loc}; - pval_type; - pval_loc = loc; - pval_prim; - pval_attributes; - }; - pstr_loc = loc; - }; - ]; - pmod_loc = loc; - pmod_attributes = []; - }, + Ast_helper.Mod.structure ~loc + [ + Ast_helper.Str.primitive ~loc + { + pval_name = {txt = local_fun_name; loc}; + pval_type; + pval_loc = loc; + pval_prim; + pval_attributes; + }; + ], Ast_helper.Exp.apply ~loc - ({ - pexp_desc = - Pexp_ident - {txt = Ldot (Lident local_module_name, local_fun_name); loc}; - pexp_attributes = []; - pexp_loc = loc; - } - : Parsetree.expression) + (Ast_helper.Exp.ident ~loc + {txt = Ldot (Lident local_module_name, local_fun_name); loc}) (Ext_list.map args (fun (l, a) -> (Asttypes.Labelled {txt = l; loc = Location.none}, a))) ) diff --git a/compiler/frontend/ast_tdcls.ml b/compiler/frontend/ast_tdcls.ml index f0effb7e5b..b7b4f51db7 100644 --- a/compiler/frontend/ast_tdcls.ml +++ b/compiler/frontend/ast_tdcls.ml @@ -35,7 +35,7 @@ let new_tdcls (tdcls : Parsetree.type_declaration list) Ext_list.map_last tdcls (fun last x -> if last then {x with Parsetree.ptype_attributes = new_attrs} else x) -let handle_tdcls_in_sigi (self : Bs_ast_mapper.mapper) +let handle_tdcls_in_sigi (self : Ast_mapper.mapper) (sigi : Parsetree.signature_item) rf (tdcls : Parsetree.type_declaration list) : Ast_signature.item = match @@ -46,7 +46,7 @@ let handle_tdcls_in_sigi (self : Bs_ast_mapper.mapper) let original_tdcls_new_attrs = new_tdcls tdcls new_attrs in (* remove the processed attr*) let new_tdcls_new_attrs = - self.type_declaration_list self original_tdcls_new_attrs + List.map (self.type_declaration self) original_tdcls_new_attrs in let kind = Ast_derive_abstract.is_abstract actions in if kind <> Not_abstract then @@ -68,9 +68,9 @@ let handle_tdcls_in_sigi (self : Bs_ast_mapper.mapper) (Sig.type_ ~loc rf new_tdcls_new_attrs :: self.signature self (Ast_derive.gen_signature tdcls actions rf)) | {bs_deriving = None}, _ -> - Bs_ast_mapper.default_mapper.signature_item self sigi + Ast_mapper.default_mapper.signature_item self sigi -let handle_tdcls_in_stru (self : Bs_ast_mapper.mapper) +let handle_tdcls_in_stru (self : Ast_mapper.mapper) (str : Parsetree.structure_item) rf (tdcls : Parsetree.type_declaration list) : Ast_structure.item = match @@ -81,7 +81,7 @@ let handle_tdcls_in_stru (self : Bs_ast_mapper.mapper) let original_tdcls_new_attrs = new_tdcls tdcls new_attrs in let new_str : Parsetree.structure_item = Str.type_ ~loc rf - (self.type_declaration_list self original_tdcls_new_attrs) + (List.map (self.type_declaration self) original_tdcls_new_attrs) in let kind = Ast_derive_abstract.is_abstract actions in if kind <> Not_abstract then @@ -102,5 +102,4 @@ let handle_tdcls_in_stru (self : Bs_ast_mapper.mapper) (fun action -> Ast_derive.gen_structure_signature loc tdcls action rf) actions)) - | {bs_deriving = None}, _ -> - Bs_ast_mapper.default_mapper.structure_item self str + | {bs_deriving = None}, _ -> Ast_mapper.default_mapper.structure_item self str diff --git a/compiler/frontend/ast_tdcls.mli b/compiler/frontend/ast_tdcls.mli index 1ebdfb833a..0f6a08d2de 100644 --- a/compiler/frontend/ast_tdcls.mli +++ b/compiler/frontend/ast_tdcls.mli @@ -23,14 +23,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) val handle_tdcls_in_sigi : - Bs_ast_mapper.mapper -> + Ast_mapper.mapper -> Parsetree.signature_item -> Asttypes.rec_flag -> Parsetree.type_declaration list -> Ast_signature.item val handle_tdcls_in_stru : - Bs_ast_mapper.mapper -> + Ast_mapper.mapper -> Parsetree.structure_item -> Asttypes.rec_flag -> Parsetree.type_declaration list -> diff --git a/compiler/frontend/ast_tuple_pattern_flatten.ml b/compiler/frontend/ast_tuple_pattern_flatten.ml index 626a4c543d..702a7357f8 100644 --- a/compiler/frontend/ast_tuple_pattern_flatten.ml +++ b/compiler/frontend/ast_tuple_pattern_flatten.ml @@ -41,7 +41,7 @@ let rec is_simple_pattern (p : Parsetree.pattern) = [ let a = M.N.c and b = M.N.d ] *) -let flattern_tuple_pattern_vb (self : Bs_ast_mapper.mapper) +let flattern_tuple_pattern_vb (self : Ast_mapper.mapper) (vb : Parsetree.value_binding) (acc : Parsetree.value_binding list) : Parsetree.value_binding list = let pvb_pat = self.pat self vb.pvb_pat in @@ -108,8 +108,8 @@ let flattern_tuple_pattern_vb (self : Bs_ast_mapper.mapper) {pvb_pat; pvb_expr; pvb_constraint; pvb_loc = vb.pvb_loc; pvb_attributes} :: acc -let value_bindings_mapper (self : Bs_ast_mapper.mapper) +let value_bindings_mapper (self : Ast_mapper.mapper) (vbs : Parsetree.value_binding list) = - (* Bs_ast_mapper.default_mapper.value_bindings self vbs *) + (* Ast_mapper.default_mapper.value_bindings self vbs *) Ext_list.fold_right vbs [] (fun vb acc -> flattern_tuple_pattern_vb self vb acc) diff --git a/compiler/frontend/ast_tuple_pattern_flatten.mli b/compiler/frontend/ast_tuple_pattern_flatten.mli index 3718b5d93b..38e08bbab5 100644 --- a/compiler/frontend/ast_tuple_pattern_flatten.mli +++ b/compiler/frontend/ast_tuple_pattern_flatten.mli @@ -23,6 +23,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) val value_bindings_mapper : - Bs_ast_mapper.mapper -> + Ast_mapper.mapper -> Parsetree.value_binding list -> Parsetree.value_binding list diff --git a/compiler/frontend/ast_typ_uncurry.ml b/compiler/frontend/ast_typ_uncurry.ml deleted file mode 100644 index f3d6f083b4..0000000000 --- a/compiler/frontend/ast_typ_uncurry.ml +++ /dev/null @@ -1,35 +0,0 @@ -(* Copyright (C) 2020 Hongbo Zhang, Authors of ReScript - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * In addition to the permissions granted to you by the LGPL, you may combine - * or link a "work that uses the Library" with a publicly distributed version - * of this file to produce a combined library or application, then distribute - * that combined work under the terms of your choosing, with no requirement - * to comply with the obligations normally placed on you by section 4 of the - * LGPL version 3 (or the corresponding section of a later version of the LGPL - * should you choose to use a later version). - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) - -type typ = Parsetree.core_type - -let to_method_callback_type loc (mapper : Bs_ast_mapper.mapper) ~arity - (meth_type : Parsetree.core_type) = - let meth_type = Bs_ast_mapper.default_mapper.typ mapper meth_type in - Ast_helper.Typ.constr - { - txt = Ldot (Ast_literal.Lid.method_callback, "arity" ^ string_of_int arity); - loc; - } - [meth_type] diff --git a/compiler/frontend/ast_typ_uncurry.mli b/compiler/frontend/ast_typ_uncurry.mli deleted file mode 100644 index 5dcb092a69..0000000000 --- a/compiler/frontend/ast_typ_uncurry.mli +++ /dev/null @@ -1,40 +0,0 @@ -(* Copyright (C) 2020 Authors of ReScript - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * In addition to the permissions granted to you by the LGPL, you may combine - * or link a "work that uses the Library" with a publicly distributed version - * of this file to produce a combined library or application, then distribute - * that combined work under the terms of your choosing, with no requirement - * to comply with the obligations normally placed on you by section 4 of the - * LGPL version 3 (or the corresponding section of a later version of the LGPL - * should you choose to use a later version). - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) - -(* Method callbacks encode their arity with - [Primitive_js_extern.Callback.arityN]. The arity is never zero. *) - -type typ = Parsetree.core_type - -val to_method_callback_type : - Ast_helper.loc -> - Bs_ast_mapper.mapper -> - arity:int -> - typ -> - (* Method type *) - typ - -(** syntax: - {[ 'obj -> int -> int [@this] ]} -*) diff --git a/compiler/frontend/ast_uncurry_gen.ml b/compiler/frontend/ast_uncurry_gen.ml index 44ff379096..f5fc2a4c40 100644 --- a/compiler/frontend/ast_uncurry_gen.ml +++ b/compiler/frontend/ast_uncurry_gen.ml @@ -25,7 +25,7 @@ open Ast_helper (* Handling `fun [@this]` used in `object [@bs] end` *) -let to_method_callback ~async ~newtypes loc (self : Bs_ast_mapper.mapper) +let to_method_callback ~async ~newtypes loc (self : Ast_mapper.mapper) (params : Parsetree.fun_param list) body : Parsetree.expression_desc = match params with | [] -> assert false diff --git a/compiler/frontend/ast_uncurry_gen.mli b/compiler/frontend/ast_uncurry_gen.mli index 362a7133c4..64805b400a 100644 --- a/compiler/frontend/ast_uncurry_gen.mli +++ b/compiler/frontend/ast_uncurry_gen.mli @@ -26,7 +26,7 @@ val to_method_callback : async:bool -> newtypes:(string Asttypes.loc * Parsetree.attributes) list -> Location.t -> - Bs_ast_mapper.mapper -> + Ast_mapper.mapper -> Parsetree.fun_param list -> Parsetree.expression -> Parsetree.expression_desc diff --git a/compiler/frontend/ast_util.ml b/compiler/frontend/ast_util.ml index 798b6f4717..f32cc50d8b 100644 --- a/compiler/frontend/ast_util.ml +++ b/compiler/frontend/ast_util.ml @@ -25,7 +25,7 @@ let js_property loc obj (name : string) = Parsetree.Pexp_send (obj, {loc; txt = name}) -let record_as_js_object loc (self : Bs_ast_mapper.mapper) +let record_as_js_object loc (self : Ast_mapper.mapper) (label_exprs : Parsetree.expression Parsetree.record_element list) : Parsetree.expression_desc = let labels, args, arity = diff --git a/compiler/frontend/ast_util.mli b/compiler/frontend/ast_util.mli index 4b44a1bba8..8ffdbf0c0e 100644 --- a/compiler/frontend/ast_util.mli +++ b/compiler/frontend/ast_util.mli @@ -30,7 +30,7 @@ val record_as_js_object : Location.t -> - Bs_ast_mapper.mapper -> + Ast_mapper.mapper -> Parsetree.expression Parsetree.record_element list -> Parsetree.expression_desc diff --git a/compiler/frontend/bs_ast_mapper.ml b/compiler/frontend/bs_ast_mapper.ml deleted file mode 100644 index d8c6498c08..0000000000 --- a/compiler/frontend/bs_ast_mapper.ml +++ /dev/null @@ -1,600 +0,0 @@ -(**************************************************************************) -(* *) -(* OCaml *) -(* *) -(* Alain Frisch, LexiFi *) -(* *) -(* Copyright 2012 Institut National de Recherche en Informatique et *) -(* en Automatique. *) -(* *) -(* All rights reserved. This file is distributed under the terms of *) -(* the GNU Lesser General Public License version 2.1, with the *) -(* special exception on linking described in the file LICENSE. *) -(* *) -(**************************************************************************) - -(* A generic Parsetree mapping class *) - -(* -[@@@warning "+9"] - (* Ensure that record patterns don't miss any field. *) -*) - -open! Parsetree -open! Ast_helper -open Location - -type mapper = { - attribute: mapper -> attribute -> attribute; - attributes: mapper -> attribute list -> attribute list; - case: mapper -> case -> case; - cases: mapper -> case list -> case list; - constructor_declaration: - mapper -> constructor_declaration -> constructor_declaration; - expr: mapper -> expression -> expression; - extension: mapper -> extension -> extension; - extension_constructor: - mapper -> extension_constructor -> extension_constructor; - include_declaration: mapper -> include_declaration -> include_declaration; - include_description: mapper -> include_description -> include_description; - label_declaration: mapper -> label_declaration -> label_declaration; - location: mapper -> Location.t -> Location.t; - module_binding: mapper -> module_binding -> module_binding; - module_declaration: mapper -> module_declaration -> module_declaration; - module_expr: mapper -> module_expr -> module_expr; - module_type: mapper -> module_type -> module_type; - module_type_declaration: - mapper -> module_type_declaration -> module_type_declaration; - open_description: mapper -> open_description -> open_description; - pat: mapper -> pattern -> pattern; - payload: mapper -> payload -> payload; - signature: mapper -> signature -> signature; - signature_item: mapper -> signature_item -> signature_item; - structure: mapper -> structure -> structure; - structure_item: mapper -> structure_item -> structure_item; - typ: mapper -> core_type -> core_type; - type_declaration: mapper -> type_declaration -> type_declaration; - (* #if true then *) - type_declaration_list: - mapper -> type_declaration list -> type_declaration list; - (* #end *) - type_extension: mapper -> type_extension -> type_extension; - type_kind: mapper -> type_kind -> type_kind; - value_binding: mapper -> value_binding -> value_binding; - (* #if true then *) - value_bindings_rec: mapper -> value_binding list -> value_binding list; - value_bindings: mapper -> value_binding list -> value_binding list; - (* #end *) - value_description: mapper -> value_description -> value_description; - with_constraint: mapper -> with_constraint -> with_constraint; -} - -let map_fst f (x, y) = (f x, y) -let map_snd f (x, y) = (x, f y) -let map_tuple f1 f2 (x, y) = (f1 x, f2 y) -let map_tuple3 f1 f2 f3 (x, y, z) = (f1 x, f2 y, f3 z) -let map_opt f = function - | None -> None - | Some x -> Some (f x) - -let map_loc sub {loc; txt} = {loc = sub.location sub loc; txt} - -module T = struct - (* Type expressions for the core language *) - - let row_field sub = function - | Rtag (l, attrs, b, tl) -> - Rtag - (map_loc sub l, sub.attributes sub attrs, b, List.map (sub.typ sub) tl) - | Rinherit t -> Rinherit (sub.typ sub t) - - let object_field sub = function - | Otag (l, attrs, t) -> - Otag (map_loc sub l, sub.attributes sub attrs, sub.typ sub t) - | Oinherit t -> Oinherit (sub.typ sub t) - - let map sub {ptyp_desc = desc; ptyp_loc = loc; ptyp_attributes = attrs} = - let loc = sub.location sub loc in - let attrs = sub.attributes sub attrs in - match desc with - | Ptyp_any -> Typ.any ~loc ~attrs () - | Ptyp_var s -> Typ.var ~loc ~attrs s - | Ptyp_arrow {params; ret} -> - Typ.arrow ~loc ~attrs - (List.map - (fun (arg : Parsetree.arg) -> {arg with typ = sub.typ sub arg.typ}) - params) - (sub.typ sub ret) - | Ptyp_tuple tyl -> Typ.tuple ~loc ~attrs (List.map (sub.typ sub) tyl) - | Ptyp_constr (lid, tl) -> - Typ.constr ~loc ~attrs (map_loc sub lid) (List.map (sub.typ sub) tl) - | Ptyp_object (l, o) -> - Typ.object_ ~loc ~attrs (List.map (object_field sub) l) o - | Ptyp_alias (t, s) -> Typ.alias ~loc ~attrs (sub.typ sub t) s - | Ptyp_variant (rl, b, ll) -> - Typ.variant ~loc ~attrs (List.map (row_field sub) rl) b ll - | Ptyp_poly (sl, t) -> - Typ.poly ~loc ~attrs (List.map (map_loc sub) sl) (sub.typ sub t) - | Ptyp_package (lid, l) -> - Typ.package ~loc ~attrs (map_loc sub lid) - (List.map (map_tuple (map_loc sub) (sub.typ sub)) l) - | Ptyp_extension x -> Typ.extension ~loc ~attrs (sub.extension sub x) - - let map_type_declaration sub - { - ptype_name; - ptype_params; - ptype_cstrs; - ptype_kind; - ptype_private; - ptype_manifest; - ptype_attributes; - ptype_loc; - } = - Type.mk (map_loc sub ptype_name) - ~params:(List.map (map_fst (sub.typ sub)) ptype_params) - ~priv:ptype_private - ~cstrs: - (List.map - (map_tuple3 (sub.typ sub) (sub.typ sub) (sub.location sub)) - ptype_cstrs) - ~kind:(sub.type_kind sub ptype_kind) - ?manifest:(map_opt (sub.typ sub) ptype_manifest) - ~loc:(sub.location sub ptype_loc) - ~attrs:(sub.attributes sub ptype_attributes) - - (* #if true then *) - let map_type_declaration_list sub l = List.map (sub.type_declaration sub) l - - (* #end *) - let map_type_kind sub = function - | Ptype_abstract -> Ptype_abstract - | Ptype_variant l -> - Ptype_variant (List.map (sub.constructor_declaration sub) l) - | Ptype_record l -> Ptype_record (List.map (sub.label_declaration sub) l) - | Ptype_open -> Ptype_open - - let map_constructor_arguments (sub : mapper) = function - | Pcstr_tuple l -> Pcstr_tuple (List.map (sub.typ sub) l) - | Pcstr_record l -> Pcstr_record (List.map (sub.label_declaration sub) l) - - let map_type_extension sub - { - ptyext_path; - ptyext_params; - ptyext_constructors; - ptyext_private; - ptyext_attributes; - } = - Te.mk (map_loc sub ptyext_path) - (List.map (sub.extension_constructor sub) ptyext_constructors) - ~params:(List.map (map_fst (sub.typ sub)) ptyext_params) - ~priv:ptyext_private - ~attrs:(sub.attributes sub ptyext_attributes) - - let map_extension_constructor_kind sub = function - | Pext_decl (ctl, cto) -> - Pext_decl (map_constructor_arguments sub ctl, map_opt (sub.typ sub) cto) - | Pext_rebind li -> Pext_rebind (map_loc sub li) - - let map_extension_constructor sub - {pext_name; pext_kind; pext_loc; pext_attributes} = - Te.constructor (map_loc sub pext_name) - (map_extension_constructor_kind sub pext_kind) - ~loc:(sub.location sub pext_loc) - ~attrs:(sub.attributes sub pext_attributes) -end - -module MT = struct - (* Type expressions for the module language *) - - let map sub {pmty_desc = desc; pmty_loc = loc; pmty_attributes = attrs} = - let open Mty in - let loc = sub.location sub loc in - let attrs = sub.attributes sub attrs in - match desc with - | Pmty_ident s -> ident ~loc ~attrs (map_loc sub s) - | Pmty_alias s -> alias ~loc ~attrs (map_loc sub s) - | Pmty_signature sg -> signature ~loc ~attrs (sub.signature sub sg) - | Pmty_functor (s, mt1, mt2) -> - functor_ ~loc ~attrs (map_loc sub s) - (Misc.may_map (sub.module_type sub) mt1) - (sub.module_type sub mt2) - | Pmty_with (mt, l) -> - with_ ~loc ~attrs (sub.module_type sub mt) - (List.map (sub.with_constraint sub) l) - | Pmty_typeof me -> typeof_ ~loc ~attrs (sub.module_expr sub me) - | Pmty_extension x -> extension ~loc ~attrs (sub.extension sub x) - - let map_with_constraint sub = function - | Pwith_type (lid, d) -> - Pwith_type (map_loc sub lid, sub.type_declaration sub d) - | Pwith_module (lid, lid2) -> - Pwith_module (map_loc sub lid, map_loc sub lid2) - | Pwith_typesubst (lid, d) -> - Pwith_typesubst (map_loc sub lid, sub.type_declaration sub d) - | Pwith_modsubst (s, lid) -> Pwith_modsubst (map_loc sub s, map_loc sub lid) - - let map_signature_item sub {psig_desc = desc; psig_loc = loc} = - let open Sig in - let loc = sub.location sub loc in - match desc with - | Psig_value vd -> value ~loc (sub.value_description sub vd) - | Psig_type (rf, l) -> - (* #if false then - type_ ~loc rf (List.map (sub.type_declaration sub) l) - #else *) - type_ ~loc rf (sub.type_declaration_list sub l) - (* #end *) - | Psig_typext te -> type_extension ~loc (sub.type_extension sub te) - | Psig_exception ed -> exception_ ~loc (sub.extension_constructor sub ed) - | Psig_module x -> module_ ~loc (sub.module_declaration sub x) - | Psig_recmodule l -> - rec_module ~loc (List.map (sub.module_declaration sub) l) - | Psig_modtype x -> modtype ~loc (sub.module_type_declaration sub x) - | Psig_open x -> open_ ~loc (sub.open_description sub x) - | Psig_include x -> include_ ~loc (sub.include_description sub x) - | Psig_extension (x, attrs) -> - extension ~loc (sub.extension sub x) ~attrs:(sub.attributes sub attrs) - | Psig_attribute x -> attribute ~loc (sub.attribute sub x) -end - -module M = struct - (* Value expressions for the module language *) - - let map sub {pmod_loc = loc; pmod_desc = desc; pmod_attributes = attrs} = - let open Mod in - let loc = sub.location sub loc in - let attrs = sub.attributes sub attrs in - match desc with - | Pmod_ident x -> ident ~loc ~attrs (map_loc sub x) - | Pmod_structure str -> structure ~loc ~attrs (sub.structure sub str) - | Pmod_functor (arg, arg_ty, body) -> - functor_ ~loc ~attrs (map_loc sub arg) - (Misc.may_map (sub.module_type sub) arg_ty) - (sub.module_expr sub body) - | Pmod_apply (m1, m2) -> - apply ~loc ~attrs (sub.module_expr sub m1) (sub.module_expr sub m2) - | Pmod_constraint (m, mty) -> - constraint_ ~loc ~attrs (sub.module_expr sub m) (sub.module_type sub mty) - | Pmod_unpack e -> unpack ~loc ~attrs (sub.expr sub e) - | Pmod_extension x -> extension ~loc ~attrs (sub.extension sub x) - - let map_structure_item sub {pstr_loc = loc; pstr_desc = desc} = - let open Str in - let loc = sub.location sub loc in - match desc with - | Pstr_eval (x, attrs) -> - eval ~loc ~attrs:(sub.attributes sub attrs) (sub.expr sub x) - | Pstr_value (r, vbs) -> - (* #if false then - value ~loc r (List.map (sub.value_binding sub) vbs) - #else *) - value ~loc r - ((if r = Recursive then sub.value_bindings_rec else sub.value_bindings) - sub vbs) - (* #end *) - | Pstr_primitive vd -> primitive ~loc (sub.value_description sub vd) - | Pstr_type (rf, l) -> - (* #if false then - type_ ~loc rf (List.map (sub.type_declaration sub) l) - #else *) - type_ ~loc rf (sub.type_declaration_list sub l) - (* #end *) - | Pstr_typext te -> type_extension ~loc (sub.type_extension sub te) - | Pstr_exception ed -> exception_ ~loc (sub.extension_constructor sub ed) - | Pstr_module x -> module_ ~loc (sub.module_binding sub x) - | Pstr_recmodule l -> rec_module ~loc (List.map (sub.module_binding sub) l) - | Pstr_modtype x -> modtype ~loc (sub.module_type_declaration sub x) - | Pstr_open x -> open_ ~loc (sub.open_description sub x) - | Pstr_include x -> include_ ~loc (sub.include_declaration sub x) - | Pstr_extension (x, attrs) -> - extension ~loc (sub.extension sub x) ~attrs:(sub.attributes sub attrs) - | Pstr_attribute x -> attribute ~loc (sub.attribute sub x) -end - -module E = struct - let map_jsx_children sub xs = List.map (sub.expr sub) xs - - let map_jsx_prop sub = function - | JSXPropPunning (optional, name) -> - JSXPropPunning (optional, map_loc sub name) - | JSXPropValue (name, optional, value) -> - JSXPropValue (map_loc sub name, optional, sub.expr sub value) - | JSXPropSpreading (loc, e) -> - JSXPropSpreading (sub.location sub loc, sub.expr sub e) - - let map_jsx_props sub = List.map (map_jsx_prop sub) - - (* Value expressions for the core language *) - - let map sub {pexp_loc = loc; pexp_desc = desc; pexp_attributes = attrs} = - let open Exp in - let loc = sub.location sub loc in - let attrs = sub.attributes sub attrs in - match desc with - | Pexp_ident x -> ident ~loc ~attrs (map_loc sub x) - | Pexp_constant x -> constant ~loc ~attrs x - | Pexp_let (r, vbs, e) -> - (* #if false then - let_ ~loc ~attrs r (List.map (sub.value_binding sub) vbs) - (sub.expr sub e) - #else *) - let_ ~loc ~attrs r - ((if r = Recursive then sub.value_bindings_rec else sub.value_bindings) - sub vbs) - (sub.expr sub e) - (* #end *) - | Pexp_fun {newtypes; params; body; async} -> - fun_ ~loc ~attrs ~async - ~newtypes: - (List.map - (fun (name, attrs) -> (map_loc sub name, sub.attributes sub attrs)) - newtypes) - (List.map - (fun (param : Parsetree.fun_param) -> - { - param with - p_default = map_opt (sub.expr sub) param.p_default; - p_pat = sub.pat sub param.p_pat; - }) - params) - (sub.expr sub body) - | Pexp_apply {funct = e; args = l; partial; transformed_jsx} -> - apply ~loc ~attrs ~partial ~transformed_jsx (sub.expr sub e) - (List.map (map_snd (sub.expr sub)) l) - | Pexp_match (e, pel) -> - match_ ~loc ~attrs (sub.expr sub e) (sub.cases sub pel) - | Pexp_try (e, pel) -> try_ ~loc ~attrs (sub.expr sub e) (sub.cases sub pel) - | Pexp_tuple el -> tuple ~loc ~attrs (List.map (sub.expr sub) el) - | Pexp_construct (lid, arg) -> - construct ~loc ~attrs (map_loc sub lid) (map_opt (sub.expr sub) arg) - | Pexp_variant (lab, eo) -> - variant ~loc ~attrs lab (map_opt (sub.expr sub) eo) - | Pexp_record (l, eo) -> - record ~loc ~attrs - (List.map - (fun {lid; x = e; opt} -> - {lid = map_loc sub lid; x = sub.expr sub e; opt}) - l) - (map_opt (sub.expr sub) eo) - | Pexp_field (e, lid) -> - field ~loc ~attrs (sub.expr sub e) (map_loc sub lid) - | Pexp_setfield (e1, lid, e2) -> - setfield ~loc ~attrs (sub.expr sub e1) (map_loc sub lid) (sub.expr sub e2) - | Pexp_array el -> array ~loc ~attrs (List.map (sub.expr sub) el) - | Pexp_ifthenelse (e1, e2, e3) -> - ifthenelse ~loc ~attrs (sub.expr sub e1) (sub.expr sub e2) - (map_opt (sub.expr sub) e3) - | Pexp_sequence (e1, e2) -> - sequence ~loc ~attrs (sub.expr sub e1) (sub.expr sub e2) - | Pexp_break -> break ~loc ~attrs () - | Pexp_continue -> continue ~loc ~attrs () - | Pexp_while (e1, e2) -> - while_ ~loc ~attrs (sub.expr sub e1) (sub.expr sub e2) - | Pexp_for (p, e1, e2, d, e3) -> - for_ ~loc ~attrs (sub.pat sub p) (sub.expr sub e1) (sub.expr sub e2) d - (sub.expr sub e3) - | Pexp_coerce (e, (), t2) -> - coerce ~loc ~attrs (sub.expr sub e) (sub.typ sub t2) - | Pexp_constraint (e, t) -> - constraint_ ~loc ~attrs (sub.expr sub e) (sub.typ sub t) - | Pexp_send (e, s) -> send ~loc ~attrs (sub.expr sub e) (map_loc sub s) - | Pexp_letmodule (s, me, e) -> - letmodule ~loc ~attrs (map_loc sub s) (sub.module_expr sub me) - (sub.expr sub e) - | Pexp_letexception (cd, e) -> - letexception ~loc ~attrs - (sub.extension_constructor sub cd) - (sub.expr sub e) - | Pexp_assert e -> assert_ ~loc ~attrs (sub.expr sub e) - | Pexp_pack me -> pack ~loc ~attrs (sub.module_expr sub me) - | Pexp_open (ovf, lid, e) -> - open_ ~loc ~attrs ovf (map_loc sub lid) (sub.expr sub e) - | Pexp_extension x -> extension ~loc ~attrs (sub.extension sub x) - | Pexp_await e -> await ~loc ~attrs (sub.expr sub e) - | Pexp_jsx_element - (Jsx_fragment - { - jsx_fragment_opening = o; - jsx_fragment_children = children; - jsx_fragment_closing = c; - }) -> - jsx_fragment o (map_jsx_children sub children) c - | Pexp_jsx_element - (Jsx_unary_element - {jsx_unary_element_tag_name = name; jsx_unary_element_props = props}) - -> - jsx_unary_element ~loc ~attrs name (map_jsx_props sub props) - | Pexp_for_of (pat, e1, e2) -> - Exp.mk ~loc ~attrs - (Pexp_for_of (sub.pat sub pat, sub.expr sub e1, sub.expr sub e2)) - | Pexp_for_await_of (pat, e1, e2) -> - Exp.mk ~loc ~attrs - (Pexp_for_await_of (sub.pat sub pat, sub.expr sub e1, sub.expr sub e2)) - | Pexp_jsx_element - (Jsx_container_element - { - jsx_container_element_tag_name_start = name; - jsx_container_element_opening_tag_end = ote; - jsx_container_element_props = props; - jsx_container_element_children = children; - jsx_container_element_closing_tag = closing_tag; - }) -> - jsx_container_element ~loc ~attrs name (map_jsx_props sub props) ote - (map_jsx_children sub children) - closing_tag -end - -module P = struct - (* Patterns *) - - let map sub {ppat_desc = desc; ppat_loc = loc; ppat_attributes = attrs} = - let open Pat in - let loc = sub.location sub loc in - let attrs = sub.attributes sub attrs in - match desc with - | Ppat_any -> any ~loc ~attrs () - | Ppat_var s -> var ~loc ~attrs (map_loc sub s) - | Ppat_alias (p, s) -> alias ~loc ~attrs (sub.pat sub p) (map_loc sub s) - | Ppat_constant c -> constant ~loc ~attrs c - | Ppat_interval (c1, c2) -> interval ~loc ~attrs c1 c2 - | Ppat_tuple pl -> tuple ~loc ~attrs (List.map (sub.pat sub) pl) - | Ppat_construct (l, p) -> - construct ~loc ~attrs (map_loc sub l) (map_opt (sub.pat sub) p) - | Ppat_variant (l, p) -> variant ~loc ~attrs l (map_opt (sub.pat sub) p) - | Ppat_record (lpl, cf, rest) -> - record ~loc ~attrs - ?rest: - (match rest with - | None -> None - | Some {rest_loc; rest_name; rest_type} -> - Some - { - rest_loc = sub.location sub rest_loc; - rest_name = map_loc sub rest_name; - rest_type = map_opt (sub.typ sub) rest_type; - }) - (List.map - (fun {lid; x = p; opt} -> - {lid = map_loc sub lid; x = sub.pat sub p; opt}) - lpl) - cf - | Ppat_array pl -> array ~loc ~attrs (List.map (sub.pat sub) pl) - | Ppat_or (p1, p2) -> or_ ~loc ~attrs (sub.pat sub p1) (sub.pat sub p2) - | Ppat_constraint (p, t) -> - constraint_ ~loc ~attrs (sub.pat sub p) (sub.typ sub t) - | Ppat_type s -> type_ ~loc ~attrs (map_loc sub s) - | Ppat_unpack s -> unpack ~loc ~attrs (map_loc sub s) - | Ppat_open (lid, p) -> open_ ~loc ~attrs (map_loc sub lid) (sub.pat sub p) - | Ppat_exception p -> exception_ ~loc ~attrs (sub.pat sub p) - | Ppat_extension x -> extension ~loc ~attrs (sub.extension sub x) -end - -(* Now, a generic AST mapper, to be extended to cover all kinds and - cases of the OCaml grammar. The default behavior of the mapper is - the identity. *) - -let default_mapper = - { - structure = (fun this l -> List.map (this.structure_item this) l); - structure_item = M.map_structure_item; - module_expr = M.map; - signature = (fun this l -> List.map (this.signature_item this) l); - signature_item = MT.map_signature_item; - module_type = MT.map; - with_constraint = MT.map_with_constraint; - type_declaration = T.map_type_declaration; - (* #if true then *) - type_declaration_list = T.map_type_declaration_list; - (* #end *) - type_kind = T.map_type_kind; - typ = T.map; - type_extension = T.map_type_extension; - extension_constructor = T.map_extension_constructor; - value_description = - (fun this {pval_name; pval_type; pval_prim; pval_loc; pval_attributes} -> - Val.mk (map_loc this pval_name) (this.typ this pval_type) - ~attrs:(this.attributes this pval_attributes) - ~loc:(this.location this pval_loc) - ~prim:pval_prim); - pat = P.map; - expr = E.map; - module_declaration = - (fun this {pmd_name; pmd_type; pmd_attributes; pmd_loc} -> - Md.mk (map_loc this pmd_name) - (this.module_type this pmd_type) - ~attrs:(this.attributes this pmd_attributes) - ~loc:(this.location this pmd_loc)); - module_type_declaration = - (fun this {pmtd_name; pmtd_type; pmtd_attributes; pmtd_loc} -> - Mtd.mk (map_loc this pmtd_name) - ?typ:(map_opt (this.module_type this) pmtd_type) - ~attrs:(this.attributes this pmtd_attributes) - ~loc:(this.location this pmtd_loc)); - module_binding = - (fun this {pmb_name; pmb_expr; pmb_attributes; pmb_loc} -> - Mb.mk (map_loc this pmb_name) - (this.module_expr this pmb_expr) - ~attrs:(this.attributes this pmb_attributes) - ~loc:(this.location this pmb_loc)); - open_description = - (fun this {popen_lid; popen_override; popen_attributes; popen_loc} -> - Opn.mk (map_loc this popen_lid) ~override:popen_override - ~loc:(this.location this popen_loc) - ~attrs:(this.attributes this popen_attributes)); - include_description = - (fun this {pincl_mod; pincl_attributes; pincl_loc} -> - Incl.mk - (this.module_type this pincl_mod) - ~loc:(this.location this pincl_loc) - ~attrs:(this.attributes this pincl_attributes)); - include_declaration = - (fun this {pincl_mod; pincl_attributes; pincl_loc} -> - Incl.mk - (this.module_expr this pincl_mod) - ~loc:(this.location this pincl_loc) - ~attrs:(this.attributes this pincl_attributes)); - value_binding = - (fun this {pvb_pat; pvb_expr; pvb_constraint; pvb_attributes; pvb_loc} -> - let pvb_pat = this.pat this pvb_pat in - let constraint_ = - Option.map - (fun {pvc_newtypes; pvc_type} -> - { - pvc_newtypes = List.map (map_loc this) pvc_newtypes; - pvc_type = this.typ this pvc_type; - }) - pvb_constraint - in - let pvb_expr = this.expr this pvb_expr in - Vb.mk pvb_pat pvb_expr ?constraint_ - ~loc:(this.location this pvb_loc) - ~attrs:(this.attributes this pvb_attributes)); - (* #if true then *) - value_bindings = - (fun this vbs -> - match vbs with - | [vb] -> [this.value_binding this vb] - | _ -> List.map (this.value_binding this) vbs); - value_bindings_rec = - (fun this vbs -> - match vbs with - | [vb] -> [this.value_binding this vb] - | _ -> List.map (this.value_binding this) vbs); - (* #end *) - constructor_declaration = - (fun this {pcd_name; pcd_args; pcd_res; pcd_loc; pcd_attributes} -> - Type.constructor (map_loc this pcd_name) - ~args:(T.map_constructor_arguments this pcd_args) - ?res:(map_opt (this.typ this) pcd_res) - ~loc:(this.location this pcd_loc) - ~attrs:(this.attributes this pcd_attributes)); - label_declaration = - (fun this - {pld_name; pld_type; pld_loc; pld_mutable; pld_optional; pld_attributes} - -> - Type.field (map_loc this pld_name) (this.typ this pld_type) - ~mut:pld_mutable ~optional:pld_optional - ~loc:(this.location this pld_loc) - ~attrs:(this.attributes this pld_attributes)); - cases = (fun this l -> List.map (this.case this) l); - case = - (fun this {pc_bar; pc_lhs; pc_guard; pc_rhs} -> - { - pc_bar; - pc_lhs = this.pat this pc_lhs; - pc_guard = map_opt (this.expr this) pc_guard; - pc_rhs = this.expr this pc_rhs; - }); - location = (fun _this l -> l); - extension = (fun this (s, e) -> (map_loc this s, this.payload this e)); - attribute = (fun this (s, e) -> (map_loc this s, this.payload this e)); - attributes = (fun this l -> List.map (this.attribute this) l); - payload = - (fun this -> function - | PStr x -> PStr (this.structure this x) - | PSig x -> PSig (this.signature this x) - | PTyp x -> PTyp (this.typ this x) - | PPat (x, g) -> PPat (this.pat this x, map_opt (this.expr this) g)); - } diff --git a/compiler/frontend/bs_ast_mapper.mli b/compiler/frontend/bs_ast_mapper.mli deleted file mode 100644 index f1d54eec98..0000000000 --- a/compiler/frontend/bs_ast_mapper.mli +++ /dev/null @@ -1,101 +0,0 @@ -(**************************************************************************) -(* *) -(* OCaml *) -(* *) -(* Alain Frisch, LexiFi *) -(* *) -(* Copyright 2012 Institut National de Recherche en Informatique et *) -(* en Automatique. *) -(* *) -(* All rights reserved. This file is distributed under the terms of *) -(* the GNU Lesser General Public License version 2.1, with the *) -(* special exception on linking described in the file LICENSE. *) -(* *) -(**************************************************************************) - -(** The interface of a -ppx rewriter - - A -ppx rewriter is a program that accepts a serialized abstract syntax - tree and outputs another, possibly modified, abstract syntax tree. - This module encapsulates the interface between the compiler and - the -ppx rewriters, handling such details as the serialization format, - forwarding of command-line flags, and storing state. - - {!mapper} allows to implement AST rewriting using open recursion. - A typical mapper would be based on {!default_mapper}, a deep - identity mapper, and will fall back on it for handling the syntax it - does not modify. For example: - - {[ - open Asttypes - open Parsetree - open Ast_mapper - - let test_mapper argv = - { default_mapper with - expr = fun mapper expr -> - match expr with - | { pexp_desc = Pexp_extension ({ txt = "test" }, PStr [])} -> - Ast_helper.Exp.constant (Const_int 42) - | other -> default_mapper.expr mapper other; } - - let () = - register "ppx_test" test_mapper]} - - This -ppx rewriter, which replaces [[%test]] in expressions with - the constant [42], can be compiled using - [ocamlc -o ppx_test -I +compiler-libs ocamlcommon.cma ppx_test.ml]. - -*) - -open! Parsetree - -(** {1 A generic Parsetree mapper} *) - -type mapper = { - attribute: mapper -> attribute -> attribute; - attributes: mapper -> attribute list -> attribute list; - case: mapper -> case -> case; - cases: mapper -> case list -> case list; - constructor_declaration: - mapper -> constructor_declaration -> constructor_declaration; - expr: mapper -> expression -> expression; - extension: mapper -> extension -> extension; - extension_constructor: - mapper -> extension_constructor -> extension_constructor; - include_declaration: mapper -> include_declaration -> include_declaration; - include_description: mapper -> include_description -> include_description; - label_declaration: mapper -> label_declaration -> label_declaration; - location: mapper -> Location.t -> Location.t; - module_binding: mapper -> module_binding -> module_binding; - module_declaration: mapper -> module_declaration -> module_declaration; - module_expr: mapper -> module_expr -> module_expr; - module_type: mapper -> module_type -> module_type; - module_type_declaration: - mapper -> module_type_declaration -> module_type_declaration; - open_description: mapper -> open_description -> open_description; - pat: mapper -> pattern -> pattern; - payload: mapper -> payload -> payload; - signature: mapper -> signature -> signature; - signature_item: mapper -> signature_item -> signature_item; - structure: mapper -> structure -> structure; - structure_item: mapper -> structure_item -> structure_item; - typ: mapper -> core_type -> core_type; - type_declaration: mapper -> type_declaration -> type_declaration; - type_declaration_list: - mapper -> type_declaration list -> type_declaration list; - type_extension: mapper -> type_extension -> type_extension; - type_kind: mapper -> type_kind -> type_kind; - value_binding: mapper -> value_binding -> value_binding; - value_bindings_rec: mapper -> value_binding list -> value_binding list; - value_bindings: mapper -> value_binding list -> value_binding list; - value_description: mapper -> value_description -> value_description; - with_constraint: mapper -> with_constraint -> with_constraint; -} -(** A mapper record implements one "method" per syntactic category, - using an open recursion style: each method takes as its first - argument the mapper to be applied to children in the syntax - tree. *) - -val default_mapper : mapper -(** A default mapper, which implements a "deep identity" mapping. *) diff --git a/compiler/frontend/bs_builtin_ppx.ml b/compiler/frontend/bs_builtin_ppx.ml index b71c3d2524..10275e69ac 100644 --- a/compiler/frontend/bs_builtin_ppx.ml +++ b/compiler/frontend/bs_builtin_ppx.ml @@ -58,11 +58,28 @@ let succeed attr attrs = Used_attributes.mark_used_attribute attr; Bs_ast_invariant.warn_discarded_unused_attributes attrs -type mapper = Bs_ast_mapper.mapper +type mapper = Ast_mapper.mapper -let default_mapper = Bs_ast_mapper.default_mapper -let default_expr_mapper = Bs_ast_mapper.default_mapper.expr -let default_pat_mapper = Bs_ast_mapper.default_mapper.pat +let default_mapper = Ast_mapper.default_mapper + +(* [Ast_mapper.default_mapper.expr], with non-recursive binding groups + routed through tuple/module-record pattern flattening ([let rec] groups + only admit variable patterns, so they map per binding). Every fallback in + [expr_mapper] funnels through here, so the flattening applies uniformly. *) +let default_expr_mapper (self : mapper) (e : Parsetree.expression) = + match e.pexp_desc with + | Pexp_let (Nonrecursive, vbs, body) -> + { + e with + pexp_desc = + Pexp_let + ( Nonrecursive, + Ast_tuple_pattern_flatten.value_bindings_mapper self vbs, + self.expr self body ); + pexp_attributes = self.attributes self e.pexp_attributes; + } + | _ -> Ast_mapper.default_mapper.expr self e +let default_pat_mapper = Ast_mapper.default_mapper.pat let pat_mapper (self : mapper) (p : Parsetree.pattern) = match p.ppat_desc with @@ -602,6 +619,9 @@ let structure_item_mapper (self : mapper) (str : Parsetree.structure_item) : ] ); }) | Pstr_attribute ({txt = "config"}, _) -> str + | Pstr_value (Nonrecursive, vbs) -> + Ast_helper.Str.value ~loc:str.pstr_loc Nonrecursive + (Ast_tuple_pattern_flatten.value_bindings_mapper self vbs) | _ -> default_mapper.structure_item self str let local_module_name = @@ -784,7 +804,6 @@ let mapper : mapper = pat = pat_mapper; typ = typ_mapper; signature_item = signature_item_mapper; - value_bindings = Ast_tuple_pattern_flatten.value_bindings_mapper; structure_item = structure_item_mapper; structure = structure_mapper ~await_context:(ref (Hashtbl.create 10)); (* Ad-hoc way to internalize stuff *) diff --git a/compiler/frontend/bs_builtin_ppx.mli b/compiler/frontend/bs_builtin_ppx.mli index 0508221b34..7533a1f5c6 100644 --- a/compiler/frontend/bs_builtin_ppx.mli +++ b/compiler/frontend/bs_builtin_ppx.mli @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -val mapper : Bs_ast_mapper.mapper +val mapper : Ast_mapper.mapper (* object for setter : we can push more into [Lsend] and enclose it with a unit type