diff --git a/jscomp/core/js_call_info.ml b/jscomp/core/js_call_info.ml index 715bcb36f2..11fb669471 100644 --- a/jscomp/core/js_call_info.ml +++ b/jscomp/core/js_call_info.ml @@ -37,7 +37,7 @@ type call_info = | Call_ml (* called by plain ocaml expression *) | Call_builtin_runtime (* built-in externals *) | Call_na - (* either from [@@bs.val] or not available, + (* either from [@@val] or not available, such calls does not follow such rules {[ fun x y -> (f x y) === f ]} when [f] is an atom diff --git a/jscomp/core/js_call_info.mli b/jscomp/core/js_call_info.mli index 191a277b83..ecdc988b39 100644 --- a/jscomp/core/js_call_info.mli +++ b/jscomp/core/js_call_info.mli @@ -40,7 +40,7 @@ type call_info = | Call_ml (* called by plain ocaml expression *) | Call_builtin_runtime (* built-in externals *) | Call_na - (* either from [@@bs.val] or not available, + (* either from [@@val] or not available, such calls does not follow such rules {[ fun x y -> f x y === f ]} when [f] is an atom *) diff --git a/jscomp/core/lam.ml b/jscomp/core/lam.ml index df108d32b3..0f6b4cb957 100644 --- a/jscomp/core/lam.ml +++ b/jscomp/core/lam.ml @@ -287,8 +287,8 @@ exception Not_simple_form where [wrap] used to be simple instructions Note that [external] functions are forced to do eta-conversion when combined with [|>] operator, we need to make sure beta-reduction - is applied though since `[@bs.splice]` needs such guarantee. - Since `[@bs.splice] is the tail position + is applied though since `[@variadic]` needs such guarantee. + Since `[@variadic] is the tail position *) let rec is_eta_conversion_exn params inner_args outer_args : t list = @@ -819,7 +819,7 @@ let sequand l r = if_ l r false_ (** only [handle_bs_non_obj_ffi] will be used outside *) (** [no_auto_uncurried_arg_types xs] - check if the FFI have [@@bs.uncurry] attribute. + check if the FFI have @uncurry attribute. if it does not we wrap it in a nomral way otherwise *) let rec no_auto_uncurried_arg_types diff --git a/jscomp/core/lam_compile_external_call.ml b/jscomp/core/lam_compile_external_call.ml index 28347498e9..4e1b9ccf3b 100644 --- a/jscomp/core/lam_compile_external_call.ml +++ b/jscomp/core/lam_compile_external_call.ml @@ -78,7 +78,7 @@ let append_list x xs = unbox it in the first place. Note when optional value is not passed, the unboxed value would be - [undefined], with the combination of `[@bs.int]` it would be still be + [undefined], with the combination of `[@int]` it would be still be [undefined], this by default is still correct.. {[ (function () { @@ -252,7 +252,7 @@ let translate_scoped_module_val Ext_list.fold_left (Ext_list.append rest [fn]) start E.dot end | None -> - (* no [@@bs.module], assume it's global *) + (* no [@@module], assume it's global *) begin match scopes with | [] -> E.js_global fn @@ -309,7 +309,7 @@ let translate_ffi | Js_new { external_module_name = module_name; name = fn; scopes - } -> (* handle [@@bs.new]*) + } -> (* handle [@@new]*) (* This has some side effect, it will mark its identifier (If it has) as an object, ATTENTION: @@ -356,7 +356,7 @@ let translate_ffi begin match args with | self :: args -> (* PR2162 [self_type] more checks in syntax: - - should not be [bs.as] *) + - should not be [@as] *) let [@warning"-8"] ( _self_type::arg_types ) = arg_types in if splice then @@ -382,7 +382,7 @@ let translate_ffi (* TODO #11 1. check args -- error checking - 2. support [@@bs.scope "window"] + 2. support [@@scope "window"] we need know whether we should call [add_js_module] or not *) translate_scoped_module_val external_module_name name scopes diff --git a/jscomp/core/lam_compile_external_call.mli b/jscomp/core/lam_compile_external_call.mli index 2186ccc140..24ccb32b78 100644 --- a/jscomp/core/lam_compile_external_call.mli +++ b/jscomp/core/lam_compile_external_call.mli @@ -45,5 +45,5 @@ val translate_ffi : (** TODO: document supported attributes Attributes starting with `js` are reserved - examples: "bs.splice" + examples: "variadic" *) diff --git a/jscomp/core/lam_convert.ml b/jscomp/core/lam_convert.ml index 1710fd6aff..4de80f31b8 100644 --- a/jscomp/core/lam_convert.ml +++ b/jscomp/core/lam_convert.ml @@ -904,7 +904,7 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) : Lam.t * Lam_module_i ]} is also wrong. - It seems, we need handle [@bs.splice] earlier + It seems, we need handle [@variadic] earlier or {[ @@ -912,7 +912,7 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) : Lam.t * Lam_module_i let x0, x1, x2 =1,2,3 in (fun y -> f [|x0;x1;x2|] y) ]} - But this still need us to know [@bs.splice] in advance + But this still need us to know [@variadic] in advance we should not remove it immediately, since we have to be careful diff --git a/jscomp/core/lam_eta_conversion.ml b/jscomp/core/lam_eta_conversion.ml index 7ba237c078..b91b344685 100644 --- a/jscomp/core/lam_eta_conversion.ml +++ b/jscomp/core/lam_eta_conversion.ml @@ -119,7 +119,7 @@ let transform_under_supply n ap_info fn args = cautiously, since [let u = f] and we are chaning the arity of [f] it will affect the collection of [u] - A typical use case is to pass an OCaml function to JS side as a callback (i.e, [@bs.uncurry]) + A typical use case is to pass an OCaml function to JS side as a callback (i.e, [@uncurry]) *) let unsafe_adjust_to_arity loc ~(to_:int) ?(from : int option) (fn : Lam.t) : Lam.t = let ap_info : Lam.ap_info = {ap_loc = loc; ap_inlined = Default_inline; ap_status = App_na } in diff --git a/jscomp/core/record_attributes_check.ml b/jscomp/core/record_attributes_check.ml index ac56010745..8c3bd27865 100644 --- a/jscomp/core/record_attributes_check.ml +++ b/jscomp/core/record_attributes_check.ml @@ -26,7 +26,7 @@ type label = Types.label_description let find_name (attr : Parsetree.attribute) = match attr with - | {txt = "bs.as"}, PStr + | {txt = "bs.as" | "as"}, PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_constant (Pconst_string(s,_))},_ )}] -> Some s | _ -> None @@ -35,7 +35,7 @@ let find_name (attr : Parsetree.attribute) = let find_name_with_loc (attr : Parsetree.attribute) : string Asttypes.loc option = match attr with - | {txt = "bs.as";loc}, PStr + | {txt = "bs.as" | "as";loc}, PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_constant (Pconst_string(s,_))},_ )}] -> Some {txt = s; loc} | _ -> None @@ -79,7 +79,7 @@ let rec check_duplicated_labels_aux | Some ({txt = s;} as l) -> if Set_string.mem coll s (*use coll to make check a bit looser - allow cases like [ x : int [@bs.as "x"]] + allow cases like [ x : int [@as "x"]] *) then Some l else diff --git a/jscomp/ext/ext_array.ml b/jscomp/ext/ext_array.ml index 79e9563b5c..b59b9966f0 100644 --- a/jscomp/ext/ext_array.ml +++ b/jscomp/ext/ext_array.ml @@ -207,7 +207,7 @@ let find_and_split arr cmp v : _ split = (** TODO: available since 4.03, use {!Array.exists} *) -let exists p a = +let exists a p = let n = Array.length a in let rec loop i = if i = n then false diff --git a/jscomp/ext/ext_array.mli b/jscomp/ext/ext_array.mli index d33951b601..1e55f29c83 100644 --- a/jscomp/ext/ext_array.mli +++ b/jscomp/ext/ext_array.mli @@ -75,7 +75,10 @@ val find_and_split : ('a -> 'b -> bool) -> 'b -> 'a split -val exists : ('a -> bool) -> 'a array -> bool +val exists : + 'a array -> + ('a -> bool) -> + bool val is_empty : 'a array -> bool diff --git a/jscomp/ounit_tests/ounit_cmd_tests.ml b/jscomp/ounit_tests/ounit_cmd_tests.ml index 5f3887f9eb..b1f1f161dc 100644 --- a/jscomp/ounit_tests/ounit_cmd_tests.ml +++ b/jscomp/ounit_tests/ounit_cmd_tests.ml @@ -50,7 +50,7 @@ let suites = = "" [@@bs.send.pipe:int] [@@bs.splice]|}|] in - OUnit.assert_bool __LOC__ (Ext_string.contain_substring v_output.stderr "bs.splice") + OUnit.assert_bool __LOC__ (Ext_string.contain_substring v_output.stderr "variadic") end; __LOC__ >:: begin fun _ -> let v_output = perform_bsc [|"-bs-eval"; {|external @@ -59,7 +59,7 @@ let suites = = "" [@@bs.send.pipe:int] [@@bs.splice] |}|] in - OUnit.assert_bool __LOC__ (Ext_string.contain_substring v_output.stderr "bs.splice") + OUnit.assert_bool __LOC__ (Ext_string.contain_substring v_output.stderr "variadic") end; __LOC__ >:: begin fun _ -> @@ -115,7 +115,7 @@ external ff : (* Ounit_cmd_util.debug_output should_err ; *) OUnit.assert_bool __LOC__ (Ext_string.contain_substring - should_err.stderr "bs.uncurry") + should_err.stderr "uncurry") end ; __LOC__ >:: begin fun _ -> diff --git a/jscomp/ounit_tests/ounit_ffi_error_debug_test.ml b/jscomp/ounit_tests/ounit_ffi_error_debug_test.ml index d10ede6701..40fc5a4e83 100644 --- a/jscomp/ounit_tests/ounit_ffi_error_debug_test.ml +++ b/jscomp/ounit_tests/ounit_ffi_error_debug_test.ml @@ -58,7 +58,7 @@ let output = bsc_eval {| |} in OUnit.assert_bool __LOC__ - (Ext_string.contain_substring output.stderr "bs.unwrap") + (Ext_string.contain_substring output.stderr "unwrap") end; __LOC__ >:: begin fun _ -> diff --git a/jscomp/outcome_printer/tweaked_reason_oprint.cppo.ml b/jscomp/outcome_printer/tweaked_reason_oprint.cppo.ml index 8b395dc960..d1b5450d0c 100644 --- a/jscomp/outcome_printer/tweaked_reason_oprint.cppo.ml +++ b/jscomp/outcome_printer/tweaked_reason_oprint.cppo.ml @@ -316,14 +316,14 @@ and print_simple_out_type ppf = let res = if name = "arity0" then Otyp_arrow ("", Otyp_constr (Oide_ident "unit", []),ty) else ty in - fprintf ppf "@[<0>(%a)@ [@bs.meth]@]" (print_out_type_1 ~uncurried:false) res + fprintf ppf "@[<0>(%a)@ [%@meth]@]" (print_out_type_1 ~uncurried:false) res | Otyp_constr ( Oide_dot (Oide_dot ( Oide_ident "Js_OO", "Callback" ), _), [res] ) -> - fprintf ppf "@[<0>(%a)@ [@bs.this]@]" (print_out_type_1 ~uncurried:false) res + fprintf ppf "@[<0>(%a)@ [%@this]@]" (print_out_type_1 ~uncurried:false) res (* also BuckleScript-specific. Turns Js.t({. foo: bar}) into {. "foo": bar} *) | Otyp_constr ( diff --git a/jscomp/reserved_attributs.md b/jscomp/reserved_attributs.md index 66fd649769..93e4f33227 100644 --- a/jscomp/reserved_attributs.md +++ b/jscomp/reserved_attributs.md @@ -4,43 +4,47 @@ This is a list of reserved attributes, we may use such information to detect unused attributes in the future -get -set -this -meth + + + +scope +val -- done +module -- done +obj -- done +variadic -- done +send -- done +return -- done +new -- done +get_index -- done +set_index -- done +get -- done +set -- done +optional -- done +uncurry -- done + note [@uncurry 3] is okay but rarely used + maybe we should remove it +unwrap -- done +string -- done +int -- done +ignore -- done +as -- done +meth -- done +this -- done +send.pipe -- deprecated, no short-cut +splice -- deprecated, use variadic +config -- done open -- not decided -inline -- +inline -- done this would conflict exist one or not? invalid payload in bs.inline seems that we need loose the check -deriving -string -int -ignore -unwrap -uncurry -as -optional -get_index -return -config -obj +deriving -- done raw -- not needed re -- not needed external -- not needed time -- not needed node -- not needed debugger -- not needed -val -module -scope -splice -- deprecated, use variadic -variadic -send -send.pipe -- deprecated, no short-cut -new -set_index - debugger.chrome -- deprecated keywords is okay `[@open]` is a valid syntax diff --git a/jscomp/syntax/ast_attributes.ml b/jscomp/syntax/ast_attributes.ml index 87b104a35a..0814ad0ce0 100644 --- a/jscomp/syntax/ast_attributes.ml +++ b/jscomp/syntax/ast_attributes.ml @@ -33,7 +33,7 @@ type ('a,'b) st = let process_method_attributes_rev (attrs : t) = Ext_list.fold_left attrs ({get = None ; set = None}, []) (fun (st,acc) (({txt ; loc}, payload) as attr ) -> match txt with - | "bs.get" (* [@@bs.get{null; undefined}]*) + | "bs.get" | "get" (* @bs.get{null; undefined}*) -> let result = Ext_list.fold_left (Ast_payload.ident_or_record_as_config loc payload) (false, false) @@ -63,7 +63,7 @@ let process_method_attributes_rev (attrs : t) = ({st with get = Some result}, acc ) - | "bs.set" + | "bs.set" | "set" -> let result = Ext_list.fold_left (Ast_payload.ident_or_record_as_config loc payload) `Get @@ -78,7 +78,7 @@ let process_method_attributes_rev (attrs : t) = else Bs_syntaxerr.err loc Unsupported_predicates ) in (* properties -- void - [@@bs.set{only}] + [@@set{only}] *) {st with set = Some result }, acc | _ -> @@ -97,12 +97,11 @@ let process_attributes_rev (attrs : t) : attr_kind * t = | "bs", (Nothing | Uncurry _) -> Uncurry attr, acc (* TODO: warn unused/duplicated attribute *) - | "bs.this", (Nothing | Meth_callback _) + | ("bs.this" | "this"), (Nothing | Meth_callback _) -> Meth_callback attr, acc - | "bs.meth", (Nothing | Method _) + | ("bs.meth" | "meth"), (Nothing | Method _) -> Method attr, acc - | "bs", _ - | "bs.this", _ + | ("bs" | "bs.this" | "this"), _ -> Bs_syntaxerr.err loc Conflict_bs_bs_this_bs_meth | _ , _ -> st, attr::acc @@ -129,10 +128,27 @@ let process_bs (attrs : t) = st, attr::acc ) +let external_attrs = [| + "get"; + "set"; + "get_index"; + "return"; + "obj"; + "val"; + "module"; + "scope"; + "variadic"; + "send"; + "new"; + "set_index"; + Literals.gentype_import +|] +(* ATT: Special cases for built-in attributes handling *) let external_needs_to_be_encoded (attrs : t)= Ext_list.exists_fst attrs (fun {txt} -> - Ext_string.starts_with txt "bs." || txt = Literals.gentype_import) + Ext_string.starts_with txt "bs." || + Ext_array.exists external_attrs (fun (x : string) -> txt = x) ) let is_inline : attr -> bool = (fun @@ -152,24 +168,26 @@ type derive_attr = { let process_derive_type (attrs : t) : derive_attr * t = Ext_list.fold_left attrs ({bs_deriving = None }, []) (fun (st, acc) ({txt ; loc}, payload as attr) -> - match st, txt with - | {bs_deriving = None}, "bs.deriving" - -> - { - bs_deriving = Some - (Ast_payload.ident_or_record_as_config loc payload)}, acc - | {bs_deriving = Some _}, "bs.deriving" - -> - Bs_syntaxerr.err loc Duplicated_bs_deriving - - | _ , _ -> - st, attr::acc + match txt with + | "bs.deriving" | "deriving" + -> + begin match st.bs_deriving with + | None -> + { + bs_deriving = Some + (Ast_payload.ident_or_record_as_config loc payload)}, acc + | Some _ + -> + Bs_syntaxerr.err loc Duplicated_bs_deriving + end + | _ -> + st, attr::acc ) -(* duplicated [bs.uncurry] [bs.string] not allowed, - it is worse in bs.uncurry since it will introduce +(* duplicated @uncurry @string not allowed, + it is worse in @uncurry since it will introduce inconsistency in arity *) let iter_process_bs_string_int_unwrap_uncurry (attrs : t) = @@ -183,15 +201,15 @@ let iter_process_bs_string_int_unwrap_uncurry (attrs : t) = else Bs_syntaxerr.err loc Conflict_attributes in Ext_list.iter attrs (fun (({txt ; loc=_}, (payload : _ ) ) as attr) -> match txt with - | "bs.string" + | "bs.string" | "string" -> assign `String attr - | "bs.int" + | "bs.int" | "int" -> assign `Int attr - | "bs.ignore" + | "bs.ignore" | "ignore" -> assign `Ignore attr - | "bs.unwrap" + | "bs.unwrap" | "unwrap" -> assign `Unwrap attr - | "bs.uncurry" + | "bs.uncurry" | "uncurry" -> assign (`Uncurry (Ast_payload.is_single_int payload)) attr | _ -> () @@ -205,7 +223,7 @@ let iter_process_bs_string_as (attrs : t) : string option = (fun (({txt ; loc}, payload ) as attr ) -> match txt with - | "bs.as" + | "bs.as" | "as" -> if !st = None then match Ast_payload.is_single_string payload with @@ -225,7 +243,7 @@ let has_bs_optional (attrs : t) : bool = Ext_list.exists attrs (fun (({txt ; }, _ ) as attr) -> match txt with - | "bs.optional" + | "bs.optional" | "optional" -> Bs_ast_invariant.mark_used_bs_attribute attr ; true @@ -240,7 +258,7 @@ let iter_process_bs_int_as (attrs : t) = (fun (({txt ; loc}, payload ) as attr) -> match txt with - | "bs.as" + | "bs.as" | "as" -> if !st = None then match Ast_payload.is_single_int payload with @@ -264,7 +282,7 @@ let iter_process_bs_string_or_int_as (attrs : Parsetree.attributes) = (fun (({txt ; loc}, payload ) as attr) -> match txt with - | "bs.as" + | "bs.as" | "as" -> if !st = None then (Bs_ast_invariant.mark_used_bs_attribute attr ; diff --git a/jscomp/syntax/ast_config.ml b/jscomp/syntax/ast_config.ml index 2da98a8b1d..fda7f6c316 100644 --- a/jscomp/syntax/ast_config.ml +++ b/jscomp/syntax/ast_config.ml @@ -51,7 +51,7 @@ let add_signature k v = let rec iter_on_bs_config_stru (x :Parsetree.structure) = match x with | [] -> () - | {pstr_desc = Pstr_attribute (({txt = "bs.config"; loc}, payload) as attr)}::_ -> + | {pstr_desc = Pstr_attribute (({txt = "bs.config" | "config"; loc}, payload) as attr)}::_ -> Bs_ast_invariant.mark_used_bs_attribute attr; Ext_list.iter (Ast_payload.ident_or_record_as_config loc payload) (Ast_payload.table_dispatch !structural_config_table) @@ -62,7 +62,7 @@ let rec iter_on_bs_config_stru (x :Parsetree.structure) = let rec iter_on_bs_config_sigi (x :Parsetree.signature) = match x with | [] -> () - | {psig_desc = Psig_attribute (({txt = "bs.config"; loc}, payload) as attr)}::_ -> + | {psig_desc = Psig_attribute (({txt = "bs.config" | "config"; loc}, payload) as attr)}::_ -> Bs_ast_invariant.mark_used_bs_attribute attr; Ext_list.iter (Ast_payload.ident_or_record_as_config loc payload) (Ast_payload.table_dispatch !signature_config_table) diff --git a/jscomp/syntax/ast_core_type_class_type.ml b/jscomp/syntax/ast_core_type_class_type.ml index d76996f634..c11a61c6da 100644 --- a/jscomp/syntax/ast_core_type_class_type.ml +++ b/jscomp/syntax/ast_core_type_class_type.ml @@ -174,7 +174,7 @@ let typ_mapper | Uncurry attr , attrs -> attrs, attr +> ty | Method _, _ - -> Location.raise_errorf ~loc "bs.get/set conflicts with bs.meth" + -> Location.raise_errorf ~loc "%@get/set conflicts with %@meth" | Meth_callback attr, attrs -> attrs, attr +> ty in @@ -186,7 +186,7 @@ let typ_mapper | Uncurry attr, attrs -> attrs, attr +> ty | Method _, _ - -> Location.raise_errorf ~loc "bs.get/set conflicts with bs.meth" + -> Location.raise_errorf ~loc "%@get/set conflicts with %@meth" | Meth_callback attr, attrs -> attrs, attr +> ty in diff --git a/jscomp/syntax/ast_external_process.ml b/jscomp/syntax/ast_external_process.ml index 36f30984fc..6fe96165af 100644 --- a/jscomp/syntax/ast_external_process.ml +++ b/jscomp/syntax/ast_external_process.ml @@ -103,7 +103,7 @@ let refine_arg_type ~(nolabel:bool) (ptyp : Ast_core_type.t) match result with | None -> spec_of_ptyp nolabel ptyp - | Some cst -> (* (_[@bs.as ])*) + | Some cst -> (* (_[@as ])*) (* when ppx start dropping attributes we should warn, there is a trade off whether we should warn dropped non bs attribute or not @@ -111,14 +111,14 @@ let refine_arg_type ~(nolabel:bool) (ptyp : Ast_core_type.t) Bs_ast_invariant.warn_discarded_unused_attributes ptyp_attrs; begin match cst with | Int i -> - (* This type is used in bs.obj only to construct obj type*) + (* This type is used in obj only to construct obj type*) Arg_cst(External_arg_spec.cst_int i) | Str i-> Arg_cst (External_arg_spec.cst_string i) | Js_literal_str s -> Arg_cst (External_arg_spec.cst_obj_literal s) end - else (* ([`a|`b] [@bs.string]) *) + else (* ([`a|`b] [@string]) *) spec_of_ptyp nolabel ptyp ) @@ -135,22 +135,22 @@ let refine_obj_arg_type ~(nolabel:bool) (ptyp : Ast_core_type.t) match result with | None -> Bs_syntaxerr.err ptyp.ptyp_loc Invalid_underscore_type_in_external - | Some (Int i) -> (* (_[@bs.as ])*) - (* This type is used in bs.obj only to construct obj type*) + | Some (Int i) -> (* (_[@as ])*) + (* This type is used in obj only to construct obj type*) Arg_cst(External_arg_spec.cst_int i) | Some (Str i)-> Arg_cst (External_arg_spec.cst_string i) | Some (Js_literal_str s ) -> Arg_cst (External_arg_spec.cst_obj_literal s) - else (* ([`a|`b] [@bs.string]) *) + else (* ([`a|`b] [@string]) *) spec_of_ptyp nolabel ptyp (** Given the type of argument, process its [bs.] attribute and new type, The new type is currently used to reconstruct the external type - and result type in [@@bs.obj] + and result type in [@@obj] They are not the same though, for example {[ - external f : hi:([ `hi | `lo ] [@bs.string]) -> unit -> _ = "" [@@bs.obj] + external f : hi:([ `hi | `lo ] [@string]) -> unit -> _ = "" [@@obj] ]} The result type would be [ hi:string ] *) @@ -158,20 +158,20 @@ let get_opt_arg_type ~(nolabel : bool) (ptyp : Ast_core_type.t) : External_arg_spec.attr = - if ptyp.ptyp_desc = Ptyp_any then (* (_[@bs.as ])*) - (* extenral f : ?x:_ -> y:int -> _ = "" [@@bs.obj] is not allowed *) + if ptyp.ptyp_desc = Ptyp_any then (* (_[@as ])*) + (* extenral f : ?x:_ -> y:int -> _ = "" [@@obj] is not allowed *) Bs_syntaxerr.err ptyp.ptyp_loc Invalid_underscore_type_in_external; - (* ([`a|`b] [@bs.string]) *) + (* ([`a|`b] [@@string]) *) spec_of_ptyp nolabel ptyp (** - [@@bs.module "react"] - [@@bs.module "react"] + [@@module "react"] + [@@module "react"] --- - [@@bs.module "@" "react"] - [@@bs.module "@" "react"] + [@@module "@" "react"] + [@@module "@" "react"] They should have the same module name @@ -179,7 +179,7 @@ let get_opt_arg_type two external files to the same module name *) type bundle_source = - [`Nm_payload of string (* from payload [@@bs.val "xx" ]*) + [`Nm_payload of string (* from payload [@@val "xx" ]*) |`Nm_external of string (* from "" in external *) | `Nm_val of string lazy_t (* from function name *) ] @@ -251,6 +251,7 @@ let return_wrapper loc (txt : string) : External_ffi_types.return_wrapper = | _ -> Bs_syntaxerr.err loc Not_supported_directive_in_bs_return +exception Not_handled_external_attribute (* The processed attributes will be dropped *) let parse_external_attributes @@ -259,15 +260,15 @@ let parse_external_attributes (prim_name_or_pval_prim: bundle_source ) (prim_attributes : Ast_attributes.t) : Ast_attributes.t * external_desc = - (* shared by `[@@bs.val]`, `[@@bs.send]`, - `[@@bs.set]`, `[@@bs.get]` , `[@@bs.new]` + (* shared by `[@@val]`, `[@@send]`, + `[@@set]`, `[@@get]` , `[@@new]` `[@@bs.send.pipe]` does not use it *) let name_from_payload_or_prim ~loc (payload : Parsetree.payload) : name_source = match payload with | PStr [] -> (prim_name_or_pval_prim :> name_source) - (* It is okay to have [@@bs.val] without payload *) + (* It is okay to have [@@val] without payload *) | _ -> begin match Ast_payload.is_single_string payload with | Some (val_name, _) -> `Nm_payload val_name @@ -286,15 +287,15 @@ let parse_external_attributes in attr::attrs, {st with external_module_name = Some { bundle; module_bind_name = Phint_nothing}} - else if Ext_string.starts_with txt "bs." then - attrs, begin match txt with - | "bs.val" -> + else + let action () = begin match txt with + | "bs.val" | "val" -> if no_arguments then {st with val_name = name_from_payload_or_prim ~loc payload} else {st with call_name = name_from_payload_or_prim ~loc payload} - | "bs.module" -> + | "bs.module" | "module" -> begin match Ast_payload.assert_strings loc payload with | [bundle] -> {st with external_module_name = @@ -314,7 +315,7 @@ let parse_external_attributes | _ -> Bs_syntaxerr.err loc Illegal_attribute end - | "bs.scope" -> + | "bs.scope" | "scope" -> begin match Ast_payload.assert_strings loc payload with | [] -> Bs_syntaxerr.err loc Illegal_attribute @@ -323,27 +324,29 @@ let parse_external_attributes *) | scopes -> { st with scopes = scopes } end - | "bs.splice" | "bs.variadic" -> {st with splice = true} - | "bs.send" -> + | "bs.splice" + | "bs.variadic" | "variadic" -> {st with splice = true} + | "bs.send" | "send" -> { st with val_send = name_from_payload_or_prim ~loc payload} | "bs.send.pipe" -> { st with val_send_pipe = Some (Ast_payload.as_core_type loc payload)} - | "bs.set" -> + | "bs.set" | "set" -> {st with set_name = name_from_payload_or_prim ~loc payload} - | "bs.get" -> {st with get_name = name_from_payload_or_prim ~loc payload} + | "bs.get" | "get" -> + {st with get_name = name_from_payload_or_prim ~loc payload} - | "bs.new" -> {st with new_name = name_from_payload_or_prim ~loc payload} - | "bs.set_index" -> + | "bs.new" | "new" -> {st with new_name = name_from_payload_or_prim ~loc payload} + | "bs.set_index" | "set_index" -> if String.length prim_name_check <> 0 then - Location.raise_errorf ~loc "[@@bs.set_index] this particular external's name needs to be a placeholder empty string"; + Location.raise_errorf ~loc "%@set_index this particular external's name needs to be a placeholder empty string"; {st with set_index = true} - | "bs.get_index"-> + | "bs.get_index" | "get_index" -> if String.length prim_name_check <> 0 then - Location.raise_errorf ~loc "[@@bs.get_index] this particular external's name needs to be a placeholder empty string"; + Location.raise_errorf ~loc "%@get_index this particular external's name needs to be a placeholder empty string"; {st with get_index = true} - | "bs.obj" -> {st with mk_obj = true} - | "bs.return" -> + | "bs.obj" | "obj" -> {st with mk_obj = true} + | "bs.return" | "return" -> let actions = Ast_payload.ident_or_record_as_config loc payload in begin match actions with @@ -352,15 +355,16 @@ let parse_external_attributes | _ -> Bs_syntaxerr.err loc Not_supported_directive_in_bs_return end - | _ -> (Location.prerr_warning loc (Bs_unused_attribute txt); st) - end - else attr :: attrs, st + | _ -> raise_notrace Not_handled_external_attribute + end in + try attrs, action () with + | Not_handled_external_attribute -> attr::attrs, st ) let has_bs_uncurry (attrs : Ast_attributes.t) = - Ext_list.exists_fst attrs (fun x -> x.txt = "bs.uncurry") + Ext_list.exists_fst attrs (fun {txt;loc=_} -> txt = "bs.uncurry" || txt = "uncurry") let check_return_wrapper @@ -420,11 +424,11 @@ let process_obj set_index = false ; mk_obj = _; scopes = []; - (* wrapper does not work with [bs.obj] + (* wrapper does not work with @obj TODO: better error message *) } -> if String.length prim_name <> 0 then - Location.raise_errorf ~loc "[@@bs.obj] expect external names to be empty string"; + Location.raise_errorf ~loc "%@obj expect external names to be empty string"; let arg_kinds, new_arg_types_ty, (result_types : Parsetree.object_field list) = Ext_list.fold_right arg_types_ty ( [], [], []) (fun param_type ( arg_labels, (arg_types : Ast_compatible.param_type list), result_types) -> @@ -470,15 +474,15 @@ let process_obj (Otag({Asttypes.txt = name; loc}, [], Ast_literal.type_string ~loc ()) :: result_types) | Fn_uncurry_arity _ -> Location.raise_errorf ~loc - "The combination of [@@bs.obj], [@@bs.uncurry] is not supported yet" + "The combination of %@obj, %@uncurry is not supported yet" | Extern_unit -> assert false | Poly_var _ -> Location.raise_errorf ~loc - "bs.obj label %s does not support such arg type" name + "%@obj label %s does not support such arg type" name | Unwrap -> Location.raise_errorf ~loc - "bs.obj label %s does not support [@bs.unwrap] arguments" name + "%@obj label %s does not support %@unwrap arguments" name end | Optional name -> let obj_arg_type = get_opt_arg_type ~nolabel:false ty in @@ -503,18 +507,18 @@ let process_obj (Otag ({Asttypes.txt = name; loc}, [], Ast_comb.to_undefined_type loc @@ Ast_literal.type_string ~loc ()) :: result_types) | Arg_cst _ -> - Location.raise_errorf ~loc "bs.as is not supported with optional yet" + Location.raise_errorf ~loc "%@as is not supported with optional yet" | Fn_uncurry_arity _ -> Location.raise_errorf ~loc - "The combination of [@@bs.obj], [@@bs.uncurry] is not supported yet" + "The combination of %@obj, %@uncurry is not supported yet" | Extern_unit -> assert false | Poly_var _ -> Location.raise_errorf ~loc - "bs.obj label %s does not support such arg type" name + "%@obj label %s does not support such arg type" name | Unwrap -> Location.raise_errorf ~loc - "bs.obj label %s does not support [@bs.unwrap] arguments" name + "%@obj label %s does not support %@unwrap arguments" name end in new_arg_label::arg_labels, @@ -531,7 +535,7 @@ let process_obj in Ast_compatible.mk_fn_type new_arg_types_ty result, External_ffi_types.ffi_obj_create arg_kinds - | _ -> Location.raise_errorf ~loc "Attribute found that conflicts with [@@bs.obj]" + | _ -> Location.raise_errorf ~loc "Attribute found that conflicts with %@obj" let external_desc_of_non_obj @@ -564,9 +568,9 @@ let external_desc_of_non_obj if arg_type_specs_length = 3 then Js_set_index {js_set_index_scopes = scopes} else - Location.raise_errorf ~loc "Ill defined attribute [@@bs.set_index](arity of 3)" + Location.raise_errorf ~loc "Ill defined attribute %@set_index (arity of 3)" | {set_index = true; _} -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.set_index]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@set_index") | {get_index = true; val_name = `Nm_na; external_module_name = None ; @@ -587,10 +591,10 @@ let external_desc_of_non_obj if arg_type_specs_length = 2 then Js_get_index {js_get_index_scopes = scopes} else Location.raise_errorf ~loc - "Ill defined attribute [@@bs.get_index] (arity expected 2 : while %d)" arg_type_specs_length + "Ill defined attribute %@get_index (arity expected 2 : while %d)" arg_type_specs_length | {get_index = true; _} -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.get_index]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@get_index") | {module_as_val = Some external_module_name ; get_index = false; @@ -613,17 +617,17 @@ let external_desc_of_non_obj | [], `Nm_na, _ -> Js_module_as_var external_module_name | _, `Nm_na, _ -> Js_module_as_fn {splice; external_module_name } | _, #bundle_source, #bundle_source -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.module].") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@module.") | _, (`Nm_val _ | `Nm_external _) , `Nm_na -> Js_module_as_class external_module_name | _, `Nm_payload _ , `Nm_na -> Location.raise_errorf ~loc - "Incorrect FFI attribute found: (bs.new should not carry a payload here)" + "Incorrect FFI attribute found: (%@new should not carry a payload here)" end | {module_as_val = Some _; _} -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.module].") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@module.") | {call_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name) ; splice; scopes ; @@ -645,7 +649,7 @@ let external_desc_of_non_obj Js_call {splice; name; external_module_name; scopes } | {call_name = #bundle_source ; _ } -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.val]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@val") | {val_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name); external_module_name; @@ -666,13 +670,13 @@ let external_desc_of_non_obj -> (* if no_arguments --> {[ - external ff : int = "" [@@bs.val] + external ff : int = "" [@@val] ]} *) Js_var { name; external_module_name; scopes} | {val_name = #bundle_source ; _ } -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.val]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@val") | {splice ; scopes ; @@ -695,7 +699,7 @@ let external_desc_of_non_obj if arg_type_specs_length = 0 then (* {[ - external ff : int = "" [@@bs.module "xx"] + external ff : int = "" [@@module "xx"] ]} *) Js_var { name; external_module_name; scopes} @@ -717,21 +721,21 @@ let external_desc_of_non_obj return_wrapper = _ ; } -> (* PR #2162 - since when we assemble arguments the first argument in - [@@bs.send] is ignored + [@@send] is ignored *) begin match arg_type_specs with | [] -> Location.raise_errorf - ~loc "Ill defined attribute [@@bs.send] (the external needs to be a regular function call with at least one argument)" + ~loc "Ill defined attribute %@send(the external needs to be a regular function call with at least one argument)" | {arg_type = Arg_cst _ ; arg_label = _} :: _ -> Location.raise_errorf - ~loc "Ill defined attribute [@@bs.send] (first argument can't be const)" + ~loc "Ill defined attribute %@send(first argument can't be const)" | _ :: _ -> Js_send {splice ; name; js_send_scopes = scopes ; pipe = false} end | {val_send = #bundle_source; _ } - -> Location.raise_errorf ~loc "You used a FFI attribute that can't be used with [@@bs.send]" + -> Location.raise_errorf ~loc "You used a FFI attribute that can't be used with %@send" | {val_send_pipe = Some _; (* splice = (false as splice); *) val_send = `Nm_na; @@ -756,7 +760,7 @@ let external_desc_of_non_obj pipe = true} | {val_send_pipe = Some _ ; _} - -> Location.raise_errorf ~loc "conflict attributes found with [@@bs.send.pipe]" + -> Location.raise_errorf ~loc "conflict attributes found with [%@%@bs.send.pipe]" | {new_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name); external_module_name; @@ -777,7 +781,7 @@ let external_desc_of_non_obj } -> Js_new {name; external_module_name; scopes} | {new_name = #bundle_source ; _ } -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.new]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@new") | {set_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name); val_name = `Nm_na ; call_name = `Nm_na ; @@ -797,9 +801,9 @@ let external_desc_of_non_obj -> if arg_type_specs_length = 2 then Js_set { js_set_scopes = scopes ; js_set_name = name} - else Location.raise_errorf ~loc "Ill defined attribute [@@bs.set] (two args required)" + else Location.raise_errorf ~loc "Ill defined attribute %@set (two args required)" | {set_name = #bundle_source; _} - -> Location.raise_errorf ~loc "conflict attributes found with [@@bs.set]" + -> Location.raise_errorf ~loc "conflict attributes found with %@set" | {get_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name); val_name = `Nm_na ; @@ -821,9 +825,9 @@ let external_desc_of_non_obj if arg_type_specs_length = 1 then Js_get { js_get_name = name; js_get_scopes = scopes } else - Location.raise_errorf ~loc "Ill defined attribute [@@bs.get] (only one argument)" + Location.raise_errorf ~loc "Ill defined attribute %@bs.get (only one argument)" | {get_name = #bundle_source; _} - -> Location.raise_errorf ~loc "Attribute found that conflicts with [@@bs.get]" + -> Location.raise_errorf ~loc "Attribute found that conflicts with %@bs.get" | {get_name = `Nm_na; val_name = `Nm_na ; @@ -842,7 +846,7 @@ let external_desc_of_non_obj return_wrapper = _; } - -> Location.raise_errorf ~loc "Could not infer which FFI category it belongs to, maybe you forgot [%@%@bs.val]? " + -> Location.raise_errorf ~loc "Could not infer which FFI category it belongs to, maybe you forgot %@val? " (** Note that the passed [type_annotation] is already processed by visitor pattern before*) let handle_attributes @@ -854,12 +858,12 @@ let handle_attributes : Parsetree.core_type * External_ffi_types.t * Parsetree.attributes * bool = (** sanity check here - {[ int -> int -> (int -> int -> int [@bs.uncurry])]} + {[ int -> int -> (int -> int -> int [@uncurry])]} It does not make sense *) if has_bs_uncurry type_annotation.ptyp_attributes then Location.raise_errorf - ~loc "[@@bs.uncurry] can not be applied to the whole definition"; + ~loc "%@uncurry can not be applied to the whole definition"; let prim_name_or_pval_name = if String.length prim_name = 0 then `Nm_val (lazy (Location.prerr_warning loc (Bs_fragile_external pval_name); pval_name)) @@ -870,7 +874,7 @@ let handle_attributes if has_bs_uncurry result_type.ptyp_attributes then Location.raise_errorf ~loc:result_type.ptyp_loc - "[@@bs.uncurry] can not be applied to tailed position"; + "%@uncurry can not be applied to tailed position"; let no_arguments = arg_types_ty = [] in let unused_attrs, external_desc = parse_external_attributes no_arguments @@ -888,7 +892,7 @@ let handle_attributes let arg_type = refine_arg_type ~nolabel:true obj in begin match arg_type with | Arg_cst _ -> - Location.raise_errorf ~loc:obj.ptyp_loc "[@bs.as] is not supported in bs.send type " + Location.raise_errorf ~loc:obj.ptyp_loc "%@as is not supported in %@send type " | _ -> (* more error checking *) [{arg_label = Arg_empty; arg_type}], @@ -906,17 +910,17 @@ let handle_attributes if i = 0 && splice then begin match arg_label with | Optional _ -> - Location.raise_errorf ~loc "[@@@@bs.splice] expect the last type to be a non optional" + Location.raise_errorf ~loc "%@variadic expect the last type to be a non optional" | Labelled _ | Nolabel -> if ty.ptyp_desc = Ptyp_any then - Location.raise_errorf ~loc "[@@@@bs.splice] expect the last type to be an array"; + Location.raise_errorf ~loc "%@variadic expect the last type to be an array"; if spec_of_ptyp true ty <> Nothing then - Location.raise_errorf ~loc "[@@@@bs.splice] expect the last type to be an array"; + Location.raise_errorf ~loc "%@variadic expect the last type to be an array"; match ty.ptyp_desc with | Ptyp_constr({txt = Lident "array"; _}, [_]) -> () - | _ -> Location.raise_errorf ~loc "[@@@@bs.splice] expect the last type to be an array"; + | _ -> Location.raise_errorf ~loc "%@variadic expect the last type to be an array"; end ; let (arg_label : External_arg_spec.label_noname), arg_type, new_arg_types = match arg_label with @@ -924,10 +928,10 @@ let handle_attributes let arg_type = get_opt_arg_type ~nolabel:false ty in begin match arg_type with | Poly_var _ -> - (* ?x:([`x of int ] [@bs.string]) does not make sense *) + (* ?x:([`x of int ] [@string]) does not make sense *) Location.raise_errorf ~loc - "[@@bs.string] does not work with optional when it has arities in label %s" s + "%@string does not work with optional when it has arities in label %s" s | _ -> Arg_optional, arg_type, param_type :: arg_types end diff --git a/jscomp/syntax/ast_polyvar.ml b/jscomp/syntax/ast_polyvar.ml index e7b51571a2..c8130df950 100644 --- a/jscomp/syntax/ast_polyvar.ml +++ b/jscomp/syntax/ast_polyvar.ml @@ -114,7 +114,7 @@ let map_row_fields_into_strings ptyp_loc let descr = if !has_bs_as then Some result else None in match has_payload, descr with | false, None -> - Location.prerr_warning ptyp_loc (Bs_ffi_warning "bs.string is redundant here, you can safely remove it"); + Location.prerr_warning ptyp_loc (Bs_ffi_warning "%@string is redundant here, you can safely remove it"); Nothing | false , Some descr -> External_arg_spec.Poly_var_string {descr } diff --git a/jscomp/syntax/ast_tdcls.ml b/jscomp/syntax/ast_tdcls.ml index 8e41b16f7b..70d637fd79 100644 --- a/jscomp/syntax/ast_tdcls.ml +++ b/jscomp/syntax/ast_tdcls.ml @@ -44,29 +44,6 @@ let newTdcls else x ) -#if BS_NATIVE_PPX then - -let turn_bs_optional_into_optional (tdcls : Parsetree.type_declaration list) = - List.map (fun tdcl -> match tdcl.Parsetree.ptype_kind with - | Ptype_record labels -> - {tdcl with ptype_kind = Ptype_record (List.map (fun ({Parsetree.pld_type; pld_loc; pld_attributes} as dcl : Parsetree.label_declaration) -> - let has_optional_field = Ast_attributes.has_bs_optional pld_attributes in - if has_optional_field then - { dcl with - Parsetree.pld_type = {dcl.pld_type with ptyp_desc = - Ptyp_constr( - {txt = Lident "option"; - loc = pld_loc} - , [pld_type]); - ptyp_loc = pld_loc; - }; - pld_attributes = Ext_list.exclude pld_attributes (fun x -> (Ast_attributes.is_optional x) || (Ast_attributes.is_bs_as x)) - } - else dcl - ) labels)} - | _ -> tdcl) tdcls - -#end let handleTdclsInSigi @@ -84,11 +61,7 @@ let handleTdclsInSigi let newTdclsNewAttrs = self.type_declaration_list self originalTdclsNewAttrs in let kind = Ast_derive_abstract.isAbstract actions in if kind <> Not_abstract then -#if BS_NATIVE_PPX then - let codes = Native_ast_derive_abstract.handleTdclsInSig ~light:(kind = Light_abstract) originalTdclsNewAttrs in -#else let codes = Ast_derive_abstract.handleTdclsInSig ~light:(kind = Light_abstract) rf originalTdclsNewAttrs in -#end Ast_signature.fuseAll ~loc ( Sig.include_ ~loc @@ -96,11 +69,7 @@ let handleTdclsInSigi (Mty.typeof_ ~loc (Mod.constraint_ ~loc (Mod.structure ~loc [ -#if BS_NATIVE_PPX then - Ast_compatible.rec_type_str ~loc (turn_bs_optional_into_optional newTdclsNewAttrs) -#else Ast_compatible.rec_type_str ~loc rf newTdclsNewAttrs -#end ] ) (Mty.signature ~loc [])) ) ) :: (* include module type of struct [processed_code for checking like invariance ]end *) @@ -138,13 +107,6 @@ let handleTdclsInStru in let kind = Ast_derive_abstract.isAbstract actions in if kind <> Not_abstract then -#if BS_NATIVE_PPX then - let (codes, codes_sig) = Native_ast_derive_abstract.handleTdclsInStr ~light:(kind = Light_abstract) originalTdclsNewAttrs in - (* the codes_sig will hide the implementation of the type that is a record. *) - Ast_structure.constraint_ ~loc - (self.structure self codes) - (self.signature self codes_sig) -#else let codes = Ast_derive_abstract.handleTdclsInStr ~light:(kind = Light_abstract) rf originalTdclsNewAttrs in (* use [tdcls2] avoid nonterminating *) @@ -153,8 +115,6 @@ let handleTdclsInStru Ast_structure.constraint_ ~loc [newStr] [] :: (* [include struct end : sig end] for error checking *) self.structure self codes) -#end - else Ast_structure.fuseAll ~loc (newStr :: diff --git a/jscomp/syntax/ast_uncurry_gen.ml b/jscomp/syntax/ast_uncurry_gen.ml index 119c298302..0eb173feb1 100644 --- a/jscomp/syntax/ast_uncurry_gen.ml +++ b/jscomp/syntax/ast_uncurry_gen.ml @@ -24,7 +24,7 @@ open Ast_helper -(* Handling `fun [@bs.this]` used in `object [@bs] end` *) +(* Handling `fun [@this]` used in `object [@bs] end` *) let to_method_callback loc (self : Bs_ast_mapper.mapper) label pat body : Parsetree.expression_desc = diff --git a/jscomp/syntax/ast_util.ml b/jscomp/syntax/ast_util.ml index 3308894638..8379c8c9d4 100644 --- a/jscomp/syntax/ast_util.ml +++ b/jscomp/syntax/ast_util.ml @@ -81,8 +81,8 @@ let ocaml_obj_as_js_object (** we need calculate the real object type and exposed object type, in some cases there are equivalent - for public object type its [@bs.meth] it does not depend on itself - while for label argument it is [@bs.this] which depends internal object + for public object type its [@meth] it does not depend on itself + while for label argument it is [@this] which depends internal object *) let (internal_label_attr_types : Parsetree.object_field list), (public_label_attr_types : Parsetree.object_field list) = diff --git a/jscomp/syntax/bs_ast_invariant.ml b/jscomp/syntax/bs_ast_invariant.ml index f4df67076a..f57db6f6bb 100644 --- a/jscomp/syntax/bs_ast_invariant.ml +++ b/jscomp/syntax/bs_ast_invariant.ml @@ -23,6 +23,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) +(** Warning unused bs attributes + Note if we warn `deriving` too, + it may fail third party ppxes +*) let is_bs_attribute txt = let len = String.length txt in len >= 2 && @@ -120,7 +124,7 @@ let emit_external_warnings : iterator= Ext_list.iter lbl.pld_attributes (fun attr -> match attr with - | {txt = "bs.as"}, _ -> mark_used_bs_attribute attr + | {txt = "bs.as" | "as"}, _ -> mark_used_bs_attribute attr | _ -> () ); default_iterator.label_declaration self lbl diff --git a/jscomp/syntax/bs_builtin_ppx.ml b/jscomp/syntax/bs_builtin_ppx.ml index 5baa80bcb4..867c553c61 100644 --- a/jscomp/syntax/bs_builtin_ppx.ml +++ b/jscomp/syntax/bs_builtin_ppx.ml @@ -125,7 +125,7 @@ let expr_mapper (self : mapper) (e : Parsetree.expression) = pexp_desc = Ast_uncurry_gen.to_uncurry_fn e.pexp_loc self label pat body ; pexp_attributes} | Method _ , _ - -> Location.raise_errorf ~loc:e.pexp_loc "bs.meth is not supported in function expression" + -> Location.raise_errorf ~loc:e.pexp_loc "%@meth is not supported in function expression" | Meth_callback _, pexp_attributes -> (** FIXME: does it make sense to have a label for [this] ? *) @@ -151,7 +151,7 @@ let expr_mapper (self : mapper) (e : Parsetree.expression) = } | Some e -> Location.raise_errorf - ~loc:e.pexp_loc "`with` construct is not supported in bs.obj ") + ~loc:e.pexp_loc "`with` construct is not supported in js obj ") else default_expr_mapper self e | Pexp_object {pcstr_self; pcstr_fields} -> @@ -389,7 +389,7 @@ let structure_item_mapper (self : mapper) (str : Parsetree.structure_item) = | _ -> { str with pstr_desc = Pstr_value(Nonrecursive, [{pvb_pat ; pvb_expr; pvb_attributes; pvb_loc}])} end - | Pstr_attribute({txt = "bs.config" },_) -> str + | Pstr_attribute({txt = "bs.config" | "config" },_) -> str | _ -> default_mapper.structure_item self str diff --git a/jscomp/syntax/bs_syntaxerr.ml b/jscomp/syntax/bs_syntaxerr.ml index 8e293460ef..325ccb49da 100644 --- a/jscomp/syntax/bs_syntaxerr.ml +++ b/jscomp/syntax/bs_syntaxerr.ml @@ -67,7 +67,7 @@ let pp_error fmt err = -> "Uncurried function doesn't support optional arguments yet" | Expect_opt_in_bs_return_to_opt -> - "bs.return directive *_to_opt expect return type to be \n\ + "%@return directive *_to_opt expect return type to be \n\ syntax wise `_ option` for safety" | Not_supported_directive_in_bs_return @@ -76,7 +76,7 @@ let pp_error fmt err = | Illegal_attribute -> "Illegal attributes" | Canot_infer_arity_by_syntax - -> "Cannot infer the arity through the syntax, either [@bs.uncurry n] or \n\ + -> "Cannot infer the arity through the syntax, either [%@uncurry n] or \n\ write it in arrow syntax " | Inconsistent_arity (arity,n) -> Printf.sprintf "Inconsistent arity %d vs %d" arity n @@ -87,7 +87,7 @@ let pp_error fmt err = -> "unsupported predicates" | Conflict_bs_bs_this_bs_meth -> - "[@bs.this], [@bs], [@bs.meth] can not be applied at the same time" + "%@this, %@bs, %@meth can not be applied at the same time" | Duplicated_bs_deriving -> "duplicate bs.deriving attribute" | Conflict_attributes @@ -96,7 +96,7 @@ let pp_error fmt err = -> "expect string literal " | Duplicated_bs_as -> - "duplicate bs.as " + "duplicate %@as " | Expect_int_literal -> "expect int literal " @@ -113,20 +113,20 @@ let pp_error fmt err = "_ is not allowed in combination with external optional type" | Invalid_bs_string_type -> - "Not a valid type for [@bs.string]" + "Not a valid type for %@string" | Invalid_bs_int_type -> - "Not a valid type for [@bs.int]" + "Not a valid type for %@int" | Invalid_bs_unwrap_type -> - "Not a valid type for [@bs.unwrap]. Type must be an inline variant (closed), and\n\ + "Not a valid type for %@unwrap. Type must be an inline variant (closed), and\n\ each constructor must have an argument." | Conflict_ffi_attribute str -> "Conflicting FFI attributes found: " ^ str | Bs_this_simple_pattern -> - "[@bs.this] expect its pattern variable to be simple form") + "%@this expect its pattern variable to be simple form") type exn += Error of Location.t * error diff --git a/jscomp/syntax/external_arg_spec.ml b/jscomp/syntax/external_arg_spec.ml index 3a3f21d8dd..d08dd55c03 100644 --- a/jscomp/syntax/external_arg_spec.ml +++ b/jscomp/syntax/external_arg_spec.ml @@ -46,21 +46,21 @@ type attr = | Poly_var_string of { descr : (string * string) list - (* introduced by attributes bs.string - and bs.as + (* introduced by attributes @string + and @as *) } | Poly_var of { descr : (string * string) list option - (* introduced by attributes bs.string - and bs.as + (* introduced by attributes @string + and @as *) } (* `a does not have any value*) - | Int of (string * int ) list (* ([`a | `b ] [@bs.int])*) + | Int of (string * int ) list (* ([`a | `b ] [@int])*) | Arg_cst of cst - | Fn_uncurry_arity of int (* annotated with [@bs.uncurry ] or [@bs.uncurry 2]*) + | Fn_uncurry_arity of int (* annotated with [@uncurry ] or [@uncurry 2]*) (* maybe we can improve it as a combination of {!Asttypes.constant} and tuple *) | Extern_unit | Nothing diff --git a/jscomp/syntax/external_ffi_types.ml b/jscomp/syntax/external_ffi_types.ml index 411b137b1d..f801c5cc9f 100644 --- a/jscomp/syntax/external_ffi_types.ml +++ b/jscomp/syntax/external_ffi_types.ml @@ -94,22 +94,22 @@ type external_spec = (* let name_of_ffi ffi = match ffi with - | Js_get_index _scope -> "[@@bs.get_index ..]" - | Js_set_index _scope -> "[@@bs.set_index ..]" - | Js_get { js_get_name = s} -> Printf.sprintf "[@@bs.get %S]" s - | Js_set { js_set_name = s} -> Printf.sprintf "[@@bs.set %S]" s - | Js_call v -> Printf.sprintf "[@@bs.val %S]" v.name - | Js_send v -> Printf.sprintf "[@@bs.send %S]" v.name - | Js_module_as_fn v -> Printf.sprintf "[@@bs.val %S]" v.external_module_name.bundle - | Js_new v -> Printf.sprintf "[@@bs.new %S]" v.name + | Js_get_index _scope -> "@get_index .." + | Js_set_index _scope -> "@set_index .." + | Js_get { js_get_name = s} -> Printf.sprintf "[@@get %S]" s + | Js_set { js_set_name = s} -> Printf.sprintf "[@@set %S]" s + | Js_call v -> Printf.sprintf "[@@val %S]" v.name + | Js_send v -> Printf.sprintf "[@@send %S]" v.name + | Js_module_as_fn v -> Printf.sprintf "[@@val %S]" v.external_module_name.bundle + | Js_new v -> Printf.sprintf "[@@new %S]" v.name | Js_module_as_class v - -> Printf.sprintf "[@@bs.module] %S " v.bundle + -> Printf.sprintf "[@@module] %S " v.bundle | Js_module_as_var v -> - Printf.sprintf "[@@bs.module] %S " v.bundle - | Js_var v (* FIXME: could be [@@bs.module "xx"] as well *) + Printf.sprintf "[@@module] %S " v.bundle + | Js_var v (* FIXME: could be [@@module "xx"] as well *) -> - Printf.sprintf "[@@bs.val] %S " v.name *) + Printf.sprintf "[@@val] %S " v.name *) type return_wrapper = | Return_unset @@ -179,7 +179,7 @@ let valid_global_name ?loc txt = (* We loose such check (see #2583), - it also helps with the implementation deriving abstract [@bs.as] + it also helps with the implementation deriving abstract [@as] *) let valid_method_name ?loc:_ _txt = diff --git a/jscomp/syntax/native_ast_derive_abstract.ml b/jscomp/syntax/native_ast_derive_abstract.ml deleted file mode 100644 index a41bef5363..0000000000 --- a/jscomp/syntax/native_ast_derive_abstract.ml +++ /dev/null @@ -1,240 +0,0 @@ -module U = Ast_derive_util -open Ast_helper -type tdcls = Parsetree.type_declaration list - -module Ast_attributes = struct - include Ast_attributes - let deprecated s : Ast_attributes.attr = - {txt = "ocaml.deprecated"; loc = Location.none }, - PStr - [ - {pstr_desc = - Pstr_eval ( - Ast_compatible.const_exp_string ~loc:Location.none s, - []) - ; pstr_loc = Location.none}] - let is_optional (attr : attr) = - match attr with - | {Location.txt = "bs.optional"; _}, _ -> true - | _ -> false - - let is_bs_as (attr : attr) = - match attr with - | {Location.txt = "bs.as"; _}, _ -> true - | _ -> false -end -let deprecated name = - Ast_attributes.deprecated - ("use " ^ name ^ "Get instead or use {abstract = light} explicitly") - -let strip_option arg_name = - match arg_name with - | Asttypes.Nolabel -> assert false - | Optional s - | Labelled s -> s -[@@@ocaml.warning "-a"] -let handleTdcl light (tdcl : Parsetree.type_declaration) = - let core_type = U.core_type_of_type_declaration tdcl in - let loc = tdcl.ptype_loc in - let type_name = tdcl.ptype_name.txt in - match tdcl.ptype_kind with - | Ptype_record label_declarations -> - let is_private = tdcl.ptype_private = Private in - let (has_optional_field, new_label_declarations) = - Ext_list.fold_right label_declarations (false, []) (fun ({pld_type; pld_loc; pld_attributes} as dcl : Parsetree.label_declaration) (has_optional_field, acc) -> - let has_optional_field_local = Ast_attributes.has_bs_optional pld_attributes in - let acc = if has_optional_field_local then - { dcl with - pld_type = { - dcl.pld_type with - ptyp_desc = Ptyp_constr({txt = Lident "option"; loc = pld_loc}, [pld_type]); - ptyp_loc = pld_loc; - }; - pld_attributes = Ext_list.exclude pld_attributes (fun x -> (Ast_attributes.is_optional x) || (Ast_attributes.is_bs_as x)) - } :: acc - else dcl :: acc in - (has_optional_field || has_optional_field_local, acc) - ) in - let newTdcl = { - tdcl with - ptype_kind = Ptype_record new_label_declarations; - ptype_attributes = []; - } in - let setter_accessor, makeType, labels = - Ext_list.fold_right - label_declarations - ([], - (if has_optional_field then - Ast_compatible.arrow ~loc (Ast_literal.type_unit ()) core_type - else core_type), - []) - (fun - ({pld_name = - {txt = label_name; loc = label_loc} as pld_name; - pld_type; - pld_mutable; - pld_attributes; - pld_loc - }: - Parsetree.label_declaration) (acc, maker, labels) -> - let is_optional = Ast_attributes.has_bs_optional pld_attributes in - - let newLabel = - if is_optional - then {pld_name with txt = Asttypes.Optional pld_name.Asttypes.txt} - else {pld_name with txt = Asttypes.Labelled pld_name.Asttypes.txt} - in - - let maker, getter_type = - if is_optional then - let maker_optional_type = Ast_core_type.lift_option_type pld_type in - let getter_optional_type = { - Parsetree.ptyp_desc = - Ptyp_constr( - {txt = Lident "option"; - loc = pld_loc - }, [pld_type]); - ptyp_loc = pld_loc; - ptyp_attributes = []; - } in - Ast_compatible.opt_arrow ~loc:pld_loc label_name - pld_type - maker, - Ast_compatible.arrow ~loc core_type getter_optional_type - else - Ast_compatible.label_arrow ~loc:pld_loc label_name pld_type maker, - Ast_compatible.arrow ~loc core_type pld_type - in - let makeGetter light deprec pld_name = - Str.value Nonrecursive [ - Vb.mk - ~loc:pld_loc - ~attrs:(if deprec then deprecated (pld_name.Asttypes.txt) :: [] - else []) - (Pat.var {pld_name with txt = if light then label_name else label_name ^ "Get"}) - (Exp.constraint_ (Ast_compatible.fun_ ~loc:pld_loc - (Pat.var {Location.txt = "o"; loc = pld_loc}) - (Exp.field (Exp.ident {Location.txt = Longident.Lident "o"; loc = pld_loc}) {txt = Longident.Lident pld_name.Location.txt; loc = pld_loc})) getter_type)] - in - let acc = if not light then - makeGetter true true pld_name :: makeGetter false false pld_name :: acc - else makeGetter true false pld_name :: acc in - let is_current_field_mutable = pld_mutable = Mutable in - let acc = - if is_current_field_mutable then - let setter_type = - (Ast_compatible.arrow core_type - (Ast_compatible.arrow - pld_type (* setter *) - (Ast_literal.type_unit ()))) in - let variable = (Exp.ident {Location.txt = Longident.Lident "v"; loc = pld_loc}) in - let setter = Str.value Nonrecursive [ - Vb.mk - (Pat.var {loc = label_loc; txt = label_name ^ "Set"}) - (Exp.constraint_ (Ast_compatible.fun_ ~loc:pld_loc - (Pat.var {Location.txt = "o"; loc = pld_loc}) - (Ast_compatible.fun_ ~loc:pld_loc - (Pat.var {Location.txt = "v"; loc = pld_loc}) - (Exp.setfield - (Exp.ident {Location.txt = Longident.Lident "o"; loc = pld_loc}) - {txt = Longident.Lident pld_name.Location.txt; loc = pld_loc} - (if is_optional then Exp.construct {txt=Lident "Some"; loc = pld_loc} (Some variable) else variable)))) - setter_type) - ] - in - setter :: acc - else acc in - acc, - maker, - newLabel::labels - ) - in - newTdcl, - (if is_private then - setter_accessor - else - let my_loc = match labels with - | [] -> !default_loc - | { Asttypes.loc = label_loc } :: _ -> label_loc - in - let maker_body = Exp.record (Ext_list.fold_right labels [] (fun ({ Asttypes.txt; loc = label_loc }) rest -> - let field_name = {Asttypes.txt = Longident.Lident (strip_option txt); loc = label_loc} in - (field_name, Exp.ident field_name) :: rest - )) None in - (* This is to support bs.optional, which makes certain args of the function optional so we - add a unit at the end to prevent auto-currying issues. *) - let body_with_extra_unit_fun = (if has_optional_field then - (Ast_compatible.fun_ ~loc:my_loc - (Pat.var ({txt = "()"; loc = my_loc})) maker_body) - else maker_body) in - - let myMaker = -#if BS_NATIVE_PPX then - - Str.value Nonrecursive [ - Vb.mk - (Pat.var {loc; txt = type_name}) - (Exp.constraint_ ( - Ext_list.fold_right - labels - body_with_extra_unit_fun - (fun arg_name rest -> - (Ast_compatible.label_fun ~label:arg_name.Asttypes.txt ~loc:my_loc - (Pat.var ({arg_name with txt = strip_option arg_name.Asttypes.txt})) rest)) - ) makeType) - ] -#else assert false -#end - in - (myMaker :: setter_accessor)) - - | Ptype_abstract - | Ptype_variant _ - | Ptype_open -> - (* Looks obvious that it does not make sense to warn *) - (* U.notApplicable tdcl.ptype_loc derivingName; *) - tdcl, [] - -let code_sig_transform sigi = match sigi with - | {Parsetree.pstr_loc; pstr_desc = - Pstr_value (_, (({ - pvb_pat = {ppat_desc = Ppat_var name}; - pvb_expr = {pexp_desc = Pexp_constraint (_, typ)} - } as _makerVb) :: [])) - } -> - Sig.value (Val.mk ~loc:pstr_loc name typ) - | _ -> -#if BS_NATIVE_PPX then - Sig.type_ Nonrecursive [] -#else assert false -#end - -let handleTdclsInStr ~light rf tdcls = - let tdcls, tdcls_sig, code, code_sig = - Ext_list.fold_right tdcls ([],[], [], []) (fun tdcl (tdcls, tdcls_sig, sts, code_sig) -> - match handleTdcl light tdcl with - ntdcl, value_descriptions -> - let open Parsetree in - ( - ntdcl::tdcls, - {ntdcl with ptype_kind = Ptype_abstract }::tdcls_sig, - Ext_list.map_append value_descriptions sts (fun x -> x), - Ext_list.map_append value_descriptions code_sig code_sig_transform - ) - ) in - (Ast_compatible.rec_type_str rf tdcls :: code, - Ast_compatible.rec_type_sig rf tdcls_sig :: code_sig) - (* still need perform transformation for non-abstract type*) - -let handleTdclsInSig ~light rf tdcls = - let tdcls_sig, code = - Ext_list.fold_right tdcls ([], []) (fun tdcl (tdcls_sig, sts) -> - match handleTdcl light tdcl with - ntdcl, value_descriptions -> - let open Parsetree in - ( - {ntdcl with ptype_kind = Ptype_abstract }::tdcls_sig, - Ext_list.map_append value_descriptions sts code_sig_transform - ) - ) in - Ast_compatible.rec_type_sig rf tdcls_sig :: code diff --git a/jscomp/test/ast_abstract_test.ml b/jscomp/test/ast_abstract_test.ml index 24ee4f9859..38623f9d37 100644 --- a/jscomp/test/ast_abstract_test.ml +++ b/jscomp/test/ast_abstract_test.ml @@ -25,8 +25,8 @@ type x = [`a |`b |`c] -[@@bs.deriving {jsConverter = newType}] - + +[@@deriving {jsConverter = newType}] let idx v = eq __LOC__ (xFromJs (xToJs v)) v @@ -41,7 +41,7 @@ let () = type a = | A - | B [@bs.as 3] + | B [@as 3] | C [@@bs.deriving {jsConverter = newType}] diff --git a/jscomp/test/bs_auto_uncurry.ml b/jscomp/test/bs_auto_uncurry.ml index 52f9f9f72a..331df6647f 100644 --- a/jscomp/test/bs_auto_uncurry.ml +++ b/jscomp/test/bs_auto_uncurry.ml @@ -39,11 +39,11 @@ external map2 : external ff : - int -> (int [@bs.ignore]) -> (int -> int -> int [@bs.uncurry]) -> int + int -> (int [@ignore]) -> (int -> int -> int [@bs.uncurry]) -> int = "ff" [@@bs.val] external ff1 : - int -> (_ [@bs.as 3 ]) -> (int -> int -> int [@bs.uncurry]) -> int + int -> (_ [@as 3 ]) -> (int -> int -> int [@bs.uncurry]) -> int = "ff1" [@@bs.val] diff --git a/jscomp/test/bs_qualified.ml b/jscomp/test/bs_qualified.ml index aa4c502407..8a10100dc9 100644 --- a/jscomp/test/bs_qualified.ml +++ b/jscomp/test/bs_qualified.ml @@ -59,10 +59,10 @@ external getMockFn3 : t -> int -> string = "" [@@bs.get_index] [@@bs.scope "a0", "a1", "a2"] external setMocFn1 : t -> int -> string -> unit = "" -[@@bs.set_index] [@@bs.scope "a0"] +[@@set_index] [@@bs.scope "a0"] external setMocFn2 : t -> int -> string -> unit = "" -[@@bs.set_index] [@@bs.scope "a0", "a1"] +[@@set_index] [@@bs.scope "a0", "a1"] external setMocFn3 : t -> int -> string -> unit = "" [@@bs.set_index] [@@bs.scope "a0", "a1", "a2"] diff --git a/jscomp/test/bs_unwrap_test.ml b/jscomp/test/bs_unwrap_test.ml index 616932ef5c..d54dc0199a 100644 --- a/jscomp/test/bs_unwrap_test.ml +++ b/jscomp/test/bs_unwrap_test.ml @@ -20,7 +20,7 @@ let _ = log1 arg_pair external log2 : ( [ `Unit of unit - ] [@bs.unwrap] + ] [@unwrap] ) -> unit = "console.log" [@@bs.val] diff --git a/jscomp/test/debug_tmp.ml b/jscomp/test/debug_tmp.ml index 76b78a8fc4..d938845e17 100644 --- a/jscomp/test/debug_tmp.ml +++ b/jscomp/test/debug_tmp.ml @@ -1,5 +1,5 @@ -[@@@bs.config { +[@@@config { flags = [| (* "-drawlambda"; *) (* "-dtypedtree"; *) diff --git a/jscomp/test/demo_binding.ml b/jscomp/test/demo_binding.ml index 67c0b61825..1ced3f6231 100644 --- a/jscomp/test/demo_binding.ml +++ b/jscomp/test/demo_binding.ml @@ -22,12 +22,12 @@ class type title = class type text = object - method text : string [@@bs.set] + method text : string [@@set] end[@bs] class type measure = object - method minHeight : int [@@bs.set] + method minHeight : int [@@set] method minWidth : int [@@bs.set] method maxHeight : int [@@bs.set] method maxWidth : int [@@bs.set] @@ -106,4 +106,4 @@ class type textArea = external set_interval : (unit -> unit [@bs]) -> float -> unit = "setInterval" [@@bs.module "@runtime", "Runtime"] -external toFixed : float -> int -> string = "toFixed" [@@bs.send ] +external toFixed : float -> int -> string = "toFixed" [@@send] diff --git a/jscomp/test/ffi_js_test.ml b/jscomp/test/ffi_js_test.ml index 7c6f4f2324..34c9ba82f9 100644 --- a/jscomp/test/ffi_js_test.ml +++ b/jscomp/test/ffi_js_test.ml @@ -96,12 +96,12 @@ external getGADTI3 : external setGADTI2 : t -> ('a kind [@bs.ignore]) -> ('b kind [@bs.ignore]) -> int - -> ('a * 'b) -> unit = "" [@@bs.set_index] + -> ('a * 'b) -> unit = "" [@@set_index] external setGADTI3 : t -> ('a kind [@bs.ignore]) -> ('b kind [@bs.ignore]) -> (_ [@bs.as 3] ) - -> ('a * 'b) -> unit = "" [@@bs.set_index] + -> ('a * 'b) -> unit = "" [@@set_index] let ffff x = begin diff --git a/jscomp/test/ffi_splice_test.ml b/jscomp/test/ffi_splice_test.ml index 9f4fab5cea..20fc550af8 100644 --- a/jscomp/test/ffi_splice_test.ml +++ b/jscomp/test/ffi_splice_test.ml @@ -33,7 +33,7 @@ Make.prototype.add = function(){ type t -external make : int -> int -> int -> int -> t = "Make" [@@bs.new] +external make : int -> int -> int -> int -> t = "Make" [@@new] external sum : t -> unit -> int = "sum" [@@bs.send] diff --git a/jscomp/test/format_test.ml b/jscomp/test/format_test.ml index 05403c3ddf..cef5f2e9fd 100644 --- a/jscomp/test/format_test.ml +++ b/jscomp/test/format_test.ml @@ -14,7 +14,7 @@ let u () = "xx %s" ^^ "yy" module M = struct external infinity : float = "POSITIVE_INFINITY" - [@@bs.val] [@@bs.scope "Number"] + [@@val] [@@scope "Number"] external neg_infinity : float = "NEGATIVE_INFINITY" [@@bs.val] [@@bs.scope "Number"] external nan : float = "NaN" diff --git a/jscomp/test/gpr_1072_reg.ml b/jscomp/test/gpr_1072_reg.ml index 4180fa3545..8f132a79b3 100644 --- a/jscomp/test/gpr_1072_reg.ml +++ b/jscomp/test/gpr_1072_reg.ml @@ -19,7 +19,7 @@ `short | `long | `numeric | - `two_digit [@bs.as "2-digit"]] [@bs.string]) -> + `two_digit [@as "2-digit"]] [@string]) -> ?day:([`numeric | `two_digit [@bs.as "2-digit"]] [@bs.string]) -> ?hour:([`numeric | `two_digit [@bs.as "2-digit"]] [@bs.string]) -> diff --git a/jscomp/test/gpr_2614_test.ml b/jscomp/test/gpr_2614_test.ml index 55fe6eb058..f5744df512 100644 --- a/jscomp/test/gpr_2614_test.ml +++ b/jscomp/test/gpr_2614_test.ml @@ -29,11 +29,11 @@ let ff () = type a = { mutable low : string - [@bs.optional] - [@bs.as "lo-x"] + [@optional] + [@as "lo-x"] ; hi : int -} [@@bs.deriving abstract] +} [@@deriving abstract] (** diff --git a/jscomp/test/gpr_3492_test.ml b/jscomp/test/gpr_3492_test.ml index 5e8e992c93..508443c8d9 100644 --- a/jscomp/test/gpr_3492_test.ml +++ b/jscomp/test/gpr_3492_test.ml @@ -4,7 +4,7 @@ let eq loc x y = Mt.eq_suites ~test_id ~suites loc x y [%%bs.raw "function foo(a){return a()}"] -external foo : ((unit -> int)[@bs.uncurry ]) -> int = ""[@@bs.val "foo"] +external foo : ((unit -> int)[@uncurry ]) -> int = ""[@@bs.val "foo"] let fn () = Js.log "hi"; 1 diff --git a/jscomp/test/prepend_data_ffi.ml b/jscomp/test/prepend_data_ffi.ml index d10e4590e5..f89e735b66 100644 --- a/jscomp/test/prepend_data_ffi.ml +++ b/jscomp/test/prepend_data_ffi.ml @@ -80,7 +80,7 @@ external on_exit_slice4 : int -> (_ [@bs.as 3]) -> (_ [@bs.as "xxx"]) - -> ([`a|`b|`c] [@bs.int]) + -> ([`a|`b|`c] [@int]) -> ([`a|`b|`c] ) -> int array -> unit diff --git a/jscomp/test/return_check.ml b/jscomp/test/return_check.ml index de1911df66..2dc146bacd 100644 --- a/jscomp/test/return_check.ml +++ b/jscomp/test/return_check.ml @@ -23,7 +23,7 @@ let test dom = external get_undefined : int array -> int -> int option = "" -[@@bs.get_index] [@@bs.return { undefined_to_opt }] +[@@bs.get_index] [@@return undefined_to_opt ] let f_undefined xs i = diff --git a/jscomp/test/test_bs_this.ml b/jscomp/test/test_bs_this.ml index 3091bb7127..5b78f66697 100644 --- a/jscomp/test/test_bs_this.ml +++ b/jscomp/test/test_bs_this.ml @@ -25,7 +25,7 @@ let js_obj : 'self = } ] class type _x = object [@bs] - method onload : _x Js.t -> unit [@bs.this] [@@bs.set] + method onload : _x Js.t -> unit [@this] [@@bs.set] method addEventListener : string -> (_x Js.t -> unit [@bs.this]) -> unit method response : string end @@ -39,4 +39,4 @@ let f (x : x ) = end end -let u = fun [@bs.this] (_ : int) (x : int) -> x +let u = fun [@this] (_ : int) (x : int) -> x diff --git a/jscomp/test/uncurry_method.ml b/jscomp/test/uncurry_method.ml index f4dfaeea3b..db3e50bcf5 100644 --- a/jscomp/test/uncurry_method.ml +++ b/jscomp/test/uncurry_method.ml @@ -49,7 +49,7 @@ end < hh : (unit -> 'c [@bs.meth]); hi : (name:string -> age:int -> unit [@bs.meth]) > Js.t *) -type add_meth = int -> int -> int [@bs.meth] +type add_meth = int -> int -> int [@meth] let obj2 : < hi : add_meth; diff --git a/lib/4.06.1/bsb.ml b/lib/4.06.1/bsb.ml index 244969d6af..209f194de5 100644 --- a/lib/4.06.1/bsb.ml +++ b/lib/4.06.1/bsb.ml @@ -140,7 +140,10 @@ val find_and_split : ('a -> 'b -> bool) -> 'b -> 'a split -val exists : ('a -> bool) -> 'a array -> bool +val exists : + 'a array -> + ('a -> bool) -> + bool val is_empty : 'a array -> bool @@ -387,7 +390,7 @@ let find_and_split arr cmp v : _ split = (** TODO: available since 4.03, use {!Array.exists} *) -let exists p a = +let exists a p = let n = Array.length a in let rec loop i = if i = n then false diff --git a/lib/4.06.1/unstable/all_ounit_tests.ml b/lib/4.06.1/unstable/all_ounit_tests.ml index 98c898f868..f72d9892d7 100644 --- a/lib/4.06.1/unstable/all_ounit_tests.ml +++ b/lib/4.06.1/unstable/all_ounit_tests.ml @@ -1326,7 +1326,10 @@ val find_and_split : ('a -> 'b -> bool) -> 'b -> 'a split -val exists : ('a -> bool) -> 'a array -> bool +val exists : + 'a array -> + ('a -> bool) -> + bool val is_empty : 'a array -> bool @@ -1573,7 +1576,7 @@ let find_and_split arr cmp v : _ split = (** TODO: available since 4.03, use {!Array.exists} *) -let exists p a = +let exists a p = let n = Array.length a in let rec loop i = if i = n then false @@ -8101,7 +8104,7 @@ let suites = = "" [@@bs.send.pipe:int] [@@bs.splice]|}|] in - OUnit.assert_bool __LOC__ (Ext_string.contain_substring v_output.stderr "bs.splice") + OUnit.assert_bool __LOC__ (Ext_string.contain_substring v_output.stderr "variadic") end; __LOC__ >:: begin fun _ -> let v_output = perform_bsc [|"-bs-eval"; {|external @@ -8110,7 +8113,7 @@ let suites = = "" [@@bs.send.pipe:int] [@@bs.splice] |}|] in - OUnit.assert_bool __LOC__ (Ext_string.contain_substring v_output.stderr "bs.splice") + OUnit.assert_bool __LOC__ (Ext_string.contain_substring v_output.stderr "variadic") end; __LOC__ >:: begin fun _ -> @@ -8166,7 +8169,7 @@ external ff : (* Ounit_cmd_util.debug_output should_err ; *) OUnit.assert_bool __LOC__ (Ext_string.contain_substring - should_err.stderr "bs.uncurry") + should_err.stderr "uncurry") end ; __LOC__ >:: begin fun _ -> @@ -8775,7 +8778,7 @@ let output = bsc_eval {| |} in OUnit.assert_bool __LOC__ - (Ext_string.contain_substring output.stderr "bs.unwrap") + (Ext_string.contain_substring output.stderr "unwrap") end; __LOC__ >:: begin fun _ -> diff --git a/lib/4.06.1/unstable/bspack.ml b/lib/4.06.1/unstable/bspack.ml index 01413c4923..5cb2f013bc 100644 --- a/lib/4.06.1/unstable/bspack.ml +++ b/lib/4.06.1/unstable/bspack.ml @@ -6645,7 +6645,10 @@ val find_and_split : ('a -> 'b -> bool) -> 'b -> 'a split -val exists : ('a -> bool) -> 'a array -> bool +val exists : + 'a array -> + ('a -> bool) -> + bool val is_empty : 'a array -> bool @@ -6892,7 +6895,7 @@ let find_and_split arr cmp v : _ split = (** TODO: available since 4.03, use {!Array.exists} *) -let exists p a = +let exists a p = let n = Array.length a in let rec loop i = if i = n then false diff --git a/lib/4.06.1/unstable/js_compiler.ml b/lib/4.06.1/unstable/js_compiler.ml index 84da6f717f..7735251c46 100644 --- a/lib/4.06.1/unstable/js_compiler.ml +++ b/lib/4.06.1/unstable/js_compiler.ml @@ -18041,7 +18041,10 @@ val find_and_split : ('a -> 'b -> bool) -> 'b -> 'a split -val exists : ('a -> bool) -> 'a array -> bool +val exists : + 'a array -> + ('a -> bool) -> + bool val is_empty : 'a array -> bool @@ -18288,7 +18291,7 @@ let find_and_split arr cmp v : _ split = (** TODO: available since 4.03, use {!Array.exists} *) -let exists p a = +let exists a p = let n = Array.length a in let rec loop i = if i = n then false @@ -70920,7 +70923,7 @@ type label = Types.label_description let find_name (attr : Parsetree.attribute) = match attr with - | {txt = "bs.as"}, PStr + | {txt = "bs.as" | "as"}, PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_constant (Pconst_string(s,_))},_ )}] -> Some s | _ -> None @@ -70929,7 +70932,7 @@ let find_name (attr : Parsetree.attribute) = let find_name_with_loc (attr : Parsetree.attribute) : string Asttypes.loc option = match attr with - | {txt = "bs.as";loc}, PStr + | {txt = "bs.as" | "as";loc}, PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_constant (Pconst_string(s,_))},_ )}] -> Some {txt = s; loc} | _ -> None @@ -70973,7 +70976,7 @@ let rec check_duplicated_labels_aux | Some ({txt = s;} as l) -> if Set_string.mem coll s (*use coll to make check a bit looser - allow cases like [ x : int [@bs.as "x"]] + allow cases like [ x : int [@as "x"]] *) then Some l else @@ -84645,7 +84648,7 @@ type call_info = | Call_ml (* called by plain ocaml expression *) | Call_builtin_runtime (* built-in externals *) | Call_na - (* either from [@@bs.val] or not available, + (* either from [@@val] or not available, such calls does not follow such rules {[ fun x y -> f x y === f ]} when [f] is an atom *) @@ -84703,7 +84706,7 @@ type call_info = | Call_ml (* called by plain ocaml expression *) | Call_builtin_runtime (* built-in externals *) | Call_na - (* either from [@@bs.val] or not available, + (* either from [@@val] or not available, such calls does not follow such rules {[ fun x y -> (f x y) === f ]} when [f] is an atom @@ -94700,21 +94703,21 @@ type attr = | Poly_var_string of { descr : (string * string) list - (* introduced by attributes bs.string - and bs.as + (* introduced by attributes @string + and @as *) } | Poly_var of { descr : (string * string) list option - (* introduced by attributes bs.string - and bs.as + (* introduced by attributes @string + and @as *) } (* `a does not have any value*) - | Int of (string * int ) list (* ([`a | `b ] [@bs.int])*) + | Int of (string * int ) list (* ([`a | `b ] [@int])*) | Arg_cst of cst - | Fn_uncurry_arity of int (* annotated with [@bs.uncurry ] or [@bs.uncurry 2]*) + | Fn_uncurry_arity of int (* annotated with [@uncurry ] or [@uncurry 2]*) (* maybe we can improve it as a combination of {!Asttypes.constant} and tuple *) | Extern_unit | Nothing @@ -95158,22 +95161,22 @@ type external_spec = (* let name_of_ffi ffi = match ffi with - | Js_get_index _scope -> "[@@bs.get_index ..]" - | Js_set_index _scope -> "[@@bs.set_index ..]" - | Js_get { js_get_name = s} -> Printf.sprintf "[@@bs.get %S]" s - | Js_set { js_set_name = s} -> Printf.sprintf "[@@bs.set %S]" s - | Js_call v -> Printf.sprintf "[@@bs.val %S]" v.name - | Js_send v -> Printf.sprintf "[@@bs.send %S]" v.name - | Js_module_as_fn v -> Printf.sprintf "[@@bs.val %S]" v.external_module_name.bundle - | Js_new v -> Printf.sprintf "[@@bs.new %S]" v.name + | Js_get_index _scope -> "@get_index .." + | Js_set_index _scope -> "@set_index .." + | Js_get { js_get_name = s} -> Printf.sprintf "[@@get %S]" s + | Js_set { js_set_name = s} -> Printf.sprintf "[@@set %S]" s + | Js_call v -> Printf.sprintf "[@@val %S]" v.name + | Js_send v -> Printf.sprintf "[@@send %S]" v.name + | Js_module_as_fn v -> Printf.sprintf "[@@val %S]" v.external_module_name.bundle + | Js_new v -> Printf.sprintf "[@@new %S]" v.name | Js_module_as_class v - -> Printf.sprintf "[@@bs.module] %S " v.bundle + -> Printf.sprintf "[@@module] %S " v.bundle | Js_module_as_var v -> - Printf.sprintf "[@@bs.module] %S " v.bundle - | Js_var v (* FIXME: could be [@@bs.module "xx"] as well *) + Printf.sprintf "[@@module] %S " v.bundle + | Js_var v (* FIXME: could be [@@module "xx"] as well *) -> - Printf.sprintf "[@@bs.val] %S " v.name *) + Printf.sprintf "[@@val] %S " v.name *) type return_wrapper = | Return_unset @@ -95243,7 +95246,7 @@ let valid_global_name ?loc txt = (* We loose such check (see #2583), - it also helps with the implementation deriving abstract [@bs.as] + it also helps with the implementation deriving abstract [@as] *) let valid_method_name ?loc:_ _txt = @@ -96378,8 +96381,8 @@ exception Not_simple_form where [wrap] used to be simple instructions Note that [external] functions are forced to do eta-conversion when combined with [|>] operator, we need to make sure beta-reduction - is applied though since `[@bs.splice]` needs such guarantee. - Since `[@bs.splice] is the tail position + is applied though since `[@variadic]` needs such guarantee. + Since `[@variadic] is the tail position *) let rec is_eta_conversion_exn params inner_args outer_args : t list = @@ -96910,7 +96913,7 @@ let sequand l r = if_ l r false_ (** only [handle_bs_non_obj_ffi] will be used outside *) (** [no_auto_uncurried_arg_types xs] - check if the FFI have [@@bs.uncurry] attribute. + check if the FFI have @uncurry attribute. if it does not we wrap it in a nomral way otherwise *) let rec no_auto_uncurried_arg_types @@ -108633,7 +108636,7 @@ val translate_ffi : (** TODO: document supported attributes Attributes starting with `js` are reserved - examples: "bs.splice" + examples: "variadic" *) end = struct @@ -108718,7 +108721,7 @@ let append_list x xs = unbox it in the first place. Note when optional value is not passed, the unboxed value would be - [undefined], with the combination of `[@bs.int]` it would be still be + [undefined], with the combination of `[@int]` it would be still be [undefined], this by default is still correct.. {[ (function () { @@ -108892,7 +108895,7 @@ let translate_scoped_module_val Ext_list.fold_left (Ext_list.append rest [fn]) start E.dot end | None -> - (* no [@@bs.module], assume it's global *) + (* no [@@module], assume it's global *) begin match scopes with | [] -> E.js_global fn @@ -108949,7 +108952,7 @@ let translate_ffi | Js_new { external_module_name = module_name; name = fn; scopes - } -> (* handle [@@bs.new]*) + } -> (* handle [@@new]*) (* This has some side effect, it will mark its identifier (If it has) as an object, ATTENTION: @@ -108996,7 +108999,7 @@ let translate_ffi begin match args with | self :: args -> (* PR2162 [self_type] more checks in syntax: - - should not be [bs.as] *) + - should not be [@as] *) let [@warning"-8"] ( _self_type::arg_types ) = arg_types in if splice then @@ -109022,7 +109025,7 @@ let translate_ffi (* TODO #11 1. check args -- error checking - 2. support [@@bs.scope "window"] + 2. support [@@scope "window"] we need know whether we should call [add_js_module] or not *) translate_scoped_module_val external_module_name name scopes @@ -110934,7 +110937,7 @@ let transform_under_supply n ap_info fn args = cautiously, since [let u = f] and we are chaning the arity of [f] it will affect the collection of [u] - A typical use case is to pass an OCaml function to JS side as a callback (i.e, [@bs.uncurry]) + A typical use case is to pass an OCaml function to JS side as a callback (i.e, [@uncurry]) *) let unsafe_adjust_to_arity loc ~(to_:int) ?(from : int option) (fn : Lam.t) : Lam.t = let ap_info : Lam.ap_info = {ap_loc = loc; ap_inlined = Default_inline; ap_status = App_na } in @@ -395776,7 +395779,7 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) : Lam.t * Lam_module_i ]} is also wrong. - It seems, we need handle [@bs.splice] earlier + It seems, we need handle [@variadic] earlier or {[ @@ -395784,7 +395787,7 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) : Lam.t * Lam_module_i let x0, x1, x2 =1,2,3 in (fun y -> f [|x0;x1;x2|] y) ]} - But this still need us to know [@bs.splice] in advance + But this still need us to know [@variadic] in advance we should not remove it immediately, since we have to be careful @@ -399808,7 +399811,7 @@ let pp_error fmt err = -> "Uncurried function doesn't support optional arguments yet" | Expect_opt_in_bs_return_to_opt -> - "bs.return directive *_to_opt expect return type to be \n\ + "%@return directive *_to_opt expect return type to be \n\ syntax wise `_ option` for safety" | Not_supported_directive_in_bs_return @@ -399817,7 +399820,7 @@ let pp_error fmt err = | Illegal_attribute -> "Illegal attributes" | Canot_infer_arity_by_syntax - -> "Cannot infer the arity through the syntax, either [@bs.uncurry n] or \n\ + -> "Cannot infer the arity through the syntax, either [%@uncurry n] or \n\ write it in arrow syntax " | Inconsistent_arity (arity,n) -> Printf.sprintf "Inconsistent arity %d vs %d" arity n @@ -399828,7 +399831,7 @@ let pp_error fmt err = -> "unsupported predicates" | Conflict_bs_bs_this_bs_meth -> - "[@bs.this], [@bs], [@bs.meth] can not be applied at the same time" + "%@this, %@bs, %@meth can not be applied at the same time" | Duplicated_bs_deriving -> "duplicate bs.deriving attribute" | Conflict_attributes @@ -399837,7 +399840,7 @@ let pp_error fmt err = -> "expect string literal " | Duplicated_bs_as -> - "duplicate bs.as " + "duplicate %@as " | Expect_int_literal -> "expect int literal " @@ -399854,20 +399857,20 @@ let pp_error fmt err = "_ is not allowed in combination with external optional type" | Invalid_bs_string_type -> - "Not a valid type for [@bs.string]" + "Not a valid type for %@string" | Invalid_bs_int_type -> - "Not a valid type for [@bs.int]" + "Not a valid type for %@int" | Invalid_bs_unwrap_type -> - "Not a valid type for [@bs.unwrap]. Type must be an inline variant (closed), and\n\ + "Not a valid type for %@unwrap. Type must be an inline variant (closed), and\n\ each constructor must have an argument." | Conflict_ffi_attribute str -> "Conflicting FFI attributes found: " ^ str | Bs_this_simple_pattern -> - "[@bs.this] expect its pattern variable to be simple form") + "%@this expect its pattern variable to be simple form") type exn += Error of Location.t * error @@ -400379,6 +400382,10 @@ end = struct * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) +(** Warning unused bs attributes + Note if we warn `deriving` too, + it may fail third party ppxes +*) let is_bs_attribute txt = let len = String.length txt in len >= 2 && @@ -400464,7 +400471,7 @@ let emit_external_warnings : iterator= Ext_list.iter lbl.pld_attributes (fun attr -> match attr with - | {txt = "bs.as"}, _ -> mark_used_bs_attribute attr + | {txt = "bs.as" | "as"}, _ -> mark_used_bs_attribute attr | _ -> () ); default_iterator.label_declaration self lbl @@ -400635,7 +400642,7 @@ let add_signature k v = let rec iter_on_bs_config_stru (x :Parsetree.structure) = match x with | [] -> () - | {pstr_desc = Pstr_attribute (({txt = "bs.config"; loc}, payload) as attr)}::_ -> + | {pstr_desc = Pstr_attribute (({txt = "bs.config" | "config"; loc}, payload) as attr)}::_ -> Bs_ast_invariant.mark_used_bs_attribute attr; Ext_list.iter (Ast_payload.ident_or_record_as_config loc payload) (Ast_payload.table_dispatch !structural_config_table) @@ -400646,7 +400653,7 @@ let rec iter_on_bs_config_stru (x :Parsetree.structure) = let rec iter_on_bs_config_sigi (x :Parsetree.signature) = match x with | [] -> () - | {psig_desc = Psig_attribute (({txt = "bs.config"; loc}, payload) as attr)}::_ -> + | {psig_desc = Psig_attribute (({txt = "bs.config" | "config"; loc}, payload) as attr)}::_ -> Bs_ast_invariant.mark_used_bs_attribute attr; Ext_list.iter (Ast_payload.ident_or_record_as_config loc payload) (Ast_payload.table_dispatch !signature_config_table) @@ -400803,7 +400810,7 @@ type ('a,'b) st = let process_method_attributes_rev (attrs : t) = Ext_list.fold_left attrs ({get = None ; set = None}, []) (fun (st,acc) (({txt ; loc}, payload) as attr ) -> match txt with - | "bs.get" (* [@@bs.get{null; undefined}]*) + | "bs.get" | "get" (* @bs.get{null; undefined}*) -> let result = Ext_list.fold_left (Ast_payload.ident_or_record_as_config loc payload) (false, false) @@ -400833,7 +400840,7 @@ let process_method_attributes_rev (attrs : t) = ({st with get = Some result}, acc ) - | "bs.set" + | "bs.set" | "set" -> let result = Ext_list.fold_left (Ast_payload.ident_or_record_as_config loc payload) `Get @@ -400848,7 +400855,7 @@ let process_method_attributes_rev (attrs : t) = else Bs_syntaxerr.err loc Unsupported_predicates ) in (* properties -- void - [@@bs.set{only}] + [@@set{only}] *) {st with set = Some result }, acc | _ -> @@ -400867,12 +400874,11 @@ let process_attributes_rev (attrs : t) : attr_kind * t = | "bs", (Nothing | Uncurry _) -> Uncurry attr, acc (* TODO: warn unused/duplicated attribute *) - | "bs.this", (Nothing | Meth_callback _) + | ("bs.this" | "this"), (Nothing | Meth_callback _) -> Meth_callback attr, acc - | "bs.meth", (Nothing | Method _) + | ("bs.meth" | "meth"), (Nothing | Method _) -> Method attr, acc - | "bs", _ - | "bs.this", _ + | ("bs" | "bs.this" | "this"), _ -> Bs_syntaxerr.err loc Conflict_bs_bs_this_bs_meth | _ , _ -> st, attr::acc @@ -400899,10 +400905,27 @@ let process_bs (attrs : t) = st, attr::acc ) +let external_attrs = [| + "get"; + "set"; + "get_index"; + "return"; + "obj"; + "val"; + "module"; + "scope"; + "variadic"; + "send"; + "new"; + "set_index"; + Literals.gentype_import +|] +(* ATT: Special cases for built-in attributes handling *) let external_needs_to_be_encoded (attrs : t)= Ext_list.exists_fst attrs (fun {txt} -> - Ext_string.starts_with txt "bs." || txt = Literals.gentype_import) + Ext_string.starts_with txt "bs." || + Ext_array.exists external_attrs (fun (x : string) -> txt = x) ) let is_inline : attr -> bool = (fun @@ -400922,24 +400945,26 @@ type derive_attr = { let process_derive_type (attrs : t) : derive_attr * t = Ext_list.fold_left attrs ({bs_deriving = None }, []) (fun (st, acc) ({txt ; loc}, payload as attr) -> - match st, txt with - | {bs_deriving = None}, "bs.deriving" - -> - { - bs_deriving = Some - (Ast_payload.ident_or_record_as_config loc payload)}, acc - | {bs_deriving = Some _}, "bs.deriving" - -> - Bs_syntaxerr.err loc Duplicated_bs_deriving - - | _ , _ -> - st, attr::acc + match txt with + | "bs.deriving" | "deriving" + -> + begin match st.bs_deriving with + | None -> + { + bs_deriving = Some + (Ast_payload.ident_or_record_as_config loc payload)}, acc + | Some _ + -> + Bs_syntaxerr.err loc Duplicated_bs_deriving + end + | _ -> + st, attr::acc ) -(* duplicated [bs.uncurry] [bs.string] not allowed, - it is worse in bs.uncurry since it will introduce +(* duplicated @uncurry @string not allowed, + it is worse in @uncurry since it will introduce inconsistency in arity *) let iter_process_bs_string_int_unwrap_uncurry (attrs : t) = @@ -400953,15 +400978,15 @@ let iter_process_bs_string_int_unwrap_uncurry (attrs : t) = else Bs_syntaxerr.err loc Conflict_attributes in Ext_list.iter attrs (fun (({txt ; loc=_}, (payload : _ ) ) as attr) -> match txt with - | "bs.string" + | "bs.string" | "string" -> assign `String attr - | "bs.int" + | "bs.int" | "int" -> assign `Int attr - | "bs.ignore" + | "bs.ignore" | "ignore" -> assign `Ignore attr - | "bs.unwrap" + | "bs.unwrap" | "unwrap" -> assign `Unwrap attr - | "bs.uncurry" + | "bs.uncurry" | "uncurry" -> assign (`Uncurry (Ast_payload.is_single_int payload)) attr | _ -> () @@ -400975,7 +401000,7 @@ let iter_process_bs_string_as (attrs : t) : string option = (fun (({txt ; loc}, payload ) as attr ) -> match txt with - | "bs.as" + | "bs.as" | "as" -> if !st = None then match Ast_payload.is_single_string payload with @@ -400995,7 +401020,7 @@ let has_bs_optional (attrs : t) : bool = Ext_list.exists attrs (fun (({txt ; }, _ ) as attr) -> match txt with - | "bs.optional" + | "bs.optional" | "optional" -> Bs_ast_invariant.mark_used_bs_attribute attr ; true @@ -401010,7 +401035,7 @@ let iter_process_bs_int_as (attrs : t) = (fun (({txt ; loc}, payload ) as attr) -> match txt with - | "bs.as" + | "bs.as" | "as" -> if !st = None then match Ast_payload.is_single_int payload with @@ -401034,7 +401059,7 @@ let iter_process_bs_string_or_int_as (attrs : Parsetree.attributes) = (fun (({txt ; loc}, payload ) as attr) -> match txt with - | "bs.as" + | "bs.as" | "as" -> if !st = None then (Bs_ast_invariant.mark_used_bs_attribute attr ; @@ -402783,7 +402808,7 @@ let typ_mapper | Uncurry attr , attrs -> attrs, attr +> ty | Method _, _ - -> Location.raise_errorf ~loc "bs.get/set conflicts with bs.meth" + -> Location.raise_errorf ~loc "%@get/set conflicts with %@meth" | Meth_callback attr, attrs -> attrs, attr +> ty in @@ -402795,7 +402820,7 @@ let typ_mapper | Uncurry attr, attrs -> attrs, attr +> ty | Method _, _ - -> Location.raise_errorf ~loc "bs.get/set conflicts with bs.meth" + -> Location.raise_errorf ~loc "%@get/set conflicts with %@meth" | Meth_callback attr, attrs -> attrs, attr +> ty in @@ -403465,7 +403490,7 @@ let map_row_fields_into_strings ptyp_loc let descr = if !has_bs_as then Some result else None in match has_payload, descr with | false, None -> - Location.prerr_warning ptyp_loc (Bs_ffi_warning "bs.string is redundant here, you can safely remove it"); + Location.prerr_warning ptyp_loc (Bs_ffi_warning "%@string is redundant here, you can safely remove it"); Nothing | false , Some descr -> External_arg_spec.Poly_var_string {descr } @@ -404676,7 +404701,7 @@ let refine_arg_type ~(nolabel:bool) (ptyp : Ast_core_type.t) match result with | None -> spec_of_ptyp nolabel ptyp - | Some cst -> (* (_[@bs.as ])*) + | Some cst -> (* (_[@as ])*) (* when ppx start dropping attributes we should warn, there is a trade off whether we should warn dropped non bs attribute or not @@ -404684,14 +404709,14 @@ let refine_arg_type ~(nolabel:bool) (ptyp : Ast_core_type.t) Bs_ast_invariant.warn_discarded_unused_attributes ptyp_attrs; begin match cst with | Int i -> - (* This type is used in bs.obj only to construct obj type*) + (* This type is used in obj only to construct obj type*) Arg_cst(External_arg_spec.cst_int i) | Str i-> Arg_cst (External_arg_spec.cst_string i) | Js_literal_str s -> Arg_cst (External_arg_spec.cst_obj_literal s) end - else (* ([`a|`b] [@bs.string]) *) + else (* ([`a|`b] [@string]) *) spec_of_ptyp nolabel ptyp ) @@ -404708,22 +404733,22 @@ let refine_obj_arg_type ~(nolabel:bool) (ptyp : Ast_core_type.t) match result with | None -> Bs_syntaxerr.err ptyp.ptyp_loc Invalid_underscore_type_in_external - | Some (Int i) -> (* (_[@bs.as ])*) - (* This type is used in bs.obj only to construct obj type*) + | Some (Int i) -> (* (_[@as ])*) + (* This type is used in obj only to construct obj type*) Arg_cst(External_arg_spec.cst_int i) | Some (Str i)-> Arg_cst (External_arg_spec.cst_string i) | Some (Js_literal_str s ) -> Arg_cst (External_arg_spec.cst_obj_literal s) - else (* ([`a|`b] [@bs.string]) *) + else (* ([`a|`b] [@string]) *) spec_of_ptyp nolabel ptyp (** Given the type of argument, process its [bs.] attribute and new type, The new type is currently used to reconstruct the external type - and result type in [@@bs.obj] + and result type in [@@obj] They are not the same though, for example {[ - external f : hi:([ `hi | `lo ] [@bs.string]) -> unit -> _ = "" [@@bs.obj] + external f : hi:([ `hi | `lo ] [@string]) -> unit -> _ = "" [@@obj] ]} The result type would be [ hi:string ] *) @@ -404731,20 +404756,20 @@ let get_opt_arg_type ~(nolabel : bool) (ptyp : Ast_core_type.t) : External_arg_spec.attr = - if ptyp.ptyp_desc = Ptyp_any then (* (_[@bs.as ])*) - (* extenral f : ?x:_ -> y:int -> _ = "" [@@bs.obj] is not allowed *) + if ptyp.ptyp_desc = Ptyp_any then (* (_[@as ])*) + (* extenral f : ?x:_ -> y:int -> _ = "" [@@obj] is not allowed *) Bs_syntaxerr.err ptyp.ptyp_loc Invalid_underscore_type_in_external; - (* ([`a|`b] [@bs.string]) *) + (* ([`a|`b] [@@string]) *) spec_of_ptyp nolabel ptyp (** - [@@bs.module "react"] - [@@bs.module "react"] + [@@module "react"] + [@@module "react"] --- - [@@bs.module "@" "react"] - [@@bs.module "@" "react"] + [@@module "@" "react"] + [@@module "@" "react"] They should have the same module name @@ -404752,7 +404777,7 @@ let get_opt_arg_type two external files to the same module name *) type bundle_source = - [`Nm_payload of string (* from payload [@@bs.val "xx" ]*) + [`Nm_payload of string (* from payload [@@val "xx" ]*) |`Nm_external of string (* from "" in external *) | `Nm_val of string lazy_t (* from function name *) ] @@ -404824,6 +404849,7 @@ let return_wrapper loc (txt : string) : External_ffi_types.return_wrapper = | _ -> Bs_syntaxerr.err loc Not_supported_directive_in_bs_return +exception Not_handled_external_attribute (* The processed attributes will be dropped *) let parse_external_attributes @@ -404832,15 +404858,15 @@ let parse_external_attributes (prim_name_or_pval_prim: bundle_source ) (prim_attributes : Ast_attributes.t) : Ast_attributes.t * external_desc = - (* shared by `[@@bs.val]`, `[@@bs.send]`, - `[@@bs.set]`, `[@@bs.get]` , `[@@bs.new]` + (* shared by `[@@val]`, `[@@send]`, + `[@@set]`, `[@@get]` , `[@@new]` `[@@bs.send.pipe]` does not use it *) let name_from_payload_or_prim ~loc (payload : Parsetree.payload) : name_source = match payload with | PStr [] -> (prim_name_or_pval_prim :> name_source) - (* It is okay to have [@@bs.val] without payload *) + (* It is okay to have [@@val] without payload *) | _ -> begin match Ast_payload.is_single_string payload with | Some (val_name, _) -> `Nm_payload val_name @@ -404859,15 +404885,15 @@ let parse_external_attributes in attr::attrs, {st with external_module_name = Some { bundle; module_bind_name = Phint_nothing}} - else if Ext_string.starts_with txt "bs." then - attrs, begin match txt with - | "bs.val" -> + else + let action () = begin match txt with + | "bs.val" | "val" -> if no_arguments then {st with val_name = name_from_payload_or_prim ~loc payload} else {st with call_name = name_from_payload_or_prim ~loc payload} - | "bs.module" -> + | "bs.module" | "module" -> begin match Ast_payload.assert_strings loc payload with | [bundle] -> {st with external_module_name = @@ -404887,7 +404913,7 @@ let parse_external_attributes | _ -> Bs_syntaxerr.err loc Illegal_attribute end - | "bs.scope" -> + | "bs.scope" | "scope" -> begin match Ast_payload.assert_strings loc payload with | [] -> Bs_syntaxerr.err loc Illegal_attribute @@ -404896,27 +404922,29 @@ let parse_external_attributes *) | scopes -> { st with scopes = scopes } end - | "bs.splice" | "bs.variadic" -> {st with splice = true} - | "bs.send" -> + | "bs.splice" + | "bs.variadic" | "variadic" -> {st with splice = true} + | "bs.send" | "send" -> { st with val_send = name_from_payload_or_prim ~loc payload} | "bs.send.pipe" -> { st with val_send_pipe = Some (Ast_payload.as_core_type loc payload)} - | "bs.set" -> + | "bs.set" | "set" -> {st with set_name = name_from_payload_or_prim ~loc payload} - | "bs.get" -> {st with get_name = name_from_payload_or_prim ~loc payload} + | "bs.get" | "get" -> + {st with get_name = name_from_payload_or_prim ~loc payload} - | "bs.new" -> {st with new_name = name_from_payload_or_prim ~loc payload} - | "bs.set_index" -> + | "bs.new" | "new" -> {st with new_name = name_from_payload_or_prim ~loc payload} + | "bs.set_index" | "set_index" -> if String.length prim_name_check <> 0 then - Location.raise_errorf ~loc "[@@bs.set_index] this particular external's name needs to be a placeholder empty string"; + Location.raise_errorf ~loc "%@set_index this particular external's name needs to be a placeholder empty string"; {st with set_index = true} - | "bs.get_index"-> + | "bs.get_index" | "get_index" -> if String.length prim_name_check <> 0 then - Location.raise_errorf ~loc "[@@bs.get_index] this particular external's name needs to be a placeholder empty string"; + Location.raise_errorf ~loc "%@get_index this particular external's name needs to be a placeholder empty string"; {st with get_index = true} - | "bs.obj" -> {st with mk_obj = true} - | "bs.return" -> + | "bs.obj" | "obj" -> {st with mk_obj = true} + | "bs.return" | "return" -> let actions = Ast_payload.ident_or_record_as_config loc payload in begin match actions with @@ -404925,15 +404953,16 @@ let parse_external_attributes | _ -> Bs_syntaxerr.err loc Not_supported_directive_in_bs_return end - | _ -> (Location.prerr_warning loc (Bs_unused_attribute txt); st) - end - else attr :: attrs, st + | _ -> raise_notrace Not_handled_external_attribute + end in + try attrs, action () with + | Not_handled_external_attribute -> attr::attrs, st ) let has_bs_uncurry (attrs : Ast_attributes.t) = - Ext_list.exists_fst attrs (fun x -> x.txt = "bs.uncurry") + Ext_list.exists_fst attrs (fun {txt;loc=_} -> txt = "bs.uncurry" || txt = "uncurry") let check_return_wrapper @@ -404993,11 +405022,11 @@ let process_obj set_index = false ; mk_obj = _; scopes = []; - (* wrapper does not work with [bs.obj] + (* wrapper does not work with @obj TODO: better error message *) } -> if String.length prim_name <> 0 then - Location.raise_errorf ~loc "[@@bs.obj] expect external names to be empty string"; + Location.raise_errorf ~loc "%@obj expect external names to be empty string"; let arg_kinds, new_arg_types_ty, (result_types : Parsetree.object_field list) = Ext_list.fold_right arg_types_ty ( [], [], []) (fun param_type ( arg_labels, (arg_types : Ast_compatible.param_type list), result_types) -> @@ -405043,15 +405072,15 @@ let process_obj (Otag({Asttypes.txt = name; loc}, [], Ast_literal.type_string ~loc ()) :: result_types) | Fn_uncurry_arity _ -> Location.raise_errorf ~loc - "The combination of [@@bs.obj], [@@bs.uncurry] is not supported yet" + "The combination of %@obj, %@uncurry is not supported yet" | Extern_unit -> assert false | Poly_var _ -> Location.raise_errorf ~loc - "bs.obj label %s does not support such arg type" name + "%@obj label %s does not support such arg type" name | Unwrap -> Location.raise_errorf ~loc - "bs.obj label %s does not support [@bs.unwrap] arguments" name + "%@obj label %s does not support %@unwrap arguments" name end | Optional name -> let obj_arg_type = get_opt_arg_type ~nolabel:false ty in @@ -405076,18 +405105,18 @@ let process_obj (Otag ({Asttypes.txt = name; loc}, [], Ast_comb.to_undefined_type loc @@ Ast_literal.type_string ~loc ()) :: result_types) | Arg_cst _ -> - Location.raise_errorf ~loc "bs.as is not supported with optional yet" + Location.raise_errorf ~loc "%@as is not supported with optional yet" | Fn_uncurry_arity _ -> Location.raise_errorf ~loc - "The combination of [@@bs.obj], [@@bs.uncurry] is not supported yet" + "The combination of %@obj, %@uncurry is not supported yet" | Extern_unit -> assert false | Poly_var _ -> Location.raise_errorf ~loc - "bs.obj label %s does not support such arg type" name + "%@obj label %s does not support such arg type" name | Unwrap -> Location.raise_errorf ~loc - "bs.obj label %s does not support [@bs.unwrap] arguments" name + "%@obj label %s does not support %@unwrap arguments" name end in new_arg_label::arg_labels, @@ -405104,7 +405133,7 @@ let process_obj in Ast_compatible.mk_fn_type new_arg_types_ty result, External_ffi_types.ffi_obj_create arg_kinds - | _ -> Location.raise_errorf ~loc "Attribute found that conflicts with [@@bs.obj]" + | _ -> Location.raise_errorf ~loc "Attribute found that conflicts with %@obj" let external_desc_of_non_obj @@ -405137,9 +405166,9 @@ let external_desc_of_non_obj if arg_type_specs_length = 3 then Js_set_index {js_set_index_scopes = scopes} else - Location.raise_errorf ~loc "Ill defined attribute [@@bs.set_index](arity of 3)" + Location.raise_errorf ~loc "Ill defined attribute %@set_index (arity of 3)" | {set_index = true; _} -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.set_index]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@set_index") | {get_index = true; val_name = `Nm_na; external_module_name = None ; @@ -405160,10 +405189,10 @@ let external_desc_of_non_obj if arg_type_specs_length = 2 then Js_get_index {js_get_index_scopes = scopes} else Location.raise_errorf ~loc - "Ill defined attribute [@@bs.get_index] (arity expected 2 : while %d)" arg_type_specs_length + "Ill defined attribute %@get_index (arity expected 2 : while %d)" arg_type_specs_length | {get_index = true; _} -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.get_index]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@get_index") | {module_as_val = Some external_module_name ; get_index = false; @@ -405186,17 +405215,17 @@ let external_desc_of_non_obj | [], `Nm_na, _ -> Js_module_as_var external_module_name | _, `Nm_na, _ -> Js_module_as_fn {splice; external_module_name } | _, #bundle_source, #bundle_source -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.module].") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@module.") | _, (`Nm_val _ | `Nm_external _) , `Nm_na -> Js_module_as_class external_module_name | _, `Nm_payload _ , `Nm_na -> Location.raise_errorf ~loc - "Incorrect FFI attribute found: (bs.new should not carry a payload here)" + "Incorrect FFI attribute found: (%@new should not carry a payload here)" end | {module_as_val = Some _; _} -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.module].") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@module.") | {call_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name) ; splice; scopes ; @@ -405218,7 +405247,7 @@ let external_desc_of_non_obj Js_call {splice; name; external_module_name; scopes } | {call_name = #bundle_source ; _ } -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.val]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@val") | {val_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name); external_module_name; @@ -405239,13 +405268,13 @@ let external_desc_of_non_obj -> (* if no_arguments --> {[ - external ff : int = "" [@@bs.val] + external ff : int = "" [@@val] ]} *) Js_var { name; external_module_name; scopes} | {val_name = #bundle_source ; _ } -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.val]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@val") | {splice ; scopes ; @@ -405268,7 +405297,7 @@ let external_desc_of_non_obj if arg_type_specs_length = 0 then (* {[ - external ff : int = "" [@@bs.module "xx"] + external ff : int = "" [@@module "xx"] ]} *) Js_var { name; external_module_name; scopes} @@ -405290,21 +405319,21 @@ let external_desc_of_non_obj return_wrapper = _ ; } -> (* PR #2162 - since when we assemble arguments the first argument in - [@@bs.send] is ignored + [@@send] is ignored *) begin match arg_type_specs with | [] -> Location.raise_errorf - ~loc "Ill defined attribute [@@bs.send] (the external needs to be a regular function call with at least one argument)" + ~loc "Ill defined attribute %@send(the external needs to be a regular function call with at least one argument)" | {arg_type = Arg_cst _ ; arg_label = _} :: _ -> Location.raise_errorf - ~loc "Ill defined attribute [@@bs.send] (first argument can't be const)" + ~loc "Ill defined attribute %@send(first argument can't be const)" | _ :: _ -> Js_send {splice ; name; js_send_scopes = scopes ; pipe = false} end | {val_send = #bundle_source; _ } - -> Location.raise_errorf ~loc "You used a FFI attribute that can't be used with [@@bs.send]" + -> Location.raise_errorf ~loc "You used a FFI attribute that can't be used with %@send" | {val_send_pipe = Some _; (* splice = (false as splice); *) val_send = `Nm_na; @@ -405329,7 +405358,7 @@ let external_desc_of_non_obj pipe = true} | {val_send_pipe = Some _ ; _} - -> Location.raise_errorf ~loc "conflict attributes found with [@@bs.send.pipe]" + -> Location.raise_errorf ~loc "conflict attributes found with [%@%@bs.send.pipe]" | {new_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name); external_module_name; @@ -405350,7 +405379,7 @@ let external_desc_of_non_obj } -> Js_new {name; external_module_name; scopes} | {new_name = #bundle_source ; _ } -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.new]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@new") | {set_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name); val_name = `Nm_na ; call_name = `Nm_na ; @@ -405370,9 +405399,9 @@ let external_desc_of_non_obj -> if arg_type_specs_length = 2 then Js_set { js_set_scopes = scopes ; js_set_name = name} - else Location.raise_errorf ~loc "Ill defined attribute [@@bs.set] (two args required)" + else Location.raise_errorf ~loc "Ill defined attribute %@set (two args required)" | {set_name = #bundle_source; _} - -> Location.raise_errorf ~loc "conflict attributes found with [@@bs.set]" + -> Location.raise_errorf ~loc "conflict attributes found with %@set" | {get_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name); val_name = `Nm_na ; @@ -405394,9 +405423,9 @@ let external_desc_of_non_obj if arg_type_specs_length = 1 then Js_get { js_get_name = name; js_get_scopes = scopes } else - Location.raise_errorf ~loc "Ill defined attribute [@@bs.get] (only one argument)" + Location.raise_errorf ~loc "Ill defined attribute %@bs.get (only one argument)" | {get_name = #bundle_source; _} - -> Location.raise_errorf ~loc "Attribute found that conflicts with [@@bs.get]" + -> Location.raise_errorf ~loc "Attribute found that conflicts with %@bs.get" | {get_name = `Nm_na; val_name = `Nm_na ; @@ -405415,7 +405444,7 @@ let external_desc_of_non_obj return_wrapper = _; } - -> Location.raise_errorf ~loc "Could not infer which FFI category it belongs to, maybe you forgot [%@%@bs.val]? " + -> Location.raise_errorf ~loc "Could not infer which FFI category it belongs to, maybe you forgot %@val? " (** Note that the passed [type_annotation] is already processed by visitor pattern before*) let handle_attributes @@ -405427,12 +405456,12 @@ let handle_attributes : Parsetree.core_type * External_ffi_types.t * Parsetree.attributes * bool = (** sanity check here - {[ int -> int -> (int -> int -> int [@bs.uncurry])]} + {[ int -> int -> (int -> int -> int [@uncurry])]} It does not make sense *) if has_bs_uncurry type_annotation.ptyp_attributes then Location.raise_errorf - ~loc "[@@bs.uncurry] can not be applied to the whole definition"; + ~loc "%@uncurry can not be applied to the whole definition"; let prim_name_or_pval_name = if String.length prim_name = 0 then `Nm_val (lazy (Location.prerr_warning loc (Bs_fragile_external pval_name); pval_name)) @@ -405443,7 +405472,7 @@ let handle_attributes if has_bs_uncurry result_type.ptyp_attributes then Location.raise_errorf ~loc:result_type.ptyp_loc - "[@@bs.uncurry] can not be applied to tailed position"; + "%@uncurry can not be applied to tailed position"; let no_arguments = arg_types_ty = [] in let unused_attrs, external_desc = parse_external_attributes no_arguments @@ -405461,7 +405490,7 @@ let handle_attributes let arg_type = refine_arg_type ~nolabel:true obj in begin match arg_type with | Arg_cst _ -> - Location.raise_errorf ~loc:obj.ptyp_loc "[@bs.as] is not supported in bs.send type " + Location.raise_errorf ~loc:obj.ptyp_loc "%@as is not supported in %@send type " | _ -> (* more error checking *) [{arg_label = Arg_empty; arg_type}], @@ -405479,17 +405508,17 @@ let handle_attributes if i = 0 && splice then begin match arg_label with | Optional _ -> - Location.raise_errorf ~loc "[@@@@bs.splice] expect the last type to be a non optional" + Location.raise_errorf ~loc "%@variadic expect the last type to be a non optional" | Labelled _ | Nolabel -> if ty.ptyp_desc = Ptyp_any then - Location.raise_errorf ~loc "[@@@@bs.splice] expect the last type to be an array"; + Location.raise_errorf ~loc "%@variadic expect the last type to be an array"; if spec_of_ptyp true ty <> Nothing then - Location.raise_errorf ~loc "[@@@@bs.splice] expect the last type to be an array"; + Location.raise_errorf ~loc "%@variadic expect the last type to be an array"; match ty.ptyp_desc with | Ptyp_constr({txt = Lident "array"; _}, [_]) -> () - | _ -> Location.raise_errorf ~loc "[@@@@bs.splice] expect the last type to be an array"; + | _ -> Location.raise_errorf ~loc "%@variadic expect the last type to be an array"; end ; let (arg_label : External_arg_spec.label_noname), arg_type, new_arg_types = match arg_label with @@ -405497,10 +405526,10 @@ let handle_attributes let arg_type = get_opt_arg_type ~nolabel:false ty in begin match arg_type with | Poly_var _ -> - (* ?x:([`x of int ] [@bs.string]) does not make sense *) + (* ?x:([`x of int ] [@string]) does not make sense *) Location.raise_errorf ~loc - "[@@bs.string] does not work with optional when it has arities in label %s" s + "%@string does not work with optional when it has arities in label %s" s | _ -> Arg_optional, arg_type, param_type :: arg_types end @@ -405682,7 +405711,7 @@ end = struct open Ast_helper -(* Handling `fun [@bs.this]` used in `object [@bs] end` *) +(* Handling `fun [@this]` used in `object [@bs] end` *) let to_method_callback loc (self : Bs_ast_mapper.mapper) label pat body : Parsetree.expression_desc = @@ -405913,8 +405942,8 @@ let ocaml_obj_as_js_object (** we need calculate the real object type and exposed object type, in some cases there are equivalent - for public object type its [@bs.meth] it does not depend on itself - while for label argument it is [@bs.this] which depends internal object + for public object type its [@meth] it does not depend on itself + while for label argument it is [@this] which depends internal object *) let (internal_label_attr_types : Parsetree.object_field list), (public_label_attr_types : Parsetree.object_field list) = @@ -407452,7 +407481,6 @@ let newTdcls - let handleTdclsInSigi (self : Bs_ast_mapper.mapper) (sigi : Parsetree.signature_item) @@ -407468,9 +407496,7 @@ let handleTdclsInSigi let newTdclsNewAttrs = self.type_declaration_list self originalTdclsNewAttrs in let kind = Ast_derive_abstract.isAbstract actions in if kind <> Not_abstract then - let codes = Ast_derive_abstract.handleTdclsInSig ~light:(kind = Light_abstract) rf originalTdclsNewAttrs in - Ast_signature.fuseAll ~loc ( Sig.include_ ~loc @@ -407478,9 +407504,7 @@ let handleTdclsInSigi (Mty.typeof_ ~loc (Mod.constraint_ ~loc (Mod.structure ~loc [ - Ast_compatible.rec_type_str ~loc rf newTdclsNewAttrs - ] ) (Mty.signature ~loc [])) ) ) :: (* include module type of struct [processed_code for checking like invariance ]end *) @@ -407518,7 +407542,6 @@ let handleTdclsInStru in let kind = Ast_derive_abstract.isAbstract actions in if kind <> Not_abstract then - let codes = Ast_derive_abstract.handleTdclsInStr ~light:(kind = Light_abstract) rf originalTdclsNewAttrs in (* use [tdcls2] avoid nonterminating *) @@ -407527,8 +407550,6 @@ let handleTdclsInStru Ast_structure.constraint_ ~loc [newStr] [] :: (* [include struct end : sig end] for error checking *) self.structure self codes) - - else Ast_structure.fuseAll ~loc (newStr :: @@ -407876,7 +407897,7 @@ let expr_mapper (self : mapper) (e : Parsetree.expression) = pexp_desc = Ast_uncurry_gen.to_uncurry_fn e.pexp_loc self label pat body ; pexp_attributes} | Method _ , _ - -> Location.raise_errorf ~loc:e.pexp_loc "bs.meth is not supported in function expression" + -> Location.raise_errorf ~loc:e.pexp_loc "%@meth is not supported in function expression" | Meth_callback _, pexp_attributes -> (** FIXME: does it make sense to have a label for [this] ? *) @@ -407902,7 +407923,7 @@ let expr_mapper (self : mapper) (e : Parsetree.expression) = } | Some e -> Location.raise_errorf - ~loc:e.pexp_loc "`with` construct is not supported in bs.obj ") + ~loc:e.pexp_loc "`with` construct is not supported in js obj ") else default_expr_mapper self e | Pexp_object {pcstr_self; pcstr_fields} -> @@ -408140,7 +408161,7 @@ let structure_item_mapper (self : mapper) (str : Parsetree.structure_item) = | _ -> { str with pstr_desc = Pstr_value(Nonrecursive, [{pvb_pat ; pvb_expr; pvb_attributes; pvb_loc}])} end - | Pstr_attribute({txt = "bs.config" },_) -> str + | Pstr_attribute({txt = "bs.config" | "config" },_) -> str | _ -> default_mapper.structure_item self str diff --git a/lib/4.06.1/unstable/js_refmt_compiler.ml b/lib/4.06.1/unstable/js_refmt_compiler.ml index 4133aa7368..a25b937190 100644 --- a/lib/4.06.1/unstable/js_refmt_compiler.ml +++ b/lib/4.06.1/unstable/js_refmt_compiler.ml @@ -18041,7 +18041,10 @@ val find_and_split : ('a -> 'b -> bool) -> 'b -> 'a split -val exists : ('a -> bool) -> 'a array -> bool +val exists : + 'a array -> + ('a -> bool) -> + bool val is_empty : 'a array -> bool @@ -18288,7 +18291,7 @@ let find_and_split arr cmp v : _ split = (** TODO: available since 4.03, use {!Array.exists} *) -let exists p a = +let exists a p = let n = Array.length a in let rec loop i = if i = n then false @@ -70920,7 +70923,7 @@ type label = Types.label_description let find_name (attr : Parsetree.attribute) = match attr with - | {txt = "bs.as"}, PStr + | {txt = "bs.as" | "as"}, PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_constant (Pconst_string(s,_))},_ )}] -> Some s | _ -> None @@ -70929,7 +70932,7 @@ let find_name (attr : Parsetree.attribute) = let find_name_with_loc (attr : Parsetree.attribute) : string Asttypes.loc option = match attr with - | {txt = "bs.as";loc}, PStr + | {txt = "bs.as" | "as";loc}, PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_constant (Pconst_string(s,_))},_ )}] -> Some {txt = s; loc} | _ -> None @@ -70973,7 +70976,7 @@ let rec check_duplicated_labels_aux | Some ({txt = s;} as l) -> if Set_string.mem coll s (*use coll to make check a bit looser - allow cases like [ x : int [@bs.as "x"]] + allow cases like [ x : int [@as "x"]] *) then Some l else @@ -84645,7 +84648,7 @@ type call_info = | Call_ml (* called by plain ocaml expression *) | Call_builtin_runtime (* built-in externals *) | Call_na - (* either from [@@bs.val] or not available, + (* either from [@@val] or not available, such calls does not follow such rules {[ fun x y -> f x y === f ]} when [f] is an atom *) @@ -84703,7 +84706,7 @@ type call_info = | Call_ml (* called by plain ocaml expression *) | Call_builtin_runtime (* built-in externals *) | Call_na - (* either from [@@bs.val] or not available, + (* either from [@@val] or not available, such calls does not follow such rules {[ fun x y -> (f x y) === f ]} when [f] is an atom @@ -94700,21 +94703,21 @@ type attr = | Poly_var_string of { descr : (string * string) list - (* introduced by attributes bs.string - and bs.as + (* introduced by attributes @string + and @as *) } | Poly_var of { descr : (string * string) list option - (* introduced by attributes bs.string - and bs.as + (* introduced by attributes @string + and @as *) } (* `a does not have any value*) - | Int of (string * int ) list (* ([`a | `b ] [@bs.int])*) + | Int of (string * int ) list (* ([`a | `b ] [@int])*) | Arg_cst of cst - | Fn_uncurry_arity of int (* annotated with [@bs.uncurry ] or [@bs.uncurry 2]*) + | Fn_uncurry_arity of int (* annotated with [@uncurry ] or [@uncurry 2]*) (* maybe we can improve it as a combination of {!Asttypes.constant} and tuple *) | Extern_unit | Nothing @@ -95158,22 +95161,22 @@ type external_spec = (* let name_of_ffi ffi = match ffi with - | Js_get_index _scope -> "[@@bs.get_index ..]" - | Js_set_index _scope -> "[@@bs.set_index ..]" - | Js_get { js_get_name = s} -> Printf.sprintf "[@@bs.get %S]" s - | Js_set { js_set_name = s} -> Printf.sprintf "[@@bs.set %S]" s - | Js_call v -> Printf.sprintf "[@@bs.val %S]" v.name - | Js_send v -> Printf.sprintf "[@@bs.send %S]" v.name - | Js_module_as_fn v -> Printf.sprintf "[@@bs.val %S]" v.external_module_name.bundle - | Js_new v -> Printf.sprintf "[@@bs.new %S]" v.name + | Js_get_index _scope -> "@get_index .." + | Js_set_index _scope -> "@set_index .." + | Js_get { js_get_name = s} -> Printf.sprintf "[@@get %S]" s + | Js_set { js_set_name = s} -> Printf.sprintf "[@@set %S]" s + | Js_call v -> Printf.sprintf "[@@val %S]" v.name + | Js_send v -> Printf.sprintf "[@@send %S]" v.name + | Js_module_as_fn v -> Printf.sprintf "[@@val %S]" v.external_module_name.bundle + | Js_new v -> Printf.sprintf "[@@new %S]" v.name | Js_module_as_class v - -> Printf.sprintf "[@@bs.module] %S " v.bundle + -> Printf.sprintf "[@@module] %S " v.bundle | Js_module_as_var v -> - Printf.sprintf "[@@bs.module] %S " v.bundle - | Js_var v (* FIXME: could be [@@bs.module "xx"] as well *) + Printf.sprintf "[@@module] %S " v.bundle + | Js_var v (* FIXME: could be [@@module "xx"] as well *) -> - Printf.sprintf "[@@bs.val] %S " v.name *) + Printf.sprintf "[@@val] %S " v.name *) type return_wrapper = | Return_unset @@ -95243,7 +95246,7 @@ let valid_global_name ?loc txt = (* We loose such check (see #2583), - it also helps with the implementation deriving abstract [@bs.as] + it also helps with the implementation deriving abstract [@as] *) let valid_method_name ?loc:_ _txt = @@ -96378,8 +96381,8 @@ exception Not_simple_form where [wrap] used to be simple instructions Note that [external] functions are forced to do eta-conversion when combined with [|>] operator, we need to make sure beta-reduction - is applied though since `[@bs.splice]` needs such guarantee. - Since `[@bs.splice] is the tail position + is applied though since `[@variadic]` needs such guarantee. + Since `[@variadic] is the tail position *) let rec is_eta_conversion_exn params inner_args outer_args : t list = @@ -96910,7 +96913,7 @@ let sequand l r = if_ l r false_ (** only [handle_bs_non_obj_ffi] will be used outside *) (** [no_auto_uncurried_arg_types xs] - check if the FFI have [@@bs.uncurry] attribute. + check if the FFI have @uncurry attribute. if it does not we wrap it in a nomral way otherwise *) let rec no_auto_uncurried_arg_types @@ -108633,7 +108636,7 @@ val translate_ffi : (** TODO: document supported attributes Attributes starting with `js` are reserved - examples: "bs.splice" + examples: "variadic" *) end = struct @@ -108718,7 +108721,7 @@ let append_list x xs = unbox it in the first place. Note when optional value is not passed, the unboxed value would be - [undefined], with the combination of `[@bs.int]` it would be still be + [undefined], with the combination of `[@int]` it would be still be [undefined], this by default is still correct.. {[ (function () { @@ -108892,7 +108895,7 @@ let translate_scoped_module_val Ext_list.fold_left (Ext_list.append rest [fn]) start E.dot end | None -> - (* no [@@bs.module], assume it's global *) + (* no [@@module], assume it's global *) begin match scopes with | [] -> E.js_global fn @@ -108949,7 +108952,7 @@ let translate_ffi | Js_new { external_module_name = module_name; name = fn; scopes - } -> (* handle [@@bs.new]*) + } -> (* handle [@@new]*) (* This has some side effect, it will mark its identifier (If it has) as an object, ATTENTION: @@ -108996,7 +108999,7 @@ let translate_ffi begin match args with | self :: args -> (* PR2162 [self_type] more checks in syntax: - - should not be [bs.as] *) + - should not be [@as] *) let [@warning"-8"] ( _self_type::arg_types ) = arg_types in if splice then @@ -109022,7 +109025,7 @@ let translate_ffi (* TODO #11 1. check args -- error checking - 2. support [@@bs.scope "window"] + 2. support [@@scope "window"] we need know whether we should call [add_js_module] or not *) translate_scoped_module_val external_module_name name scopes @@ -110934,7 +110937,7 @@ let transform_under_supply n ap_info fn args = cautiously, since [let u = f] and we are chaning the arity of [f] it will affect the collection of [u] - A typical use case is to pass an OCaml function to JS side as a callback (i.e, [@bs.uncurry]) + A typical use case is to pass an OCaml function to JS side as a callback (i.e, [@uncurry]) *) let unsafe_adjust_to_arity loc ~(to_:int) ?(from : int option) (fn : Lam.t) : Lam.t = let ap_info : Lam.ap_info = {ap_loc = loc; ap_inlined = Default_inline; ap_status = App_na } in @@ -395776,7 +395779,7 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) : Lam.t * Lam_module_i ]} is also wrong. - It seems, we need handle [@bs.splice] earlier + It seems, we need handle [@variadic] earlier or {[ @@ -395784,7 +395787,7 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) : Lam.t * Lam_module_i let x0, x1, x2 =1,2,3 in (fun y -> f [|x0;x1;x2|] y) ]} - But this still need us to know [@bs.splice] in advance + But this still need us to know [@variadic] in advance we should not remove it immediately, since we have to be careful @@ -399808,7 +399811,7 @@ let pp_error fmt err = -> "Uncurried function doesn't support optional arguments yet" | Expect_opt_in_bs_return_to_opt -> - "bs.return directive *_to_opt expect return type to be \n\ + "%@return directive *_to_opt expect return type to be \n\ syntax wise `_ option` for safety" | Not_supported_directive_in_bs_return @@ -399817,7 +399820,7 @@ let pp_error fmt err = | Illegal_attribute -> "Illegal attributes" | Canot_infer_arity_by_syntax - -> "Cannot infer the arity through the syntax, either [@bs.uncurry n] or \n\ + -> "Cannot infer the arity through the syntax, either [%@uncurry n] or \n\ write it in arrow syntax " | Inconsistent_arity (arity,n) -> Printf.sprintf "Inconsistent arity %d vs %d" arity n @@ -399828,7 +399831,7 @@ let pp_error fmt err = -> "unsupported predicates" | Conflict_bs_bs_this_bs_meth -> - "[@bs.this], [@bs], [@bs.meth] can not be applied at the same time" + "%@this, %@bs, %@meth can not be applied at the same time" | Duplicated_bs_deriving -> "duplicate bs.deriving attribute" | Conflict_attributes @@ -399837,7 +399840,7 @@ let pp_error fmt err = -> "expect string literal " | Duplicated_bs_as -> - "duplicate bs.as " + "duplicate %@as " | Expect_int_literal -> "expect int literal " @@ -399854,20 +399857,20 @@ let pp_error fmt err = "_ is not allowed in combination with external optional type" | Invalid_bs_string_type -> - "Not a valid type for [@bs.string]" + "Not a valid type for %@string" | Invalid_bs_int_type -> - "Not a valid type for [@bs.int]" + "Not a valid type for %@int" | Invalid_bs_unwrap_type -> - "Not a valid type for [@bs.unwrap]. Type must be an inline variant (closed), and\n\ + "Not a valid type for %@unwrap. Type must be an inline variant (closed), and\n\ each constructor must have an argument." | Conflict_ffi_attribute str -> "Conflicting FFI attributes found: " ^ str | Bs_this_simple_pattern -> - "[@bs.this] expect its pattern variable to be simple form") + "%@this expect its pattern variable to be simple form") type exn += Error of Location.t * error @@ -400379,6 +400382,10 @@ end = struct * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) +(** Warning unused bs attributes + Note if we warn `deriving` too, + it may fail third party ppxes +*) let is_bs_attribute txt = let len = String.length txt in len >= 2 && @@ -400464,7 +400471,7 @@ let emit_external_warnings : iterator= Ext_list.iter lbl.pld_attributes (fun attr -> match attr with - | {txt = "bs.as"}, _ -> mark_used_bs_attribute attr + | {txt = "bs.as" | "as"}, _ -> mark_used_bs_attribute attr | _ -> () ); default_iterator.label_declaration self lbl @@ -400635,7 +400642,7 @@ let add_signature k v = let rec iter_on_bs_config_stru (x :Parsetree.structure) = match x with | [] -> () - | {pstr_desc = Pstr_attribute (({txt = "bs.config"; loc}, payload) as attr)}::_ -> + | {pstr_desc = Pstr_attribute (({txt = "bs.config" | "config"; loc}, payload) as attr)}::_ -> Bs_ast_invariant.mark_used_bs_attribute attr; Ext_list.iter (Ast_payload.ident_or_record_as_config loc payload) (Ast_payload.table_dispatch !structural_config_table) @@ -400646,7 +400653,7 @@ let rec iter_on_bs_config_stru (x :Parsetree.structure) = let rec iter_on_bs_config_sigi (x :Parsetree.signature) = match x with | [] -> () - | {psig_desc = Psig_attribute (({txt = "bs.config"; loc}, payload) as attr)}::_ -> + | {psig_desc = Psig_attribute (({txt = "bs.config" | "config"; loc}, payload) as attr)}::_ -> Bs_ast_invariant.mark_used_bs_attribute attr; Ext_list.iter (Ast_payload.ident_or_record_as_config loc payload) (Ast_payload.table_dispatch !signature_config_table) @@ -400803,7 +400810,7 @@ type ('a,'b) st = let process_method_attributes_rev (attrs : t) = Ext_list.fold_left attrs ({get = None ; set = None}, []) (fun (st,acc) (({txt ; loc}, payload) as attr ) -> match txt with - | "bs.get" (* [@@bs.get{null; undefined}]*) + | "bs.get" | "get" (* @bs.get{null; undefined}*) -> let result = Ext_list.fold_left (Ast_payload.ident_or_record_as_config loc payload) (false, false) @@ -400833,7 +400840,7 @@ let process_method_attributes_rev (attrs : t) = ({st with get = Some result}, acc ) - | "bs.set" + | "bs.set" | "set" -> let result = Ext_list.fold_left (Ast_payload.ident_or_record_as_config loc payload) `Get @@ -400848,7 +400855,7 @@ let process_method_attributes_rev (attrs : t) = else Bs_syntaxerr.err loc Unsupported_predicates ) in (* properties -- void - [@@bs.set{only}] + [@@set{only}] *) {st with set = Some result }, acc | _ -> @@ -400867,12 +400874,11 @@ let process_attributes_rev (attrs : t) : attr_kind * t = | "bs", (Nothing | Uncurry _) -> Uncurry attr, acc (* TODO: warn unused/duplicated attribute *) - | "bs.this", (Nothing | Meth_callback _) + | ("bs.this" | "this"), (Nothing | Meth_callback _) -> Meth_callback attr, acc - | "bs.meth", (Nothing | Method _) + | ("bs.meth" | "meth"), (Nothing | Method _) -> Method attr, acc - | "bs", _ - | "bs.this", _ + | ("bs" | "bs.this" | "this"), _ -> Bs_syntaxerr.err loc Conflict_bs_bs_this_bs_meth | _ , _ -> st, attr::acc @@ -400899,10 +400905,27 @@ let process_bs (attrs : t) = st, attr::acc ) +let external_attrs = [| + "get"; + "set"; + "get_index"; + "return"; + "obj"; + "val"; + "module"; + "scope"; + "variadic"; + "send"; + "new"; + "set_index"; + Literals.gentype_import +|] +(* ATT: Special cases for built-in attributes handling *) let external_needs_to_be_encoded (attrs : t)= Ext_list.exists_fst attrs (fun {txt} -> - Ext_string.starts_with txt "bs." || txt = Literals.gentype_import) + Ext_string.starts_with txt "bs." || + Ext_array.exists external_attrs (fun (x : string) -> txt = x) ) let is_inline : attr -> bool = (fun @@ -400922,24 +400945,26 @@ type derive_attr = { let process_derive_type (attrs : t) : derive_attr * t = Ext_list.fold_left attrs ({bs_deriving = None }, []) (fun (st, acc) ({txt ; loc}, payload as attr) -> - match st, txt with - | {bs_deriving = None}, "bs.deriving" - -> - { - bs_deriving = Some - (Ast_payload.ident_or_record_as_config loc payload)}, acc - | {bs_deriving = Some _}, "bs.deriving" - -> - Bs_syntaxerr.err loc Duplicated_bs_deriving - - | _ , _ -> - st, attr::acc + match txt with + | "bs.deriving" | "deriving" + -> + begin match st.bs_deriving with + | None -> + { + bs_deriving = Some + (Ast_payload.ident_or_record_as_config loc payload)}, acc + | Some _ + -> + Bs_syntaxerr.err loc Duplicated_bs_deriving + end + | _ -> + st, attr::acc ) -(* duplicated [bs.uncurry] [bs.string] not allowed, - it is worse in bs.uncurry since it will introduce +(* duplicated @uncurry @string not allowed, + it is worse in @uncurry since it will introduce inconsistency in arity *) let iter_process_bs_string_int_unwrap_uncurry (attrs : t) = @@ -400953,15 +400978,15 @@ let iter_process_bs_string_int_unwrap_uncurry (attrs : t) = else Bs_syntaxerr.err loc Conflict_attributes in Ext_list.iter attrs (fun (({txt ; loc=_}, (payload : _ ) ) as attr) -> match txt with - | "bs.string" + | "bs.string" | "string" -> assign `String attr - | "bs.int" + | "bs.int" | "int" -> assign `Int attr - | "bs.ignore" + | "bs.ignore" | "ignore" -> assign `Ignore attr - | "bs.unwrap" + | "bs.unwrap" | "unwrap" -> assign `Unwrap attr - | "bs.uncurry" + | "bs.uncurry" | "uncurry" -> assign (`Uncurry (Ast_payload.is_single_int payload)) attr | _ -> () @@ -400975,7 +401000,7 @@ let iter_process_bs_string_as (attrs : t) : string option = (fun (({txt ; loc}, payload ) as attr ) -> match txt with - | "bs.as" + | "bs.as" | "as" -> if !st = None then match Ast_payload.is_single_string payload with @@ -400995,7 +401020,7 @@ let has_bs_optional (attrs : t) : bool = Ext_list.exists attrs (fun (({txt ; }, _ ) as attr) -> match txt with - | "bs.optional" + | "bs.optional" | "optional" -> Bs_ast_invariant.mark_used_bs_attribute attr ; true @@ -401010,7 +401035,7 @@ let iter_process_bs_int_as (attrs : t) = (fun (({txt ; loc}, payload ) as attr) -> match txt with - | "bs.as" + | "bs.as" | "as" -> if !st = None then match Ast_payload.is_single_int payload with @@ -401034,7 +401059,7 @@ let iter_process_bs_string_or_int_as (attrs : Parsetree.attributes) = (fun (({txt ; loc}, payload ) as attr) -> match txt with - | "bs.as" + | "bs.as" | "as" -> if !st = None then (Bs_ast_invariant.mark_used_bs_attribute attr ; @@ -402783,7 +402808,7 @@ let typ_mapper | Uncurry attr , attrs -> attrs, attr +> ty | Method _, _ - -> Location.raise_errorf ~loc "bs.get/set conflicts with bs.meth" + -> Location.raise_errorf ~loc "%@get/set conflicts with %@meth" | Meth_callback attr, attrs -> attrs, attr +> ty in @@ -402795,7 +402820,7 @@ let typ_mapper | Uncurry attr, attrs -> attrs, attr +> ty | Method _, _ - -> Location.raise_errorf ~loc "bs.get/set conflicts with bs.meth" + -> Location.raise_errorf ~loc "%@get/set conflicts with %@meth" | Meth_callback attr, attrs -> attrs, attr +> ty in @@ -403465,7 +403490,7 @@ let map_row_fields_into_strings ptyp_loc let descr = if !has_bs_as then Some result else None in match has_payload, descr with | false, None -> - Location.prerr_warning ptyp_loc (Bs_ffi_warning "bs.string is redundant here, you can safely remove it"); + Location.prerr_warning ptyp_loc (Bs_ffi_warning "%@string is redundant here, you can safely remove it"); Nothing | false , Some descr -> External_arg_spec.Poly_var_string {descr } @@ -404676,7 +404701,7 @@ let refine_arg_type ~(nolabel:bool) (ptyp : Ast_core_type.t) match result with | None -> spec_of_ptyp nolabel ptyp - | Some cst -> (* (_[@bs.as ])*) + | Some cst -> (* (_[@as ])*) (* when ppx start dropping attributes we should warn, there is a trade off whether we should warn dropped non bs attribute or not @@ -404684,14 +404709,14 @@ let refine_arg_type ~(nolabel:bool) (ptyp : Ast_core_type.t) Bs_ast_invariant.warn_discarded_unused_attributes ptyp_attrs; begin match cst with | Int i -> - (* This type is used in bs.obj only to construct obj type*) + (* This type is used in obj only to construct obj type*) Arg_cst(External_arg_spec.cst_int i) | Str i-> Arg_cst (External_arg_spec.cst_string i) | Js_literal_str s -> Arg_cst (External_arg_spec.cst_obj_literal s) end - else (* ([`a|`b] [@bs.string]) *) + else (* ([`a|`b] [@string]) *) spec_of_ptyp nolabel ptyp ) @@ -404708,22 +404733,22 @@ let refine_obj_arg_type ~(nolabel:bool) (ptyp : Ast_core_type.t) match result with | None -> Bs_syntaxerr.err ptyp.ptyp_loc Invalid_underscore_type_in_external - | Some (Int i) -> (* (_[@bs.as ])*) - (* This type is used in bs.obj only to construct obj type*) + | Some (Int i) -> (* (_[@as ])*) + (* This type is used in obj only to construct obj type*) Arg_cst(External_arg_spec.cst_int i) | Some (Str i)-> Arg_cst (External_arg_spec.cst_string i) | Some (Js_literal_str s ) -> Arg_cst (External_arg_spec.cst_obj_literal s) - else (* ([`a|`b] [@bs.string]) *) + else (* ([`a|`b] [@string]) *) spec_of_ptyp nolabel ptyp (** Given the type of argument, process its [bs.] attribute and new type, The new type is currently used to reconstruct the external type - and result type in [@@bs.obj] + and result type in [@@obj] They are not the same though, for example {[ - external f : hi:([ `hi | `lo ] [@bs.string]) -> unit -> _ = "" [@@bs.obj] + external f : hi:([ `hi | `lo ] [@string]) -> unit -> _ = "" [@@obj] ]} The result type would be [ hi:string ] *) @@ -404731,20 +404756,20 @@ let get_opt_arg_type ~(nolabel : bool) (ptyp : Ast_core_type.t) : External_arg_spec.attr = - if ptyp.ptyp_desc = Ptyp_any then (* (_[@bs.as ])*) - (* extenral f : ?x:_ -> y:int -> _ = "" [@@bs.obj] is not allowed *) + if ptyp.ptyp_desc = Ptyp_any then (* (_[@as ])*) + (* extenral f : ?x:_ -> y:int -> _ = "" [@@obj] is not allowed *) Bs_syntaxerr.err ptyp.ptyp_loc Invalid_underscore_type_in_external; - (* ([`a|`b] [@bs.string]) *) + (* ([`a|`b] [@@string]) *) spec_of_ptyp nolabel ptyp (** - [@@bs.module "react"] - [@@bs.module "react"] + [@@module "react"] + [@@module "react"] --- - [@@bs.module "@" "react"] - [@@bs.module "@" "react"] + [@@module "@" "react"] + [@@module "@" "react"] They should have the same module name @@ -404752,7 +404777,7 @@ let get_opt_arg_type two external files to the same module name *) type bundle_source = - [`Nm_payload of string (* from payload [@@bs.val "xx" ]*) + [`Nm_payload of string (* from payload [@@val "xx" ]*) |`Nm_external of string (* from "" in external *) | `Nm_val of string lazy_t (* from function name *) ] @@ -404824,6 +404849,7 @@ let return_wrapper loc (txt : string) : External_ffi_types.return_wrapper = | _ -> Bs_syntaxerr.err loc Not_supported_directive_in_bs_return +exception Not_handled_external_attribute (* The processed attributes will be dropped *) let parse_external_attributes @@ -404832,15 +404858,15 @@ let parse_external_attributes (prim_name_or_pval_prim: bundle_source ) (prim_attributes : Ast_attributes.t) : Ast_attributes.t * external_desc = - (* shared by `[@@bs.val]`, `[@@bs.send]`, - `[@@bs.set]`, `[@@bs.get]` , `[@@bs.new]` + (* shared by `[@@val]`, `[@@send]`, + `[@@set]`, `[@@get]` , `[@@new]` `[@@bs.send.pipe]` does not use it *) let name_from_payload_or_prim ~loc (payload : Parsetree.payload) : name_source = match payload with | PStr [] -> (prim_name_or_pval_prim :> name_source) - (* It is okay to have [@@bs.val] without payload *) + (* It is okay to have [@@val] without payload *) | _ -> begin match Ast_payload.is_single_string payload with | Some (val_name, _) -> `Nm_payload val_name @@ -404859,15 +404885,15 @@ let parse_external_attributes in attr::attrs, {st with external_module_name = Some { bundle; module_bind_name = Phint_nothing}} - else if Ext_string.starts_with txt "bs." then - attrs, begin match txt with - | "bs.val" -> + else + let action () = begin match txt with + | "bs.val" | "val" -> if no_arguments then {st with val_name = name_from_payload_or_prim ~loc payload} else {st with call_name = name_from_payload_or_prim ~loc payload} - | "bs.module" -> + | "bs.module" | "module" -> begin match Ast_payload.assert_strings loc payload with | [bundle] -> {st with external_module_name = @@ -404887,7 +404913,7 @@ let parse_external_attributes | _ -> Bs_syntaxerr.err loc Illegal_attribute end - | "bs.scope" -> + | "bs.scope" | "scope" -> begin match Ast_payload.assert_strings loc payload with | [] -> Bs_syntaxerr.err loc Illegal_attribute @@ -404896,27 +404922,29 @@ let parse_external_attributes *) | scopes -> { st with scopes = scopes } end - | "bs.splice" | "bs.variadic" -> {st with splice = true} - | "bs.send" -> + | "bs.splice" + | "bs.variadic" | "variadic" -> {st with splice = true} + | "bs.send" | "send" -> { st with val_send = name_from_payload_or_prim ~loc payload} | "bs.send.pipe" -> { st with val_send_pipe = Some (Ast_payload.as_core_type loc payload)} - | "bs.set" -> + | "bs.set" | "set" -> {st with set_name = name_from_payload_or_prim ~loc payload} - | "bs.get" -> {st with get_name = name_from_payload_or_prim ~loc payload} + | "bs.get" | "get" -> + {st with get_name = name_from_payload_or_prim ~loc payload} - | "bs.new" -> {st with new_name = name_from_payload_or_prim ~loc payload} - | "bs.set_index" -> + | "bs.new" | "new" -> {st with new_name = name_from_payload_or_prim ~loc payload} + | "bs.set_index" | "set_index" -> if String.length prim_name_check <> 0 then - Location.raise_errorf ~loc "[@@bs.set_index] this particular external's name needs to be a placeholder empty string"; + Location.raise_errorf ~loc "%@set_index this particular external's name needs to be a placeholder empty string"; {st with set_index = true} - | "bs.get_index"-> + | "bs.get_index" | "get_index" -> if String.length prim_name_check <> 0 then - Location.raise_errorf ~loc "[@@bs.get_index] this particular external's name needs to be a placeholder empty string"; + Location.raise_errorf ~loc "%@get_index this particular external's name needs to be a placeholder empty string"; {st with get_index = true} - | "bs.obj" -> {st with mk_obj = true} - | "bs.return" -> + | "bs.obj" | "obj" -> {st with mk_obj = true} + | "bs.return" | "return" -> let actions = Ast_payload.ident_or_record_as_config loc payload in begin match actions with @@ -404925,15 +404953,16 @@ let parse_external_attributes | _ -> Bs_syntaxerr.err loc Not_supported_directive_in_bs_return end - | _ -> (Location.prerr_warning loc (Bs_unused_attribute txt); st) - end - else attr :: attrs, st + | _ -> raise_notrace Not_handled_external_attribute + end in + try attrs, action () with + | Not_handled_external_attribute -> attr::attrs, st ) let has_bs_uncurry (attrs : Ast_attributes.t) = - Ext_list.exists_fst attrs (fun x -> x.txt = "bs.uncurry") + Ext_list.exists_fst attrs (fun {txt;loc=_} -> txt = "bs.uncurry" || txt = "uncurry") let check_return_wrapper @@ -404993,11 +405022,11 @@ let process_obj set_index = false ; mk_obj = _; scopes = []; - (* wrapper does not work with [bs.obj] + (* wrapper does not work with @obj TODO: better error message *) } -> if String.length prim_name <> 0 then - Location.raise_errorf ~loc "[@@bs.obj] expect external names to be empty string"; + Location.raise_errorf ~loc "%@obj expect external names to be empty string"; let arg_kinds, new_arg_types_ty, (result_types : Parsetree.object_field list) = Ext_list.fold_right arg_types_ty ( [], [], []) (fun param_type ( arg_labels, (arg_types : Ast_compatible.param_type list), result_types) -> @@ -405043,15 +405072,15 @@ let process_obj (Otag({Asttypes.txt = name; loc}, [], Ast_literal.type_string ~loc ()) :: result_types) | Fn_uncurry_arity _ -> Location.raise_errorf ~loc - "The combination of [@@bs.obj], [@@bs.uncurry] is not supported yet" + "The combination of %@obj, %@uncurry is not supported yet" | Extern_unit -> assert false | Poly_var _ -> Location.raise_errorf ~loc - "bs.obj label %s does not support such arg type" name + "%@obj label %s does not support such arg type" name | Unwrap -> Location.raise_errorf ~loc - "bs.obj label %s does not support [@bs.unwrap] arguments" name + "%@obj label %s does not support %@unwrap arguments" name end | Optional name -> let obj_arg_type = get_opt_arg_type ~nolabel:false ty in @@ -405076,18 +405105,18 @@ let process_obj (Otag ({Asttypes.txt = name; loc}, [], Ast_comb.to_undefined_type loc @@ Ast_literal.type_string ~loc ()) :: result_types) | Arg_cst _ -> - Location.raise_errorf ~loc "bs.as is not supported with optional yet" + Location.raise_errorf ~loc "%@as is not supported with optional yet" | Fn_uncurry_arity _ -> Location.raise_errorf ~loc - "The combination of [@@bs.obj], [@@bs.uncurry] is not supported yet" + "The combination of %@obj, %@uncurry is not supported yet" | Extern_unit -> assert false | Poly_var _ -> Location.raise_errorf ~loc - "bs.obj label %s does not support such arg type" name + "%@obj label %s does not support such arg type" name | Unwrap -> Location.raise_errorf ~loc - "bs.obj label %s does not support [@bs.unwrap] arguments" name + "%@obj label %s does not support %@unwrap arguments" name end in new_arg_label::arg_labels, @@ -405104,7 +405133,7 @@ let process_obj in Ast_compatible.mk_fn_type new_arg_types_ty result, External_ffi_types.ffi_obj_create arg_kinds - | _ -> Location.raise_errorf ~loc "Attribute found that conflicts with [@@bs.obj]" + | _ -> Location.raise_errorf ~loc "Attribute found that conflicts with %@obj" let external_desc_of_non_obj @@ -405137,9 +405166,9 @@ let external_desc_of_non_obj if arg_type_specs_length = 3 then Js_set_index {js_set_index_scopes = scopes} else - Location.raise_errorf ~loc "Ill defined attribute [@@bs.set_index](arity of 3)" + Location.raise_errorf ~loc "Ill defined attribute %@set_index (arity of 3)" | {set_index = true; _} -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.set_index]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@set_index") | {get_index = true; val_name = `Nm_na; external_module_name = None ; @@ -405160,10 +405189,10 @@ let external_desc_of_non_obj if arg_type_specs_length = 2 then Js_get_index {js_get_index_scopes = scopes} else Location.raise_errorf ~loc - "Ill defined attribute [@@bs.get_index] (arity expected 2 : while %d)" arg_type_specs_length + "Ill defined attribute %@get_index (arity expected 2 : while %d)" arg_type_specs_length | {get_index = true; _} -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.get_index]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@get_index") | {module_as_val = Some external_module_name ; get_index = false; @@ -405186,17 +405215,17 @@ let external_desc_of_non_obj | [], `Nm_na, _ -> Js_module_as_var external_module_name | _, `Nm_na, _ -> Js_module_as_fn {splice; external_module_name } | _, #bundle_source, #bundle_source -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.module].") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@module.") | _, (`Nm_val _ | `Nm_external _) , `Nm_na -> Js_module_as_class external_module_name | _, `Nm_payload _ , `Nm_na -> Location.raise_errorf ~loc - "Incorrect FFI attribute found: (bs.new should not carry a payload here)" + "Incorrect FFI attribute found: (%@new should not carry a payload here)" end | {module_as_val = Some _; _} -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.module].") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@module.") | {call_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name) ; splice; scopes ; @@ -405218,7 +405247,7 @@ let external_desc_of_non_obj Js_call {splice; name; external_module_name; scopes } | {call_name = #bundle_source ; _ } -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.val]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@val") | {val_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name); external_module_name; @@ -405239,13 +405268,13 @@ let external_desc_of_non_obj -> (* if no_arguments --> {[ - external ff : int = "" [@@bs.val] + external ff : int = "" [@@val] ]} *) Js_var { name; external_module_name; scopes} | {val_name = #bundle_source ; _ } -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.val]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@val") | {splice ; scopes ; @@ -405268,7 +405297,7 @@ let external_desc_of_non_obj if arg_type_specs_length = 0 then (* {[ - external ff : int = "" [@@bs.module "xx"] + external ff : int = "" [@@module "xx"] ]} *) Js_var { name; external_module_name; scopes} @@ -405290,21 +405319,21 @@ let external_desc_of_non_obj return_wrapper = _ ; } -> (* PR #2162 - since when we assemble arguments the first argument in - [@@bs.send] is ignored + [@@send] is ignored *) begin match arg_type_specs with | [] -> Location.raise_errorf - ~loc "Ill defined attribute [@@bs.send] (the external needs to be a regular function call with at least one argument)" + ~loc "Ill defined attribute %@send(the external needs to be a regular function call with at least one argument)" | {arg_type = Arg_cst _ ; arg_label = _} :: _ -> Location.raise_errorf - ~loc "Ill defined attribute [@@bs.send] (first argument can't be const)" + ~loc "Ill defined attribute %@send(first argument can't be const)" | _ :: _ -> Js_send {splice ; name; js_send_scopes = scopes ; pipe = false} end | {val_send = #bundle_source; _ } - -> Location.raise_errorf ~loc "You used a FFI attribute that can't be used with [@@bs.send]" + -> Location.raise_errorf ~loc "You used a FFI attribute that can't be used with %@send" | {val_send_pipe = Some _; (* splice = (false as splice); *) val_send = `Nm_na; @@ -405329,7 +405358,7 @@ let external_desc_of_non_obj pipe = true} | {val_send_pipe = Some _ ; _} - -> Location.raise_errorf ~loc "conflict attributes found with [@@bs.send.pipe]" + -> Location.raise_errorf ~loc "conflict attributes found with [%@%@bs.send.pipe]" | {new_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name); external_module_name; @@ -405350,7 +405379,7 @@ let external_desc_of_non_obj } -> Js_new {name; external_module_name; scopes} | {new_name = #bundle_source ; _ } -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.new]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@new") | {set_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name); val_name = `Nm_na ; call_name = `Nm_na ; @@ -405370,9 +405399,9 @@ let external_desc_of_non_obj -> if arg_type_specs_length = 2 then Js_set { js_set_scopes = scopes ; js_set_name = name} - else Location.raise_errorf ~loc "Ill defined attribute [@@bs.set] (two args required)" + else Location.raise_errorf ~loc "Ill defined attribute %@set (two args required)" | {set_name = #bundle_source; _} - -> Location.raise_errorf ~loc "conflict attributes found with [@@bs.set]" + -> Location.raise_errorf ~loc "conflict attributes found with %@set" | {get_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name); val_name = `Nm_na ; @@ -405394,9 +405423,9 @@ let external_desc_of_non_obj if arg_type_specs_length = 1 then Js_get { js_get_name = name; js_get_scopes = scopes } else - Location.raise_errorf ~loc "Ill defined attribute [@@bs.get] (only one argument)" + Location.raise_errorf ~loc "Ill defined attribute %@bs.get (only one argument)" | {get_name = #bundle_source; _} - -> Location.raise_errorf ~loc "Attribute found that conflicts with [@@bs.get]" + -> Location.raise_errorf ~loc "Attribute found that conflicts with %@bs.get" | {get_name = `Nm_na; val_name = `Nm_na ; @@ -405415,7 +405444,7 @@ let external_desc_of_non_obj return_wrapper = _; } - -> Location.raise_errorf ~loc "Could not infer which FFI category it belongs to, maybe you forgot [%@%@bs.val]? " + -> Location.raise_errorf ~loc "Could not infer which FFI category it belongs to, maybe you forgot %@val? " (** Note that the passed [type_annotation] is already processed by visitor pattern before*) let handle_attributes @@ -405427,12 +405456,12 @@ let handle_attributes : Parsetree.core_type * External_ffi_types.t * Parsetree.attributes * bool = (** sanity check here - {[ int -> int -> (int -> int -> int [@bs.uncurry])]} + {[ int -> int -> (int -> int -> int [@uncurry])]} It does not make sense *) if has_bs_uncurry type_annotation.ptyp_attributes then Location.raise_errorf - ~loc "[@@bs.uncurry] can not be applied to the whole definition"; + ~loc "%@uncurry can not be applied to the whole definition"; let prim_name_or_pval_name = if String.length prim_name = 0 then `Nm_val (lazy (Location.prerr_warning loc (Bs_fragile_external pval_name); pval_name)) @@ -405443,7 +405472,7 @@ let handle_attributes if has_bs_uncurry result_type.ptyp_attributes then Location.raise_errorf ~loc:result_type.ptyp_loc - "[@@bs.uncurry] can not be applied to tailed position"; + "%@uncurry can not be applied to tailed position"; let no_arguments = arg_types_ty = [] in let unused_attrs, external_desc = parse_external_attributes no_arguments @@ -405461,7 +405490,7 @@ let handle_attributes let arg_type = refine_arg_type ~nolabel:true obj in begin match arg_type with | Arg_cst _ -> - Location.raise_errorf ~loc:obj.ptyp_loc "[@bs.as] is not supported in bs.send type " + Location.raise_errorf ~loc:obj.ptyp_loc "%@as is not supported in %@send type " | _ -> (* more error checking *) [{arg_label = Arg_empty; arg_type}], @@ -405479,17 +405508,17 @@ let handle_attributes if i = 0 && splice then begin match arg_label with | Optional _ -> - Location.raise_errorf ~loc "[@@@@bs.splice] expect the last type to be a non optional" + Location.raise_errorf ~loc "%@variadic expect the last type to be a non optional" | Labelled _ | Nolabel -> if ty.ptyp_desc = Ptyp_any then - Location.raise_errorf ~loc "[@@@@bs.splice] expect the last type to be an array"; + Location.raise_errorf ~loc "%@variadic expect the last type to be an array"; if spec_of_ptyp true ty <> Nothing then - Location.raise_errorf ~loc "[@@@@bs.splice] expect the last type to be an array"; + Location.raise_errorf ~loc "%@variadic expect the last type to be an array"; match ty.ptyp_desc with | Ptyp_constr({txt = Lident "array"; _}, [_]) -> () - | _ -> Location.raise_errorf ~loc "[@@@@bs.splice] expect the last type to be an array"; + | _ -> Location.raise_errorf ~loc "%@variadic expect the last type to be an array"; end ; let (arg_label : External_arg_spec.label_noname), arg_type, new_arg_types = match arg_label with @@ -405497,10 +405526,10 @@ let handle_attributes let arg_type = get_opt_arg_type ~nolabel:false ty in begin match arg_type with | Poly_var _ -> - (* ?x:([`x of int ] [@bs.string]) does not make sense *) + (* ?x:([`x of int ] [@string]) does not make sense *) Location.raise_errorf ~loc - "[@@bs.string] does not work with optional when it has arities in label %s" s + "%@string does not work with optional when it has arities in label %s" s | _ -> Arg_optional, arg_type, param_type :: arg_types end @@ -405682,7 +405711,7 @@ end = struct open Ast_helper -(* Handling `fun [@bs.this]` used in `object [@bs] end` *) +(* Handling `fun [@this]` used in `object [@bs] end` *) let to_method_callback loc (self : Bs_ast_mapper.mapper) label pat body : Parsetree.expression_desc = @@ -405913,8 +405942,8 @@ let ocaml_obj_as_js_object (** we need calculate the real object type and exposed object type, in some cases there are equivalent - for public object type its [@bs.meth] it does not depend on itself - while for label argument it is [@bs.this] which depends internal object + for public object type its [@meth] it does not depend on itself + while for label argument it is [@this] which depends internal object *) let (internal_label_attr_types : Parsetree.object_field list), (public_label_attr_types : Parsetree.object_field list) = @@ -407452,7 +407481,6 @@ let newTdcls - let handleTdclsInSigi (self : Bs_ast_mapper.mapper) (sigi : Parsetree.signature_item) @@ -407468,9 +407496,7 @@ let handleTdclsInSigi let newTdclsNewAttrs = self.type_declaration_list self originalTdclsNewAttrs in let kind = Ast_derive_abstract.isAbstract actions in if kind <> Not_abstract then - let codes = Ast_derive_abstract.handleTdclsInSig ~light:(kind = Light_abstract) rf originalTdclsNewAttrs in - Ast_signature.fuseAll ~loc ( Sig.include_ ~loc @@ -407478,9 +407504,7 @@ let handleTdclsInSigi (Mty.typeof_ ~loc (Mod.constraint_ ~loc (Mod.structure ~loc [ - Ast_compatible.rec_type_str ~loc rf newTdclsNewAttrs - ] ) (Mty.signature ~loc [])) ) ) :: (* include module type of struct [processed_code for checking like invariance ]end *) @@ -407518,7 +407542,6 @@ let handleTdclsInStru in let kind = Ast_derive_abstract.isAbstract actions in if kind <> Not_abstract then - let codes = Ast_derive_abstract.handleTdclsInStr ~light:(kind = Light_abstract) rf originalTdclsNewAttrs in (* use [tdcls2] avoid nonterminating *) @@ -407527,8 +407550,6 @@ let handleTdclsInStru Ast_structure.constraint_ ~loc [newStr] [] :: (* [include struct end : sig end] for error checking *) self.structure self codes) - - else Ast_structure.fuseAll ~loc (newStr :: @@ -407876,7 +407897,7 @@ let expr_mapper (self : mapper) (e : Parsetree.expression) = pexp_desc = Ast_uncurry_gen.to_uncurry_fn e.pexp_loc self label pat body ; pexp_attributes} | Method _ , _ - -> Location.raise_errorf ~loc:e.pexp_loc "bs.meth is not supported in function expression" + -> Location.raise_errorf ~loc:e.pexp_loc "%@meth is not supported in function expression" | Meth_callback _, pexp_attributes -> (** FIXME: does it make sense to have a label for [this] ? *) @@ -407902,7 +407923,7 @@ let expr_mapper (self : mapper) (e : Parsetree.expression) = } | Some e -> Location.raise_errorf - ~loc:e.pexp_loc "`with` construct is not supported in bs.obj ") + ~loc:e.pexp_loc "`with` construct is not supported in js obj ") else default_expr_mapper self e | Pexp_object {pcstr_self; pcstr_fields} -> @@ -408140,7 +408161,7 @@ let structure_item_mapper (self : mapper) (str : Parsetree.structure_item) = | _ -> { str with pstr_desc = Pstr_value(Nonrecursive, [{pvb_pat ; pvb_expr; pvb_attributes; pvb_loc}])} end - | Pstr_attribute({txt = "bs.config" },_) -> str + | Pstr_attribute({txt = "bs.config" | "config" },_) -> str | _ -> default_mapper.structure_item self str diff --git a/lib/4.06.1/whole_compiler.ml b/lib/4.06.1/whole_compiler.ml index 91cdab1941..ea92bbbc4c 100644 --- a/lib/4.06.1/whole_compiler.ml +++ b/lib/4.06.1/whole_compiler.ml @@ -5541,7 +5541,10 @@ val find_and_split : ('a -> 'b -> bool) -> 'b -> 'a split -val exists : ('a -> bool) -> 'a array -> bool +val exists : + 'a array -> + ('a -> bool) -> + bool val is_empty : 'a array -> bool @@ -5788,7 +5791,7 @@ let find_and_split arr cmp v : _ split = (** TODO: available since 4.03, use {!Array.exists} *) -let exists p a = +let exists a p = let n = Array.length a in let rec loop i = if i = n then false @@ -290981,7 +290984,7 @@ let pp_error fmt err = -> "Uncurried function doesn't support optional arguments yet" | Expect_opt_in_bs_return_to_opt -> - "bs.return directive *_to_opt expect return type to be \n\ + "%@return directive *_to_opt expect return type to be \n\ syntax wise `_ option` for safety" | Not_supported_directive_in_bs_return @@ -290990,7 +290993,7 @@ let pp_error fmt err = | Illegal_attribute -> "Illegal attributes" | Canot_infer_arity_by_syntax - -> "Cannot infer the arity through the syntax, either [@bs.uncurry n] or \n\ + -> "Cannot infer the arity through the syntax, either [%@uncurry n] or \n\ write it in arrow syntax " | Inconsistent_arity (arity,n) -> Printf.sprintf "Inconsistent arity %d vs %d" arity n @@ -291001,7 +291004,7 @@ let pp_error fmt err = -> "unsupported predicates" | Conflict_bs_bs_this_bs_meth -> - "[@bs.this], [@bs], [@bs.meth] can not be applied at the same time" + "%@this, %@bs, %@meth can not be applied at the same time" | Duplicated_bs_deriving -> "duplicate bs.deriving attribute" | Conflict_attributes @@ -291010,7 +291013,7 @@ let pp_error fmt err = -> "expect string literal " | Duplicated_bs_as -> - "duplicate bs.as " + "duplicate %@as " | Expect_int_literal -> "expect int literal " @@ -291027,20 +291030,20 @@ let pp_error fmt err = "_ is not allowed in combination with external optional type" | Invalid_bs_string_type -> - "Not a valid type for [@bs.string]" + "Not a valid type for %@string" | Invalid_bs_int_type -> - "Not a valid type for [@bs.int]" + "Not a valid type for %@int" | Invalid_bs_unwrap_type -> - "Not a valid type for [@bs.unwrap]. Type must be an inline variant (closed), and\n\ + "Not a valid type for %@unwrap. Type must be an inline variant (closed), and\n\ each constructor must have an argument." | Conflict_ffi_attribute str -> "Conflicting FFI attributes found: " ^ str | Bs_this_simple_pattern -> - "[@bs.this] expect its pattern variable to be simple form") + "%@this expect its pattern variable to be simple form") type exn += Error of Location.t * error @@ -294032,6 +294035,10 @@ end = struct * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) +(** Warning unused bs attributes + Note if we warn `deriving` too, + it may fail third party ppxes +*) let is_bs_attribute txt = let len = String.length txt in len >= 2 && @@ -294117,7 +294124,7 @@ let emit_external_warnings : iterator= Ext_list.iter lbl.pld_attributes (fun attr -> match attr with - | {txt = "bs.as"}, _ -> mark_used_bs_attribute attr + | {txt = "bs.as" | "as"}, _ -> mark_used_bs_attribute attr | _ -> () ); default_iterator.label_declaration self lbl @@ -294488,7 +294495,7 @@ let add_signature k v = let rec iter_on_bs_config_stru (x :Parsetree.structure) = match x with | [] -> () - | {pstr_desc = Pstr_attribute (({txt = "bs.config"; loc}, payload) as attr)}::_ -> + | {pstr_desc = Pstr_attribute (({txt = "bs.config" | "config"; loc}, payload) as attr)}::_ -> Bs_ast_invariant.mark_used_bs_attribute attr; Ext_list.iter (Ast_payload.ident_or_record_as_config loc payload) (Ast_payload.table_dispatch !structural_config_table) @@ -294499,7 +294506,7 @@ let rec iter_on_bs_config_stru (x :Parsetree.structure) = let rec iter_on_bs_config_sigi (x :Parsetree.signature) = match x with | [] -> () - | {psig_desc = Psig_attribute (({txt = "bs.config"; loc}, payload) as attr)}::_ -> + | {psig_desc = Psig_attribute (({txt = "bs.config" | "config"; loc}, payload) as attr)}::_ -> Bs_ast_invariant.mark_used_bs_attribute attr; Ext_list.iter (Ast_payload.ident_or_record_as_config loc payload) (Ast_payload.table_dispatch !signature_config_table) @@ -354770,7 +354777,7 @@ type label = Types.label_description let find_name (attr : Parsetree.attribute) = match attr with - | {txt = "bs.as"}, PStr + | {txt = "bs.as" | "as"}, PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_constant (Pconst_string(s,_))},_ )}] -> Some s | _ -> None @@ -354779,7 +354786,7 @@ let find_name (attr : Parsetree.attribute) = let find_name_with_loc (attr : Parsetree.attribute) : string Asttypes.loc option = match attr with - | {txt = "bs.as";loc}, PStr + | {txt = "bs.as" | "as";loc}, PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_constant (Pconst_string(s,_))},_ )}] -> Some {txt = s; loc} | _ -> None @@ -354823,7 +354830,7 @@ let rec check_duplicated_labels_aux | Some ({txt = s;} as l) -> if Set_string.mem coll s (*use coll to make check a bit looser - allow cases like [ x : int [@bs.as "x"]] + allow cases like [ x : int [@as "x"]] *) then Some l else @@ -367666,21 +367673,21 @@ type attr = | Poly_var_string of { descr : (string * string) list - (* introduced by attributes bs.string - and bs.as + (* introduced by attributes @string + and @as *) } | Poly_var of { descr : (string * string) list option - (* introduced by attributes bs.string - and bs.as + (* introduced by attributes @string + and @as *) } (* `a does not have any value*) - | Int of (string * int ) list (* ([`a | `b ] [@bs.int])*) + | Int of (string * int ) list (* ([`a | `b ] [@int])*) | Arg_cst of cst - | Fn_uncurry_arity of int (* annotated with [@bs.uncurry ] or [@bs.uncurry 2]*) + | Fn_uncurry_arity of int (* annotated with [@uncurry ] or [@uncurry 2]*) (* maybe we can improve it as a combination of {!Asttypes.constant} and tuple *) | Extern_unit | Nothing @@ -368244,22 +368251,22 @@ type external_spec = (* let name_of_ffi ffi = match ffi with - | Js_get_index _scope -> "[@@bs.get_index ..]" - | Js_set_index _scope -> "[@@bs.set_index ..]" - | Js_get { js_get_name = s} -> Printf.sprintf "[@@bs.get %S]" s - | Js_set { js_set_name = s} -> Printf.sprintf "[@@bs.set %S]" s - | Js_call v -> Printf.sprintf "[@@bs.val %S]" v.name - | Js_send v -> Printf.sprintf "[@@bs.send %S]" v.name - | Js_module_as_fn v -> Printf.sprintf "[@@bs.val %S]" v.external_module_name.bundle - | Js_new v -> Printf.sprintf "[@@bs.new %S]" v.name + | Js_get_index _scope -> "@get_index .." + | Js_set_index _scope -> "@set_index .." + | Js_get { js_get_name = s} -> Printf.sprintf "[@@get %S]" s + | Js_set { js_set_name = s} -> Printf.sprintf "[@@set %S]" s + | Js_call v -> Printf.sprintf "[@@val %S]" v.name + | Js_send v -> Printf.sprintf "[@@send %S]" v.name + | Js_module_as_fn v -> Printf.sprintf "[@@val %S]" v.external_module_name.bundle + | Js_new v -> Printf.sprintf "[@@new %S]" v.name | Js_module_as_class v - -> Printf.sprintf "[@@bs.module] %S " v.bundle + -> Printf.sprintf "[@@module] %S " v.bundle | Js_module_as_var v -> - Printf.sprintf "[@@bs.module] %S " v.bundle - | Js_var v (* FIXME: could be [@@bs.module "xx"] as well *) + Printf.sprintf "[@@module] %S " v.bundle + | Js_var v (* FIXME: could be [@@module "xx"] as well *) -> - Printf.sprintf "[@@bs.val] %S " v.name *) + Printf.sprintf "[@@val] %S " v.name *) type return_wrapper = | Return_unset @@ -368329,7 +368336,7 @@ let valid_global_name ?loc txt = (* We loose such check (see #2583), - it also helps with the implementation deriving abstract [@bs.as] + it also helps with the implementation deriving abstract [@as] *) let valid_method_name ?loc:_ _txt = @@ -368536,7 +368543,7 @@ type call_info = | Call_ml (* called by plain ocaml expression *) | Call_builtin_runtime (* built-in externals *) | Call_na - (* either from [@@bs.val] or not available, + (* either from [@@val] or not available, such calls does not follow such rules {[ fun x y -> f x y === f ]} when [f] is an atom *) @@ -368594,7 +368601,7 @@ type call_info = | Call_ml (* called by plain ocaml expression *) | Call_builtin_runtime (* built-in externals *) | Call_na - (* either from [@@bs.val] or not available, + (* either from [@@val] or not available, such calls does not follow such rules {[ fun x y -> (f x y) === f ]} when [f] is an atom @@ -371157,8 +371164,8 @@ exception Not_simple_form where [wrap] used to be simple instructions Note that [external] functions are forced to do eta-conversion when combined with [|>] operator, we need to make sure beta-reduction - is applied though since `[@bs.splice]` needs such guarantee. - Since `[@bs.splice] is the tail position + is applied though since `[@variadic]` needs such guarantee. + Since `[@variadic] is the tail position *) let rec is_eta_conversion_exn params inner_args outer_args : t list = @@ -371689,7 +371696,7 @@ let sequand l r = if_ l r false_ (** only [handle_bs_non_obj_ffi] will be used outside *) (** [no_auto_uncurried_arg_types xs] - check if the FFI have [@@bs.uncurry] attribute. + check if the FFI have @uncurry attribute. if it does not we wrap it in a nomral way otherwise *) let rec no_auto_uncurried_arg_types @@ -391156,7 +391163,7 @@ val translate_ffi : (** TODO: document supported attributes Attributes starting with `js` are reserved - examples: "bs.splice" + examples: "variadic" *) end = struct @@ -391241,7 +391248,7 @@ let append_list x xs = unbox it in the first place. Note when optional value is not passed, the unboxed value would be - [undefined], with the combination of `[@bs.int]` it would be still be + [undefined], with the combination of `[@int]` it would be still be [undefined], this by default is still correct.. {[ (function () { @@ -391415,7 +391422,7 @@ let translate_scoped_module_val Ext_list.fold_left (Ext_list.append rest [fn]) start E.dot end | None -> - (* no [@@bs.module], assume it's global *) + (* no [@@module], assume it's global *) begin match scopes with | [] -> E.js_global fn @@ -391472,7 +391479,7 @@ let translate_ffi | Js_new { external_module_name = module_name; name = fn; scopes - } -> (* handle [@@bs.new]*) + } -> (* handle [@@new]*) (* This has some side effect, it will mark its identifier (If it has) as an object, ATTENTION: @@ -391519,7 +391526,7 @@ let translate_ffi begin match args with | self :: args -> (* PR2162 [self_type] more checks in syntax: - - should not be [bs.as] *) + - should not be [@as] *) let [@warning"-8"] ( _self_type::arg_types ) = arg_types in if splice then @@ -391545,7 +391552,7 @@ let translate_ffi (* TODO #11 1. check args -- error checking - 2. support [@@bs.scope "window"] + 2. support [@@scope "window"] we need know whether we should call [add_js_module] or not *) translate_scoped_module_val external_module_name name scopes @@ -393369,7 +393376,7 @@ let transform_under_supply n ap_info fn args = cautiously, since [let u = f] and we are chaning the arity of [f] it will affect the collection of [u] - A typical use case is to pass an OCaml function to JS side as a callback (i.e, [@bs.uncurry]) + A typical use case is to pass an OCaml function to JS side as a callback (i.e, [@uncurry]) *) let unsafe_adjust_to_arity loc ~(to_:int) ?(from : int option) (fn : Lam.t) : Lam.t = let ap_info : Lam.ap_info = {ap_loc = loc; ap_inlined = Default_inline; ap_status = App_na } in @@ -399003,7 +399010,7 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) : Lam.t * Lam_module_i ]} is also wrong. - It seems, we need handle [@bs.splice] earlier + It seems, we need handle [@variadic] earlier or {[ @@ -399011,7 +399018,7 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) : Lam.t * Lam_module_i let x0, x1, x2 =1,2,3 in (fun y -> f [|x0;x1;x2|] y) ]} - But this still need us to know [@bs.splice] in advance + But this still need us to know [@variadic] in advance we should not remove it immediately, since we have to be careful @@ -403806,7 +403813,7 @@ type ('a,'b) st = let process_method_attributes_rev (attrs : t) = Ext_list.fold_left attrs ({get = None ; set = None}, []) (fun (st,acc) (({txt ; loc}, payload) as attr ) -> match txt with - | "bs.get" (* [@@bs.get{null; undefined}]*) + | "bs.get" | "get" (* @bs.get{null; undefined}*) -> let result = Ext_list.fold_left (Ast_payload.ident_or_record_as_config loc payload) (false, false) @@ -403836,7 +403843,7 @@ let process_method_attributes_rev (attrs : t) = ({st with get = Some result}, acc ) - | "bs.set" + | "bs.set" | "set" -> let result = Ext_list.fold_left (Ast_payload.ident_or_record_as_config loc payload) `Get @@ -403851,7 +403858,7 @@ let process_method_attributes_rev (attrs : t) = else Bs_syntaxerr.err loc Unsupported_predicates ) in (* properties -- void - [@@bs.set{only}] + [@@set{only}] *) {st with set = Some result }, acc | _ -> @@ -403870,12 +403877,11 @@ let process_attributes_rev (attrs : t) : attr_kind * t = | "bs", (Nothing | Uncurry _) -> Uncurry attr, acc (* TODO: warn unused/duplicated attribute *) - | "bs.this", (Nothing | Meth_callback _) + | ("bs.this" | "this"), (Nothing | Meth_callback _) -> Meth_callback attr, acc - | "bs.meth", (Nothing | Method _) + | ("bs.meth" | "meth"), (Nothing | Method _) -> Method attr, acc - | "bs", _ - | "bs.this", _ + | ("bs" | "bs.this" | "this"), _ -> Bs_syntaxerr.err loc Conflict_bs_bs_this_bs_meth | _ , _ -> st, attr::acc @@ -403902,10 +403908,27 @@ let process_bs (attrs : t) = st, attr::acc ) +let external_attrs = [| + "get"; + "set"; + "get_index"; + "return"; + "obj"; + "val"; + "module"; + "scope"; + "variadic"; + "send"; + "new"; + "set_index"; + Literals.gentype_import +|] +(* ATT: Special cases for built-in attributes handling *) let external_needs_to_be_encoded (attrs : t)= Ext_list.exists_fst attrs (fun {txt} -> - Ext_string.starts_with txt "bs." || txt = Literals.gentype_import) + Ext_string.starts_with txt "bs." || + Ext_array.exists external_attrs (fun (x : string) -> txt = x) ) let is_inline : attr -> bool = (fun @@ -403925,24 +403948,26 @@ type derive_attr = { let process_derive_type (attrs : t) : derive_attr * t = Ext_list.fold_left attrs ({bs_deriving = None }, []) (fun (st, acc) ({txt ; loc}, payload as attr) -> - match st, txt with - | {bs_deriving = None}, "bs.deriving" - -> - { - bs_deriving = Some - (Ast_payload.ident_or_record_as_config loc payload)}, acc - | {bs_deriving = Some _}, "bs.deriving" - -> - Bs_syntaxerr.err loc Duplicated_bs_deriving - - | _ , _ -> - st, attr::acc + match txt with + | "bs.deriving" | "deriving" + -> + begin match st.bs_deriving with + | None -> + { + bs_deriving = Some + (Ast_payload.ident_or_record_as_config loc payload)}, acc + | Some _ + -> + Bs_syntaxerr.err loc Duplicated_bs_deriving + end + | _ -> + st, attr::acc ) -(* duplicated [bs.uncurry] [bs.string] not allowed, - it is worse in bs.uncurry since it will introduce +(* duplicated @uncurry @string not allowed, + it is worse in @uncurry since it will introduce inconsistency in arity *) let iter_process_bs_string_int_unwrap_uncurry (attrs : t) = @@ -403956,15 +403981,15 @@ let iter_process_bs_string_int_unwrap_uncurry (attrs : t) = else Bs_syntaxerr.err loc Conflict_attributes in Ext_list.iter attrs (fun (({txt ; loc=_}, (payload : _ ) ) as attr) -> match txt with - | "bs.string" + | "bs.string" | "string" -> assign `String attr - | "bs.int" + | "bs.int" | "int" -> assign `Int attr - | "bs.ignore" + | "bs.ignore" | "ignore" -> assign `Ignore attr - | "bs.unwrap" + | "bs.unwrap" | "unwrap" -> assign `Unwrap attr - | "bs.uncurry" + | "bs.uncurry" | "uncurry" -> assign (`Uncurry (Ast_payload.is_single_int payload)) attr | _ -> () @@ -403978,7 +404003,7 @@ let iter_process_bs_string_as (attrs : t) : string option = (fun (({txt ; loc}, payload ) as attr ) -> match txt with - | "bs.as" + | "bs.as" | "as" -> if !st = None then match Ast_payload.is_single_string payload with @@ -403998,7 +404023,7 @@ let has_bs_optional (attrs : t) : bool = Ext_list.exists attrs (fun (({txt ; }, _ ) as attr) -> match txt with - | "bs.optional" + | "bs.optional" | "optional" -> Bs_ast_invariant.mark_used_bs_attribute attr ; true @@ -404013,7 +404038,7 @@ let iter_process_bs_int_as (attrs : t) = (fun (({txt ; loc}, payload ) as attr) -> match txt with - | "bs.as" + | "bs.as" | "as" -> if !st = None then match Ast_payload.is_single_int payload with @@ -404037,7 +404062,7 @@ let iter_process_bs_string_or_int_as (attrs : Parsetree.attributes) = (fun (({txt ; loc}, payload ) as attr) -> match txt with - | "bs.as" + | "bs.as" | "as" -> if !st = None then (Bs_ast_invariant.mark_used_bs_attribute attr ; @@ -405663,7 +405688,7 @@ let typ_mapper | Uncurry attr , attrs -> attrs, attr +> ty | Method _, _ - -> Location.raise_errorf ~loc "bs.get/set conflicts with bs.meth" + -> Location.raise_errorf ~loc "%@get/set conflicts with %@meth" | Meth_callback attr, attrs -> attrs, attr +> ty in @@ -405675,7 +405700,7 @@ let typ_mapper | Uncurry attr, attrs -> attrs, attr +> ty | Method _, _ - -> Location.raise_errorf ~loc "bs.get/set conflicts with bs.meth" + -> Location.raise_errorf ~loc "%@get/set conflicts with %@meth" | Meth_callback attr, attrs -> attrs, attr +> ty in @@ -406345,7 +406370,7 @@ let map_row_fields_into_strings ptyp_loc let descr = if !has_bs_as then Some result else None in match has_payload, descr with | false, None -> - Location.prerr_warning ptyp_loc (Bs_ffi_warning "bs.string is redundant here, you can safely remove it"); + Location.prerr_warning ptyp_loc (Bs_ffi_warning "%@string is redundant here, you can safely remove it"); Nothing | false , Some descr -> External_arg_spec.Poly_var_string {descr } @@ -407556,7 +407581,7 @@ let refine_arg_type ~(nolabel:bool) (ptyp : Ast_core_type.t) match result with | None -> spec_of_ptyp nolabel ptyp - | Some cst -> (* (_[@bs.as ])*) + | Some cst -> (* (_[@as ])*) (* when ppx start dropping attributes we should warn, there is a trade off whether we should warn dropped non bs attribute or not @@ -407564,14 +407589,14 @@ let refine_arg_type ~(nolabel:bool) (ptyp : Ast_core_type.t) Bs_ast_invariant.warn_discarded_unused_attributes ptyp_attrs; begin match cst with | Int i -> - (* This type is used in bs.obj only to construct obj type*) + (* This type is used in obj only to construct obj type*) Arg_cst(External_arg_spec.cst_int i) | Str i-> Arg_cst (External_arg_spec.cst_string i) | Js_literal_str s -> Arg_cst (External_arg_spec.cst_obj_literal s) end - else (* ([`a|`b] [@bs.string]) *) + else (* ([`a|`b] [@string]) *) spec_of_ptyp nolabel ptyp ) @@ -407588,22 +407613,22 @@ let refine_obj_arg_type ~(nolabel:bool) (ptyp : Ast_core_type.t) match result with | None -> Bs_syntaxerr.err ptyp.ptyp_loc Invalid_underscore_type_in_external - | Some (Int i) -> (* (_[@bs.as ])*) - (* This type is used in bs.obj only to construct obj type*) + | Some (Int i) -> (* (_[@as ])*) + (* This type is used in obj only to construct obj type*) Arg_cst(External_arg_spec.cst_int i) | Some (Str i)-> Arg_cst (External_arg_spec.cst_string i) | Some (Js_literal_str s ) -> Arg_cst (External_arg_spec.cst_obj_literal s) - else (* ([`a|`b] [@bs.string]) *) + else (* ([`a|`b] [@string]) *) spec_of_ptyp nolabel ptyp (** Given the type of argument, process its [bs.] attribute and new type, The new type is currently used to reconstruct the external type - and result type in [@@bs.obj] + and result type in [@@obj] They are not the same though, for example {[ - external f : hi:([ `hi | `lo ] [@bs.string]) -> unit -> _ = "" [@@bs.obj] + external f : hi:([ `hi | `lo ] [@string]) -> unit -> _ = "" [@@obj] ]} The result type would be [ hi:string ] *) @@ -407611,20 +407636,20 @@ let get_opt_arg_type ~(nolabel : bool) (ptyp : Ast_core_type.t) : External_arg_spec.attr = - if ptyp.ptyp_desc = Ptyp_any then (* (_[@bs.as ])*) - (* extenral f : ?x:_ -> y:int -> _ = "" [@@bs.obj] is not allowed *) + if ptyp.ptyp_desc = Ptyp_any then (* (_[@as ])*) + (* extenral f : ?x:_ -> y:int -> _ = "" [@@obj] is not allowed *) Bs_syntaxerr.err ptyp.ptyp_loc Invalid_underscore_type_in_external; - (* ([`a|`b] [@bs.string]) *) + (* ([`a|`b] [@@string]) *) spec_of_ptyp nolabel ptyp (** - [@@bs.module "react"] - [@@bs.module "react"] + [@@module "react"] + [@@module "react"] --- - [@@bs.module "@" "react"] - [@@bs.module "@" "react"] + [@@module "@" "react"] + [@@module "@" "react"] They should have the same module name @@ -407632,7 +407657,7 @@ let get_opt_arg_type two external files to the same module name *) type bundle_source = - [`Nm_payload of string (* from payload [@@bs.val "xx" ]*) + [`Nm_payload of string (* from payload [@@val "xx" ]*) |`Nm_external of string (* from "" in external *) | `Nm_val of string lazy_t (* from function name *) ] @@ -407704,6 +407729,7 @@ let return_wrapper loc (txt : string) : External_ffi_types.return_wrapper = | _ -> Bs_syntaxerr.err loc Not_supported_directive_in_bs_return +exception Not_handled_external_attribute (* The processed attributes will be dropped *) let parse_external_attributes @@ -407712,15 +407738,15 @@ let parse_external_attributes (prim_name_or_pval_prim: bundle_source ) (prim_attributes : Ast_attributes.t) : Ast_attributes.t * external_desc = - (* shared by `[@@bs.val]`, `[@@bs.send]`, - `[@@bs.set]`, `[@@bs.get]` , `[@@bs.new]` + (* shared by `[@@val]`, `[@@send]`, + `[@@set]`, `[@@get]` , `[@@new]` `[@@bs.send.pipe]` does not use it *) let name_from_payload_or_prim ~loc (payload : Parsetree.payload) : name_source = match payload with | PStr [] -> (prim_name_or_pval_prim :> name_source) - (* It is okay to have [@@bs.val] without payload *) + (* It is okay to have [@@val] without payload *) | _ -> begin match Ast_payload.is_single_string payload with | Some (val_name, _) -> `Nm_payload val_name @@ -407739,15 +407765,15 @@ let parse_external_attributes in attr::attrs, {st with external_module_name = Some { bundle; module_bind_name = Phint_nothing}} - else if Ext_string.starts_with txt "bs." then - attrs, begin match txt with - | "bs.val" -> + else + let action () = begin match txt with + | "bs.val" | "val" -> if no_arguments then {st with val_name = name_from_payload_or_prim ~loc payload} else {st with call_name = name_from_payload_or_prim ~loc payload} - | "bs.module" -> + | "bs.module" | "module" -> begin match Ast_payload.assert_strings loc payload with | [bundle] -> {st with external_module_name = @@ -407767,7 +407793,7 @@ let parse_external_attributes | _ -> Bs_syntaxerr.err loc Illegal_attribute end - | "bs.scope" -> + | "bs.scope" | "scope" -> begin match Ast_payload.assert_strings loc payload with | [] -> Bs_syntaxerr.err loc Illegal_attribute @@ -407776,27 +407802,29 @@ let parse_external_attributes *) | scopes -> { st with scopes = scopes } end - | "bs.splice" | "bs.variadic" -> {st with splice = true} - | "bs.send" -> + | "bs.splice" + | "bs.variadic" | "variadic" -> {st with splice = true} + | "bs.send" | "send" -> { st with val_send = name_from_payload_or_prim ~loc payload} | "bs.send.pipe" -> { st with val_send_pipe = Some (Ast_payload.as_core_type loc payload)} - | "bs.set" -> + | "bs.set" | "set" -> {st with set_name = name_from_payload_or_prim ~loc payload} - | "bs.get" -> {st with get_name = name_from_payload_or_prim ~loc payload} + | "bs.get" | "get" -> + {st with get_name = name_from_payload_or_prim ~loc payload} - | "bs.new" -> {st with new_name = name_from_payload_or_prim ~loc payload} - | "bs.set_index" -> + | "bs.new" | "new" -> {st with new_name = name_from_payload_or_prim ~loc payload} + | "bs.set_index" | "set_index" -> if String.length prim_name_check <> 0 then - Location.raise_errorf ~loc "[@@bs.set_index] this particular external's name needs to be a placeholder empty string"; + Location.raise_errorf ~loc "%@set_index this particular external's name needs to be a placeholder empty string"; {st with set_index = true} - | "bs.get_index"-> + | "bs.get_index" | "get_index" -> if String.length prim_name_check <> 0 then - Location.raise_errorf ~loc "[@@bs.get_index] this particular external's name needs to be a placeholder empty string"; + Location.raise_errorf ~loc "%@get_index this particular external's name needs to be a placeholder empty string"; {st with get_index = true} - | "bs.obj" -> {st with mk_obj = true} - | "bs.return" -> + | "bs.obj" | "obj" -> {st with mk_obj = true} + | "bs.return" | "return" -> let actions = Ast_payload.ident_or_record_as_config loc payload in begin match actions with @@ -407805,15 +407833,16 @@ let parse_external_attributes | _ -> Bs_syntaxerr.err loc Not_supported_directive_in_bs_return end - | _ -> (Location.prerr_warning loc (Bs_unused_attribute txt); st) - end - else attr :: attrs, st + | _ -> raise_notrace Not_handled_external_attribute + end in + try attrs, action () with + | Not_handled_external_attribute -> attr::attrs, st ) let has_bs_uncurry (attrs : Ast_attributes.t) = - Ext_list.exists_fst attrs (fun x -> x.txt = "bs.uncurry") + Ext_list.exists_fst attrs (fun {txt;loc=_} -> txt = "bs.uncurry" || txt = "uncurry") let check_return_wrapper @@ -407873,11 +407902,11 @@ let process_obj set_index = false ; mk_obj = _; scopes = []; - (* wrapper does not work with [bs.obj] + (* wrapper does not work with @obj TODO: better error message *) } -> if String.length prim_name <> 0 then - Location.raise_errorf ~loc "[@@bs.obj] expect external names to be empty string"; + Location.raise_errorf ~loc "%@obj expect external names to be empty string"; let arg_kinds, new_arg_types_ty, (result_types : Parsetree.object_field list) = Ext_list.fold_right arg_types_ty ( [], [], []) (fun param_type ( arg_labels, (arg_types : Ast_compatible.param_type list), result_types) -> @@ -407923,15 +407952,15 @@ let process_obj (Otag({Asttypes.txt = name; loc}, [], Ast_literal.type_string ~loc ()) :: result_types) | Fn_uncurry_arity _ -> Location.raise_errorf ~loc - "The combination of [@@bs.obj], [@@bs.uncurry] is not supported yet" + "The combination of %@obj, %@uncurry is not supported yet" | Extern_unit -> assert false | Poly_var _ -> Location.raise_errorf ~loc - "bs.obj label %s does not support such arg type" name + "%@obj label %s does not support such arg type" name | Unwrap -> Location.raise_errorf ~loc - "bs.obj label %s does not support [@bs.unwrap] arguments" name + "%@obj label %s does not support %@unwrap arguments" name end | Optional name -> let obj_arg_type = get_opt_arg_type ~nolabel:false ty in @@ -407956,18 +407985,18 @@ let process_obj (Otag ({Asttypes.txt = name; loc}, [], Ast_comb.to_undefined_type loc @@ Ast_literal.type_string ~loc ()) :: result_types) | Arg_cst _ -> - Location.raise_errorf ~loc "bs.as is not supported with optional yet" + Location.raise_errorf ~loc "%@as is not supported with optional yet" | Fn_uncurry_arity _ -> Location.raise_errorf ~loc - "The combination of [@@bs.obj], [@@bs.uncurry] is not supported yet" + "The combination of %@obj, %@uncurry is not supported yet" | Extern_unit -> assert false | Poly_var _ -> Location.raise_errorf ~loc - "bs.obj label %s does not support such arg type" name + "%@obj label %s does not support such arg type" name | Unwrap -> Location.raise_errorf ~loc - "bs.obj label %s does not support [@bs.unwrap] arguments" name + "%@obj label %s does not support %@unwrap arguments" name end in new_arg_label::arg_labels, @@ -407984,7 +408013,7 @@ let process_obj in Ast_compatible.mk_fn_type new_arg_types_ty result, External_ffi_types.ffi_obj_create arg_kinds - | _ -> Location.raise_errorf ~loc "Attribute found that conflicts with [@@bs.obj]" + | _ -> Location.raise_errorf ~loc "Attribute found that conflicts with %@obj" let external_desc_of_non_obj @@ -408017,9 +408046,9 @@ let external_desc_of_non_obj if arg_type_specs_length = 3 then Js_set_index {js_set_index_scopes = scopes} else - Location.raise_errorf ~loc "Ill defined attribute [@@bs.set_index](arity of 3)" + Location.raise_errorf ~loc "Ill defined attribute %@set_index (arity of 3)" | {set_index = true; _} -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.set_index]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@set_index") | {get_index = true; val_name = `Nm_na; external_module_name = None ; @@ -408040,10 +408069,10 @@ let external_desc_of_non_obj if arg_type_specs_length = 2 then Js_get_index {js_get_index_scopes = scopes} else Location.raise_errorf ~loc - "Ill defined attribute [@@bs.get_index] (arity expected 2 : while %d)" arg_type_specs_length + "Ill defined attribute %@get_index (arity expected 2 : while %d)" arg_type_specs_length | {get_index = true; _} -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.get_index]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@get_index") | {module_as_val = Some external_module_name ; get_index = false; @@ -408066,17 +408095,17 @@ let external_desc_of_non_obj | [], `Nm_na, _ -> Js_module_as_var external_module_name | _, `Nm_na, _ -> Js_module_as_fn {splice; external_module_name } | _, #bundle_source, #bundle_source -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.module].") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@module.") | _, (`Nm_val _ | `Nm_external _) , `Nm_na -> Js_module_as_class external_module_name | _, `Nm_payload _ , `Nm_na -> Location.raise_errorf ~loc - "Incorrect FFI attribute found: (bs.new should not carry a payload here)" + "Incorrect FFI attribute found: (%@new should not carry a payload here)" end | {module_as_val = Some _; _} -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.module].") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@module.") | {call_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name) ; splice; scopes ; @@ -408098,7 +408127,7 @@ let external_desc_of_non_obj Js_call {splice; name; external_module_name; scopes } | {call_name = #bundle_source ; _ } -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.val]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@val") | {val_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name); external_module_name; @@ -408119,13 +408148,13 @@ let external_desc_of_non_obj -> (* if no_arguments --> {[ - external ff : int = "" [@@bs.val] + external ff : int = "" [@@val] ]} *) Js_var { name; external_module_name; scopes} | {val_name = #bundle_source ; _ } -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.val]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@val") | {splice ; scopes ; @@ -408148,7 +408177,7 @@ let external_desc_of_non_obj if arg_type_specs_length = 0 then (* {[ - external ff : int = "" [@@bs.module "xx"] + external ff : int = "" [@@module "xx"] ]} *) Js_var { name; external_module_name; scopes} @@ -408170,21 +408199,21 @@ let external_desc_of_non_obj return_wrapper = _ ; } -> (* PR #2162 - since when we assemble arguments the first argument in - [@@bs.send] is ignored + [@@send] is ignored *) begin match arg_type_specs with | [] -> Location.raise_errorf - ~loc "Ill defined attribute [@@bs.send] (the external needs to be a regular function call with at least one argument)" + ~loc "Ill defined attribute %@send(the external needs to be a regular function call with at least one argument)" | {arg_type = Arg_cst _ ; arg_label = _} :: _ -> Location.raise_errorf - ~loc "Ill defined attribute [@@bs.send] (first argument can't be const)" + ~loc "Ill defined attribute %@send(first argument can't be const)" | _ :: _ -> Js_send {splice ; name; js_send_scopes = scopes ; pipe = false} end | {val_send = #bundle_source; _ } - -> Location.raise_errorf ~loc "You used a FFI attribute that can't be used with [@@bs.send]" + -> Location.raise_errorf ~loc "You used a FFI attribute that can't be used with %@send" | {val_send_pipe = Some _; (* splice = (false as splice); *) val_send = `Nm_na; @@ -408209,7 +408238,7 @@ let external_desc_of_non_obj pipe = true} | {val_send_pipe = Some _ ; _} - -> Location.raise_errorf ~loc "conflict attributes found with [@@bs.send.pipe]" + -> Location.raise_errorf ~loc "conflict attributes found with [%@%@bs.send.pipe]" | {new_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name); external_module_name; @@ -408230,7 +408259,7 @@ let external_desc_of_non_obj } -> Js_new {name; external_module_name; scopes} | {new_name = #bundle_source ; _ } -> - Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with [@@bs.new]") + Bs_syntaxerr.err loc (Conflict_ffi_attribute "Attribute found that conflicts with %@new") | {set_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name); val_name = `Nm_na ; call_name = `Nm_na ; @@ -408250,9 +408279,9 @@ let external_desc_of_non_obj -> if arg_type_specs_length = 2 then Js_set { js_set_scopes = scopes ; js_set_name = name} - else Location.raise_errorf ~loc "Ill defined attribute [@@bs.set] (two args required)" + else Location.raise_errorf ~loc "Ill defined attribute %@set (two args required)" | {set_name = #bundle_source; _} - -> Location.raise_errorf ~loc "conflict attributes found with [@@bs.set]" + -> Location.raise_errorf ~loc "conflict attributes found with %@set" | {get_name = (`Nm_val lazy name | `Nm_external name | `Nm_payload name); val_name = `Nm_na ; @@ -408274,9 +408303,9 @@ let external_desc_of_non_obj if arg_type_specs_length = 1 then Js_get { js_get_name = name; js_get_scopes = scopes } else - Location.raise_errorf ~loc "Ill defined attribute [@@bs.get] (only one argument)" + Location.raise_errorf ~loc "Ill defined attribute %@bs.get (only one argument)" | {get_name = #bundle_source; _} - -> Location.raise_errorf ~loc "Attribute found that conflicts with [@@bs.get]" + -> Location.raise_errorf ~loc "Attribute found that conflicts with %@bs.get" | {get_name = `Nm_na; val_name = `Nm_na ; @@ -408295,7 +408324,7 @@ let external_desc_of_non_obj return_wrapper = _; } - -> Location.raise_errorf ~loc "Could not infer which FFI category it belongs to, maybe you forgot [%@%@bs.val]? " + -> Location.raise_errorf ~loc "Could not infer which FFI category it belongs to, maybe you forgot %@val? " (** Note that the passed [type_annotation] is already processed by visitor pattern before*) let handle_attributes @@ -408307,12 +408336,12 @@ let handle_attributes : Parsetree.core_type * External_ffi_types.t * Parsetree.attributes * bool = (** sanity check here - {[ int -> int -> (int -> int -> int [@bs.uncurry])]} + {[ int -> int -> (int -> int -> int [@uncurry])]} It does not make sense *) if has_bs_uncurry type_annotation.ptyp_attributes then Location.raise_errorf - ~loc "[@@bs.uncurry] can not be applied to the whole definition"; + ~loc "%@uncurry can not be applied to the whole definition"; let prim_name_or_pval_name = if String.length prim_name = 0 then `Nm_val (lazy (Location.prerr_warning loc (Bs_fragile_external pval_name); pval_name)) @@ -408323,7 +408352,7 @@ let handle_attributes if has_bs_uncurry result_type.ptyp_attributes then Location.raise_errorf ~loc:result_type.ptyp_loc - "[@@bs.uncurry] can not be applied to tailed position"; + "%@uncurry can not be applied to tailed position"; let no_arguments = arg_types_ty = [] in let unused_attrs, external_desc = parse_external_attributes no_arguments @@ -408341,7 +408370,7 @@ let handle_attributes let arg_type = refine_arg_type ~nolabel:true obj in begin match arg_type with | Arg_cst _ -> - Location.raise_errorf ~loc:obj.ptyp_loc "[@bs.as] is not supported in bs.send type " + Location.raise_errorf ~loc:obj.ptyp_loc "%@as is not supported in %@send type " | _ -> (* more error checking *) [{arg_label = Arg_empty; arg_type}], @@ -408359,17 +408388,17 @@ let handle_attributes if i = 0 && splice then begin match arg_label with | Optional _ -> - Location.raise_errorf ~loc "[@@@@bs.splice] expect the last type to be a non optional" + Location.raise_errorf ~loc "%@variadic expect the last type to be a non optional" | Labelled _ | Nolabel -> if ty.ptyp_desc = Ptyp_any then - Location.raise_errorf ~loc "[@@@@bs.splice] expect the last type to be an array"; + Location.raise_errorf ~loc "%@variadic expect the last type to be an array"; if spec_of_ptyp true ty <> Nothing then - Location.raise_errorf ~loc "[@@@@bs.splice] expect the last type to be an array"; + Location.raise_errorf ~loc "%@variadic expect the last type to be an array"; match ty.ptyp_desc with | Ptyp_constr({txt = Lident "array"; _}, [_]) -> () - | _ -> Location.raise_errorf ~loc "[@@@@bs.splice] expect the last type to be an array"; + | _ -> Location.raise_errorf ~loc "%@variadic expect the last type to be an array"; end ; let (arg_label : External_arg_spec.label_noname), arg_type, new_arg_types = match arg_label with @@ -408377,10 +408406,10 @@ let handle_attributes let arg_type = get_opt_arg_type ~nolabel:false ty in begin match arg_type with | Poly_var _ -> - (* ?x:([`x of int ] [@bs.string]) does not make sense *) + (* ?x:([`x of int ] [@string]) does not make sense *) Location.raise_errorf ~loc - "[@@bs.string] does not work with optional when it has arities in label %s" s + "%@string does not work with optional when it has arities in label %s" s | _ -> Arg_optional, arg_type, param_type :: arg_types end @@ -408562,7 +408591,7 @@ end = struct open Ast_helper -(* Handling `fun [@bs.this]` used in `object [@bs] end` *) +(* Handling `fun [@this]` used in `object [@bs] end` *) let to_method_callback loc (self : Bs_ast_mapper.mapper) label pat body : Parsetree.expression_desc = @@ -408793,8 +408822,8 @@ let ocaml_obj_as_js_object (** we need calculate the real object type and exposed object type, in some cases there are equivalent - for public object type its [@bs.meth] it does not depend on itself - while for label argument it is [@bs.this] which depends internal object + for public object type its [@meth] it does not depend on itself + while for label argument it is [@this] which depends internal object *) let (internal_label_attr_types : Parsetree.object_field list), (public_label_attr_types : Parsetree.object_field list) = @@ -410332,7 +410361,6 @@ let newTdcls - let handleTdclsInSigi (self : Bs_ast_mapper.mapper) (sigi : Parsetree.signature_item) @@ -410348,9 +410376,7 @@ let handleTdclsInSigi let newTdclsNewAttrs = self.type_declaration_list self originalTdclsNewAttrs in let kind = Ast_derive_abstract.isAbstract actions in if kind <> Not_abstract then - let codes = Ast_derive_abstract.handleTdclsInSig ~light:(kind = Light_abstract) rf originalTdclsNewAttrs in - Ast_signature.fuseAll ~loc ( Sig.include_ ~loc @@ -410358,9 +410384,7 @@ let handleTdclsInSigi (Mty.typeof_ ~loc (Mod.constraint_ ~loc (Mod.structure ~loc [ - Ast_compatible.rec_type_str ~loc rf newTdclsNewAttrs - ] ) (Mty.signature ~loc [])) ) ) :: (* include module type of struct [processed_code for checking like invariance ]end *) @@ -410398,7 +410422,6 @@ let handleTdclsInStru in let kind = Ast_derive_abstract.isAbstract actions in if kind <> Not_abstract then - let codes = Ast_derive_abstract.handleTdclsInStr ~light:(kind = Light_abstract) rf originalTdclsNewAttrs in (* use [tdcls2] avoid nonterminating *) @@ -410407,8 +410430,6 @@ let handleTdclsInStru Ast_structure.constraint_ ~loc [newStr] [] :: (* [include struct end : sig end] for error checking *) self.structure self codes) - - else Ast_structure.fuseAll ~loc (newStr :: @@ -410756,7 +410777,7 @@ let expr_mapper (self : mapper) (e : Parsetree.expression) = pexp_desc = Ast_uncurry_gen.to_uncurry_fn e.pexp_loc self label pat body ; pexp_attributes} | Method _ , _ - -> Location.raise_errorf ~loc:e.pexp_loc "bs.meth is not supported in function expression" + -> Location.raise_errorf ~loc:e.pexp_loc "%@meth is not supported in function expression" | Meth_callback _, pexp_attributes -> (** FIXME: does it make sense to have a label for [this] ? *) @@ -410782,7 +410803,7 @@ let expr_mapper (self : mapper) (e : Parsetree.expression) = } | Some e -> Location.raise_errorf - ~loc:e.pexp_loc "`with` construct is not supported in bs.obj ") + ~loc:e.pexp_loc "`with` construct is not supported in js obj ") else default_expr_mapper self e | Pexp_object {pcstr_self; pcstr_fields} -> @@ -411020,7 +411041,7 @@ let structure_item_mapper (self : mapper) (str : Parsetree.structure_item) = | _ -> { str with pstr_desc = Pstr_value(Nonrecursive, [{pvb_pat ; pvb_expr; pvb_attributes; pvb_loc}])} end - | Pstr_attribute({txt = "bs.config" },_) -> str + | Pstr_attribute({txt = "bs.config" | "config" },_) -> str | _ -> default_mapper.structure_item self str @@ -415217,14 +415238,14 @@ and print_simple_out_type ppf = let res = if name = "arity0" then Otyp_arrow ("", Otyp_constr (Oide_ident "unit", []),ty) else ty in - fprintf ppf "@[<0>(%a)@ [@bs.meth]@]" (print_out_type_1 ~uncurried:false) res + fprintf ppf "@[<0>(%a)@ [%@meth]@]" (print_out_type_1 ~uncurried:false) res | Otyp_constr ( Oide_dot (Oide_dot ( Oide_ident "Js_OO", "Callback" ), _), [res] ) -> - fprintf ppf "@[<0>(%a)@ [@bs.this]@]" (print_out_type_1 ~uncurried:false) res + fprintf ppf "@[<0>(%a)@ [%@this]@]" (print_out_type_1 ~uncurried:false) res (* also BuckleScript-specific. Turns Js.t({. foo: bar}) into {. "foo": bar} *) | Otyp_constr (