diff --git a/jscomp/common/bs_version.ml b/jscomp/common/bs_version.ml index 5904f82214..68d43aa5a5 100644 --- a/jscomp/common/bs_version.ml +++ b/jscomp/common/bs_version.ml @@ -22,8 +22,8 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -let version = "2.2.1" +let version = "2.2.2" let header = - "// Generated by BUCKLESCRIPT VERSION 2.2.1, PLEASE EDIT WITH CARE" + "// Generated by BUCKLESCRIPT VERSION 2.2.2, PLEASE EDIT WITH CARE" let package_name = "bs-platform" \ No newline at end of file diff --git a/jscomp/others/belt_List.ml b/jscomp/others/belt_List.ml index 0581c3de16..5147516f0e 100644 --- a/jscomp/others/belt_List.ml +++ b/jscomp/others/belt_List.ml @@ -407,6 +407,11 @@ let toArray ( x : _ t) = fillAux arr 0 x; arr +let shuffle xs = + let v = toArray xs in + A.shuffleInPlace v ; + ofArray v + let rec fillAuxMap arr i x f = match x with | [] -> () diff --git a/jscomp/others/belt_List.mli b/jscomp/others/belt_List.mli index 6f826cd10c..8c80617e68 100644 --- a/jscomp/others/belt_List.mli +++ b/jscomp/others/belt_List.mli @@ -126,6 +126,12 @@ val makeBy: int -> (int -> 'a) -> 'a t ]} *) +val shuffle: 'a t -> 'a t +(** [shuffle xs] + @return a new list in random order +*) + + val drop: 'a t -> int -> 'a t option (** [drop xs n] diff --git a/jscomp/others/js_null_undefined.ml b/jscomp/others/js_null_undefined.ml index 0f10ce0a57..c4d10ad0d4 100644 --- a/jscomp/others/js_null_undefined.ml +++ b/jscomp/others/js_null_undefined.ml @@ -25,6 +25,7 @@ (** Contains functionality for dealing with values that can be both [null] and [undefined] *) type + 'a t = 'a Js.nullable +external toOption : 'a t -> 'a option = "#null_undefined_to_opt" external to_opt : 'a t -> 'a option = "#null_undefined_to_opt" external return : 'a -> 'a t = "%identity" external test : 'a t -> bool = "#is_nil_undef" @@ -41,7 +42,9 @@ let iter x f = | None -> () | Some x -> f x [@bs] -let from_opt x = +let fromOption x = match x with | None -> undefined | Some x -> return x + +let from_opt = fromOption \ No newline at end of file diff --git a/jscomp/others/js_null_undefined.mli b/jscomp/others/js_null_undefined.mli index 2c05960c10..6dd23b350c 100644 --- a/jscomp/others/js_null_undefined.mli +++ b/jscomp/others/js_null_undefined.mli @@ -74,7 +74,10 @@ val iter : 'a t -> ('a -> unit [@bs]) -> unit %} *) -val from_opt : 'a option -> 'a t +val fromOption : 'a option -> 'a t + +val from_opt: 'a option -> 'a t +[@@ocaml.deprecated "Use fromOption instead"] (** Maps ['a Js.null_undefined] to ['a option] @@ -86,4 +89,7 @@ val from_opt : 'a option -> 'a t %} *) +external toOption : 'a t -> 'a option = "#null_undefined_to_opt" + external to_opt : 'a t -> 'a option = "#null_undefined_to_opt" +[@@ocaml.deprecated "Use toOption instead"] \ No newline at end of file diff --git a/jscomp/xwatcher/xwatcher.js b/jscomp/xwatcher/xwatcher.js index 14d91574ab..01f6d9c2a4 100644 --- a/jscomp/xwatcher/xwatcher.js +++ b/jscomp/xwatcher/xwatcher.js @@ -1,4 +1,4 @@ -'use strict'; + import * as Path from "path"; import * as Js_option from "../../lib/es6/js_option.js"; diff --git a/jscomp/xwatcher/xwatcher_current.js b/jscomp/xwatcher/xwatcher_current.js index 690f790f3c..8ff608bc3b 100644 --- a/jscomp/xwatcher/xwatcher_current.js +++ b/jscomp/xwatcher/xwatcher_current.js @@ -1,4 +1,4 @@ -'use strict'; + import * as Fs from "fs"; import * as Path from "path"; diff --git a/jscomp/xwatcher/xwatcher_util.js b/jscomp/xwatcher/xwatcher_util.js index 4b0b971f62..1299df3758 100644 --- a/jscomp/xwatcher/xwatcher_util.js +++ b/jscomp/xwatcher/xwatcher_util.js @@ -1,4 +1,4 @@ -'use strict'; + import * as Fs from "fs"; import * as Path from "path"; diff --git a/lib/bsb.darwin b/lib/bsb.darwin new file mode 100755 index 0000000000..4de9b731d2 Binary files /dev/null and b/lib/bsb.darwin differ diff --git a/lib/bsb.ml b/lib/bsb.ml index 9d7edb9a70..1d30095557 100644 --- a/lib/bsb.ml +++ b/lib/bsb.ml @@ -55,9 +55,9 @@ end = struct * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -let version = "2.2.1" +let version = "2.2.2" let header = - "// Generated by BUCKLESCRIPT VERSION 2.2.1, PLEASE EDIT WITH CARE" + "// Generated by BUCKLESCRIPT VERSION 2.2.2, PLEASE EDIT WITH CARE" let package_name = "bs-platform" end diff --git a/lib/bsb.win b/lib/bsb.win new file mode 100644 index 0000000000..75d9898b9e Binary files /dev/null and b/lib/bsb.win differ diff --git a/lib/bsb_helper.darwin b/lib/bsb_helper.darwin new file mode 100755 index 0000000000..e2e4a768f0 Binary files /dev/null and b/lib/bsb_helper.darwin differ diff --git a/lib/bsb_helper.ml b/lib/bsb_helper.ml index fa5854ae8a..7cc6a82618 100644 --- a/lib/bsb_helper.ml +++ b/lib/bsb_helper.ml @@ -177,9 +177,9 @@ end = struct * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -let version = "2.2.1" +let version = "2.2.2" let header = - "// Generated by BUCKLESCRIPT VERSION 2.2.1, PLEASE EDIT WITH CARE" + "// Generated by BUCKLESCRIPT VERSION 2.2.2, PLEASE EDIT WITH CARE" let package_name = "bs-platform" end diff --git a/lib/bsb_helper.win b/lib/bsb_helper.win new file mode 100644 index 0000000000..32a3990063 Binary files /dev/null and b/lib/bsb_helper.win differ diff --git a/lib/bsc.darwin b/lib/bsc.darwin new file mode 100755 index 0000000000..e906ebba06 Binary files /dev/null and b/lib/bsc.darwin differ diff --git a/lib/bsc.win b/lib/bsc.win new file mode 100644 index 0000000000..c05439a953 Binary files /dev/null and b/lib/bsc.win differ diff --git a/lib/bsdep.ml b/lib/bsdep.ml index 5dec84995a..242ec61058 100644 --- a/lib/bsdep.ml +++ b/lib/bsdep.ml @@ -55,9 +55,9 @@ end = struct * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -let version = "2.2.1" +let version = "2.2.2" let header = - "// Generated by BUCKLESCRIPT VERSION 2.2.1, PLEASE EDIT WITH CARE" + "// Generated by BUCKLESCRIPT VERSION 2.2.2, PLEASE EDIT WITH CARE" let package_name = "bs-platform" end diff --git a/lib/bsppx.darwin b/lib/bsppx.darwin new file mode 100755 index 0000000000..f708da8ff4 Binary files /dev/null and b/lib/bsppx.darwin differ diff --git a/lib/bsppx.ml b/lib/bsppx.ml index 564a86d50c..46a232955e 100644 --- a/lib/bsppx.ml +++ b/lib/bsppx.ml @@ -15823,9 +15823,9 @@ end = struct * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -let version = "2.2.1" +let version = "2.2.2" let header = - "// Generated by BUCKLESCRIPT VERSION 2.2.1, PLEASE EDIT WITH CARE" + "// Generated by BUCKLESCRIPT VERSION 2.2.2, PLEASE EDIT WITH CARE" let package_name = "bs-platform" end diff --git a/lib/bsppx.win b/lib/bsppx.win new file mode 100644 index 0000000000..67dca7b586 Binary files /dev/null and b/lib/bsppx.win differ diff --git a/lib/es6/js_typed_array.js b/lib/es6/js_typed_array.js index 846cab8cea..d67bd49727 100644 --- a/lib/es6/js_typed_array.js +++ b/lib/es6/js_typed_array.js @@ -1,4 +1,4 @@ -'use strict'; + var ArrayBuffer = /* module */[]; diff --git a/lib/js/belt_List.js b/lib/js/belt_List.js index c31a378b3c..9f19633aaf 100644 --- a/lib/js/belt_List.js +++ b/lib/js/belt_List.js @@ -692,6 +692,12 @@ function toArray(x) { return arr; } +function shuffle(xs) { + var v = toArray(xs); + Belt_Array.shuffleInPlace(v); + return ofArray(v); +} + function reverseConcat(_l1, _l2) { while(true) { var l2 = _l2; @@ -1463,6 +1469,7 @@ exports.getExn = getExn; exports.make = make; exports.makeByU = makeByU; exports.makeBy = makeBy; +exports.shuffle = shuffle; exports.drop = drop; exports.take = take; exports.splitAt = splitAt; diff --git a/lib/js/js_null_undefined.js b/lib/js/js_null_undefined.js index fc2c6c3c05..ff1d11d361 100644 --- a/lib/js/js_null_undefined.js +++ b/lib/js/js_null_undefined.js @@ -17,7 +17,7 @@ function iter(x, f) { } } -function from_opt(x) { +function fromOption(x) { if (x) { return x[0]; } else { @@ -25,7 +25,10 @@ function from_opt(x) { } } +var from_opt = fromOption; + exports.bind = bind; exports.iter = iter; +exports.fromOption = fromOption; exports.from_opt = from_opt; /* No side effect */ diff --git a/lib/reactjs_jsx_ppx_2.darwin b/lib/reactjs_jsx_ppx_2.darwin new file mode 100755 index 0000000000..3254e85a29 Binary files /dev/null and b/lib/reactjs_jsx_ppx_2.darwin differ diff --git a/lib/reactjs_jsx_ppx_2.win b/lib/reactjs_jsx_ppx_2.win new file mode 100644 index 0000000000..47cf071dca Binary files /dev/null and b/lib/reactjs_jsx_ppx_2.win differ diff --git a/lib/refmt.darwin b/lib/refmt.darwin new file mode 100755 index 0000000000..b7bfaf9d5c Binary files /dev/null and b/lib/refmt.darwin differ diff --git a/lib/refmt.win b/lib/refmt.win new file mode 100644 index 0000000000..1f0daae26c Binary files /dev/null and b/lib/refmt.win differ diff --git a/lib/refmt3.darwin b/lib/refmt3.darwin new file mode 100755 index 0000000000..187ae3c204 Binary files /dev/null and b/lib/refmt3.darwin differ diff --git a/lib/refmt3.win b/lib/refmt3.win new file mode 100644 index 0000000000..1a43481c16 Binary files /dev/null and b/lib/refmt3.win differ diff --git a/lib/whole_compiler.ml b/lib/whole_compiler.ml index d052e9cbd0..a9e9876ac8 100644 --- a/lib/whole_compiler.ml +++ b/lib/whole_compiler.ml @@ -55,9 +55,9 @@ end = struct * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -let version = "2.2.1" +let version = "2.2.2" let header = - "// Generated by BUCKLESCRIPT VERSION 2.2.1, PLEASE EDIT WITH CARE" + "// Generated by BUCKLESCRIPT VERSION 2.2.2, PLEASE EDIT WITH CARE" let package_name = "bs-platform" end @@ -85961,6 +85961,8 @@ let dump_program (x : J.program) oc = let node_program ~output_dir f ( x : J.deps_program) = + P.string f L.strict_directive; + P.newline f ; let cxt = Js_dump_import_export.requires L.require @@ -85979,6 +85981,8 @@ let node_program ~output_dir f ( x : J.deps_program) = let amd_program ~output_dir kind f ( x : J.deps_program) = let cxt = Ext_pp_scope.empty in + P.string f L.strict_directive; + P.newline f ; P.vgroup f 1 @@ fun _ -> P.string f L.define; P.string f "(["; @@ -86057,9 +86061,7 @@ let pp_deps_program P.string f empty_explanation (* This is empty module, it won't be referred anywhere *) else - let output_dir = Filename.dirname output_prefix in - P.string f L.strict_directive; - P.newline f ; + let output_dir = Filename.dirname output_prefix in begin ignore (match kind with | Es6 | Es6_global -> @@ -116135,9 +116137,9 @@ module Tweaked_reason_oprint other printer called reason_pprint_ast, our actual, main pretty-printer. Why is this one separated from reason_pprint_ast? Because the outcome printer's use-case is a bit different and needs different entry points blablabla... - These are mostly excuses. But for example, currently, `Js.t {. foo: bar}` by + These are mostly excuses. But for example, currently, `Js.t({. foo: bar})` by itself is *invalid syntax* for a pretty printer (the correct, minimal valid - code would be `type myObject = Js.t {. foo: bar}`), but the terminal error + code would be `type myObject = Js.t({. foo: bar})`), but the terminal error report do want to provide just that snippet and have you print it. Hopefully OCaml can unify actual code pretty-printing and terminal type info pretty- printing one day. @@ -116195,9 +116197,62 @@ let parenthesized_ident name = false | _ -> true) + + +(* please keep this section in sync with Reason repo's Syntax_util file's + helpers of the same names *) + +let string_add_suffix x = x ^ "_" +let string_drop_suffix x = String.sub x 0 (String.length x - 1) +(** Check to see if the string `s` is made up of `keyword` and zero or more + trailing `_` characters. *) +let potentially_conflicts_with ~keyword s = + let s_length = String.length s in + let keyword_length = String.length keyword in + (* It can't be a match if s is shorter than keyword *) + s_length >= keyword_length && ( + try + (* Ensure s starts with keyword... *) + for i = 0 to keyword_length - 1 do + if keyword.[i] <> s.[i] then raise Exit; + done; + (* ...and contains nothing else except trailing _ characters *) + for i = keyword_length to s_length - 1 do + if s.[i] <> '_' then raise Exit; + done; + (* If we've made it this far there's a potential conflict *) + true + with + | Exit -> false + ) +let ml_to_reason_swap = function + | "not" -> "!" + | "!" -> "^" + | "^" -> "++" + | "==" -> "===" + | "=" -> "==" + (* ===\/ and !==\/ are not representable in OCaml but + * representable in Reason + *) + | "!==" -> "\\!==" + | "===" -> "\\===" + | "<>" -> "!=" + | "!=" -> "!==" + | x when ( + potentially_conflicts_with ~keyword:"match_" x + || potentially_conflicts_with ~keyword:"method_" x + || potentially_conflicts_with ~keyword:"private_" x) -> string_drop_suffix x + | x when ( + potentially_conflicts_with ~keyword:"switch" x + || potentially_conflicts_with ~keyword:"pub" x + || potentially_conflicts_with ~keyword:"pri" x) -> string_add_suffix x + | everything_else -> everything_else + + + let value_ident ppf name = if parenthesized_ident name then - fprintf ppf "( %s )" name + fprintf ppf "( %s )" (ml_to_reason_swap name) else pp_print_string ppf name @@ -116346,7 +116401,7 @@ let rec print_out_type ppf = pr_vars sl print_out_type ty | ty -> - print_out_type_1 ppf ty + print_out_type_1 ~uncurried:false ppf ty and print_arg ppf (lab, typ) = let suffix = @@ -116366,7 +116421,7 @@ and print_arg ppf (lab, typ) = print_out_type_2 ppf typ; pp_print_string ppf suffix; -and print_out_type_1 ppf = +and print_out_type_1 ~uncurried ppf = function Otyp_arrow (lab, ty1, ty2) -> let rec collect_args args typ = match typ with @@ -116374,13 +116429,23 @@ and print_out_type_1 ppf = | _ -> (args, typ) in pp_open_box ppf 0; - pp_print_string ppf "("; let (args, result) = collect_args [(lab, ty1)] ty2 in + let should_wrap_with_parens = match (uncurried, args) with + (* single argument should not be wrapped *) + (* though uncurried type are always wrapped in parens. `. a => 1` isn't supported *) + | (false, [(_, Otyp_tuple _)]) -> true + | (false, [("", typ)]) -> false + | (_, args) -> true + in + + if should_wrap_with_parens then pp_print_string ppf "("; + if uncurried then fprintf ppf ".@ "; print_list print_arg (fun ppf -> fprintf ppf ",@ ") ppf args; - pp_print_string ppf ")"; + if should_wrap_with_parens then pp_print_string ppf ")"; + pp_print_string ppf " =>"; pp_print_space ppf (); - print_out_type_1 ppf result; + print_out_type_1 ~uncurried ppf result; pp_close_box ppf () | ty -> print_out_type_2 ppf ty and print_out_type_2 ppf = @@ -116397,8 +116462,8 @@ and print_simple_out_type ppf = (* BuckleScript-specific external. See the manual for the usage of [@bs]. This [@bs] is processed into a type that looks like `Js.Internal.fn ...`. This leaks during error reporting, where the type is printed. Here, we print it - back from `Js.Internal.fn [ `Arity_2 ('c, 'd) ] 'e` into `('a => 'b => int) [@bs]` *) - (* same for `Js_internal.fn ...`. Either might shown *) + back from `Js.Internal.fn([ `Arity_2 ('c, 'd) ], 'e)` into `('a => 'b => int) [@bs]` *) + (* same for `Js_internal.fn(...)`. Either might shown *) | Otyp_constr ( (Oide_dot ( (Oide_dot ((Oide_ident "Js"), "Internal") | Oide_ident "Js_internal"), @@ -116432,8 +116497,8 @@ and print_simple_out_type ppf = end | res -> begin match name with - | "fn" -> fprintf ppf "@[<0>(%a)@ [@bs]@]" print_out_type_1 res - | "meth" -> fprintf ppf "@[<0>(%a)@ [@bs.meth]@]" print_out_type_1 res + | "fn" -> print_out_type_1 ~uncurried:true ppf res + | "meth" -> fprintf ppf "@[<0>(%a)@ [@bs.meth]@]" (print_out_type_1 ~uncurried:false) res | _ -> assert false end end @@ -116465,8 +116530,18 @@ and print_simple_out_type ppf = pp_close_box ppf () end | res -> - fprintf ppf "@[<0>(%a)@ [@bs.this]@]" print_out_type_1 res + fprintf ppf "@[<0>(%a)@ [@bs.this]@]" (print_out_type_1 ~uncurried:false) res end + (* also BuckleScript-specific. Turns Js.t({. foo: bar}) into {. "foo": bar} *) + | Otyp_constr ( + (Oide_dot ((Oide_ident "Js"), "t")), + [Otyp_object (fields, rest)] + ) -> + let dot = match rest with + Some non_gen -> (if non_gen then "_" else "") ^ ".." + | None -> "." + in + fprintf ppf "@[<2>{%s %a}@]" dot (print_object_fields ~quote_fields:true) fields | Otyp_constr (id, tyl) -> pp_open_box ppf 0; @@ -116482,7 +116557,7 @@ and print_simple_out_type ppf = Some non_gen -> (if non_gen then "_" else "") ^ ".." | None -> "." in - fprintf ppf "@[<2>{%s %a }@]" dot print_object_fields fields + fprintf ppf "@[<2>{%s %a}@]" dot (print_object_fields ~quote_fields:false) fields | Otyp_stuff s -> pp_print_string ppf s | Otyp_var (ng, s) -> fprintf ppf "'%s%s" (if ng then "_" else "") s | Otyp_variant (non_gen, row_fields, closed, tags) -> @@ -116523,22 +116598,30 @@ and print_simple_out_type ppf = fprintf ppf ")@]" -and print_object_fields ppf = +and print_object_fields ~quote_fields ppf = function [] -> () - | [s, t] -> - fprintf ppf "%s : %a" s print_out_type t; - print_object_fields ppf [] - | (s, t) :: l -> - fprintf ppf "%s : %a,@ %a" s print_out_type t print_object_fields l + | [field, typ] -> + let field = (if quote_fields then "\"" ^ field ^ "\"" else field) in + fprintf ppf "%s: %a" field print_out_type typ; + (print_object_fields ~quote_fields) ppf [] + | (field, typ) :: rest -> + let field = (if quote_fields then "\"" ^ field ^ "\"" else field) in + fprintf ppf "%s: %a,@ %a" field print_out_type typ (print_object_fields ~quote_fields) rest and print_row_field ppf (l, opt_amp, tyl) = let pr_of ppf = if opt_amp then fprintf ppf " &@ " - else if tyl <> [] then fprintf ppf " " - else fprintf ppf "" - in - fprintf ppf "@[`%s%t%a@]" l pr_of (print_typlist print_out_type " &") - tyl + else fprintf ppf "" in + let parens = match tyl with + | [ (Otyp_tuple _) ] -> false (* tuples already have parentheses *) + | [ _ ] -> true + | _ -> false in + fprintf ppf "@[`%s%t%s%a%s@]" + l + pr_of + (if parens then "(" else "") + (print_typlist print_out_type " &") tyl + (if parens then ")" else "") and print_typlist print_elem sep ppf = function [] -> () @@ -116737,25 +116820,34 @@ and print_out_sig_item ppf = ppf td | Osig_value(oval_name, oval_type, oval_prims) -> - let kwd = if oval_prims = [] then "let" else "external" in - let pr_prims ppf = + let printAttributes ppf attrs = () in + let oval_attributes = [] in + + let keyword = if oval_prims = [] then "let" else "external" in + let (hackyBucklescriptExternalAnnotation, rhsValues) = List.partition (fun item -> + (* "BS:" is considered as a bucklescript external annotation, `[@bs.module]` and the sort. + + "What's going on here? Isn't [@bs.foo] supposed to be an attribute in oval_attributes?" + Usually yes. But here, we're intercepting things a little too late. BuckleScript already + finished its pre/post-processing work before we get to print anything. The original + attribute is already gone, replaced by a "BS:asdfasdfasd" thing here. + *) + String.length item >= 3 && item.[0] = 'B' && item.[1] = 'S' && item.[2] = ':' + ) oval_prims in + let print_right_hand_side ppf = function [] -> () | s :: sl -> fprintf ppf "@ = \"%s\"" s; - List.iter (fun s -> - (* TODO: in general, we should print bs attributes, some attributes like - bs.splice does need it *) - let len = String.length s in - if len >= 3 && s.[0] = 'B' && s.[1] = 'S' && s.[2] = ':' then - fprintf ppf "@ \"BuckleScript External\"" - else - fprintf ppf "@ \"%s\"" s - ) sl + List.iter (fun s -> fprintf ppf "@ \"%s\"" s) sl in - fprintf ppf "@[<2>%s %a:@ %a%a@]" kwd value_ident oval_name - !out_type oval_type pr_prims oval_prims - + fprintf ppf "@[<2>%a%a%s %a:@ %a%a@]" + (fun ppf -> List.iter (fun _ -> fprintf ppf "[@@bs...]@ ")) hackyBucklescriptExternalAnnotation + printAttributes oval_attributes + keyword + value_ident oval_name + !out_type oval_type + print_right_hand_side rhsValues and print_out_type_decl kwd ppf td = let print_constraints ppf = @@ -117553,13 +117645,15 @@ let show_extra_help ppf env trace = begin | _ -> (); end -let rec collect_missing_arguments rettype targettype = match rettype with - | {desc=Tarrow (label, argtype, rettype, _)} when rettype.desc = targettype.desc -> Some ((label, argtype) :: []) - | {desc=Tarrow (label, argtype, rettype, _)} -> begin - match collect_missing_arguments rettype targettype with +(* given type1 is foo => bar => baz and type 2 is bar => baz, return Some(foo) *) +let rec collect_missing_arguments env type1 type2 = match type1 with + | {desc=Tarrow (label, argtype, typ, _)} when Ctype.equal env true [typ] [type2] -> + Some [(label, argtype)] + | {desc=Tarrow (label, argtype, typ, _)} -> begin + match collect_missing_arguments env typ type2 with | Some res -> Some ((label, argtype) :: res) | None -> None - end + end | _ -> None let check_bs_arity_mismatch ppf trace = @@ -117630,6 +117724,8 @@ let report_error env ppf = function (Ident.name id) | Expr_type_clash trace -> (* modified *) + (* this is the most frequent error. Do whatever we can to provide specific + guidance to this generic error before giving up *) if Super_reason_react.state_escape_scope trace then fprintf ppf "@[\ @[@{Is this a ReasonReact reducerComponent or component with retained props?@}@ \ @@ -117644,24 +117740,49 @@ let report_error env ppf = function @[@{Here's the original error message@}@]@,\ @]"; begin - let missing_arguments = match bottom_aliases trace with - | Some (actual, expected) -> collect_missing_arguments actual expected + let bottom_aliases_result = bottom_aliases trace in + let missing_arguments = match bottom_aliases_result with + | Some (actual, expected) -> collect_missing_arguments env actual expected | None -> assert false in - match missing_arguments with + let print_arguments = + Format.pp_print_list + ~pp_sep:(fun ppf _ -> fprintf ppf ",@ ") + (fun ppf (label, argtype) -> + if label = "" then fprintf ppf "@[%a@]" type_expr argtype + else fprintf ppf "@[(~%s: %a)@]" label type_expr argtype + ) + in + begin match missing_arguments with + | Some [singleArgument] -> + fprintf ppf "@[@{This call is missing a final argument@} of type@ %a@]" + print_arguments [singleArgument] | Some arguments -> - fprintf ppf "You're missing arguments: @[%a@]" (Format.pp_print_list ~pp_sep:(fun ppf _ -> fprintf ppf ", ") (fun ppf (label, argtype) -> - if label = "" then type_expr ppf argtype - else fprintf ppf "~%s: %a" label type_expr argtype - )) arguments + fprintf ppf "@[@{This call is missing final arguments@} of type:@ %a@]" + print_arguments arguments | None -> - check_bs_arity_mismatch ppf trace; - super_report_unification_error ppf env trace - (function ppf -> - fprintf ppf "This has type:") - (function ppf -> - fprintf ppf "But somewhere wanted:"); - show_extra_help ppf env trace + let missing_parameters = match bottom_aliases_result with + | Some (actual, expected) -> collect_missing_arguments env expected actual + | None -> assert false + in + begin match missing_parameters with + | Some [singleParameter] -> + fprintf ppf "@[This value seems to @{need to be wrapped in a function@ that@ takes@ an@ extra@ argument@}@ of@ type@ %a@]" + print_arguments [singleParameter] + | Some arguments -> + fprintf ppf "@[This value seems to @{need to be wrapped in a function that takes extra@ arguments@}@ of@ type:@ @[%a@]@]" + print_arguments arguments + | None -> + (* final fallback: show the generic type mismatch error *) + check_bs_arity_mismatch ppf trace; + super_report_unification_error ppf env trace + (function ppf -> + fprintf ppf "This has type:") + (function ppf -> + fprintf ppf "But somewhere wanted:"); + show_extra_help ppf env trace; + end; + end; end | Apply_non_function typ -> (* modified *) @@ -118144,22 +118265,53 @@ let report_error env ppf = function spellcheck ppf Env.fold_values env lid; | Unbound_module lid -> (* modified *) - fprintf ppf "@[\ - @{The module or file %a can't be found.@}@,@,\ - @[- If it's a third-party dependency:@,\ - - Did you list it in bsconfig.json?@,\ - - @[Did you run `bsb` instead of `bsb -make-world`@ (latter builds third-parties)@]?\ - @]@,\ - - Did you include the file's directory in bsconfig.json?@]\ - @]" - longident lid; + begin match lid with + | Lident "Str" -> + begin + fprintf ppf "@[\ + @{The module or file %a can't be found.@}@,@,\ + Are you trying to use the standard library's Str?@ \ + If you're compiling to JavaScript,@ use @{Js.Re@} instead.@ \ + Otherwise, add str.cma to your ocamlc/ocamlopt command.\ + @]" + longident lid + end + | lid -> + begin + fprintf ppf "@[\ + @{The module or file %a can't be found.@}@,\ + @[- If it's a third-party dependency:@,\ + - Did you list it in bsconfig.json?@,\ + - @[Did you run `bsb` instead of `bsb -make-world`@ (latter builds third-parties)@]?\ + @]@,\ + - Did you include the file's directory in bsconfig.json?@]\ + @]" + longident lid + end + end; spellcheck ppf Env.fold_modules env lid | Unbound_constructor lid -> - fprintf ppf "Unbound constructor %a" longident lid; + (* modified *) + fprintf ppf "@[\ + @{The variant constructor %a can't be found.@}@,@,\ + @[- If it's defined in another module or file, bring it into scope by:@,\ + @[- Annotating it with said module name:@ @{let food = MyModule.Apple@}@]@,\ + @[- Or specifying its type:@ @{let food: MyModule.fruit = Apple@}@]\ + @]@,\ + - @[Constructors and modules are both capitalized.@ Did you want the latter?@ Then instead of @{let foo = Bar@}, try @{module Foo = Bar@}.@]\ + @]" + longident lid; Typetexp.spellcheck_simple ppf Env.fold_constructors (fun d -> d.cstr_name) env lid; | Unbound_label lid -> - fprintf ppf "Unbound record field %a" longident lid; + (* modified *) + fprintf ppf "@[\ + @{The record field %a can't be found.@}@,@,\ + If it's defined in another module or file, bring it into scope by:@,\ + @[- Annotating it with said module name:@ @{let baby = {myModule.age: 3}@}@]@,\ + @[- Or specifying its type:@ @{let baby: MyModule.person = {age: 3}@}@]\ + @]" + longident lid; Typetexp.spellcheck_simple ppf Env.fold_labels (fun d -> d.lbl_name) env lid; | Unbound_class lid -> fprintf ppf "Unbound class %a" longident lid; diff --git a/package.json b/package.json index 48b2c22496..94783548ae 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "postinstall": "node scripts/install.js" }, "name": "bs-platform", - "version": "2.2.1", + "version": "2.2.2", "description": "bucklescript compiler, ocaml standard libary by bucklescript and its required runtime support", "repository": { "type": "git",