From 72a7bf50b689092489203d5855a08aae7c434d1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Cha=CC=81varri?= Date: Mon, 31 Aug 2020 21:47:02 +0200 Subject: [PATCH 1/4] adapt ninja config to use react ppx from upstream syntax submodule --- jscomp/syntax/ppx_entry.ml | 4 +- jscomp/syntax/reactjs_jsx_ppx.cppo.ml | 974 -------------------------- scripts/ninja.js | 5 +- 3 files changed, 3 insertions(+), 980 deletions(-) delete mode 100644 jscomp/syntax/reactjs_jsx_ppx.cppo.ml diff --git a/jscomp/syntax/ppx_entry.ml b/jscomp/syntax/ppx_entry.ml index 5631ee4c83..ba6abc7754 100644 --- a/jscomp/syntax/ppx_entry.ml +++ b/jscomp/syntax/ppx_entry.ml @@ -29,7 +29,7 @@ let rewrite_signature (ast : Parsetree.signature) : Parsetree.signature = Ast_config.iter_on_bs_config_sigi ast; let ast = match !Js_config.jsx_version with - | 3 -> Reactjs_jsx_ppx_v3.rewrite_signature ast + | 3 -> Reactjs_jsx_ppx.rewrite_signature ast | _ -> ast (* react-jsx ppx relies on built-in ones like `##` *) in @@ -48,7 +48,7 @@ let rewrite_implementation (ast : Parsetree.structure) : Parsetree.structure = Ast_config.iter_on_bs_config_stru ast ; let ast = match !Js_config.jsx_version with - | 3 -> Reactjs_jsx_ppx_v3.rewrite_implementation ast + | 3 -> Reactjs_jsx_ppx.rewrite_implementation ast | _ -> ast in if !Js_config.no_builtin_ppx then ast else diff --git a/jscomp/syntax/reactjs_jsx_ppx.cppo.ml b/jscomp/syntax/reactjs_jsx_ppx.cppo.ml deleted file mode 100644 index 21ae3fb1bf..0000000000 --- a/jscomp/syntax/reactjs_jsx_ppx.cppo.ml +++ /dev/null @@ -1,974 +0,0 @@ -(* - This is the file that handles turning Reason JSX' agnostic function call into - a ReasonReact-specific function call. Aka, this is a macro, using OCaml's ppx - facilities; https://whitequark.org/blog/2014/04/16/a-guide-to-extension- - points-in-ocaml/ - You wouldn't use this file directly; it's used by BuckleScript's - bsconfig.json. Specifically, there's a field called `react-jsx` inside the - field `reason`, which enables this ppx through some internal call in bsb -*) - -(* - There are two different transforms that can be selected in this file (v2 and v3): - v2: - transform `[@JSX] div(~props1=a, ~props2=b, ~children=[foo, bar], ())` into - `ReactDOMRe.createElement("div", ~props={"props1": 1, "props2": b}, [|foo, - bar|])`. - transform `[@JSX] div(~props1=a, ~props2=b, ~children=foo, ())` into - `ReactDOMRe.createElementVariadic("div", ~props={"props1": 1, "props2": b}, foo)`. - transform the upper-cased case - `[@JSX] Foo.createElement(~key=a, ~ref=b, ~foo=bar, ~children=[], ())` into - `ReasonReact.element(~key=a, ~ref=b, Foo.make(~foo=bar, [||]))` - transform `[@JSX] [foo]` into - `ReactDOMRe.createElement(ReasonReact.fragment, [|foo|])` - v3: - transform `[@JSX] div(~props1=a, ~props2=b, ~children=[foo, bar], ())` into - `ReactDOMRe.createDOMElementVariadic("div", ReactDOMRe.domProps(~props1=1, ~props2=b), [|foo, bar|])`. - transform the upper-cased case - `[@JSX] Foo.createElement(~key=a, ~ref=b, ~foo=bar, ~children=[], ())` into - `React.createElement(Foo.make, Foo.makeProps(~key=a, ~ref=b, ~foo=bar, ()))` - transform the upper-cased case - `[@JSX] Foo.createElement(~foo=bar, ~children=[foo, bar], ())` into - `React.createElementVariadic(Foo.make, Foo.makeProps(~foo=bar, ~children=React.null, ()), [|foo, bar|])` - transform `[@JSX] [foo]` into - `ReactDOMRe.createElement(ReasonReact.fragment, [|foo|])` -*) - -open Ast_helper -open Ast_mapper -open Asttypes -open Parsetree -open Longident - -let rec find_opt p = function - | [] -> None - | x :: l -> if p x then Some x else find_opt p l - - - -let nolabel = Nolabel -let labelled str = Labelled str -let optional str = Optional str -let isOptional str = match str with -| Optional _ -> true -| _ -> false -let isLabelled str = match str with -| Labelled _ -> true -| _ -> false -let getLabel str = match str with -| Optional str | Labelled str -> str -| Nolabel -> "" -let optionIdent = Lident "option" - -let argIsKeyRef = function - | (Labelled ("key" | "ref"), _) | (Optional ("key" | "ref"), _) -> true - | _ -> false -let constantString ~loc str = Ast_helper.Exp.constant ~loc (Pconst_string (str, None)) - - -let safeTypeFromValue valueStr = -let valueStr = getLabel valueStr in -match String.sub valueStr 0 1 with -| "_" -> "T" ^ valueStr -| _ -> valueStr -let keyType loc = Typ.constr ~loc {loc; txt=optionIdent} [Typ.constr ~loc {loc; txt=Lident "string"} []] - -type 'a children = | ListLiteral of 'a | Exact of 'a -type componentConfig = { - propsName: string; -} - -(* if children is a list, convert it to an array while mapping each element. If not, just map over it, as usual *) -let transformChildrenIfListUpper ~loc ~mapper theList = - let rec transformChildren_ theList accum = - (* not in the sense of converting a list to an array; convert the AST - reprensentation of a list to the AST reprensentation of an array *) - match theList with - | {pexp_desc = Pexp_construct ({txt = Lident "[]"}, None)} -> begin - match accum with - | [singleElement] -> Exact singleElement - | accum -> ListLiteral (List.rev accum |> Exp.array ~loc) - end - | {pexp_desc = Pexp_construct ( - {txt = Lident "::"}, - Some {pexp_desc = Pexp_tuple (v::acc::[])} - )} -> - transformChildren_ acc ((mapper.expr mapper v)::accum) - | notAList -> Exact (mapper.expr mapper notAList) - in - transformChildren_ theList [] - -let transformChildrenIfList ~loc ~mapper theList = - let rec transformChildren_ theList accum = - (* not in the sense of converting a list to an array; convert the AST - reprensentation of a list to the AST reprensentation of an array *) - match theList with - | {pexp_desc = Pexp_construct ({txt = Lident "[]"}, None)} -> - List.rev accum |> Exp.array ~loc - | {pexp_desc = Pexp_construct ( - {txt = Lident "::"}, - Some {pexp_desc = Pexp_tuple (v::acc::[])} - )} -> - transformChildren_ acc ((mapper.expr mapper v)::accum) - | notAList -> mapper.expr mapper notAList - in - transformChildren_ theList [] - -let extractChildren ?(removeLastPositionUnit=false) ~loc propsAndChildren = - let rec allButLast_ lst acc = match lst with - | [] -> [] - | (Nolabel, {pexp_desc = Pexp_construct ({txt = Lident "()"}, None)})::[] -> acc - | (Nolabel, _) :: _rest -> raise (Invalid_argument "JSX: found non-labelled argument before the last position") - | arg::rest -> allButLast_ rest (arg::acc) - in - let allButLast lst = allButLast_ lst [] |> List.rev in - match (List.partition (fun (label, _) -> label = labelled "children") propsAndChildren) with - | ([], props) -> - (* no children provided? Place a placeholder list *) - (Exp.construct ~loc {loc; txt = Lident "[]"} None, if removeLastPositionUnit then allButLast props else props) - | ([(_, childrenExpr)], props) -> - (childrenExpr, if removeLastPositionUnit then allButLast props else props) - | _ -> raise (Invalid_argument "JSX: somehow there's more than one `children` label") - -let unerasableIgnore loc = ({loc; txt = "warning"}, (PStr [Str.eval (Exp.constant (Pconst_string ("-16", None)))])) -let merlinFocus = ({loc = Location.none; txt = "merlin.focus"}, (PStr [])) - -(* Helper method to look up the [@react.component] attribute *) -let hasAttr (loc, _) = - loc.txt = "react.component" - -(* Helper method to filter out any attribute that isn't [@react.component] *) -let otherAttrsPure (loc, _) = - loc.txt <> "react.component" - -(* Iterate over the attributes and try to find the [@react.component] attribute *) -let hasAttrOnBinding {pvb_attributes} = find_opt hasAttr pvb_attributes <> None - -(* Filter the [@react.component] attribute and immutably replace them on the binding *) -let filterAttrOnBinding binding = {binding with pvb_attributes = List.filter otherAttrsPure binding.pvb_attributes} - -(* Finds the name of the variable the binding is assigned to, otherwise raises Invalid_argument *) -let getFnName binding = - match binding with - | {pvb_pat = { - ppat_desc = Ppat_var {txt} - }} -> txt - | _ -> raise (Invalid_argument "react.component calls cannot be destructured.") - -let makeNewBinding binding expression newName = - match binding with - | {pvb_pat = { - ppat_desc = Ppat_var ( ppat_var) - } as pvb_pat} ->{ binding with pvb_pat = { - pvb_pat with - ppat_desc = Ppat_var {ppat_var with txt = newName}; - }; - pvb_expr = expression; - pvb_attributes = [merlinFocus]; - } - | _ -> raise (Invalid_argument "react.component calls cannot be destructured.") - -(* Lookup the value of `props` otherwise raise Invalid_argument error *) -let getPropsNameValue _acc (loc, exp) = - match (loc, exp) with - | ({ txt = Lident "props" }, { pexp_desc = Pexp_ident {txt = Lident str} }) -> { propsName = str } - | ({ txt }, _) -> raise (Invalid_argument ("react.component only accepts props as an option, given: " ^ Longident.last txt)) - -(* Lookup the `props` record or string as part of [@react.component] and store the name for use when rewriting *) -let getPropsAttr payload = - let defaultProps = {propsName = "Props"} in - match payload with - | Some(PStr( - {pstr_desc = Pstr_eval ({ - pexp_desc = Pexp_record (recordFields, None) - }, _)}::_rest - )) -> - List.fold_left getPropsNameValue defaultProps recordFields - | Some(PStr({pstr_desc = Pstr_eval ({pexp_desc = Pexp_ident {txt = Lident "props"}}, _)}::_rest)) -> {propsName = "props"} - | Some(PStr({pstr_desc = Pstr_eval (_, _)}::_rest)) -> raise (Invalid_argument ("react.component accepts a record config with props as an options.")) - | _ -> defaultProps - -(* Plucks the label, loc, and type_ from an AST node *) -let pluckLabelDefaultLocType (label, default, _, _, loc, type_) = (label, default, loc, type_) - -(* Lookup the filename from the location information on the AST node and turn it into a valid module identifier *) -let filenameFromLoc (pstr_loc: Location.t) = - let fileName = match pstr_loc.loc_start.pos_fname with - | "" -> !Location.input_name - | fileName -> fileName - in - let fileName = try - Filename.chop_extension (Filename.basename fileName) - with | Invalid_argument _-> fileName in - let fileName = String.capitalize_ascii fileName in - fileName - -(* Build a string representation of a module name with segments separated by $ *) -let makeModuleName fileName nestedModules fnName = - let fullModuleName = match (fileName, nestedModules, fnName) with - (* TODO: is this even reachable? It seems like the fileName always exists *) - | ("", nestedModules, "make") -> nestedModules - | ("", nestedModules, fnName) -> List.rev (fnName :: nestedModules) - | (fileName, nestedModules, "make") -> fileName :: (List.rev nestedModules) - | (fileName, nestedModules, fnName) -> fileName :: (List.rev (fnName :: nestedModules)) - in - let fullModuleName = String.concat "$" fullModuleName in - fullModuleName - -(* - AST node builders - These functions help us build AST nodes that are needed when transforming a [@react.component] into a - constructor and a props external -*) - -(* Build an AST node representing all named args for the `external` definition for a component's props *) -let rec recursivelyMakeNamedArgsForExternal list args = - match list with - | (label, default, loc, interiorType)::tl -> - recursivelyMakeNamedArgsForExternal tl (Typ.arrow - ~loc - label - (match (label, interiorType, default) with - (* ~foo=1 *) - | (label, None, Some _) -> - { - ptyp_desc = Ptyp_var (safeTypeFromValue label); - ptyp_loc = loc; - ptyp_attributes = []; - } - (* ~foo: int=1 *) - | (_label, Some type_, Some _) -> - type_ - - (* ~foo: option(int)=? *) - | (label, Some ({ptyp_desc = Ptyp_constr ({txt=(Lident "option")}, [type_])}), _) - | (label, Some ({ptyp_desc = Ptyp_constr ({txt=(Ldot (Lident "*predef*", "option"))}, [type_])}), _) - (* ~foo: int=? - note this isnt valid. but we want to get a type error *) - | (label, Some type_, _) when isOptional label -> - type_ - (* ~foo=? *) - | (label, None, _) when isOptional label -> - { - ptyp_desc = Ptyp_var (safeTypeFromValue label); - ptyp_loc = loc; - ptyp_attributes = []; - } - - (* ~foo *) - | (label, None, _) -> - { - ptyp_desc = Ptyp_var (safeTypeFromValue label); - ptyp_loc = loc; - ptyp_attributes = []; - } - | (_label, Some type_, _) -> - type_ - ) - args) - | [] -> args - -(* Build an AST node for the [@bs.obj] representing props for a component *) -let makePropsValue fnName loc namedArgListWithKeyAndRef propsType = - let propsName = fnName ^ "Props" in { - pval_name = {txt = propsName; loc}; - pval_type = - recursivelyMakeNamedArgsForExternal - namedArgListWithKeyAndRef - (Typ.arrow - nolabel - { - ptyp_desc = Ptyp_constr ({txt= Lident("unit"); loc}, []); - ptyp_loc = loc; - ptyp_attributes = []; - } - propsType - ); - pval_prim = [""]; - pval_attributes = [({txt = "bs.obj"; loc = loc}, PStr [])]; - pval_loc = loc; -} - -(* Build an AST node representing an `external` with the definition of the [@bs.obj] *) -let makePropsExternal fnName loc namedArgListWithKeyAndRef propsType = - { - pstr_loc = loc; - pstr_desc = Pstr_primitive (makePropsValue fnName loc namedArgListWithKeyAndRef propsType) - } - -(* Build an AST node for the signature of the `external` definition *) -let makePropsExternalSig fnName loc namedArgListWithKeyAndRef propsType = - { - psig_loc = loc; - psig_desc = Psig_value (makePropsValue fnName loc namedArgListWithKeyAndRef propsType) - } - -(* Build an AST node for the props name when converted to a Js.t inside the function signature *) -let makePropsName ~loc name = - { - ppat_desc = Ppat_var {txt = name; loc}; - ppat_loc = loc; - ppat_attributes = []; - } - - -let makeObjectField loc (str, attrs, type_) = - Otag ({ loc; txt = str }, attrs, type_) - - -(* Build an AST node representing a "closed" Js.t object representing a component's props *) -let makePropsType ~loc namedTypeList = - Typ.mk ~loc ( - Ptyp_constr({txt= Ldot (Lident("Js"), "t"); loc}, [{ - ptyp_desc = Ptyp_object( - List.map (makeObjectField loc) namedTypeList, - Closed - ); - ptyp_loc = loc; - ptyp_attributes = []; - }]) - ) - -(* Builds an AST node for the entire `external` definition of props *) -let makeExternalDecl fnName loc namedArgListWithKeyAndRef namedTypeList = - makePropsExternal - fnName - loc - (List.map pluckLabelDefaultLocType namedArgListWithKeyAndRef) - (makePropsType ~loc namedTypeList) - -(* TODO: some line number might still be wrong *) -let jsxMapper () = - - let jsxVersion = ref None in - - let transformUppercaseCall3 modulePath mapper loc attrs _ callArguments = - let (children, argsWithLabels) = extractChildren ~loc ~removeLastPositionUnit:true callArguments in - let argsForMake = argsWithLabels in - let childrenExpr = transformChildrenIfListUpper ~loc ~mapper children in - let recursivelyTransformedArgsForMake = argsForMake |> List.map (fun (label, expression) -> (label, mapper.expr mapper expression)) in - let childrenArg = ref None in - let args = recursivelyTransformedArgsForMake - @ (match childrenExpr with - | Exact children -> [(labelled "children", children)] - | ListLiteral ({ pexp_desc = Pexp_array list }) when list = [] -> [] - | ListLiteral expression -> - (* this is a hack to support react components that introspect into their children *) - (childrenArg := Some expression; - [(labelled "children", Exp.ident ~loc {loc; txt = Ldot (Lident "React", "null")})])) - @ [(nolabel, Exp.construct ~loc {loc; txt = Lident "()"} None)] in - let isCap str = let first = String.sub str 0 1 in - let capped = String.uppercase_ascii first in first = capped in - let ident = match modulePath with - | Lident _ -> Ldot (modulePath, "make") - | (Ldot (_modulePath, value) as fullPath) when isCap value -> Ldot (fullPath, "make") - | modulePath -> modulePath in - let propsIdent = match ident with - | Lident path -> Lident (path ^ "Props") - | Ldot(ident, path) -> Ldot (ident, path ^ "Props") - | _ -> raise (Invalid_argument "JSX name can't be the result of function applications") in - let props = - Exp.apply ~attrs ~loc (Exp.ident ~loc {loc; txt = propsIdent}) args in - (* handle key, ref, children *) - (* React.createElement(Component.make, props, ...children) *) - match (!childrenArg) with - | None -> - (Exp.apply - ~loc - ~attrs - (Exp.ident ~loc {loc; txt = Ldot (Lident "React", "createElement")}) - ([ - (nolabel, Exp.ident ~loc {txt = ident; loc}); - (nolabel, props) - ])) - | Some children -> - (Exp.apply - ~loc - ~attrs - (Exp.ident ~loc {loc; txt = Ldot (Lident "React", "createElementVariadic")}) - ([ - (nolabel, Exp.ident ~loc {txt = ident; loc}); - (nolabel, props); - (nolabel, children) - ])) - in - - let transformLowercaseCall3 mapper loc attrs callArguments id = - let (children, nonChildrenProps) = extractChildren ~loc callArguments in - let componentNameExpr = constantString ~loc id in - let childrenExpr = transformChildrenIfList ~loc ~mapper children in - let createElementCall = match children with - (* [@JSX] div(~children=[a]), coming from
a
*) - | { - pexp_desc = - Pexp_construct ({txt = Lident "::"}, Some {pexp_desc = Pexp_tuple _ }) - | Pexp_construct ({txt = Lident "[]"}, None) - } -> "createDOMElementVariadic" - (* [@JSX] div(~children= value), coming from
...(value)
*) - | _ -> raise (Invalid_argument "A spread as a DOM element's \ - children don't make sense written together. You can simply remove the spread.") - in - let args = match nonChildrenProps with - | [_justTheUnitArgumentAtEnd] -> - [ - (* "div" *) - (nolabel, componentNameExpr); - (* [|moreCreateElementCallsHere|] *) - (nolabel, childrenExpr) - ] - | nonEmptyProps -> - let propsCall = - Exp.apply - ~loc - (Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOMRe", "domProps")}) - (nonEmptyProps |> List.map (fun (label, expression) -> (label, mapper.expr mapper expression))) - in - [ - (* "div" *) - (nolabel, componentNameExpr); - (* ReactDOMRe.props(~className=blabla, ~foo=bar, ()) *) - (labelled "props", propsCall); - (* [|moreCreateElementCallsHere|] *) - (nolabel, childrenExpr) - ] in - Exp.apply - ~loc - (* throw away the [@JSX] attribute and keep the others, if any *) - ~attrs - (* ReactDOMRe.createElement *) - (Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOMRe", createElementCall)}) - args - in - - - - - let rec recursivelyTransformNamedArgsForMake mapper expr list = - let expr = mapper.expr mapper expr in - match expr.pexp_desc with - (* TODO: make this show up with a loc. *) - | Pexp_fun (Labelled "key", _, _, _) - | Pexp_fun (Optional "key", _, _, _) -> raise (Invalid_argument "Key cannot be accessed inside of a component. Don't worry - you can always key a component from its parent!") - | Pexp_fun (Labelled "ref", _, _, _) - | Pexp_fun (Optional "ref", _, _, _) -> raise (Invalid_argument "Ref cannot be passed as a normal prop. Please use `forwardRef` API instead.") - | Pexp_fun (arg, default, pattern, expression) when isOptional arg || isLabelled arg -> - let () = - (match (isOptional arg, pattern, default) with - | (true, { ppat_desc = Ppat_constraint (_, { ptyp_desc })}, None) -> - (match ptyp_desc with - | Ptyp_constr({txt=(Lident "option")}, [_]) -> () - | _ -> - let currentType = (match ptyp_desc with - | Ptyp_constr({txt}, []) -> String.concat "." (Longident.flatten txt) - | Ptyp_constr({txt}, _innerTypeArgs) -> String.concat "." (Longident.flatten txt) ^ "(...)" - | _ -> "...") - in - Location.prerr_warning pattern.ppat_loc - (Preprocessor - (Printf.sprintf "ReasonReact: optional argument annotations must have explicit `option`. Did you mean `option(%s)=?`?" currentType))) - | _ -> ()) in - let alias = (match pattern with - | {ppat_desc = Ppat_alias (_, {txt}) | Ppat_var {txt}} -> txt - | {ppat_desc = Ppat_any} -> "_" - | _ -> getLabel arg) in - let type_ = (match pattern with - | {ppat_desc = Ppat_constraint (_, type_)} -> Some type_ - | _ -> None) in - - recursivelyTransformNamedArgsForMake mapper expression ((arg, default, pattern, alias, pattern.ppat_loc, type_) :: list) - | Pexp_fun (Nolabel, _, { ppat_desc = (Ppat_construct ({txt = Lident "()"}, _) | Ppat_any)}, _expression) -> - (list, None) - | Pexp_fun (Nolabel, _, { ppat_desc = Ppat_var ({txt}) | Ppat_constraint ({ ppat_desc = Ppat_var ({txt})}, _)}, _expression) -> - (list, Some txt) - | Pexp_fun (Nolabel, _, pattern, _expression) -> - Location.raise_errorf ~loc:pattern.ppat_loc "ReasonReact: react.component refs only support plain arguments and type annotations." - | _ -> (list, None) - in - - - let argToType types (name, default, _noLabelName, _alias, loc, type_) = match (type_, name, default) with - | (Some ({ptyp_desc = Ptyp_constr ({txt=(Lident "option")}, [type_])}), name, _) when isOptional name -> - (getLabel name, [], { - type_ with - ptyp_desc = Ptyp_constr ({loc=type_.ptyp_loc; txt=optionIdent}, [type_]); - }) :: types - | (Some type_, name, Some _default) -> - (getLabel name, [], { - ptyp_desc = Ptyp_constr ({loc; txt=optionIdent}, [type_]); - ptyp_loc = loc; - ptyp_attributes = []; - }) :: types - | (Some type_, name, _) -> - (getLabel name, [], type_) :: types - | (None, name, _) when isOptional name -> - (getLabel name, [], { - ptyp_desc = Ptyp_constr ({loc; txt=optionIdent}, [{ - ptyp_desc = Ptyp_var (safeTypeFromValue name); - ptyp_loc = loc; - ptyp_attributes = []; - }]); - ptyp_loc = loc; - ptyp_attributes = []; - }) :: types - | (None, name, _) when isLabelled name -> - (getLabel name, [], { - ptyp_desc = Ptyp_var (safeTypeFromValue name); - ptyp_loc = loc; - ptyp_attributes = []; - }) :: types - | _ -> types - in - - let argToConcreteType types (name, loc, type_) = match name with - | name when isLabelled name -> - (getLabel name, [], type_) :: types - | name when isOptional name -> - (getLabel name, [], Typ.constr ~loc {loc; txt=optionIdent} [type_]) :: types - | _ -> types - in - - let nestedModules = ref([]) in - let transformComponentDefinition mapper structure returnStructures = match structure with - (* external *) - | ({ - pstr_loc; - pstr_desc = Pstr_primitive ({ - pval_name = { txt = fnName }; - pval_attributes; - pval_type; - } as value_description) - } as pstr) -> - (match List.filter hasAttr pval_attributes with - | [] -> structure :: returnStructures - | [_] -> - let rec getPropTypes types ({ptyp_loc; ptyp_desc} as fullType) = - (match ptyp_desc with - | Ptyp_arrow (name, type_, ({ptyp_desc = Ptyp_arrow _} as rest)) when isLabelled name || isOptional name -> - getPropTypes ((name, ptyp_loc, type_)::types) rest - | Ptyp_arrow (Nolabel, _type, rest) -> - getPropTypes types rest - | Ptyp_arrow (name, type_, returnValue) when isLabelled name || isOptional name -> - (returnValue, (name, returnValue.ptyp_loc, type_)::types) - | _ -> (fullType, types)) - in - let (innerType, propTypes) = getPropTypes [] pval_type in - let namedTypeList = List.fold_left argToConcreteType [] propTypes in - let pluckLabelAndLoc (label, loc, type_) = (label, None (* default *), loc, Some type_) in - let retPropsType = makePropsType ~loc:pstr_loc namedTypeList in - let externalPropsDecl = makePropsExternal fnName pstr_loc (( - optional "key", - None, - pstr_loc, - Some(keyType pstr_loc) - ) :: List.map pluckLabelAndLoc propTypes) retPropsType in - (* can't be an arrow because it will defensively uncurry *) - let newExternalType = Ptyp_constr ( - {loc = pstr_loc; txt = Ldot ((Lident "React"), "componentLike")}, - [retPropsType; innerType] - ) in - let newStructure = { - pstr with pstr_desc = Pstr_primitive { - value_description with pval_type = { - pval_type with ptyp_desc = newExternalType; - }; - pval_attributes = List.filter otherAttrsPure pval_attributes; - } - } in - externalPropsDecl :: newStructure :: returnStructures - | _ -> raise (Invalid_argument "Only one react.component call can exist on a component at one time")) - (* let component = ... *) - | { - pstr_loc; - pstr_desc = Pstr_value ( - recFlag, - valueBindings - ) - } -> - let fileName = filenameFromLoc pstr_loc in - let emptyLoc = Location.in_file fileName in - let mapBinding binding = if (hasAttrOnBinding binding) then - let bindingLoc = binding.pvb_loc in - let bindingPatLoc = binding.pvb_pat.ppat_loc in - let binding = { binding with pvb_pat = { binding.pvb_pat with ppat_loc = emptyLoc}; pvb_loc = emptyLoc} in - let fnName = getFnName binding in - let internalFnName = fnName ^ "$Internal" in - let fullModuleName = makeModuleName fileName !nestedModules fnName in - let modifiedBindingOld binding = - let expression = binding.pvb_expr in - (* TODO: there is a long-tail of unsupported features inside of blocks - Pexp_letmodule , Pexp_letexception , Pexp_ifthenelse *) - let rec spelunkForFunExpression expression = (match expression with - (* let make = (~prop) => ... *) - | { - pexp_desc = Pexp_fun _ - } -> expression - (* let make = {let foo = bar in (~prop) => ...} *) - | { - pexp_desc = Pexp_let (_recursive, _vbs, returnExpression) - } -> - (* here's where we spelunk! *) - spelunkForFunExpression returnExpression - (* let make = React.forwardRef((~prop) => ...) *) - - | { pexp_desc = Pexp_apply (_wrapperExpression, [(Nolabel, innerFunctionExpression)]) } -> - spelunkForFunExpression innerFunctionExpression - | { - pexp_desc = Pexp_sequence (_wrapperExpression, innerFunctionExpression) - } -> - spelunkForFunExpression innerFunctionExpression - | _ -> raise (Invalid_argument "react.component calls can only be on function definitions or component wrappers (forwardRef, memo).") - ) in - spelunkForFunExpression expression - in - let modifiedBinding binding = - let hasApplication = ref(false) in - let wrapExpressionWithBinding expressionFn expression = - Vb.mk - ~loc:bindingLoc - ~attrs:(List.filter otherAttrsPure binding.pvb_attributes) - (Pat.var ~loc:bindingPatLoc {loc = bindingPatLoc; txt = fnName}) (expressionFn expression) in - let expression = binding.pvb_expr in - let unerasableIgnoreExp exp = { exp with pexp_attributes = (unerasableIgnore emptyLoc) :: exp.pexp_attributes } in - (* TODO: there is a long-tail of unsupported features inside of blocks - Pexp_letmodule , Pexp_letexception , Pexp_ifthenelse *) - let rec spelunkForFunExpression expression = (match expression with - (* let make = (~prop) => ... with no final unit *) - | { - pexp_desc = Pexp_fun ((Labelled(_) | Optional(_) as label), default, pattern, ({pexp_desc = Pexp_fun _} as internalExpression)) - } -> - let (wrap, hasUnit, exp) = spelunkForFunExpression internalExpression in - (wrap, hasUnit, unerasableIgnoreExp {expression with pexp_desc = Pexp_fun (label, default, pattern, exp)}) - (* let make = (()) => ... *) - (* let make = (_) => ... *) - | { - pexp_desc = Pexp_fun (Nolabel, _default, { ppat_desc = Ppat_construct ({txt = Lident "()"}, _) | Ppat_any}, _internalExpression) - } -> ((fun a -> a), true, expression) - (* let make = (~prop) => ... *) - | { - pexp_desc = Pexp_fun ((Labelled(_) | Optional(_)), _default, _pattern, _internalExpression) - } -> ((fun a -> a), false, unerasableIgnoreExp expression) - (* let make = (prop) => ... *) - | { - pexp_desc = Pexp_fun (_nolabel, _default, pattern, _internalExpression) - } -> - if (hasApplication.contents) then - ((fun a -> a), false, unerasableIgnoreExp expression) - else - Location.raise_errorf ~loc:pattern.ppat_loc "ReasonReact: props need to be labelled arguments.\n If you are working with refs be sure to wrap with React.forwardRef.\n If your component doesn't have any props use () or _ instead of a name." - (* let make = {let foo = bar in (~prop) => ...} *) - | { - pexp_desc = Pexp_let (recursive, vbs, internalExpression) - } -> - (* here's where we spelunk! *) - let (wrap, hasUnit, exp) = spelunkForFunExpression internalExpression in - (wrap, hasUnit, {expression with pexp_desc = Pexp_let (recursive, vbs, exp)}) - (* let make = React.forwardRef((~prop) => ...) *) - | { pexp_desc = Pexp_apply (wrapperExpression, [(Nolabel, internalExpression)]) } -> - let () = hasApplication := true in - let (_, hasUnit, exp) = spelunkForFunExpression internalExpression in - ((fun exp -> Exp.apply wrapperExpression [(nolabel, exp)]), hasUnit, exp) - | { - pexp_desc = Pexp_sequence (wrapperExpression, internalExpression) - } -> - let (wrap, hasUnit, exp) = spelunkForFunExpression internalExpression in - (wrap, hasUnit, {expression with pexp_desc = Pexp_sequence (wrapperExpression, exp)}) - | e -> ((fun a -> a), false, e) - ) in - let (wrapExpression, hasUnit, expression) = spelunkForFunExpression expression in - (wrapExpressionWithBinding wrapExpression, hasUnit, expression) - in - let (bindingWrapper, hasUnit, expression) = modifiedBinding binding in - let reactComponentAttribute = try - Some(List.find hasAttr binding.pvb_attributes) - with | Not_found -> None in - let (_attr_loc, payload) = match reactComponentAttribute with - | Some (loc, payload) -> (loc.loc, Some payload) - | None -> (emptyLoc, None) in - let props = getPropsAttr payload in - (* do stuff here! *) - let (namedArgList, forwardRef) = recursivelyTransformNamedArgsForMake mapper (modifiedBindingOld binding) [] in - let namedArgListWithKeyAndRef = (optional("key"), None, Pat.var {txt = "key"; loc = emptyLoc}, "key", emptyLoc, Some(keyType emptyLoc)) :: namedArgList in - let namedArgListWithKeyAndRef = match forwardRef with - | Some(_) -> (optional("ref"), None, Pat.var {txt = "key"; loc = emptyLoc}, "ref", emptyLoc, None) :: namedArgListWithKeyAndRef - | None -> namedArgListWithKeyAndRef - in - let namedArgListWithKeyAndRefForNew = match forwardRef with - | Some(txt) -> namedArgList @ [(nolabel, None, Pat.var {txt; loc = emptyLoc}, txt, emptyLoc, None)] - | None -> namedArgList - in - let pluckArg (label, _, _, alias, loc, _) = - let labelString = (match label with | label when isOptional label || isLabelled label -> getLabel label | _ -> "") in - (label, - (match labelString with - | "" -> (Exp.ident ~loc { - txt = (Lident alias); - loc - }) - | labelString -> (Exp.apply ~loc - (Exp.ident ~loc {txt = (Lident "##"); loc }) - [ - (nolabel, Exp.ident ~loc {txt = (Lident props.propsName); loc }); - (nolabel, Exp.ident ~loc { - txt = (Lident labelString); - loc - }) - ] - ) - ) - ) in - let namedTypeList = List.fold_left argToType [] namedArgList in - let loc = emptyLoc in - let externalDecl = makeExternalDecl fnName loc namedArgListWithKeyAndRef namedTypeList in - let innerExpressionArgs = (List.map pluckArg namedArgListWithKeyAndRefForNew) @ - if hasUnit then [(Nolabel, Exp.construct {loc; txt = Lident "()"} None)] else [] in - let innerExpression = Exp.apply (Exp.ident {loc; txt = Lident( - match recFlag with - | Recursive -> internalFnName - | Nonrecursive -> fnName - )}) innerExpressionArgs in - let innerExpressionWithRef = match (forwardRef) with - | Some txt -> - {innerExpression with pexp_desc = Pexp_fun (nolabel, None, { - ppat_desc = Ppat_var { txt; loc = emptyLoc }; - ppat_loc = emptyLoc; - ppat_attributes = []; - }, innerExpression)} - | None -> innerExpression - in - let fullExpression = Exp.fun_ - nolabel - None - { - ppat_desc = Ppat_constraint ( - makePropsName ~loc:emptyLoc props.propsName, - makePropsType ~loc:emptyLoc namedTypeList - ); - ppat_loc = emptyLoc; - ppat_attributes = []; - } - innerExpressionWithRef in - let fullExpression = match (fullModuleName) with - | ("") -> fullExpression - | (txt) -> Exp.let_ - Nonrecursive - [Vb.mk - ~loc:emptyLoc - (Pat.var ~loc:emptyLoc {loc = emptyLoc; txt}) - fullExpression - ] - (Exp.ident ~loc:emptyLoc {loc = emptyLoc; txt = Lident txt}) in - let (bindings, newBinding) = - match recFlag with - | Recursive -> ([bindingWrapper (Exp.let_ - ~loc:(emptyLoc) - Recursive - [ - makeNewBinding binding expression internalFnName; - Vb.mk (Pat.var {loc = emptyLoc; txt = fnName}) fullExpression - ] - (Exp.ident {loc = emptyLoc; txt = Lident fnName}))], None) - | Nonrecursive -> ([{ binding with pvb_expr = expression; pvb_attributes = [] }], Some(bindingWrapper fullExpression)) - in - (Some externalDecl, bindings, newBinding) - else - (None, [binding], None) - in - let structuresAndBinding = List.map mapBinding valueBindings in - let otherStructures (extern, binding, newBinding) (externs, bindings, newBindings) = - let externs = match extern with - | Some extern -> extern :: externs - | None -> externs in - let newBindings = match newBinding with - | Some newBinding -> newBinding :: newBindings - | None -> newBindings in - (externs, binding @ bindings, newBindings) - in - let (externs, bindings, newBindings) = List.fold_right otherStructures structuresAndBinding ([], [], []) in - externs @ [{ - pstr_loc; - pstr_desc = Pstr_value ( - recFlag, - bindings - ) - }] @ (match newBindings with - | [] -> [] - | newBindings -> [{ - pstr_loc = emptyLoc; - pstr_desc = Pstr_value ( - recFlag, - newBindings - ) - }]) @ returnStructures - | structure -> structure :: returnStructures in - - let reactComponentTransform mapper structures = - List.fold_right (transformComponentDefinition mapper) structures [] in - - let transformComponentSignature _mapper signature returnSignatures = match signature with - | ({ - psig_loc; - psig_desc = Psig_value ({ - pval_name = { txt = fnName }; - pval_attributes; - pval_type; - } as psig_desc) - } as psig) -> - (match List.filter hasAttr pval_attributes with - | [] -> signature :: returnSignatures - | [_] -> - let rec getPropTypes types ({ptyp_loc; ptyp_desc} as fullType) = - (match ptyp_desc with - | Ptyp_arrow (name, type_, ({ptyp_desc = Ptyp_arrow _} as rest)) when isOptional name || isLabelled name -> - getPropTypes ((name, ptyp_loc, type_)::types) rest - | Ptyp_arrow (Nolabel, _type, rest) -> - getPropTypes types rest - | Ptyp_arrow (name, type_, returnValue) when isOptional name || isLabelled name -> - (returnValue, (name, returnValue.ptyp_loc, type_)::types) - | _ -> (fullType, types)) - in - let (innerType, propTypes) = getPropTypes [] pval_type in - let namedTypeList = List.fold_left argToConcreteType [] propTypes in - let pluckLabelAndLoc (label, loc, type_) = (label, None, loc, Some type_) in - let retPropsType = makePropsType ~loc:psig_loc namedTypeList in - let externalPropsDecl = makePropsExternalSig fnName psig_loc (( - optional "key", - None, - psig_loc, - Some(keyType psig_loc) - ) :: List.map pluckLabelAndLoc propTypes) retPropsType in - (* can't be an arrow because it will defensively uncurry *) - let newExternalType = Ptyp_constr ( - {loc = psig_loc; txt = Ldot ((Lident "React"), "componentLike")}, - [retPropsType; innerType] - ) in - let newStructure = { - psig with psig_desc = Psig_value { - psig_desc with pval_type = { - pval_type with ptyp_desc = newExternalType; - }; - pval_attributes = List.filter otherAttrsPure pval_attributes; - } - } in - externalPropsDecl :: newStructure :: returnSignatures - | _ -> raise (Invalid_argument "Only one react.component call can exist on a component at one time")) - | signature -> signature :: returnSignatures in - - let reactComponentSignatureTransform mapper signatures = - List.fold_right (transformComponentSignature mapper) signatures [] in - - - let transformJsxCall mapper callExpression callArguments attrs = - (match callExpression.pexp_desc with - | Pexp_ident caller -> - (match caller with - | {txt = Lident "createElement"} -> - raise (Invalid_argument "JSX: `createElement` should be preceeded by a module name.") - - (* Foo.createElement(~prop1=foo, ~prop2=bar, ~children=[], ()) *) - | {loc; txt = Ldot (modulePath, ("createElement" | "make"))} -> - (match !jsxVersion with - | None - | Some 3 -> transformUppercaseCall3 modulePath mapper loc attrs callExpression callArguments - | Some _ -> raise (Invalid_argument "JSX: the JSX version must be 3")) - - (* div(~prop1=foo, ~prop2=bar, ~children=[bla], ()) *) - (* turn that into - ReactDOMRe.createElement(~props=ReactDOMRe.props(~props1=foo, ~props2=bar, ()), [|bla|]) *) - | {loc; txt = Lident id} -> - (match !jsxVersion with - | None - | Some 3 -> transformLowercaseCall3 mapper loc attrs callArguments id - | Some _ -> raise (Invalid_argument "JSX: the JSX version must be 3")) - - | {txt = Ldot (_, anythingNotCreateElementOrMake)} -> - raise ( - Invalid_argument - ("JSX: the JSX attribute should be attached to a `YourModuleName.createElement` or `YourModuleName.make` call. We saw `" - ^ anythingNotCreateElementOrMake - ^ "` instead" - ) - ) - - | {txt = Lapply _} -> - (* don't think there's ever a case where this is reached *) - raise ( - Invalid_argument "JSX: encountered a weird case while processing the code. Please report this!" - ) - ) - | _ -> - raise ( - Invalid_argument "JSX: `createElement` should be preceeded by a simple, direct module name." - ) - ) in - - let signature = - (fun mapper signature -> default_mapper.signature mapper @@ reactComponentSignatureTransform mapper signature) in - - let structure = - (fun mapper structure -> match structure with - | structures -> begin - default_mapper.structure mapper @@ reactComponentTransform mapper structures - end - ) in - - let expr = - (fun mapper expression -> match expression with - (* Does the function application have the @JSX attribute? *) - | { - pexp_desc = Pexp_apply (callExpression, callArguments); - pexp_attributes - } -> - let (jsxAttribute, nonJSXAttributes) = List.partition (fun (attribute, _) -> attribute.txt = "JSX") pexp_attributes in - (match (jsxAttribute, nonJSXAttributes) with - (* no JSX attribute *) - | ([], _) -> default_mapper.expr mapper expression - | (_, nonJSXAttributes) -> transformJsxCall mapper callExpression callArguments nonJSXAttributes) - - (* is it a list with jsx attribute? Reason <>foo desugars to [@JSX][foo]*) - | { - pexp_desc = - Pexp_construct ({txt = Lident "::"; loc}, Some {pexp_desc = Pexp_tuple _}) - | Pexp_construct ({txt = Lident "[]"; loc}, None); - pexp_attributes - } as listItems -> - let (jsxAttribute, nonJSXAttributes) = List.partition (fun (attribute, _) -> attribute.txt = "JSX") pexp_attributes in - (match (jsxAttribute, nonJSXAttributes) with - (* no JSX attribute *) - | ([], _) -> default_mapper.expr mapper expression - | (_, nonJSXAttributes) -> - let fragment = Exp.ident ~loc {loc; txt = Ldot (Lident "ReasonReact", "fragment")} in - let childrenExpr = transformChildrenIfList ~loc ~mapper listItems in - let args = [ - (* "div" *) - (nolabel, fragment); - (* [|moreCreateElementCallsHere|] *) - (nolabel, childrenExpr) - ] in - Exp.apply - ~loc - (* throw away the [@JSX] attribute and keep the others, if any *) - ~attrs:nonJSXAttributes - (* ReactDOMRe.createElement *) - (Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOMRe", "createElement")}) - args - ) - (* Delegate to the default mapper, a deep identity traversal *) - | e -> default_mapper.expr mapper e) in - - let module_binding = - (fun mapper module_binding -> - let _ = nestedModules := module_binding.pmb_name.txt :: !nestedModules in - let mapped = default_mapper.module_binding mapper module_binding in - let _ = nestedModules := List.tl !nestedModules in - mapped - ) in - - { default_mapper with structure; expr; signature; module_binding; } - -let rewrite_implementation (code: Parsetree.structure) : Parsetree.structure = - let mapper = jsxMapper () in - mapper.structure mapper code -let rewrite_signature (code : Parsetree.signature) : Parsetree.signature = - let mapper = jsxMapper () in - mapper.signature mapper code - -#ifdef BINARY -let () = Ast_mapper.register "JSX" (fun _argv -> jsxMapper ()) -#endif diff --git a/scripts/ninja.js b/scripts/ninja.js index bded5701e1..9976a041dc 100755 --- a/scripts/ninja.js +++ b/scripts/ninja.js @@ -1559,9 +1559,6 @@ ${cppoList("outcome_printer", [ ["reason_syntax_util.ml", "reason_syntax_util.cppo.ml", ""], ["reason_syntax_util.mli", "reason_syntax_util.cppo.mli", ""], ])} -${cppoList("syntax", [ - ["reactjs_jsx_ppx_v3.ml", "reactjs_jsx_ppx.cppo.ml", ""], -])} build ../${ process.platform }/refmt.exe: link ${refmtMainPath}/refmt_main3.mli ${refmtMainPath}/refmt_main3.ml @@ -1647,7 +1644,7 @@ build common/bs_version.ml : mk_bsversion build_version.js ../package.json build ../${ process.platform - }/bsc: link js_parser/js_parser.cmxa stubs/stubs.cmxa ext/ext.cmxa common/common.cmxa syntax/syntax.cmxa depends/depends.cmxa super_errors/super_errors.cmxa outcome_printer/outcome_printer.cmxa core/core.cmxa napkin/napkin.cmxa main/js_main.cmx + }/bsc: link napkin/napkin.cmxa js_parser/js_parser.cmxa stubs/stubs.cmxa ext/ext.cmxa common/common.cmxa syntax/syntax.cmxa depends/depends.cmxa super_errors/super_errors.cmxa outcome_printer/outcome_printer.cmxa core/core.cmxa main/js_main.cmx libs = ocamlcommon.cmxa build ../${ process.platform From 94e3b766f354d7677b173099a18837ae196ec75b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Cha=CC=81varri?= Date: Fri, 23 Oct 2020 15:31:25 +0200 Subject: [PATCH 2/4] update with latest syntax submodule --- .gitmodules | 2 +- jscomp/syntax/ppx_entry.ml | 4 +- lib/4.06.1/unstable/js_compiler.ml | 977 ------------ lib/4.06.1/unstable/js_compiler.ml.d | 2 +- lib/4.06.1/unstable/js_refmt_compiler.ml | 977 ------------ lib/4.06.1/unstable/js_refmt_compiler.ml.d | 2 +- lib/4.06.1/whole_compiler.ml | 1606 ++++++++++---------- lib/4.06.1/whole_compiler.ml.d | 2 +- syntax | 2 +- 9 files changed, 821 insertions(+), 2753 deletions(-) diff --git a/.gitmodules b/.gitmodules index 6b891b0829..0305793235 100644 --- a/.gitmodules +++ b/.gitmodules @@ -8,5 +8,5 @@ branch = master [submodule "ninja"] path = ninja - url = git@github.com:rescript-lang/ninja.git + url = https://github.com/rescript-lang/ninja ignore = untracked diff --git a/jscomp/syntax/ppx_entry.ml b/jscomp/syntax/ppx_entry.ml index ba6abc7754..5631ee4c83 100644 --- a/jscomp/syntax/ppx_entry.ml +++ b/jscomp/syntax/ppx_entry.ml @@ -29,7 +29,7 @@ let rewrite_signature (ast : Parsetree.signature) : Parsetree.signature = Ast_config.iter_on_bs_config_sigi ast; let ast = match !Js_config.jsx_version with - | 3 -> Reactjs_jsx_ppx.rewrite_signature ast + | 3 -> Reactjs_jsx_ppx_v3.rewrite_signature ast | _ -> ast (* react-jsx ppx relies on built-in ones like `##` *) in @@ -48,7 +48,7 @@ let rewrite_implementation (ast : Parsetree.structure) : Parsetree.structure = Ast_config.iter_on_bs_config_stru ast ; let ast = match !Js_config.jsx_version with - | 3 -> Reactjs_jsx_ppx.rewrite_implementation ast + | 3 -> Reactjs_jsx_ppx_v3.rewrite_implementation ast | _ -> ast in if !Js_config.no_builtin_ppx then ast else diff --git a/lib/4.06.1/unstable/js_compiler.ml b/lib/4.06.1/unstable/js_compiler.ml index a4de45c7ed..3edbf175c8 100644 --- a/lib/4.06.1/unstable/js_compiler.ml +++ b/lib/4.06.1/unstable/js_compiler.ml @@ -408271,983 +408271,6 @@ let mapper : mapper = -end -module Reactjs_jsx_ppx_v3 -= struct -#1 "reactjs_jsx_ppx_v3.ml" -# 1 "syntax/reactjs_jsx_ppx.cppo.ml" -(* - This is the file that handles turning Reason JSX' agnostic function call into - a ReasonReact-specific function call. Aka, this is a macro, using OCaml's ppx - facilities; https://whitequark.org/blog/2014/04/16/a-guide-to-extension- - points-in-ocaml/ - You wouldn't use this file directly; it's used by BuckleScript's - bsconfig.json. Specifically, there's a field called `react-jsx` inside the - field `reason`, which enables this ppx through some internal call in bsb -*) - -(* - There are two different transforms that can be selected in this file (v2 and v3): - v2: - transform `[@JSX] div(~props1=a, ~props2=b, ~children=[foo, bar], ())` into - `ReactDOMRe.createElement("div", ~props={"props1": 1, "props2": b}, [|foo, - bar|])`. - transform `[@JSX] div(~props1=a, ~props2=b, ~children=foo, ())` into - `ReactDOMRe.createElementVariadic("div", ~props={"props1": 1, "props2": b}, foo)`. - transform the upper-cased case - `[@JSX] Foo.createElement(~key=a, ~ref=b, ~foo=bar, ~children=[], ())` into - `ReasonReact.element(~key=a, ~ref=b, Foo.make(~foo=bar, [||]))` - transform `[@JSX] [foo]` into - `ReactDOMRe.createElement(ReasonReact.fragment, [|foo|])` - v3: - transform `[@JSX] div(~props1=a, ~props2=b, ~children=[foo, bar], ())` into - `ReactDOMRe.createDOMElementVariadic("div", ReactDOMRe.domProps(~props1=1, ~props2=b), [|foo, bar|])`. - transform the upper-cased case - `[@JSX] Foo.createElement(~key=a, ~ref=b, ~foo=bar, ~children=[], ())` into - `React.createElement(Foo.make, Foo.makeProps(~key=a, ~ref=b, ~foo=bar, ()))` - transform the upper-cased case - `[@JSX] Foo.createElement(~foo=bar, ~children=[foo, bar], ())` into - `React.createElementVariadic(Foo.make, Foo.makeProps(~foo=bar, ~children=React.null, ()), [|foo, bar|])` - transform `[@JSX] [foo]` into - `ReactDOMRe.createElement(ReasonReact.fragment, [|foo|])` -*) - -open Ast_helper -open Ast_mapper -open Asttypes -open Parsetree -open Longident - -let rec find_opt p = function - | [] -> None - | x :: l -> if p x then Some x else find_opt p l - - - -let nolabel = Nolabel -let labelled str = Labelled str -let optional str = Optional str -let isOptional str = match str with -| Optional _ -> true -| _ -> false -let isLabelled str = match str with -| Labelled _ -> true -| _ -> false -let getLabel str = match str with -| Optional str | Labelled str -> str -| Nolabel -> "" -let optionIdent = Lident "option" - -let argIsKeyRef = function - | (Labelled ("key" | "ref"), _) | (Optional ("key" | "ref"), _) -> true - | _ -> false -let constantString ~loc str = Ast_helper.Exp.constant ~loc (Pconst_string (str, None)) - - -let safeTypeFromValue valueStr = -let valueStr = getLabel valueStr in -match String.sub valueStr 0 1 with -| "_" -> "T" ^ valueStr -| _ -> valueStr -let keyType loc = Typ.constr ~loc {loc; txt=optionIdent} [Typ.constr ~loc {loc; txt=Lident "string"} []] - -type 'a children = | ListLiteral of 'a | Exact of 'a -type componentConfig = { - propsName: string; -} - -(* if children is a list, convert it to an array while mapping each element. If not, just map over it, as usual *) -let transformChildrenIfListUpper ~loc ~mapper theList = - let rec transformChildren_ theList accum = - (* not in the sense of converting a list to an array; convert the AST - reprensentation of a list to the AST reprensentation of an array *) - match theList with - | {pexp_desc = Pexp_construct ({txt = Lident "[]"}, None)} -> begin - match accum with - | [singleElement] -> Exact singleElement - | accum -> ListLiteral (List.rev accum |> Exp.array ~loc) - end - | {pexp_desc = Pexp_construct ( - {txt = Lident "::"}, - Some {pexp_desc = Pexp_tuple (v::acc::[])} - )} -> - transformChildren_ acc ((mapper.expr mapper v)::accum) - | notAList -> Exact (mapper.expr mapper notAList) - in - transformChildren_ theList [] - -let transformChildrenIfList ~loc ~mapper theList = - let rec transformChildren_ theList accum = - (* not in the sense of converting a list to an array; convert the AST - reprensentation of a list to the AST reprensentation of an array *) - match theList with - | {pexp_desc = Pexp_construct ({txt = Lident "[]"}, None)} -> - List.rev accum |> Exp.array ~loc - | {pexp_desc = Pexp_construct ( - {txt = Lident "::"}, - Some {pexp_desc = Pexp_tuple (v::acc::[])} - )} -> - transformChildren_ acc ((mapper.expr mapper v)::accum) - | notAList -> mapper.expr mapper notAList - in - transformChildren_ theList [] - -let extractChildren ?(removeLastPositionUnit=false) ~loc propsAndChildren = - let rec allButLast_ lst acc = match lst with - | [] -> [] - | (Nolabel, {pexp_desc = Pexp_construct ({txt = Lident "()"}, None)})::[] -> acc - | (Nolabel, _) :: _rest -> raise (Invalid_argument "JSX: found non-labelled argument before the last position") - | arg::rest -> allButLast_ rest (arg::acc) - in - let allButLast lst = allButLast_ lst [] |> List.rev in - match (List.partition (fun (label, _) -> label = labelled "children") propsAndChildren) with - | ([], props) -> - (* no children provided? Place a placeholder list *) - (Exp.construct ~loc {loc; txt = Lident "[]"} None, if removeLastPositionUnit then allButLast props else props) - | ([(_, childrenExpr)], props) -> - (childrenExpr, if removeLastPositionUnit then allButLast props else props) - | _ -> raise (Invalid_argument "JSX: somehow there's more than one `children` label") - -let unerasableIgnore loc = ({loc; txt = "warning"}, (PStr [Str.eval (Exp.constant (Pconst_string ("-16", None)))])) -let merlinFocus = ({loc = Location.none; txt = "merlin.focus"}, (PStr [])) - -(* Helper method to look up the [@react.component] attribute *) -let hasAttr (loc, _) = - loc.txt = "react.component" - -(* Helper method to filter out any attribute that isn't [@react.component] *) -let otherAttrsPure (loc, _) = - loc.txt <> "react.component" - -(* Iterate over the attributes and try to find the [@react.component] attribute *) -let hasAttrOnBinding {pvb_attributes} = find_opt hasAttr pvb_attributes <> None - -(* Filter the [@react.component] attribute and immutably replace them on the binding *) -let filterAttrOnBinding binding = {binding with pvb_attributes = List.filter otherAttrsPure binding.pvb_attributes} - -(* Finds the name of the variable the binding is assigned to, otherwise raises Invalid_argument *) -let getFnName binding = - match binding with - | {pvb_pat = { - ppat_desc = Ppat_var {txt} - }} -> txt - | _ -> raise (Invalid_argument "react.component calls cannot be destructured.") - -let makeNewBinding binding expression newName = - match binding with - | {pvb_pat = { - ppat_desc = Ppat_var ( ppat_var) - } as pvb_pat} ->{ binding with pvb_pat = { - pvb_pat with - ppat_desc = Ppat_var {ppat_var with txt = newName}; - }; - pvb_expr = expression; - pvb_attributes = [merlinFocus]; - } - | _ -> raise (Invalid_argument "react.component calls cannot be destructured.") - -(* Lookup the value of `props` otherwise raise Invalid_argument error *) -let getPropsNameValue _acc (loc, exp) = - match (loc, exp) with - | ({ txt = Lident "props" }, { pexp_desc = Pexp_ident {txt = Lident str} }) -> { propsName = str } - | ({ txt }, _) -> raise (Invalid_argument ("react.component only accepts props as an option, given: " ^ Longident.last txt)) - -(* Lookup the `props` record or string as part of [@react.component] and store the name for use when rewriting *) -let getPropsAttr payload = - let defaultProps = {propsName = "Props"} in - match payload with - | Some(PStr( - {pstr_desc = Pstr_eval ({ - pexp_desc = Pexp_record (recordFields, None) - }, _)}::_rest - )) -> - List.fold_left getPropsNameValue defaultProps recordFields - | Some(PStr({pstr_desc = Pstr_eval ({pexp_desc = Pexp_ident {txt = Lident "props"}}, _)}::_rest)) -> {propsName = "props"} - | Some(PStr({pstr_desc = Pstr_eval (_, _)}::_rest)) -> raise (Invalid_argument ("react.component accepts a record config with props as an options.")) - | _ -> defaultProps - -(* Plucks the label, loc, and type_ from an AST node *) -let pluckLabelDefaultLocType (label, default, _, _, loc, type_) = (label, default, loc, type_) - -(* Lookup the filename from the location information on the AST node and turn it into a valid module identifier *) -let filenameFromLoc (pstr_loc: Location.t) = - let fileName = match pstr_loc.loc_start.pos_fname with - | "" -> !Location.input_name - | fileName -> fileName - in - let fileName = try - Filename.chop_extension (Filename.basename fileName) - with | Invalid_argument _-> fileName in - let fileName = String.capitalize_ascii fileName in - fileName - -(* Build a string representation of a module name with segments separated by $ *) -let makeModuleName fileName nestedModules fnName = - let fullModuleName = match (fileName, nestedModules, fnName) with - (* TODO: is this even reachable? It seems like the fileName always exists *) - | ("", nestedModules, "make") -> nestedModules - | ("", nestedModules, fnName) -> List.rev (fnName :: nestedModules) - | (fileName, nestedModules, "make") -> fileName :: (List.rev nestedModules) - | (fileName, nestedModules, fnName) -> fileName :: (List.rev (fnName :: nestedModules)) - in - let fullModuleName = String.concat "$" fullModuleName in - fullModuleName - -(* - AST node builders - These functions help us build AST nodes that are needed when transforming a [@react.component] into a - constructor and a props external -*) - -(* Build an AST node representing all named args for the `external` definition for a component's props *) -let rec recursivelyMakeNamedArgsForExternal list args = - match list with - | (label, default, loc, interiorType)::tl -> - recursivelyMakeNamedArgsForExternal tl (Typ.arrow - ~loc - label - (match (label, interiorType, default) with - (* ~foo=1 *) - | (label, None, Some _) -> - { - ptyp_desc = Ptyp_var (safeTypeFromValue label); - ptyp_loc = loc; - ptyp_attributes = []; - } - (* ~foo: int=1 *) - | (_label, Some type_, Some _) -> - type_ - - (* ~foo: option(int)=? *) - | (label, Some ({ptyp_desc = Ptyp_constr ({txt=(Lident "option")}, [type_])}), _) - | (label, Some ({ptyp_desc = Ptyp_constr ({txt=(Ldot (Lident "*predef*", "option"))}, [type_])}), _) - (* ~foo: int=? - note this isnt valid. but we want to get a type error *) - | (label, Some type_, _) when isOptional label -> - type_ - (* ~foo=? *) - | (label, None, _) when isOptional label -> - { - ptyp_desc = Ptyp_var (safeTypeFromValue label); - ptyp_loc = loc; - ptyp_attributes = []; - } - - (* ~foo *) - | (label, None, _) -> - { - ptyp_desc = Ptyp_var (safeTypeFromValue label); - ptyp_loc = loc; - ptyp_attributes = []; - } - | (_label, Some type_, _) -> - type_ - ) - args) - | [] -> args - -(* Build an AST node for the [@bs.obj] representing props for a component *) -let makePropsValue fnName loc namedArgListWithKeyAndRef propsType = - let propsName = fnName ^ "Props" in { - pval_name = {txt = propsName; loc}; - pval_type = - recursivelyMakeNamedArgsForExternal - namedArgListWithKeyAndRef - (Typ.arrow - nolabel - { - ptyp_desc = Ptyp_constr ({txt= Lident("unit"); loc}, []); - ptyp_loc = loc; - ptyp_attributes = []; - } - propsType - ); - pval_prim = [""]; - pval_attributes = [({txt = "bs.obj"; loc = loc}, PStr [])]; - pval_loc = loc; -} - -(* Build an AST node representing an `external` with the definition of the [@bs.obj] *) -let makePropsExternal fnName loc namedArgListWithKeyAndRef propsType = - { - pstr_loc = loc; - pstr_desc = Pstr_primitive (makePropsValue fnName loc namedArgListWithKeyAndRef propsType) - } - -(* Build an AST node for the signature of the `external` definition *) -let makePropsExternalSig fnName loc namedArgListWithKeyAndRef propsType = - { - psig_loc = loc; - psig_desc = Psig_value (makePropsValue fnName loc namedArgListWithKeyAndRef propsType) - } - -(* Build an AST node for the props name when converted to a Js.t inside the function signature *) -let makePropsName ~loc name = - { - ppat_desc = Ppat_var {txt = name; loc}; - ppat_loc = loc; - ppat_attributes = []; - } - - -let makeObjectField loc (str, attrs, type_) = - Otag ({ loc; txt = str }, attrs, type_) - - -(* Build an AST node representing a "closed" Js.t object representing a component's props *) -let makePropsType ~loc namedTypeList = - Typ.mk ~loc ( - Ptyp_constr({txt= Ldot (Lident("Js"), "t"); loc}, [{ - ptyp_desc = Ptyp_object( - List.map (makeObjectField loc) namedTypeList, - Closed - ); - ptyp_loc = loc; - ptyp_attributes = []; - }]) - ) - -(* Builds an AST node for the entire `external` definition of props *) -let makeExternalDecl fnName loc namedArgListWithKeyAndRef namedTypeList = - makePropsExternal - fnName - loc - (List.map pluckLabelDefaultLocType namedArgListWithKeyAndRef) - (makePropsType ~loc namedTypeList) - -(* TODO: some line number might still be wrong *) -let jsxMapper () = - - let jsxVersion = ref None in - - let transformUppercaseCall3 modulePath mapper loc attrs _ callArguments = - let (children, argsWithLabels) = extractChildren ~loc ~removeLastPositionUnit:true callArguments in - let argsForMake = argsWithLabels in - let childrenExpr = transformChildrenIfListUpper ~loc ~mapper children in - let recursivelyTransformedArgsForMake = argsForMake |> List.map (fun (label, expression) -> (label, mapper.expr mapper expression)) in - let childrenArg = ref None in - let args = recursivelyTransformedArgsForMake - @ (match childrenExpr with - | Exact children -> [(labelled "children", children)] - | ListLiteral ({ pexp_desc = Pexp_array list }) when list = [] -> [] - | ListLiteral expression -> - (* this is a hack to support react components that introspect into their children *) - (childrenArg := Some expression; - [(labelled "children", Exp.ident ~loc {loc; txt = Ldot (Lident "React", "null")})])) - @ [(nolabel, Exp.construct ~loc {loc; txt = Lident "()"} None)] in - let isCap str = let first = String.sub str 0 1 in - let capped = String.uppercase_ascii first in first = capped in - let ident = match modulePath with - | Lident _ -> Ldot (modulePath, "make") - | (Ldot (_modulePath, value) as fullPath) when isCap value -> Ldot (fullPath, "make") - | modulePath -> modulePath in - let propsIdent = match ident with - | Lident path -> Lident (path ^ "Props") - | Ldot(ident, path) -> Ldot (ident, path ^ "Props") - | _ -> raise (Invalid_argument "JSX name can't be the result of function applications") in - let props = - Exp.apply ~attrs ~loc (Exp.ident ~loc {loc; txt = propsIdent}) args in - (* handle key, ref, children *) - (* React.createElement(Component.make, props, ...children) *) - match (!childrenArg) with - | None -> - (Exp.apply - ~loc - ~attrs - (Exp.ident ~loc {loc; txt = Ldot (Lident "React", "createElement")}) - ([ - (nolabel, Exp.ident ~loc {txt = ident; loc}); - (nolabel, props) - ])) - | Some children -> - (Exp.apply - ~loc - ~attrs - (Exp.ident ~loc {loc; txt = Ldot (Lident "React", "createElementVariadic")}) - ([ - (nolabel, Exp.ident ~loc {txt = ident; loc}); - (nolabel, props); - (nolabel, children) - ])) - in - - let transformLowercaseCall3 mapper loc attrs callArguments id = - let (children, nonChildrenProps) = extractChildren ~loc callArguments in - let componentNameExpr = constantString ~loc id in - let childrenExpr = transformChildrenIfList ~loc ~mapper children in - let createElementCall = match children with - (* [@JSX] div(~children=[a]), coming from
a
*) - | { - pexp_desc = - Pexp_construct ({txt = Lident "::"}, Some {pexp_desc = Pexp_tuple _ }) - | Pexp_construct ({txt = Lident "[]"}, None) - } -> "createDOMElementVariadic" - (* [@JSX] div(~children= value), coming from
...(value)
*) - | _ -> raise (Invalid_argument "A spread as a DOM element's \ - children don't make sense written together. You can simply remove the spread.") - in - let args = match nonChildrenProps with - | [_justTheUnitArgumentAtEnd] -> - [ - (* "div" *) - (nolabel, componentNameExpr); - (* [|moreCreateElementCallsHere|] *) - (nolabel, childrenExpr) - ] - | nonEmptyProps -> - let propsCall = - Exp.apply - ~loc - (Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOMRe", "domProps")}) - (nonEmptyProps |> List.map (fun (label, expression) -> (label, mapper.expr mapper expression))) - in - [ - (* "div" *) - (nolabel, componentNameExpr); - (* ReactDOMRe.props(~className=blabla, ~foo=bar, ()) *) - (labelled "props", propsCall); - (* [|moreCreateElementCallsHere|] *) - (nolabel, childrenExpr) - ] in - Exp.apply - ~loc - (* throw away the [@JSX] attribute and keep the others, if any *) - ~attrs - (* ReactDOMRe.createElement *) - (Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOMRe", createElementCall)}) - args - in - - - - - let rec recursivelyTransformNamedArgsForMake mapper expr list = - let expr = mapper.expr mapper expr in - match expr.pexp_desc with - (* TODO: make this show up with a loc. *) - | Pexp_fun (Labelled "key", _, _, _) - | Pexp_fun (Optional "key", _, _, _) -> raise (Invalid_argument "Key cannot be accessed inside of a component. Don't worry - you can always key a component from its parent!") - | Pexp_fun (Labelled "ref", _, _, _) - | Pexp_fun (Optional "ref", _, _, _) -> raise (Invalid_argument "Ref cannot be passed as a normal prop. Please use `forwardRef` API instead.") - | Pexp_fun (arg, default, pattern, expression) when isOptional arg || isLabelled arg -> - let () = - (match (isOptional arg, pattern, default) with - | (true, { ppat_desc = Ppat_constraint (_, { ptyp_desc })}, None) -> - (match ptyp_desc with - | Ptyp_constr({txt=(Lident "option")}, [_]) -> () - | _ -> - let currentType = (match ptyp_desc with - | Ptyp_constr({txt}, []) -> String.concat "." (Longident.flatten txt) - | Ptyp_constr({txt}, _innerTypeArgs) -> String.concat "." (Longident.flatten txt) ^ "(...)" - | _ -> "...") - in - Location.prerr_warning pattern.ppat_loc - (Preprocessor - (Printf.sprintf "ReasonReact: optional argument annotations must have explicit `option`. Did you mean `option(%s)=?`?" currentType))) - | _ -> ()) in - let alias = (match pattern with - | {ppat_desc = Ppat_alias (_, {txt}) | Ppat_var {txt}} -> txt - | {ppat_desc = Ppat_any} -> "_" - | _ -> getLabel arg) in - let type_ = (match pattern with - | {ppat_desc = Ppat_constraint (_, type_)} -> Some type_ - | _ -> None) in - - recursivelyTransformNamedArgsForMake mapper expression ((arg, default, pattern, alias, pattern.ppat_loc, type_) :: list) - | Pexp_fun (Nolabel, _, { ppat_desc = (Ppat_construct ({txt = Lident "()"}, _) | Ppat_any)}, _expression) -> - (list, None) - | Pexp_fun (Nolabel, _, { ppat_desc = Ppat_var ({txt}) | Ppat_constraint ({ ppat_desc = Ppat_var ({txt})}, _)}, _expression) -> - (list, Some txt) - | Pexp_fun (Nolabel, _, pattern, _expression) -> - Location.raise_errorf ~loc:pattern.ppat_loc "ReasonReact: react.component refs only support plain arguments and type annotations." - | _ -> (list, None) - in - - - let argToType types (name, default, _noLabelName, _alias, loc, type_) = match (type_, name, default) with - | (Some ({ptyp_desc = Ptyp_constr ({txt=(Lident "option")}, [type_])}), name, _) when isOptional name -> - (getLabel name, [], { - type_ with - ptyp_desc = Ptyp_constr ({loc=type_.ptyp_loc; txt=optionIdent}, [type_]); - }) :: types - | (Some type_, name, Some _default) -> - (getLabel name, [], { - ptyp_desc = Ptyp_constr ({loc; txt=optionIdent}, [type_]); - ptyp_loc = loc; - ptyp_attributes = []; - }) :: types - | (Some type_, name, _) -> - (getLabel name, [], type_) :: types - | (None, name, _) when isOptional name -> - (getLabel name, [], { - ptyp_desc = Ptyp_constr ({loc; txt=optionIdent}, [{ - ptyp_desc = Ptyp_var (safeTypeFromValue name); - ptyp_loc = loc; - ptyp_attributes = []; - }]); - ptyp_loc = loc; - ptyp_attributes = []; - }) :: types - | (None, name, _) when isLabelled name -> - (getLabel name, [], { - ptyp_desc = Ptyp_var (safeTypeFromValue name); - ptyp_loc = loc; - ptyp_attributes = []; - }) :: types - | _ -> types - in - - let argToConcreteType types (name, loc, type_) = match name with - | name when isLabelled name -> - (getLabel name, [], type_) :: types - | name when isOptional name -> - (getLabel name, [], Typ.constr ~loc {loc; txt=optionIdent} [type_]) :: types - | _ -> types - in - - let nestedModules = ref([]) in - let transformComponentDefinition mapper structure returnStructures = match structure with - (* external *) - | ({ - pstr_loc; - pstr_desc = Pstr_primitive ({ - pval_name = { txt = fnName }; - pval_attributes; - pval_type; - } as value_description) - } as pstr) -> - (match List.filter hasAttr pval_attributes with - | [] -> structure :: returnStructures - | [_] -> - let rec getPropTypes types ({ptyp_loc; ptyp_desc} as fullType) = - (match ptyp_desc with - | Ptyp_arrow (name, type_, ({ptyp_desc = Ptyp_arrow _} as rest)) when isLabelled name || isOptional name -> - getPropTypes ((name, ptyp_loc, type_)::types) rest - | Ptyp_arrow (Nolabel, _type, rest) -> - getPropTypes types rest - | Ptyp_arrow (name, type_, returnValue) when isLabelled name || isOptional name -> - (returnValue, (name, returnValue.ptyp_loc, type_)::types) - | _ -> (fullType, types)) - in - let (innerType, propTypes) = getPropTypes [] pval_type in - let namedTypeList = List.fold_left argToConcreteType [] propTypes in - let pluckLabelAndLoc (label, loc, type_) = (label, None (* default *), loc, Some type_) in - let retPropsType = makePropsType ~loc:pstr_loc namedTypeList in - let externalPropsDecl = makePropsExternal fnName pstr_loc (( - optional "key", - None, - pstr_loc, - Some(keyType pstr_loc) - ) :: List.map pluckLabelAndLoc propTypes) retPropsType in - (* can't be an arrow because it will defensively uncurry *) - let newExternalType = Ptyp_constr ( - {loc = pstr_loc; txt = Ldot ((Lident "React"), "componentLike")}, - [retPropsType; innerType] - ) in - let newStructure = { - pstr with pstr_desc = Pstr_primitive { - value_description with pval_type = { - pval_type with ptyp_desc = newExternalType; - }; - pval_attributes = List.filter otherAttrsPure pval_attributes; - } - } in - externalPropsDecl :: newStructure :: returnStructures - | _ -> raise (Invalid_argument "Only one react.component call can exist on a component at one time")) - (* let component = ... *) - | { - pstr_loc; - pstr_desc = Pstr_value ( - recFlag, - valueBindings - ) - } -> - let fileName = filenameFromLoc pstr_loc in - let emptyLoc = Location.in_file fileName in - let mapBinding binding = if (hasAttrOnBinding binding) then - let bindingLoc = binding.pvb_loc in - let bindingPatLoc = binding.pvb_pat.ppat_loc in - let binding = { binding with pvb_pat = { binding.pvb_pat with ppat_loc = emptyLoc}; pvb_loc = emptyLoc} in - let fnName = getFnName binding in - let internalFnName = fnName ^ "$Internal" in - let fullModuleName = makeModuleName fileName !nestedModules fnName in - let modifiedBindingOld binding = - let expression = binding.pvb_expr in - (* TODO: there is a long-tail of unsupported features inside of blocks - Pexp_letmodule , Pexp_letexception , Pexp_ifthenelse *) - let rec spelunkForFunExpression expression = (match expression with - (* let make = (~prop) => ... *) - | { - pexp_desc = Pexp_fun _ - } -> expression - (* let make = {let foo = bar in (~prop) => ...} *) - | { - pexp_desc = Pexp_let (_recursive, _vbs, returnExpression) - } -> - (* here's where we spelunk! *) - spelunkForFunExpression returnExpression - (* let make = React.forwardRef((~prop) => ...) *) - - | { pexp_desc = Pexp_apply (_wrapperExpression, [(Nolabel, innerFunctionExpression)]) } -> - spelunkForFunExpression innerFunctionExpression - | { - pexp_desc = Pexp_sequence (_wrapperExpression, innerFunctionExpression) - } -> - spelunkForFunExpression innerFunctionExpression - | _ -> raise (Invalid_argument "react.component calls can only be on function definitions or component wrappers (forwardRef, memo).") - ) in - spelunkForFunExpression expression - in - let modifiedBinding binding = - let hasApplication = ref(false) in - let wrapExpressionWithBinding expressionFn expression = - Vb.mk - ~loc:bindingLoc - ~attrs:(List.filter otherAttrsPure binding.pvb_attributes) - (Pat.var ~loc:bindingPatLoc {loc = bindingPatLoc; txt = fnName}) (expressionFn expression) in - let expression = binding.pvb_expr in - let unerasableIgnoreExp exp = { exp with pexp_attributes = (unerasableIgnore emptyLoc) :: exp.pexp_attributes } in - (* TODO: there is a long-tail of unsupported features inside of blocks - Pexp_letmodule , Pexp_letexception , Pexp_ifthenelse *) - let rec spelunkForFunExpression expression = (match expression with - (* let make = (~prop) => ... with no final unit *) - | { - pexp_desc = Pexp_fun ((Labelled(_) | Optional(_) as label), default, pattern, ({pexp_desc = Pexp_fun _} as internalExpression)) - } -> - let (wrap, hasUnit, exp) = spelunkForFunExpression internalExpression in - (wrap, hasUnit, unerasableIgnoreExp {expression with pexp_desc = Pexp_fun (label, default, pattern, exp)}) - (* let make = (()) => ... *) - (* let make = (_) => ... *) - | { - pexp_desc = Pexp_fun (Nolabel, _default, { ppat_desc = Ppat_construct ({txt = Lident "()"}, _) | Ppat_any}, _internalExpression) - } -> ((fun a -> a), true, expression) - (* let make = (~prop) => ... *) - | { - pexp_desc = Pexp_fun ((Labelled(_) | Optional(_)), _default, _pattern, _internalExpression) - } -> ((fun a -> a), false, unerasableIgnoreExp expression) - (* let make = (prop) => ... *) - | { - pexp_desc = Pexp_fun (_nolabel, _default, pattern, _internalExpression) - } -> - if (hasApplication.contents) then - ((fun a -> a), false, unerasableIgnoreExp expression) - else - Location.raise_errorf ~loc:pattern.ppat_loc "ReasonReact: props need to be labelled arguments.\n If you are working with refs be sure to wrap with React.forwardRef.\n If your component doesn't have any props use () or _ instead of a name." - (* let make = {let foo = bar in (~prop) => ...} *) - | { - pexp_desc = Pexp_let (recursive, vbs, internalExpression) - } -> - (* here's where we spelunk! *) - let (wrap, hasUnit, exp) = spelunkForFunExpression internalExpression in - (wrap, hasUnit, {expression with pexp_desc = Pexp_let (recursive, vbs, exp)}) - (* let make = React.forwardRef((~prop) => ...) *) - | { pexp_desc = Pexp_apply (wrapperExpression, [(Nolabel, internalExpression)]) } -> - let () = hasApplication := true in - let (_, hasUnit, exp) = spelunkForFunExpression internalExpression in - ((fun exp -> Exp.apply wrapperExpression [(nolabel, exp)]), hasUnit, exp) - | { - pexp_desc = Pexp_sequence (wrapperExpression, internalExpression) - } -> - let (wrap, hasUnit, exp) = spelunkForFunExpression internalExpression in - (wrap, hasUnit, {expression with pexp_desc = Pexp_sequence (wrapperExpression, exp)}) - | e -> ((fun a -> a), false, e) - ) in - let (wrapExpression, hasUnit, expression) = spelunkForFunExpression expression in - (wrapExpressionWithBinding wrapExpression, hasUnit, expression) - in - let (bindingWrapper, hasUnit, expression) = modifiedBinding binding in - let reactComponentAttribute = try - Some(List.find hasAttr binding.pvb_attributes) - with | Not_found -> None in - let (_attr_loc, payload) = match reactComponentAttribute with - | Some (loc, payload) -> (loc.loc, Some payload) - | None -> (emptyLoc, None) in - let props = getPropsAttr payload in - (* do stuff here! *) - let (namedArgList, forwardRef) = recursivelyTransformNamedArgsForMake mapper (modifiedBindingOld binding) [] in - let namedArgListWithKeyAndRef = (optional("key"), None, Pat.var {txt = "key"; loc = emptyLoc}, "key", emptyLoc, Some(keyType emptyLoc)) :: namedArgList in - let namedArgListWithKeyAndRef = match forwardRef with - | Some(_) -> (optional("ref"), None, Pat.var {txt = "key"; loc = emptyLoc}, "ref", emptyLoc, None) :: namedArgListWithKeyAndRef - | None -> namedArgListWithKeyAndRef - in - let namedArgListWithKeyAndRefForNew = match forwardRef with - | Some(txt) -> namedArgList @ [(nolabel, None, Pat.var {txt; loc = emptyLoc}, txt, emptyLoc, None)] - | None -> namedArgList - in - let pluckArg (label, _, _, alias, loc, _) = - let labelString = (match label with | label when isOptional label || isLabelled label -> getLabel label | _ -> "") in - (label, - (match labelString with - | "" -> (Exp.ident ~loc { - txt = (Lident alias); - loc - }) - | labelString -> (Exp.apply ~loc - (Exp.ident ~loc {txt = (Lident "##"); loc }) - [ - (nolabel, Exp.ident ~loc {txt = (Lident props.propsName); loc }); - (nolabel, Exp.ident ~loc { - txt = (Lident labelString); - loc - }) - ] - ) - ) - ) in - let namedTypeList = List.fold_left argToType [] namedArgList in - let loc = emptyLoc in - let externalDecl = makeExternalDecl fnName loc namedArgListWithKeyAndRef namedTypeList in - let innerExpressionArgs = (List.map pluckArg namedArgListWithKeyAndRefForNew) @ - if hasUnit then [(Nolabel, Exp.construct {loc; txt = Lident "()"} None)] else [] in - let innerExpression = Exp.apply (Exp.ident {loc; txt = Lident( - match recFlag with - | Recursive -> internalFnName - | Nonrecursive -> fnName - )}) innerExpressionArgs in - let innerExpressionWithRef = match (forwardRef) with - | Some txt -> - {innerExpression with pexp_desc = Pexp_fun (nolabel, None, { - ppat_desc = Ppat_var { txt; loc = emptyLoc }; - ppat_loc = emptyLoc; - ppat_attributes = []; - }, innerExpression)} - | None -> innerExpression - in - let fullExpression = Exp.fun_ - nolabel - None - { - ppat_desc = Ppat_constraint ( - makePropsName ~loc:emptyLoc props.propsName, - makePropsType ~loc:emptyLoc namedTypeList - ); - ppat_loc = emptyLoc; - ppat_attributes = []; - } - innerExpressionWithRef in - let fullExpression = match (fullModuleName) with - | ("") -> fullExpression - | (txt) -> Exp.let_ - Nonrecursive - [Vb.mk - ~loc:emptyLoc - (Pat.var ~loc:emptyLoc {loc = emptyLoc; txt}) - fullExpression - ] - (Exp.ident ~loc:emptyLoc {loc = emptyLoc; txt = Lident txt}) in - let (bindings, newBinding) = - match recFlag with - | Recursive -> ([bindingWrapper (Exp.let_ - ~loc:(emptyLoc) - Recursive - [ - makeNewBinding binding expression internalFnName; - Vb.mk (Pat.var {loc = emptyLoc; txt = fnName}) fullExpression - ] - (Exp.ident {loc = emptyLoc; txt = Lident fnName}))], None) - | Nonrecursive -> ([{ binding with pvb_expr = expression; pvb_attributes = [] }], Some(bindingWrapper fullExpression)) - in - (Some externalDecl, bindings, newBinding) - else - (None, [binding], None) - in - let structuresAndBinding = List.map mapBinding valueBindings in - let otherStructures (extern, binding, newBinding) (externs, bindings, newBindings) = - let externs = match extern with - | Some extern -> extern :: externs - | None -> externs in - let newBindings = match newBinding with - | Some newBinding -> newBinding :: newBindings - | None -> newBindings in - (externs, binding @ bindings, newBindings) - in - let (externs, bindings, newBindings) = List.fold_right otherStructures structuresAndBinding ([], [], []) in - externs @ [{ - pstr_loc; - pstr_desc = Pstr_value ( - recFlag, - bindings - ) - }] @ (match newBindings with - | [] -> [] - | newBindings -> [{ - pstr_loc = emptyLoc; - pstr_desc = Pstr_value ( - recFlag, - newBindings - ) - }]) @ returnStructures - | structure -> structure :: returnStructures in - - let reactComponentTransform mapper structures = - List.fold_right (transformComponentDefinition mapper) structures [] in - - let transformComponentSignature _mapper signature returnSignatures = match signature with - | ({ - psig_loc; - psig_desc = Psig_value ({ - pval_name = { txt = fnName }; - pval_attributes; - pval_type; - } as psig_desc) - } as psig) -> - (match List.filter hasAttr pval_attributes with - | [] -> signature :: returnSignatures - | [_] -> - let rec getPropTypes types ({ptyp_loc; ptyp_desc} as fullType) = - (match ptyp_desc with - | Ptyp_arrow (name, type_, ({ptyp_desc = Ptyp_arrow _} as rest)) when isOptional name || isLabelled name -> - getPropTypes ((name, ptyp_loc, type_)::types) rest - | Ptyp_arrow (Nolabel, _type, rest) -> - getPropTypes types rest - | Ptyp_arrow (name, type_, returnValue) when isOptional name || isLabelled name -> - (returnValue, (name, returnValue.ptyp_loc, type_)::types) - | _ -> (fullType, types)) - in - let (innerType, propTypes) = getPropTypes [] pval_type in - let namedTypeList = List.fold_left argToConcreteType [] propTypes in - let pluckLabelAndLoc (label, loc, type_) = (label, None, loc, Some type_) in - let retPropsType = makePropsType ~loc:psig_loc namedTypeList in - let externalPropsDecl = makePropsExternalSig fnName psig_loc (( - optional "key", - None, - psig_loc, - Some(keyType psig_loc) - ) :: List.map pluckLabelAndLoc propTypes) retPropsType in - (* can't be an arrow because it will defensively uncurry *) - let newExternalType = Ptyp_constr ( - {loc = psig_loc; txt = Ldot ((Lident "React"), "componentLike")}, - [retPropsType; innerType] - ) in - let newStructure = { - psig with psig_desc = Psig_value { - psig_desc with pval_type = { - pval_type with ptyp_desc = newExternalType; - }; - pval_attributes = List.filter otherAttrsPure pval_attributes; - } - } in - externalPropsDecl :: newStructure :: returnSignatures - | _ -> raise (Invalid_argument "Only one react.component call can exist on a component at one time")) - | signature -> signature :: returnSignatures in - - let reactComponentSignatureTransform mapper signatures = - List.fold_right (transformComponentSignature mapper) signatures [] in - - - let transformJsxCall mapper callExpression callArguments attrs = - (match callExpression.pexp_desc with - | Pexp_ident caller -> - (match caller with - | {txt = Lident "createElement"} -> - raise (Invalid_argument "JSX: `createElement` should be preceeded by a module name.") - - (* Foo.createElement(~prop1=foo, ~prop2=bar, ~children=[], ()) *) - | {loc; txt = Ldot (modulePath, ("createElement" | "make"))} -> - (match !jsxVersion with - | None - | Some 3 -> transformUppercaseCall3 modulePath mapper loc attrs callExpression callArguments - | Some _ -> raise (Invalid_argument "JSX: the JSX version must be 3")) - - (* div(~prop1=foo, ~prop2=bar, ~children=[bla], ()) *) - (* turn that into - ReactDOMRe.createElement(~props=ReactDOMRe.props(~props1=foo, ~props2=bar, ()), [|bla|]) *) - | {loc; txt = Lident id} -> - (match !jsxVersion with - | None - | Some 3 -> transformLowercaseCall3 mapper loc attrs callArguments id - | Some _ -> raise (Invalid_argument "JSX: the JSX version must be 3")) - - | {txt = Ldot (_, anythingNotCreateElementOrMake)} -> - raise ( - Invalid_argument - ("JSX: the JSX attribute should be attached to a `YourModuleName.createElement` or `YourModuleName.make` call. We saw `" - ^ anythingNotCreateElementOrMake - ^ "` instead" - ) - ) - - | {txt = Lapply _} -> - (* don't think there's ever a case where this is reached *) - raise ( - Invalid_argument "JSX: encountered a weird case while processing the code. Please report this!" - ) - ) - | _ -> - raise ( - Invalid_argument "JSX: `createElement` should be preceeded by a simple, direct module name." - ) - ) in - - let signature = - (fun mapper signature -> default_mapper.signature mapper @@ reactComponentSignatureTransform mapper signature) in - - let structure = - (fun mapper structure -> match structure with - | structures -> begin - default_mapper.structure mapper @@ reactComponentTransform mapper structures - end - ) in - - let expr = - (fun mapper expression -> match expression with - (* Does the function application have the @JSX attribute? *) - | { - pexp_desc = Pexp_apply (callExpression, callArguments); - pexp_attributes - } -> - let (jsxAttribute, nonJSXAttributes) = List.partition (fun (attribute, _) -> attribute.txt = "JSX") pexp_attributes in - (match (jsxAttribute, nonJSXAttributes) with - (* no JSX attribute *) - | ([], _) -> default_mapper.expr mapper expression - | (_, nonJSXAttributes) -> transformJsxCall mapper callExpression callArguments nonJSXAttributes) - - (* is it a list with jsx attribute? Reason <>foo desugars to [@JSX][foo]*) - | { - pexp_desc = - Pexp_construct ({txt = Lident "::"; loc}, Some {pexp_desc = Pexp_tuple _}) - | Pexp_construct ({txt = Lident "[]"; loc}, None); - pexp_attributes - } as listItems -> - let (jsxAttribute, nonJSXAttributes) = List.partition (fun (attribute, _) -> attribute.txt = "JSX") pexp_attributes in - (match (jsxAttribute, nonJSXAttributes) with - (* no JSX attribute *) - | ([], _) -> default_mapper.expr mapper expression - | (_, nonJSXAttributes) -> - let fragment = Exp.ident ~loc {loc; txt = Ldot (Lident "ReasonReact", "fragment")} in - let childrenExpr = transformChildrenIfList ~loc ~mapper listItems in - let args = [ - (* "div" *) - (nolabel, fragment); - (* [|moreCreateElementCallsHere|] *) - (nolabel, childrenExpr) - ] in - Exp.apply - ~loc - (* throw away the [@JSX] attribute and keep the others, if any *) - ~attrs:nonJSXAttributes - (* ReactDOMRe.createElement *) - (Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOMRe", "createElement")}) - args - ) - (* Delegate to the default mapper, a deep identity traversal *) - | e -> default_mapper.expr mapper e) in - - let module_binding = - (fun mapper module_binding -> - let _ = nestedModules := module_binding.pmb_name.txt :: !nestedModules in - let mapped = default_mapper.module_binding mapper module_binding in - let _ = nestedModules := List.tl !nestedModules in - mapped - ) in - - { default_mapper with structure; expr; signature; module_binding; } - -let rewrite_implementation (code: Parsetree.structure) : Parsetree.structure = - let mapper = jsxMapper () in - mapper.structure mapper code -let rewrite_signature (code : Parsetree.signature) : Parsetree.signature = - let mapper = jsxMapper () in - mapper.signature mapper code - - end module Ppx_entry = struct diff --git a/lib/4.06.1/unstable/js_compiler.ml.d b/lib/4.06.1/unstable/js_compiler.ml.d index fb82dc653c..20398afb0e 100644 --- a/lib/4.06.1/unstable/js_compiler.ml.d +++ b/lib/4.06.1/unstable/js_compiler.ml.d @@ -1 +1 @@ -../lib/4.06.1/unstable/js_compiler.ml: ../ocaml/bytecomp/lambda.ml ../ocaml/bytecomp/lambda.mli ../ocaml/bytecomp/matching.ml ../ocaml/bytecomp/matching.mli ../ocaml/bytecomp/printlambda.ml ../ocaml/bytecomp/printlambda.mli ../ocaml/bytecomp/switch.ml ../ocaml/bytecomp/switch.mli ../ocaml/bytecomp/translattribute.ml ../ocaml/bytecomp/translattribute.mli ../ocaml/bytecomp/translclass.ml ../ocaml/bytecomp/translclass.mli ../ocaml/bytecomp/translcore.ml ../ocaml/bytecomp/translcore.mli ../ocaml/bytecomp/translmod.ml ../ocaml/bytecomp/translmod.mli ../ocaml/bytecomp/translobj.ml ../ocaml/bytecomp/translobj.mli ../ocaml/parsing/ast_helper.ml ../ocaml/parsing/ast_helper.mli ../ocaml/parsing/ast_iterator.ml ../ocaml/parsing/ast_iterator.mli ../ocaml/parsing/ast_mapper.ml ../ocaml/parsing/ast_mapper.mli ../ocaml/parsing/asttypes.mli ../ocaml/parsing/attr_helper.ml ../ocaml/parsing/attr_helper.mli ../ocaml/parsing/builtin_attributes.ml ../ocaml/parsing/builtin_attributes.mli ../ocaml/parsing/docstrings.ml ../ocaml/parsing/docstrings.mli ../ocaml/parsing/lexer.ml ../ocaml/parsing/lexer.mli ../ocaml/parsing/location.ml ../ocaml/parsing/location.mli ../ocaml/parsing/longident.ml ../ocaml/parsing/longident.mli ../ocaml/parsing/parse.ml ../ocaml/parsing/parse.mli ../ocaml/parsing/parser.ml ../ocaml/parsing/parser.mli ../ocaml/parsing/parsetree.mli ../ocaml/parsing/syntaxerr.ml ../ocaml/parsing/syntaxerr.mli ../ocaml/typing/annot.mli ../ocaml/typing/btype.ml ../ocaml/typing/btype.mli ../ocaml/typing/cmi_format.ml ../ocaml/typing/cmi_format.mli ../ocaml/typing/cmt_format.ml ../ocaml/typing/cmt_format.mli ../ocaml/typing/ctype.ml ../ocaml/typing/ctype.mli ../ocaml/typing/datarepr.ml ../ocaml/typing/datarepr.mli ../ocaml/typing/env.ml ../ocaml/typing/env.mli ../ocaml/typing/ident.ml ../ocaml/typing/ident.mli ../ocaml/typing/includeclass.ml ../ocaml/typing/includeclass.mli ../ocaml/typing/includecore.ml ../ocaml/typing/includecore.mli ../ocaml/typing/includemod.ml ../ocaml/typing/includemod.mli ../ocaml/typing/mtype.ml ../ocaml/typing/mtype.mli ../ocaml/typing/oprint.ml ../ocaml/typing/oprint.mli ../ocaml/typing/outcometree.mli ../ocaml/typing/parmatch.ml ../ocaml/typing/parmatch.mli ../ocaml/typing/path.ml ../ocaml/typing/path.mli ../ocaml/typing/predef.ml ../ocaml/typing/predef.mli ../ocaml/typing/primitive.ml ../ocaml/typing/primitive.mli ../ocaml/typing/printtyp.ml ../ocaml/typing/printtyp.mli ../ocaml/typing/stypes.ml ../ocaml/typing/stypes.mli ../ocaml/typing/subst.ml ../ocaml/typing/subst.mli ../ocaml/typing/tast_mapper.ml ../ocaml/typing/tast_mapper.mli ../ocaml/typing/typeclass.ml ../ocaml/typing/typeclass.mli ../ocaml/typing/typecore.ml ../ocaml/typing/typecore.mli ../ocaml/typing/typedecl.ml ../ocaml/typing/typedecl.mli ../ocaml/typing/typedtree.ml ../ocaml/typing/typedtree.mli ../ocaml/typing/typedtreeIter.ml ../ocaml/typing/typedtreeIter.mli ../ocaml/typing/typemod.ml ../ocaml/typing/typemod.mli ../ocaml/typing/typeopt.ml ../ocaml/typing/typeopt.mli ../ocaml/typing/types.ml ../ocaml/typing/types.mli ../ocaml/typing/typetexp.ml ../ocaml/typing/typetexp.mli ../ocaml/typing/untypeast.ml ../ocaml/typing/untypeast.mli ../ocaml/utils/arg_helper.ml ../ocaml/utils/arg_helper.mli ../ocaml/utils/ccomp.ml ../ocaml/utils/ccomp.mli ../ocaml/utils/clflags.ml ../ocaml/utils/clflags.mli ../ocaml/utils/consistbl.ml ../ocaml/utils/consistbl.mli ../ocaml/utils/identifiable.ml ../ocaml/utils/identifiable.mli ../ocaml/utils/misc.ml ../ocaml/utils/misc.mli ../ocaml/utils/numbers.ml ../ocaml/utils/numbers.mli ../ocaml/utils/profile.ml ../ocaml/utils/profile.mli ../ocaml/utils/tbl.ml ../ocaml/utils/tbl.mli ../ocaml/utils/warnings.ml ../ocaml/utils/warnings.mli ./common/bs_loc.ml ./common/bs_loc.mli ./common/bs_version.ml ./common/bs_version.mli ./common/bs_warnings.ml ./common/bs_warnings.mli ./common/ext_log.ml ./common/ext_log.mli ./common/js_config.ml ./common/js_config.mli ./common/lam_methname.ml ./common/lam_methname.mli ./core/bs_cmi_load.ml ./core/bs_conditional_initial.ml ./core/bs_conditional_initial.mli ./core/compile_rec_module.ml ./core/config_util.ml ./core/config_util.mli ./core/config_whole_compiler.ml ./core/config_whole_compiler.mli ./core/j.ml ./core/js_analyzer.ml ./core/js_analyzer.mli ./core/js_arr.ml ./core/js_arr.mli ./core/js_ast_util.ml ./core/js_ast_util.mli ./core/js_block_runtime.ml ./core/js_block_runtime.mli ./core/js_call_info.ml ./core/js_call_info.mli ./core/js_closure.ml ./core/js_closure.mli ./core/js_cmj_format.ml ./core/js_cmj_format.mli ./core/js_cmj_load.ml ./core/js_cmj_load.mli ./core/js_cmj_load_builtin_unit.ml ./core/js_dump.ml ./core/js_dump.mli ./core/js_dump_import_export.ml ./core/js_dump_import_export.mli ./core/js_dump_lit.ml ./core/js_dump_program.ml ./core/js_dump_program.mli ./core/js_dump_property.ml ./core/js_dump_property.mli ./core/js_dump_string.ml ./core/js_dump_string.mli ./core/js_exp_make.ml ./core/js_exp_make.mli ./core/js_fold.ml ./core/js_fold_basic.ml ./core/js_fold_basic.mli ./core/js_fun_env.ml ./core/js_fun_env.mli ./core/js_long.ml ./core/js_long.mli ./core/js_map.ml ./core/js_name_of_module_id.ml ./core/js_name_of_module_id.mli ./core/js_number.ml ./core/js_number.mli ./core/js_of_lam_array.ml ./core/js_of_lam_array.mli ./core/js_of_lam_block.ml ./core/js_of_lam_block.mli ./core/js_of_lam_exception.ml ./core/js_of_lam_exception.mli ./core/js_of_lam_option.ml ./core/js_of_lam_option.mli ./core/js_of_lam_string.ml ./core/js_of_lam_string.mli ./core/js_of_lam_variant.ml ./core/js_of_lam_variant.mli ./core/js_op.ml ./core/js_op_util.ml ./core/js_op_util.mli ./core/js_output.ml ./core/js_output.mli ./core/js_packages_info.ml ./core/js_packages_info.mli ./core/js_packages_state.ml ./core/js_packages_state.mli ./core/js_pass_debug.ml ./core/js_pass_debug.mli ./core/js_pass_flatten.ml ./core/js_pass_flatten.mli ./core/js_pass_flatten_and_mark_dead.ml ./core/js_pass_flatten_and_mark_dead.mli ./core/js_pass_get_used.ml ./core/js_pass_get_used.mli ./core/js_pass_scope.ml ./core/js_pass_scope.mli ./core/js_pass_tailcall_inline.ml ./core/js_pass_tailcall_inline.mli ./core/js_raw_info.ml ./core/js_shake.ml ./core/js_shake.mli ./core/js_stmt_make.ml ./core/js_stmt_make.mli ./core/lam.ml ./core/lam.mli ./core/lam_analysis.ml ./core/lam_analysis.mli ./core/lam_arity.ml ./core/lam_arity.mli ./core/lam_arity_analysis.ml ./core/lam_arity_analysis.mli ./core/lam_beta_reduce.ml ./core/lam_beta_reduce.mli ./core/lam_beta_reduce_util.ml ./core/lam_beta_reduce_util.mli ./core/lam_bounded_vars.ml ./core/lam_bounded_vars.mli ./core/lam_closure.ml ./core/lam_closure.mli ./core/lam_coercion.ml ./core/lam_coercion.mli ./core/lam_compat.ml ./core/lam_compat.mli ./core/lam_compile.ml ./core/lam_compile.mli ./core/lam_compile_const.ml ./core/lam_compile_const.mli ./core/lam_compile_context.ml ./core/lam_compile_context.mli ./core/lam_compile_env.ml ./core/lam_compile_env.mli ./core/lam_compile_external_call.ml ./core/lam_compile_external_call.mli ./core/lam_compile_external_obj.ml ./core/lam_compile_external_obj.mli ./core/lam_compile_main.ml ./core/lam_compile_main.mli ./core/lam_compile_primitive.ml ./core/lam_compile_primitive.mli ./core/lam_compile_util.ml ./core/lam_compile_util.mli ./core/lam_constant.ml ./core/lam_constant.mli ./core/lam_constant_convert.ml ./core/lam_constant_convert.mli ./core/lam_convert.ml ./core/lam_convert.mli ./core/lam_dce.ml ./core/lam_dce.mli ./core/lam_dispatch_primitive.ml ./core/lam_dispatch_primitive.mli ./core/lam_eta_conversion.ml ./core/lam_eta_conversion.mli ./core/lam_exit_code.ml ./core/lam_exit_code.mli ./core/lam_exit_count.ml ./core/lam_exit_count.mli ./core/lam_free_variables.ml ./core/lam_free_variables.mli ./core/lam_group.ml ./core/lam_group.mli ./core/lam_hit.ml ./core/lam_hit.mli ./core/lam_id_kind.ml ./core/lam_id_kind.mli ./core/lam_iter.ml ./core/lam_iter.mli ./core/lam_module_ident.ml ./core/lam_module_ident.mli ./core/lam_pass_alpha_conversion.ml ./core/lam_pass_alpha_conversion.mli ./core/lam_pass_collect.ml ./core/lam_pass_collect.mli ./core/lam_pass_count.ml ./core/lam_pass_count.mli ./core/lam_pass_deep_flatten.ml ./core/lam_pass_deep_flatten.mli ./core/lam_pass_eliminate_ref.ml ./core/lam_pass_eliminate_ref.mli ./core/lam_pass_exits.ml ./core/lam_pass_exits.mli ./core/lam_pass_lets_dce.ml ./core/lam_pass_lets_dce.mli ./core/lam_pass_remove_alias.ml ./core/lam_pass_remove_alias.mli ./core/lam_pointer_info.ml ./core/lam_pointer_info.mli ./core/lam_primitive.ml ./core/lam_primitive.mli ./core/lam_print.ml ./core/lam_print.mli ./core/lam_scc.ml ./core/lam_scc.mli ./core/lam_stats.ml ./core/lam_stats.mli ./core/lam_stats_export.ml ./core/lam_stats_export.mli ./core/lam_subst.ml ./core/lam_subst.mli ./core/lam_tag_info.ml ./core/lam_util.ml ./core/lam_util.mli ./core/lam_var_stats.ml ./core/lam_var_stats.mli ./core/matching_polyfill.ml ./core/matching_polyfill.mli ./core/polyvar_pattern_match.ml ./core/record_attributes_check.ml ./core/res_compmisc.ml ./core/res_compmisc.mli ./core/transl_single_field_record.ml ./depends/bs_exception.ml ./depends/bs_exception.mli ./ext/bsc_args.ml ./ext/bsc_args.mli ./ext/bsc_warnings.ml ./ext/ext_array.ml ./ext/ext_array.mli ./ext/ext_buffer.ml ./ext/ext_buffer.mli ./ext/ext_bytes.ml ./ext/ext_bytes.mli ./ext/ext_char.ml ./ext/ext_char.mli ./ext/ext_digest.ml ./ext/ext_digest.mli ./ext/ext_filename.ml ./ext/ext_filename.mli ./ext/ext_fmt.ml ./ext/ext_ident.ml ./ext/ext_ident.mli ./ext/ext_int.ml ./ext/ext_int.mli ./ext/ext_io.ml ./ext/ext_io.mli ./ext/ext_js_file_kind.ml ./ext/ext_js_suffix.ml ./ext/ext_list.ml ./ext/ext_list.mli ./ext/ext_marshal.ml ./ext/ext_marshal.mli ./ext/ext_modulename.ml ./ext/ext_modulename.mli ./ext/ext_namespace.ml ./ext/ext_namespace.mli ./ext/ext_option.ml ./ext/ext_option.mli ./ext/ext_path.ml ./ext/ext_path.mli ./ext/ext_pervasives.ml ./ext/ext_pervasives.mli ./ext/ext_pp.ml ./ext/ext_pp.mli ./ext/ext_pp_scope.ml ./ext/ext_pp_scope.mli ./ext/ext_ref.ml ./ext/ext_ref.mli ./ext/ext_scc.ml ./ext/ext_scc.mli ./ext/ext_spec.ml ./ext/ext_spec.mli ./ext/ext_string.ml ./ext/ext_string.mli ./ext/ext_string_array.ml ./ext/ext_string_array.mli ./ext/ext_sys.ml ./ext/ext_sys.mli ./ext/ext_utf8.ml ./ext/ext_utf8.mli ./ext/ext_util.ml ./ext/ext_util.mli ./ext/hash.ml ./ext/hash.mli ./ext/hash_gen.ml ./ext/hash_ident.ml ./ext/hash_ident.mli ./ext/hash_int.ml ./ext/hash_int.mli ./ext/hash_set.ml ./ext/hash_set.mli ./ext/hash_set_gen.ml ./ext/hash_set_ident.ml ./ext/hash_set_ident.mli ./ext/hash_set_ident_mask.ml ./ext/hash_set_ident_mask.mli ./ext/hash_set_poly.ml ./ext/hash_set_poly.mli ./ext/hash_set_string.ml ./ext/hash_set_string.mli ./ext/hash_string.ml ./ext/hash_string.mli ./ext/int_vec_util.ml ./ext/int_vec_util.mli ./ext/int_vec_vec.ml ./ext/int_vec_vec.mli ./ext/js_reserved_map.ml ./ext/js_reserved_map.mli ./ext/js_runtime_modules.ml ./ext/literals.ml ./ext/map_gen.ml ./ext/map_gen.mli ./ext/map_ident.ml ./ext/map_ident.mli ./ext/map_int.ml ./ext/map_int.mli ./ext/map_string.ml ./ext/map_string.mli ./ext/ordered_hash_map_gen.ml ./ext/ordered_hash_map_local_ident.ml ./ext/ordered_hash_map_local_ident.mli ./ext/set_gen.ml ./ext/set_gen.mli ./ext/set_ident.ml ./ext/set_ident.mli ./ext/set_string.ml ./ext/set_string.mli ./ext/vec.ml ./ext/vec.mli ./ext/vec_gen.ml ./ext/vec_int.ml ./ext/vec_int.mli ./js_parser/declaration_parser.ml ./js_parser/enum_common.ml ./js_parser/enum_parser.ml ./js_parser/expression_parser.ml ./js_parser/file_key.ml ./js_parser/flow_ast.ml ./js_parser/flow_ast_utils.ml ./js_parser/flow_ast_utils.mli ./js_parser/flow_lexer.ml ./js_parser/flow_lexer.mli ./js_parser/jsx_parser.ml ./js_parser/lex_env.ml ./js_parser/lex_result.ml ./js_parser/loc.ml ./js_parser/loc.mli ./js_parser/object_parser.ml ./js_parser/parse_error.ml ./js_parser/parser_common.ml ./js_parser/parser_env.ml ./js_parser/parser_env.mli ./js_parser/parser_flow.ml ./js_parser/pattern_cover.ml ./js_parser/pattern_parser.ml ./js_parser/sedlexing.ml ./js_parser/sedlexing.mli ./js_parser/statement_parser.ml ./js_parser/token.ml ./js_parser/type_parser.ml ./js_parser/wtf8.ml ./js_parser/wtf8.mli ./main/builtin_cmi_datasets.ml ./main/builtin_cmi_datasets.mli ./main/builtin_cmj_datasets.ml ./main/builtin_cmj_datasets.mli ./main/jsoo_common.ml ./main/jsoo_common.mli ./main/jsoo_main.ml ./main/jsoo_main.mli ./outcome_printer/outcome_printer_ns.ml ./outcome_printer/outcome_printer_ns.mli ./stubs/bs_hash_stubs.ml ./super_errors/super_env.ml ./super_errors/super_location.ml ./super_errors/super_location.mli ./super_errors/super_main.ml ./super_errors/super_misc.ml ./super_errors/super_misc.mli ./super_errors/super_pparse.ml ./super_errors/super_typecore.ml ./super_errors/super_typemod.ml ./super_errors/super_typetexp.ml ./syntax/ast_attributes.ml ./syntax/ast_attributes.mli ./syntax/ast_bs_open.ml ./syntax/ast_bs_open.mli ./syntax/ast_comb.ml ./syntax/ast_comb.mli ./syntax/ast_compatible.ml ./syntax/ast_compatible.mli ./syntax/ast_config.ml ./syntax/ast_config.mli ./syntax/ast_core_type.ml ./syntax/ast_core_type.mli ./syntax/ast_core_type_class_type.ml ./syntax/ast_core_type_class_type.mli ./syntax/ast_derive.ml ./syntax/ast_derive.mli ./syntax/ast_derive_abstract.ml ./syntax/ast_derive_abstract.mli ./syntax/ast_derive_js_mapper.ml ./syntax/ast_derive_js_mapper.mli ./syntax/ast_derive_projector.ml ./syntax/ast_derive_projector.mli ./syntax/ast_derive_util.ml ./syntax/ast_derive_util.mli ./syntax/ast_exp.ml ./syntax/ast_exp.mli ./syntax/ast_exp_apply.ml ./syntax/ast_exp_apply.mli ./syntax/ast_exp_extension.ml ./syntax/ast_exp_extension.mli ./syntax/ast_exp_handle_external.ml ./syntax/ast_exp_handle_external.mli ./syntax/ast_external.ml ./syntax/ast_external.mli ./syntax/ast_external_mk.ml ./syntax/ast_external_mk.mli ./syntax/ast_external_process.ml ./syntax/ast_external_process.mli ./syntax/ast_literal.ml ./syntax/ast_literal.mli ./syntax/ast_open_cxt.ml ./syntax/ast_open_cxt.mli ./syntax/ast_pat.ml ./syntax/ast_pat.mli ./syntax/ast_payload.ml ./syntax/ast_payload.mli ./syntax/ast_polyvar.ml ./syntax/ast_polyvar.mli ./syntax/ast_reason_pp.ml ./syntax/ast_reason_pp.mli ./syntax/ast_signature.ml ./syntax/ast_signature.mli ./syntax/ast_structure.ml ./syntax/ast_structure.mli ./syntax/ast_tdcls.ml ./syntax/ast_tdcls.mli ./syntax/ast_tuple_pattern_flatten.ml ./syntax/ast_tuple_pattern_flatten.mli ./syntax/ast_typ_uncurry.ml ./syntax/ast_typ_uncurry.mli ./syntax/ast_uncurry_apply.ml ./syntax/ast_uncurry_apply.mli ./syntax/ast_uncurry_gen.ml ./syntax/ast_uncurry_gen.mli ./syntax/ast_utf8_string.ml ./syntax/ast_utf8_string.mli ./syntax/ast_utf8_string_interp.ml ./syntax/ast_utf8_string_interp.mli ./syntax/ast_util.ml ./syntax/ast_util.mli ./syntax/bs_ast_invariant.ml ./syntax/bs_ast_invariant.mli ./syntax/bs_ast_mapper.ml ./syntax/bs_ast_mapper.mli ./syntax/bs_builtin_ppx.ml ./syntax/bs_builtin_ppx.mli ./syntax/bs_flow_ast_utils.ml ./syntax/bs_flow_ast_utils.mli ./syntax/bs_syntaxerr.ml ./syntax/bs_syntaxerr.mli ./syntax/classify_function.ml ./syntax/classify_function.mli ./syntax/external_arg_spec.ml ./syntax/external_arg_spec.mli ./syntax/external_ffi_types.ml ./syntax/external_ffi_types.mli ./syntax/ppx_entry.ml ./syntax/reactjs_jsx_ppx_v3.ml ./syntax/typemod_hide.ml \ No newline at end of file +../lib/4.06.1/unstable/js_compiler.ml: ../ocaml/bytecomp/lambda.ml ../ocaml/bytecomp/lambda.mli ../ocaml/bytecomp/matching.ml ../ocaml/bytecomp/matching.mli ../ocaml/bytecomp/printlambda.ml ../ocaml/bytecomp/printlambda.mli ../ocaml/bytecomp/switch.ml ../ocaml/bytecomp/switch.mli ../ocaml/bytecomp/translattribute.ml ../ocaml/bytecomp/translattribute.mli ../ocaml/bytecomp/translclass.ml ../ocaml/bytecomp/translclass.mli ../ocaml/bytecomp/translcore.ml ../ocaml/bytecomp/translcore.mli ../ocaml/bytecomp/translmod.ml ../ocaml/bytecomp/translmod.mli ../ocaml/bytecomp/translobj.ml ../ocaml/bytecomp/translobj.mli ../ocaml/parsing/ast_helper.ml ../ocaml/parsing/ast_helper.mli ../ocaml/parsing/ast_iterator.ml ../ocaml/parsing/ast_iterator.mli ../ocaml/parsing/ast_mapper.ml ../ocaml/parsing/ast_mapper.mli ../ocaml/parsing/asttypes.mli ../ocaml/parsing/attr_helper.ml ../ocaml/parsing/attr_helper.mli ../ocaml/parsing/builtin_attributes.ml ../ocaml/parsing/builtin_attributes.mli ../ocaml/parsing/docstrings.ml ../ocaml/parsing/docstrings.mli ../ocaml/parsing/lexer.ml ../ocaml/parsing/lexer.mli ../ocaml/parsing/location.ml ../ocaml/parsing/location.mli ../ocaml/parsing/longident.ml ../ocaml/parsing/longident.mli ../ocaml/parsing/parse.ml ../ocaml/parsing/parse.mli ../ocaml/parsing/parser.ml ../ocaml/parsing/parser.mli ../ocaml/parsing/parsetree.mli ../ocaml/parsing/syntaxerr.ml ../ocaml/parsing/syntaxerr.mli ../ocaml/typing/annot.mli ../ocaml/typing/btype.ml ../ocaml/typing/btype.mli ../ocaml/typing/cmi_format.ml ../ocaml/typing/cmi_format.mli ../ocaml/typing/cmt_format.ml ../ocaml/typing/cmt_format.mli ../ocaml/typing/ctype.ml ../ocaml/typing/ctype.mli ../ocaml/typing/datarepr.ml ../ocaml/typing/datarepr.mli ../ocaml/typing/env.ml ../ocaml/typing/env.mli ../ocaml/typing/ident.ml ../ocaml/typing/ident.mli ../ocaml/typing/includeclass.ml ../ocaml/typing/includeclass.mli ../ocaml/typing/includecore.ml ../ocaml/typing/includecore.mli ../ocaml/typing/includemod.ml ../ocaml/typing/includemod.mli ../ocaml/typing/mtype.ml ../ocaml/typing/mtype.mli ../ocaml/typing/oprint.ml ../ocaml/typing/oprint.mli ../ocaml/typing/outcometree.mli ../ocaml/typing/parmatch.ml ../ocaml/typing/parmatch.mli ../ocaml/typing/path.ml ../ocaml/typing/path.mli ../ocaml/typing/predef.ml ../ocaml/typing/predef.mli ../ocaml/typing/primitive.ml ../ocaml/typing/primitive.mli ../ocaml/typing/printtyp.ml ../ocaml/typing/printtyp.mli ../ocaml/typing/stypes.ml ../ocaml/typing/stypes.mli ../ocaml/typing/subst.ml ../ocaml/typing/subst.mli ../ocaml/typing/tast_mapper.ml ../ocaml/typing/tast_mapper.mli ../ocaml/typing/typeclass.ml ../ocaml/typing/typeclass.mli ../ocaml/typing/typecore.ml ../ocaml/typing/typecore.mli ../ocaml/typing/typedecl.ml ../ocaml/typing/typedecl.mli ../ocaml/typing/typedtree.ml ../ocaml/typing/typedtree.mli ../ocaml/typing/typedtreeIter.ml ../ocaml/typing/typedtreeIter.mli ../ocaml/typing/typemod.ml ../ocaml/typing/typemod.mli ../ocaml/typing/typeopt.ml ../ocaml/typing/typeopt.mli ../ocaml/typing/types.ml ../ocaml/typing/types.mli ../ocaml/typing/typetexp.ml ../ocaml/typing/typetexp.mli ../ocaml/typing/untypeast.ml ../ocaml/typing/untypeast.mli ../ocaml/utils/arg_helper.ml ../ocaml/utils/arg_helper.mli ../ocaml/utils/ccomp.ml ../ocaml/utils/ccomp.mli ../ocaml/utils/clflags.ml ../ocaml/utils/clflags.mli ../ocaml/utils/consistbl.ml ../ocaml/utils/consistbl.mli ../ocaml/utils/identifiable.ml ../ocaml/utils/identifiable.mli ../ocaml/utils/misc.ml ../ocaml/utils/misc.mli ../ocaml/utils/numbers.ml ../ocaml/utils/numbers.mli ../ocaml/utils/profile.ml ../ocaml/utils/profile.mli ../ocaml/utils/tbl.ml ../ocaml/utils/tbl.mli ../ocaml/utils/warnings.ml ../ocaml/utils/warnings.mli ./common/bs_loc.ml ./common/bs_loc.mli ./common/bs_version.ml ./common/bs_version.mli ./common/bs_warnings.ml ./common/bs_warnings.mli ./common/ext_log.ml ./common/ext_log.mli ./common/js_config.ml ./common/js_config.mli ./common/lam_methname.ml ./common/lam_methname.mli ./core/bs_cmi_load.ml ./core/bs_conditional_initial.ml ./core/bs_conditional_initial.mli ./core/compile_rec_module.ml ./core/config_util.ml ./core/config_util.mli ./core/config_whole_compiler.ml ./core/config_whole_compiler.mli ./core/j.ml ./core/js_analyzer.ml ./core/js_analyzer.mli ./core/js_arr.ml ./core/js_arr.mli ./core/js_ast_util.ml ./core/js_ast_util.mli ./core/js_block_runtime.ml ./core/js_block_runtime.mli ./core/js_call_info.ml ./core/js_call_info.mli ./core/js_closure.ml ./core/js_closure.mli ./core/js_cmj_format.ml ./core/js_cmj_format.mli ./core/js_cmj_load.ml ./core/js_cmj_load.mli ./core/js_cmj_load_builtin_unit.ml ./core/js_dump.ml ./core/js_dump.mli ./core/js_dump_import_export.ml ./core/js_dump_import_export.mli ./core/js_dump_lit.ml ./core/js_dump_program.ml ./core/js_dump_program.mli ./core/js_dump_property.ml ./core/js_dump_property.mli ./core/js_dump_string.ml ./core/js_dump_string.mli ./core/js_exp_make.ml ./core/js_exp_make.mli ./core/js_fold.ml ./core/js_fold_basic.ml ./core/js_fold_basic.mli ./core/js_fun_env.ml ./core/js_fun_env.mli ./core/js_long.ml ./core/js_long.mli ./core/js_map.ml ./core/js_name_of_module_id.ml ./core/js_name_of_module_id.mli ./core/js_number.ml ./core/js_number.mli ./core/js_of_lam_array.ml ./core/js_of_lam_array.mli ./core/js_of_lam_block.ml ./core/js_of_lam_block.mli ./core/js_of_lam_exception.ml ./core/js_of_lam_exception.mli ./core/js_of_lam_option.ml ./core/js_of_lam_option.mli ./core/js_of_lam_string.ml ./core/js_of_lam_string.mli ./core/js_of_lam_variant.ml ./core/js_of_lam_variant.mli ./core/js_op.ml ./core/js_op_util.ml ./core/js_op_util.mli ./core/js_output.ml ./core/js_output.mli ./core/js_packages_info.ml ./core/js_packages_info.mli ./core/js_packages_state.ml ./core/js_packages_state.mli ./core/js_pass_debug.ml ./core/js_pass_debug.mli ./core/js_pass_flatten.ml ./core/js_pass_flatten.mli ./core/js_pass_flatten_and_mark_dead.ml ./core/js_pass_flatten_and_mark_dead.mli ./core/js_pass_get_used.ml ./core/js_pass_get_used.mli ./core/js_pass_scope.ml ./core/js_pass_scope.mli ./core/js_pass_tailcall_inline.ml ./core/js_pass_tailcall_inline.mli ./core/js_raw_info.ml ./core/js_shake.ml ./core/js_shake.mli ./core/js_stmt_make.ml ./core/js_stmt_make.mli ./core/lam.ml ./core/lam.mli ./core/lam_analysis.ml ./core/lam_analysis.mli ./core/lam_arity.ml ./core/lam_arity.mli ./core/lam_arity_analysis.ml ./core/lam_arity_analysis.mli ./core/lam_beta_reduce.ml ./core/lam_beta_reduce.mli ./core/lam_beta_reduce_util.ml ./core/lam_beta_reduce_util.mli ./core/lam_bounded_vars.ml ./core/lam_bounded_vars.mli ./core/lam_closure.ml ./core/lam_closure.mli ./core/lam_coercion.ml ./core/lam_coercion.mli ./core/lam_compat.ml ./core/lam_compat.mli ./core/lam_compile.ml ./core/lam_compile.mli ./core/lam_compile_const.ml ./core/lam_compile_const.mli ./core/lam_compile_context.ml ./core/lam_compile_context.mli ./core/lam_compile_env.ml ./core/lam_compile_env.mli ./core/lam_compile_external_call.ml ./core/lam_compile_external_call.mli ./core/lam_compile_external_obj.ml ./core/lam_compile_external_obj.mli ./core/lam_compile_main.ml ./core/lam_compile_main.mli ./core/lam_compile_primitive.ml ./core/lam_compile_primitive.mli ./core/lam_compile_util.ml ./core/lam_compile_util.mli ./core/lam_constant.ml ./core/lam_constant.mli ./core/lam_constant_convert.ml ./core/lam_constant_convert.mli ./core/lam_convert.ml ./core/lam_convert.mli ./core/lam_dce.ml ./core/lam_dce.mli ./core/lam_dispatch_primitive.ml ./core/lam_dispatch_primitive.mli ./core/lam_eta_conversion.ml ./core/lam_eta_conversion.mli ./core/lam_exit_code.ml ./core/lam_exit_code.mli ./core/lam_exit_count.ml ./core/lam_exit_count.mli ./core/lam_free_variables.ml ./core/lam_free_variables.mli ./core/lam_group.ml ./core/lam_group.mli ./core/lam_hit.ml ./core/lam_hit.mli ./core/lam_id_kind.ml ./core/lam_id_kind.mli ./core/lam_iter.ml ./core/lam_iter.mli ./core/lam_module_ident.ml ./core/lam_module_ident.mli ./core/lam_pass_alpha_conversion.ml ./core/lam_pass_alpha_conversion.mli ./core/lam_pass_collect.ml ./core/lam_pass_collect.mli ./core/lam_pass_count.ml ./core/lam_pass_count.mli ./core/lam_pass_deep_flatten.ml ./core/lam_pass_deep_flatten.mli ./core/lam_pass_eliminate_ref.ml ./core/lam_pass_eliminate_ref.mli ./core/lam_pass_exits.ml ./core/lam_pass_exits.mli ./core/lam_pass_lets_dce.ml ./core/lam_pass_lets_dce.mli ./core/lam_pass_remove_alias.ml ./core/lam_pass_remove_alias.mli ./core/lam_pointer_info.ml ./core/lam_pointer_info.mli ./core/lam_primitive.ml ./core/lam_primitive.mli ./core/lam_print.ml ./core/lam_print.mli ./core/lam_scc.ml ./core/lam_scc.mli ./core/lam_stats.ml ./core/lam_stats.mli ./core/lam_stats_export.ml ./core/lam_stats_export.mli ./core/lam_subst.ml ./core/lam_subst.mli ./core/lam_tag_info.ml ./core/lam_util.ml ./core/lam_util.mli ./core/lam_var_stats.ml ./core/lam_var_stats.mli ./core/matching_polyfill.ml ./core/matching_polyfill.mli ./core/polyvar_pattern_match.ml ./core/record_attributes_check.ml ./core/res_compmisc.ml ./core/res_compmisc.mli ./core/transl_single_field_record.ml ./depends/bs_exception.ml ./depends/bs_exception.mli ./ext/bsc_args.ml ./ext/bsc_args.mli ./ext/bsc_warnings.ml ./ext/ext_array.ml ./ext/ext_array.mli ./ext/ext_buffer.ml ./ext/ext_buffer.mli ./ext/ext_bytes.ml ./ext/ext_bytes.mli ./ext/ext_char.ml ./ext/ext_char.mli ./ext/ext_digest.ml ./ext/ext_digest.mli ./ext/ext_filename.ml ./ext/ext_filename.mli ./ext/ext_fmt.ml ./ext/ext_ident.ml ./ext/ext_ident.mli ./ext/ext_int.ml ./ext/ext_int.mli ./ext/ext_io.ml ./ext/ext_io.mli ./ext/ext_js_file_kind.ml ./ext/ext_js_suffix.ml ./ext/ext_list.ml ./ext/ext_list.mli ./ext/ext_marshal.ml ./ext/ext_marshal.mli ./ext/ext_modulename.ml ./ext/ext_modulename.mli ./ext/ext_namespace.ml ./ext/ext_namespace.mli ./ext/ext_option.ml ./ext/ext_option.mli ./ext/ext_path.ml ./ext/ext_path.mli ./ext/ext_pervasives.ml ./ext/ext_pervasives.mli ./ext/ext_pp.ml ./ext/ext_pp.mli ./ext/ext_pp_scope.ml ./ext/ext_pp_scope.mli ./ext/ext_ref.ml ./ext/ext_ref.mli ./ext/ext_scc.ml ./ext/ext_scc.mli ./ext/ext_spec.ml ./ext/ext_spec.mli ./ext/ext_string.ml ./ext/ext_string.mli ./ext/ext_string_array.ml ./ext/ext_string_array.mli ./ext/ext_sys.ml ./ext/ext_sys.mli ./ext/ext_utf8.ml ./ext/ext_utf8.mli ./ext/ext_util.ml ./ext/ext_util.mli ./ext/hash.ml ./ext/hash.mli ./ext/hash_gen.ml ./ext/hash_ident.ml ./ext/hash_ident.mli ./ext/hash_int.ml ./ext/hash_int.mli ./ext/hash_set.ml ./ext/hash_set.mli ./ext/hash_set_gen.ml ./ext/hash_set_ident.ml ./ext/hash_set_ident.mli ./ext/hash_set_ident_mask.ml ./ext/hash_set_ident_mask.mli ./ext/hash_set_poly.ml ./ext/hash_set_poly.mli ./ext/hash_set_string.ml ./ext/hash_set_string.mli ./ext/hash_string.ml ./ext/hash_string.mli ./ext/int_vec_util.ml ./ext/int_vec_util.mli ./ext/int_vec_vec.ml ./ext/int_vec_vec.mli ./ext/js_reserved_map.ml ./ext/js_reserved_map.mli ./ext/js_runtime_modules.ml ./ext/literals.ml ./ext/map_gen.ml ./ext/map_gen.mli ./ext/map_ident.ml ./ext/map_ident.mli ./ext/map_int.ml ./ext/map_int.mli ./ext/map_string.ml ./ext/map_string.mli ./ext/ordered_hash_map_gen.ml ./ext/ordered_hash_map_local_ident.ml ./ext/ordered_hash_map_local_ident.mli ./ext/set_gen.ml ./ext/set_gen.mli ./ext/set_ident.ml ./ext/set_ident.mli ./ext/set_string.ml ./ext/set_string.mli ./ext/vec.ml ./ext/vec.mli ./ext/vec_gen.ml ./ext/vec_int.ml ./ext/vec_int.mli ./js_parser/declaration_parser.ml ./js_parser/enum_common.ml ./js_parser/enum_parser.ml ./js_parser/expression_parser.ml ./js_parser/file_key.ml ./js_parser/flow_ast.ml ./js_parser/flow_ast_utils.ml ./js_parser/flow_ast_utils.mli ./js_parser/flow_lexer.ml ./js_parser/flow_lexer.mli ./js_parser/jsx_parser.ml ./js_parser/lex_env.ml ./js_parser/lex_result.ml ./js_parser/loc.ml ./js_parser/loc.mli ./js_parser/object_parser.ml ./js_parser/parse_error.ml ./js_parser/parser_common.ml ./js_parser/parser_env.ml ./js_parser/parser_env.mli ./js_parser/parser_flow.ml ./js_parser/pattern_cover.ml ./js_parser/pattern_parser.ml ./js_parser/sedlexing.ml ./js_parser/sedlexing.mli ./js_parser/statement_parser.ml ./js_parser/token.ml ./js_parser/type_parser.ml ./js_parser/wtf8.ml ./js_parser/wtf8.mli ./main/builtin_cmi_datasets.ml ./main/builtin_cmi_datasets.mli ./main/builtin_cmj_datasets.ml ./main/builtin_cmj_datasets.mli ./main/jsoo_common.ml ./main/jsoo_common.mli ./main/jsoo_main.ml ./main/jsoo_main.mli ./outcome_printer/outcome_printer_ns.ml ./outcome_printer/outcome_printer_ns.mli ./stubs/bs_hash_stubs.ml ./super_errors/super_env.ml ./super_errors/super_location.ml ./super_errors/super_location.mli ./super_errors/super_main.ml ./super_errors/super_misc.ml ./super_errors/super_misc.mli ./super_errors/super_pparse.ml ./super_errors/super_typecore.ml ./super_errors/super_typemod.ml ./super_errors/super_typetexp.ml ./syntax/ast_attributes.ml ./syntax/ast_attributes.mli ./syntax/ast_bs_open.ml ./syntax/ast_bs_open.mli ./syntax/ast_comb.ml ./syntax/ast_comb.mli ./syntax/ast_compatible.ml ./syntax/ast_compatible.mli ./syntax/ast_config.ml ./syntax/ast_config.mli ./syntax/ast_core_type.ml ./syntax/ast_core_type.mli ./syntax/ast_core_type_class_type.ml ./syntax/ast_core_type_class_type.mli ./syntax/ast_derive.ml ./syntax/ast_derive.mli ./syntax/ast_derive_abstract.ml ./syntax/ast_derive_abstract.mli ./syntax/ast_derive_js_mapper.ml ./syntax/ast_derive_js_mapper.mli ./syntax/ast_derive_projector.ml ./syntax/ast_derive_projector.mli ./syntax/ast_derive_util.ml ./syntax/ast_derive_util.mli ./syntax/ast_exp.ml ./syntax/ast_exp.mli ./syntax/ast_exp_apply.ml ./syntax/ast_exp_apply.mli ./syntax/ast_exp_extension.ml ./syntax/ast_exp_extension.mli ./syntax/ast_exp_handle_external.ml ./syntax/ast_exp_handle_external.mli ./syntax/ast_external.ml ./syntax/ast_external.mli ./syntax/ast_external_mk.ml ./syntax/ast_external_mk.mli ./syntax/ast_external_process.ml ./syntax/ast_external_process.mli ./syntax/ast_literal.ml ./syntax/ast_literal.mli ./syntax/ast_open_cxt.ml ./syntax/ast_open_cxt.mli ./syntax/ast_pat.ml ./syntax/ast_pat.mli ./syntax/ast_payload.ml ./syntax/ast_payload.mli ./syntax/ast_polyvar.ml ./syntax/ast_polyvar.mli ./syntax/ast_reason_pp.ml ./syntax/ast_reason_pp.mli ./syntax/ast_signature.ml ./syntax/ast_signature.mli ./syntax/ast_structure.ml ./syntax/ast_structure.mli ./syntax/ast_tdcls.ml ./syntax/ast_tdcls.mli ./syntax/ast_tuple_pattern_flatten.ml ./syntax/ast_tuple_pattern_flatten.mli ./syntax/ast_typ_uncurry.ml ./syntax/ast_typ_uncurry.mli ./syntax/ast_uncurry_apply.ml ./syntax/ast_uncurry_apply.mli ./syntax/ast_uncurry_gen.ml ./syntax/ast_uncurry_gen.mli ./syntax/ast_utf8_string.ml ./syntax/ast_utf8_string.mli ./syntax/ast_utf8_string_interp.ml ./syntax/ast_utf8_string_interp.mli ./syntax/ast_util.ml ./syntax/ast_util.mli ./syntax/bs_ast_invariant.ml ./syntax/bs_ast_invariant.mli ./syntax/bs_ast_mapper.ml ./syntax/bs_ast_mapper.mli ./syntax/bs_builtin_ppx.ml ./syntax/bs_builtin_ppx.mli ./syntax/bs_flow_ast_utils.ml ./syntax/bs_flow_ast_utils.mli ./syntax/bs_syntaxerr.ml ./syntax/bs_syntaxerr.mli ./syntax/classify_function.ml ./syntax/classify_function.mli ./syntax/external_arg_spec.ml ./syntax/external_arg_spec.mli ./syntax/external_ffi_types.ml ./syntax/external_ffi_types.mli ./syntax/ppx_entry.ml ./syntax/typemod_hide.ml \ No newline at end of file diff --git a/lib/4.06.1/unstable/js_refmt_compiler.ml b/lib/4.06.1/unstable/js_refmt_compiler.ml index 2db83befb2..360eea346f 100644 --- a/lib/4.06.1/unstable/js_refmt_compiler.ml +++ b/lib/4.06.1/unstable/js_refmt_compiler.ml @@ -408271,983 +408271,6 @@ let mapper : mapper = -end -module Reactjs_jsx_ppx_v3 -= struct -#1 "reactjs_jsx_ppx_v3.ml" -# 1 "syntax/reactjs_jsx_ppx.cppo.ml" -(* - This is the file that handles turning Reason JSX' agnostic function call into - a ReasonReact-specific function call. Aka, this is a macro, using OCaml's ppx - facilities; https://whitequark.org/blog/2014/04/16/a-guide-to-extension- - points-in-ocaml/ - You wouldn't use this file directly; it's used by BuckleScript's - bsconfig.json. Specifically, there's a field called `react-jsx` inside the - field `reason`, which enables this ppx through some internal call in bsb -*) - -(* - There are two different transforms that can be selected in this file (v2 and v3): - v2: - transform `[@JSX] div(~props1=a, ~props2=b, ~children=[foo, bar], ())` into - `ReactDOMRe.createElement("div", ~props={"props1": 1, "props2": b}, [|foo, - bar|])`. - transform `[@JSX] div(~props1=a, ~props2=b, ~children=foo, ())` into - `ReactDOMRe.createElementVariadic("div", ~props={"props1": 1, "props2": b}, foo)`. - transform the upper-cased case - `[@JSX] Foo.createElement(~key=a, ~ref=b, ~foo=bar, ~children=[], ())` into - `ReasonReact.element(~key=a, ~ref=b, Foo.make(~foo=bar, [||]))` - transform `[@JSX] [foo]` into - `ReactDOMRe.createElement(ReasonReact.fragment, [|foo|])` - v3: - transform `[@JSX] div(~props1=a, ~props2=b, ~children=[foo, bar], ())` into - `ReactDOMRe.createDOMElementVariadic("div", ReactDOMRe.domProps(~props1=1, ~props2=b), [|foo, bar|])`. - transform the upper-cased case - `[@JSX] Foo.createElement(~key=a, ~ref=b, ~foo=bar, ~children=[], ())` into - `React.createElement(Foo.make, Foo.makeProps(~key=a, ~ref=b, ~foo=bar, ()))` - transform the upper-cased case - `[@JSX] Foo.createElement(~foo=bar, ~children=[foo, bar], ())` into - `React.createElementVariadic(Foo.make, Foo.makeProps(~foo=bar, ~children=React.null, ()), [|foo, bar|])` - transform `[@JSX] [foo]` into - `ReactDOMRe.createElement(ReasonReact.fragment, [|foo|])` -*) - -open Ast_helper -open Ast_mapper -open Asttypes -open Parsetree -open Longident - -let rec find_opt p = function - | [] -> None - | x :: l -> if p x then Some x else find_opt p l - - - -let nolabel = Nolabel -let labelled str = Labelled str -let optional str = Optional str -let isOptional str = match str with -| Optional _ -> true -| _ -> false -let isLabelled str = match str with -| Labelled _ -> true -| _ -> false -let getLabel str = match str with -| Optional str | Labelled str -> str -| Nolabel -> "" -let optionIdent = Lident "option" - -let argIsKeyRef = function - | (Labelled ("key" | "ref"), _) | (Optional ("key" | "ref"), _) -> true - | _ -> false -let constantString ~loc str = Ast_helper.Exp.constant ~loc (Pconst_string (str, None)) - - -let safeTypeFromValue valueStr = -let valueStr = getLabel valueStr in -match String.sub valueStr 0 1 with -| "_" -> "T" ^ valueStr -| _ -> valueStr -let keyType loc = Typ.constr ~loc {loc; txt=optionIdent} [Typ.constr ~loc {loc; txt=Lident "string"} []] - -type 'a children = | ListLiteral of 'a | Exact of 'a -type componentConfig = { - propsName: string; -} - -(* if children is a list, convert it to an array while mapping each element. If not, just map over it, as usual *) -let transformChildrenIfListUpper ~loc ~mapper theList = - let rec transformChildren_ theList accum = - (* not in the sense of converting a list to an array; convert the AST - reprensentation of a list to the AST reprensentation of an array *) - match theList with - | {pexp_desc = Pexp_construct ({txt = Lident "[]"}, None)} -> begin - match accum with - | [singleElement] -> Exact singleElement - | accum -> ListLiteral (List.rev accum |> Exp.array ~loc) - end - | {pexp_desc = Pexp_construct ( - {txt = Lident "::"}, - Some {pexp_desc = Pexp_tuple (v::acc::[])} - )} -> - transformChildren_ acc ((mapper.expr mapper v)::accum) - | notAList -> Exact (mapper.expr mapper notAList) - in - transformChildren_ theList [] - -let transformChildrenIfList ~loc ~mapper theList = - let rec transformChildren_ theList accum = - (* not in the sense of converting a list to an array; convert the AST - reprensentation of a list to the AST reprensentation of an array *) - match theList with - | {pexp_desc = Pexp_construct ({txt = Lident "[]"}, None)} -> - List.rev accum |> Exp.array ~loc - | {pexp_desc = Pexp_construct ( - {txt = Lident "::"}, - Some {pexp_desc = Pexp_tuple (v::acc::[])} - )} -> - transformChildren_ acc ((mapper.expr mapper v)::accum) - | notAList -> mapper.expr mapper notAList - in - transformChildren_ theList [] - -let extractChildren ?(removeLastPositionUnit=false) ~loc propsAndChildren = - let rec allButLast_ lst acc = match lst with - | [] -> [] - | (Nolabel, {pexp_desc = Pexp_construct ({txt = Lident "()"}, None)})::[] -> acc - | (Nolabel, _) :: _rest -> raise (Invalid_argument "JSX: found non-labelled argument before the last position") - | arg::rest -> allButLast_ rest (arg::acc) - in - let allButLast lst = allButLast_ lst [] |> List.rev in - match (List.partition (fun (label, _) -> label = labelled "children") propsAndChildren) with - | ([], props) -> - (* no children provided? Place a placeholder list *) - (Exp.construct ~loc {loc; txt = Lident "[]"} None, if removeLastPositionUnit then allButLast props else props) - | ([(_, childrenExpr)], props) -> - (childrenExpr, if removeLastPositionUnit then allButLast props else props) - | _ -> raise (Invalid_argument "JSX: somehow there's more than one `children` label") - -let unerasableIgnore loc = ({loc; txt = "warning"}, (PStr [Str.eval (Exp.constant (Pconst_string ("-16", None)))])) -let merlinFocus = ({loc = Location.none; txt = "merlin.focus"}, (PStr [])) - -(* Helper method to look up the [@react.component] attribute *) -let hasAttr (loc, _) = - loc.txt = "react.component" - -(* Helper method to filter out any attribute that isn't [@react.component] *) -let otherAttrsPure (loc, _) = - loc.txt <> "react.component" - -(* Iterate over the attributes and try to find the [@react.component] attribute *) -let hasAttrOnBinding {pvb_attributes} = find_opt hasAttr pvb_attributes <> None - -(* Filter the [@react.component] attribute and immutably replace them on the binding *) -let filterAttrOnBinding binding = {binding with pvb_attributes = List.filter otherAttrsPure binding.pvb_attributes} - -(* Finds the name of the variable the binding is assigned to, otherwise raises Invalid_argument *) -let getFnName binding = - match binding with - | {pvb_pat = { - ppat_desc = Ppat_var {txt} - }} -> txt - | _ -> raise (Invalid_argument "react.component calls cannot be destructured.") - -let makeNewBinding binding expression newName = - match binding with - | {pvb_pat = { - ppat_desc = Ppat_var ( ppat_var) - } as pvb_pat} ->{ binding with pvb_pat = { - pvb_pat with - ppat_desc = Ppat_var {ppat_var with txt = newName}; - }; - pvb_expr = expression; - pvb_attributes = [merlinFocus]; - } - | _ -> raise (Invalid_argument "react.component calls cannot be destructured.") - -(* Lookup the value of `props` otherwise raise Invalid_argument error *) -let getPropsNameValue _acc (loc, exp) = - match (loc, exp) with - | ({ txt = Lident "props" }, { pexp_desc = Pexp_ident {txt = Lident str} }) -> { propsName = str } - | ({ txt }, _) -> raise (Invalid_argument ("react.component only accepts props as an option, given: " ^ Longident.last txt)) - -(* Lookup the `props` record or string as part of [@react.component] and store the name for use when rewriting *) -let getPropsAttr payload = - let defaultProps = {propsName = "Props"} in - match payload with - | Some(PStr( - {pstr_desc = Pstr_eval ({ - pexp_desc = Pexp_record (recordFields, None) - }, _)}::_rest - )) -> - List.fold_left getPropsNameValue defaultProps recordFields - | Some(PStr({pstr_desc = Pstr_eval ({pexp_desc = Pexp_ident {txt = Lident "props"}}, _)}::_rest)) -> {propsName = "props"} - | Some(PStr({pstr_desc = Pstr_eval (_, _)}::_rest)) -> raise (Invalid_argument ("react.component accepts a record config with props as an options.")) - | _ -> defaultProps - -(* Plucks the label, loc, and type_ from an AST node *) -let pluckLabelDefaultLocType (label, default, _, _, loc, type_) = (label, default, loc, type_) - -(* Lookup the filename from the location information on the AST node and turn it into a valid module identifier *) -let filenameFromLoc (pstr_loc: Location.t) = - let fileName = match pstr_loc.loc_start.pos_fname with - | "" -> !Location.input_name - | fileName -> fileName - in - let fileName = try - Filename.chop_extension (Filename.basename fileName) - with | Invalid_argument _-> fileName in - let fileName = String.capitalize_ascii fileName in - fileName - -(* Build a string representation of a module name with segments separated by $ *) -let makeModuleName fileName nestedModules fnName = - let fullModuleName = match (fileName, nestedModules, fnName) with - (* TODO: is this even reachable? It seems like the fileName always exists *) - | ("", nestedModules, "make") -> nestedModules - | ("", nestedModules, fnName) -> List.rev (fnName :: nestedModules) - | (fileName, nestedModules, "make") -> fileName :: (List.rev nestedModules) - | (fileName, nestedModules, fnName) -> fileName :: (List.rev (fnName :: nestedModules)) - in - let fullModuleName = String.concat "$" fullModuleName in - fullModuleName - -(* - AST node builders - These functions help us build AST nodes that are needed when transforming a [@react.component] into a - constructor and a props external -*) - -(* Build an AST node representing all named args for the `external` definition for a component's props *) -let rec recursivelyMakeNamedArgsForExternal list args = - match list with - | (label, default, loc, interiorType)::tl -> - recursivelyMakeNamedArgsForExternal tl (Typ.arrow - ~loc - label - (match (label, interiorType, default) with - (* ~foo=1 *) - | (label, None, Some _) -> - { - ptyp_desc = Ptyp_var (safeTypeFromValue label); - ptyp_loc = loc; - ptyp_attributes = []; - } - (* ~foo: int=1 *) - | (_label, Some type_, Some _) -> - type_ - - (* ~foo: option(int)=? *) - | (label, Some ({ptyp_desc = Ptyp_constr ({txt=(Lident "option")}, [type_])}), _) - | (label, Some ({ptyp_desc = Ptyp_constr ({txt=(Ldot (Lident "*predef*", "option"))}, [type_])}), _) - (* ~foo: int=? - note this isnt valid. but we want to get a type error *) - | (label, Some type_, _) when isOptional label -> - type_ - (* ~foo=? *) - | (label, None, _) when isOptional label -> - { - ptyp_desc = Ptyp_var (safeTypeFromValue label); - ptyp_loc = loc; - ptyp_attributes = []; - } - - (* ~foo *) - | (label, None, _) -> - { - ptyp_desc = Ptyp_var (safeTypeFromValue label); - ptyp_loc = loc; - ptyp_attributes = []; - } - | (_label, Some type_, _) -> - type_ - ) - args) - | [] -> args - -(* Build an AST node for the [@bs.obj] representing props for a component *) -let makePropsValue fnName loc namedArgListWithKeyAndRef propsType = - let propsName = fnName ^ "Props" in { - pval_name = {txt = propsName; loc}; - pval_type = - recursivelyMakeNamedArgsForExternal - namedArgListWithKeyAndRef - (Typ.arrow - nolabel - { - ptyp_desc = Ptyp_constr ({txt= Lident("unit"); loc}, []); - ptyp_loc = loc; - ptyp_attributes = []; - } - propsType - ); - pval_prim = [""]; - pval_attributes = [({txt = "bs.obj"; loc = loc}, PStr [])]; - pval_loc = loc; -} - -(* Build an AST node representing an `external` with the definition of the [@bs.obj] *) -let makePropsExternal fnName loc namedArgListWithKeyAndRef propsType = - { - pstr_loc = loc; - pstr_desc = Pstr_primitive (makePropsValue fnName loc namedArgListWithKeyAndRef propsType) - } - -(* Build an AST node for the signature of the `external` definition *) -let makePropsExternalSig fnName loc namedArgListWithKeyAndRef propsType = - { - psig_loc = loc; - psig_desc = Psig_value (makePropsValue fnName loc namedArgListWithKeyAndRef propsType) - } - -(* Build an AST node for the props name when converted to a Js.t inside the function signature *) -let makePropsName ~loc name = - { - ppat_desc = Ppat_var {txt = name; loc}; - ppat_loc = loc; - ppat_attributes = []; - } - - -let makeObjectField loc (str, attrs, type_) = - Otag ({ loc; txt = str }, attrs, type_) - - -(* Build an AST node representing a "closed" Js.t object representing a component's props *) -let makePropsType ~loc namedTypeList = - Typ.mk ~loc ( - Ptyp_constr({txt= Ldot (Lident("Js"), "t"); loc}, [{ - ptyp_desc = Ptyp_object( - List.map (makeObjectField loc) namedTypeList, - Closed - ); - ptyp_loc = loc; - ptyp_attributes = []; - }]) - ) - -(* Builds an AST node for the entire `external` definition of props *) -let makeExternalDecl fnName loc namedArgListWithKeyAndRef namedTypeList = - makePropsExternal - fnName - loc - (List.map pluckLabelDefaultLocType namedArgListWithKeyAndRef) - (makePropsType ~loc namedTypeList) - -(* TODO: some line number might still be wrong *) -let jsxMapper () = - - let jsxVersion = ref None in - - let transformUppercaseCall3 modulePath mapper loc attrs _ callArguments = - let (children, argsWithLabels) = extractChildren ~loc ~removeLastPositionUnit:true callArguments in - let argsForMake = argsWithLabels in - let childrenExpr = transformChildrenIfListUpper ~loc ~mapper children in - let recursivelyTransformedArgsForMake = argsForMake |> List.map (fun (label, expression) -> (label, mapper.expr mapper expression)) in - let childrenArg = ref None in - let args = recursivelyTransformedArgsForMake - @ (match childrenExpr with - | Exact children -> [(labelled "children", children)] - | ListLiteral ({ pexp_desc = Pexp_array list }) when list = [] -> [] - | ListLiteral expression -> - (* this is a hack to support react components that introspect into their children *) - (childrenArg := Some expression; - [(labelled "children", Exp.ident ~loc {loc; txt = Ldot (Lident "React", "null")})])) - @ [(nolabel, Exp.construct ~loc {loc; txt = Lident "()"} None)] in - let isCap str = let first = String.sub str 0 1 in - let capped = String.uppercase_ascii first in first = capped in - let ident = match modulePath with - | Lident _ -> Ldot (modulePath, "make") - | (Ldot (_modulePath, value) as fullPath) when isCap value -> Ldot (fullPath, "make") - | modulePath -> modulePath in - let propsIdent = match ident with - | Lident path -> Lident (path ^ "Props") - | Ldot(ident, path) -> Ldot (ident, path ^ "Props") - | _ -> raise (Invalid_argument "JSX name can't be the result of function applications") in - let props = - Exp.apply ~attrs ~loc (Exp.ident ~loc {loc; txt = propsIdent}) args in - (* handle key, ref, children *) - (* React.createElement(Component.make, props, ...children) *) - match (!childrenArg) with - | None -> - (Exp.apply - ~loc - ~attrs - (Exp.ident ~loc {loc; txt = Ldot (Lident "React", "createElement")}) - ([ - (nolabel, Exp.ident ~loc {txt = ident; loc}); - (nolabel, props) - ])) - | Some children -> - (Exp.apply - ~loc - ~attrs - (Exp.ident ~loc {loc; txt = Ldot (Lident "React", "createElementVariadic")}) - ([ - (nolabel, Exp.ident ~loc {txt = ident; loc}); - (nolabel, props); - (nolabel, children) - ])) - in - - let transformLowercaseCall3 mapper loc attrs callArguments id = - let (children, nonChildrenProps) = extractChildren ~loc callArguments in - let componentNameExpr = constantString ~loc id in - let childrenExpr = transformChildrenIfList ~loc ~mapper children in - let createElementCall = match children with - (* [@JSX] div(~children=[a]), coming from
a
*) - | { - pexp_desc = - Pexp_construct ({txt = Lident "::"}, Some {pexp_desc = Pexp_tuple _ }) - | Pexp_construct ({txt = Lident "[]"}, None) - } -> "createDOMElementVariadic" - (* [@JSX] div(~children= value), coming from
...(value)
*) - | _ -> raise (Invalid_argument "A spread as a DOM element's \ - children don't make sense written together. You can simply remove the spread.") - in - let args = match nonChildrenProps with - | [_justTheUnitArgumentAtEnd] -> - [ - (* "div" *) - (nolabel, componentNameExpr); - (* [|moreCreateElementCallsHere|] *) - (nolabel, childrenExpr) - ] - | nonEmptyProps -> - let propsCall = - Exp.apply - ~loc - (Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOMRe", "domProps")}) - (nonEmptyProps |> List.map (fun (label, expression) -> (label, mapper.expr mapper expression))) - in - [ - (* "div" *) - (nolabel, componentNameExpr); - (* ReactDOMRe.props(~className=blabla, ~foo=bar, ()) *) - (labelled "props", propsCall); - (* [|moreCreateElementCallsHere|] *) - (nolabel, childrenExpr) - ] in - Exp.apply - ~loc - (* throw away the [@JSX] attribute and keep the others, if any *) - ~attrs - (* ReactDOMRe.createElement *) - (Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOMRe", createElementCall)}) - args - in - - - - - let rec recursivelyTransformNamedArgsForMake mapper expr list = - let expr = mapper.expr mapper expr in - match expr.pexp_desc with - (* TODO: make this show up with a loc. *) - | Pexp_fun (Labelled "key", _, _, _) - | Pexp_fun (Optional "key", _, _, _) -> raise (Invalid_argument "Key cannot be accessed inside of a component. Don't worry - you can always key a component from its parent!") - | Pexp_fun (Labelled "ref", _, _, _) - | Pexp_fun (Optional "ref", _, _, _) -> raise (Invalid_argument "Ref cannot be passed as a normal prop. Please use `forwardRef` API instead.") - | Pexp_fun (arg, default, pattern, expression) when isOptional arg || isLabelled arg -> - let () = - (match (isOptional arg, pattern, default) with - | (true, { ppat_desc = Ppat_constraint (_, { ptyp_desc })}, None) -> - (match ptyp_desc with - | Ptyp_constr({txt=(Lident "option")}, [_]) -> () - | _ -> - let currentType = (match ptyp_desc with - | Ptyp_constr({txt}, []) -> String.concat "." (Longident.flatten txt) - | Ptyp_constr({txt}, _innerTypeArgs) -> String.concat "." (Longident.flatten txt) ^ "(...)" - | _ -> "...") - in - Location.prerr_warning pattern.ppat_loc - (Preprocessor - (Printf.sprintf "ReasonReact: optional argument annotations must have explicit `option`. Did you mean `option(%s)=?`?" currentType))) - | _ -> ()) in - let alias = (match pattern with - | {ppat_desc = Ppat_alias (_, {txt}) | Ppat_var {txt}} -> txt - | {ppat_desc = Ppat_any} -> "_" - | _ -> getLabel arg) in - let type_ = (match pattern with - | {ppat_desc = Ppat_constraint (_, type_)} -> Some type_ - | _ -> None) in - - recursivelyTransformNamedArgsForMake mapper expression ((arg, default, pattern, alias, pattern.ppat_loc, type_) :: list) - | Pexp_fun (Nolabel, _, { ppat_desc = (Ppat_construct ({txt = Lident "()"}, _) | Ppat_any)}, _expression) -> - (list, None) - | Pexp_fun (Nolabel, _, { ppat_desc = Ppat_var ({txt}) | Ppat_constraint ({ ppat_desc = Ppat_var ({txt})}, _)}, _expression) -> - (list, Some txt) - | Pexp_fun (Nolabel, _, pattern, _expression) -> - Location.raise_errorf ~loc:pattern.ppat_loc "ReasonReact: react.component refs only support plain arguments and type annotations." - | _ -> (list, None) - in - - - let argToType types (name, default, _noLabelName, _alias, loc, type_) = match (type_, name, default) with - | (Some ({ptyp_desc = Ptyp_constr ({txt=(Lident "option")}, [type_])}), name, _) when isOptional name -> - (getLabel name, [], { - type_ with - ptyp_desc = Ptyp_constr ({loc=type_.ptyp_loc; txt=optionIdent}, [type_]); - }) :: types - | (Some type_, name, Some _default) -> - (getLabel name, [], { - ptyp_desc = Ptyp_constr ({loc; txt=optionIdent}, [type_]); - ptyp_loc = loc; - ptyp_attributes = []; - }) :: types - | (Some type_, name, _) -> - (getLabel name, [], type_) :: types - | (None, name, _) when isOptional name -> - (getLabel name, [], { - ptyp_desc = Ptyp_constr ({loc; txt=optionIdent}, [{ - ptyp_desc = Ptyp_var (safeTypeFromValue name); - ptyp_loc = loc; - ptyp_attributes = []; - }]); - ptyp_loc = loc; - ptyp_attributes = []; - }) :: types - | (None, name, _) when isLabelled name -> - (getLabel name, [], { - ptyp_desc = Ptyp_var (safeTypeFromValue name); - ptyp_loc = loc; - ptyp_attributes = []; - }) :: types - | _ -> types - in - - let argToConcreteType types (name, loc, type_) = match name with - | name when isLabelled name -> - (getLabel name, [], type_) :: types - | name when isOptional name -> - (getLabel name, [], Typ.constr ~loc {loc; txt=optionIdent} [type_]) :: types - | _ -> types - in - - let nestedModules = ref([]) in - let transformComponentDefinition mapper structure returnStructures = match structure with - (* external *) - | ({ - pstr_loc; - pstr_desc = Pstr_primitive ({ - pval_name = { txt = fnName }; - pval_attributes; - pval_type; - } as value_description) - } as pstr) -> - (match List.filter hasAttr pval_attributes with - | [] -> structure :: returnStructures - | [_] -> - let rec getPropTypes types ({ptyp_loc; ptyp_desc} as fullType) = - (match ptyp_desc with - | Ptyp_arrow (name, type_, ({ptyp_desc = Ptyp_arrow _} as rest)) when isLabelled name || isOptional name -> - getPropTypes ((name, ptyp_loc, type_)::types) rest - | Ptyp_arrow (Nolabel, _type, rest) -> - getPropTypes types rest - | Ptyp_arrow (name, type_, returnValue) when isLabelled name || isOptional name -> - (returnValue, (name, returnValue.ptyp_loc, type_)::types) - | _ -> (fullType, types)) - in - let (innerType, propTypes) = getPropTypes [] pval_type in - let namedTypeList = List.fold_left argToConcreteType [] propTypes in - let pluckLabelAndLoc (label, loc, type_) = (label, None (* default *), loc, Some type_) in - let retPropsType = makePropsType ~loc:pstr_loc namedTypeList in - let externalPropsDecl = makePropsExternal fnName pstr_loc (( - optional "key", - None, - pstr_loc, - Some(keyType pstr_loc) - ) :: List.map pluckLabelAndLoc propTypes) retPropsType in - (* can't be an arrow because it will defensively uncurry *) - let newExternalType = Ptyp_constr ( - {loc = pstr_loc; txt = Ldot ((Lident "React"), "componentLike")}, - [retPropsType; innerType] - ) in - let newStructure = { - pstr with pstr_desc = Pstr_primitive { - value_description with pval_type = { - pval_type with ptyp_desc = newExternalType; - }; - pval_attributes = List.filter otherAttrsPure pval_attributes; - } - } in - externalPropsDecl :: newStructure :: returnStructures - | _ -> raise (Invalid_argument "Only one react.component call can exist on a component at one time")) - (* let component = ... *) - | { - pstr_loc; - pstr_desc = Pstr_value ( - recFlag, - valueBindings - ) - } -> - let fileName = filenameFromLoc pstr_loc in - let emptyLoc = Location.in_file fileName in - let mapBinding binding = if (hasAttrOnBinding binding) then - let bindingLoc = binding.pvb_loc in - let bindingPatLoc = binding.pvb_pat.ppat_loc in - let binding = { binding with pvb_pat = { binding.pvb_pat with ppat_loc = emptyLoc}; pvb_loc = emptyLoc} in - let fnName = getFnName binding in - let internalFnName = fnName ^ "$Internal" in - let fullModuleName = makeModuleName fileName !nestedModules fnName in - let modifiedBindingOld binding = - let expression = binding.pvb_expr in - (* TODO: there is a long-tail of unsupported features inside of blocks - Pexp_letmodule , Pexp_letexception , Pexp_ifthenelse *) - let rec spelunkForFunExpression expression = (match expression with - (* let make = (~prop) => ... *) - | { - pexp_desc = Pexp_fun _ - } -> expression - (* let make = {let foo = bar in (~prop) => ...} *) - | { - pexp_desc = Pexp_let (_recursive, _vbs, returnExpression) - } -> - (* here's where we spelunk! *) - spelunkForFunExpression returnExpression - (* let make = React.forwardRef((~prop) => ...) *) - - | { pexp_desc = Pexp_apply (_wrapperExpression, [(Nolabel, innerFunctionExpression)]) } -> - spelunkForFunExpression innerFunctionExpression - | { - pexp_desc = Pexp_sequence (_wrapperExpression, innerFunctionExpression) - } -> - spelunkForFunExpression innerFunctionExpression - | _ -> raise (Invalid_argument "react.component calls can only be on function definitions or component wrappers (forwardRef, memo).") - ) in - spelunkForFunExpression expression - in - let modifiedBinding binding = - let hasApplication = ref(false) in - let wrapExpressionWithBinding expressionFn expression = - Vb.mk - ~loc:bindingLoc - ~attrs:(List.filter otherAttrsPure binding.pvb_attributes) - (Pat.var ~loc:bindingPatLoc {loc = bindingPatLoc; txt = fnName}) (expressionFn expression) in - let expression = binding.pvb_expr in - let unerasableIgnoreExp exp = { exp with pexp_attributes = (unerasableIgnore emptyLoc) :: exp.pexp_attributes } in - (* TODO: there is a long-tail of unsupported features inside of blocks - Pexp_letmodule , Pexp_letexception , Pexp_ifthenelse *) - let rec spelunkForFunExpression expression = (match expression with - (* let make = (~prop) => ... with no final unit *) - | { - pexp_desc = Pexp_fun ((Labelled(_) | Optional(_) as label), default, pattern, ({pexp_desc = Pexp_fun _} as internalExpression)) - } -> - let (wrap, hasUnit, exp) = spelunkForFunExpression internalExpression in - (wrap, hasUnit, unerasableIgnoreExp {expression with pexp_desc = Pexp_fun (label, default, pattern, exp)}) - (* let make = (()) => ... *) - (* let make = (_) => ... *) - | { - pexp_desc = Pexp_fun (Nolabel, _default, { ppat_desc = Ppat_construct ({txt = Lident "()"}, _) | Ppat_any}, _internalExpression) - } -> ((fun a -> a), true, expression) - (* let make = (~prop) => ... *) - | { - pexp_desc = Pexp_fun ((Labelled(_) | Optional(_)), _default, _pattern, _internalExpression) - } -> ((fun a -> a), false, unerasableIgnoreExp expression) - (* let make = (prop) => ... *) - | { - pexp_desc = Pexp_fun (_nolabel, _default, pattern, _internalExpression) - } -> - if (hasApplication.contents) then - ((fun a -> a), false, unerasableIgnoreExp expression) - else - Location.raise_errorf ~loc:pattern.ppat_loc "ReasonReact: props need to be labelled arguments.\n If you are working with refs be sure to wrap with React.forwardRef.\n If your component doesn't have any props use () or _ instead of a name." - (* let make = {let foo = bar in (~prop) => ...} *) - | { - pexp_desc = Pexp_let (recursive, vbs, internalExpression) - } -> - (* here's where we spelunk! *) - let (wrap, hasUnit, exp) = spelunkForFunExpression internalExpression in - (wrap, hasUnit, {expression with pexp_desc = Pexp_let (recursive, vbs, exp)}) - (* let make = React.forwardRef((~prop) => ...) *) - | { pexp_desc = Pexp_apply (wrapperExpression, [(Nolabel, internalExpression)]) } -> - let () = hasApplication := true in - let (_, hasUnit, exp) = spelunkForFunExpression internalExpression in - ((fun exp -> Exp.apply wrapperExpression [(nolabel, exp)]), hasUnit, exp) - | { - pexp_desc = Pexp_sequence (wrapperExpression, internalExpression) - } -> - let (wrap, hasUnit, exp) = spelunkForFunExpression internalExpression in - (wrap, hasUnit, {expression with pexp_desc = Pexp_sequence (wrapperExpression, exp)}) - | e -> ((fun a -> a), false, e) - ) in - let (wrapExpression, hasUnit, expression) = spelunkForFunExpression expression in - (wrapExpressionWithBinding wrapExpression, hasUnit, expression) - in - let (bindingWrapper, hasUnit, expression) = modifiedBinding binding in - let reactComponentAttribute = try - Some(List.find hasAttr binding.pvb_attributes) - with | Not_found -> None in - let (_attr_loc, payload) = match reactComponentAttribute with - | Some (loc, payload) -> (loc.loc, Some payload) - | None -> (emptyLoc, None) in - let props = getPropsAttr payload in - (* do stuff here! *) - let (namedArgList, forwardRef) = recursivelyTransformNamedArgsForMake mapper (modifiedBindingOld binding) [] in - let namedArgListWithKeyAndRef = (optional("key"), None, Pat.var {txt = "key"; loc = emptyLoc}, "key", emptyLoc, Some(keyType emptyLoc)) :: namedArgList in - let namedArgListWithKeyAndRef = match forwardRef with - | Some(_) -> (optional("ref"), None, Pat.var {txt = "key"; loc = emptyLoc}, "ref", emptyLoc, None) :: namedArgListWithKeyAndRef - | None -> namedArgListWithKeyAndRef - in - let namedArgListWithKeyAndRefForNew = match forwardRef with - | Some(txt) -> namedArgList @ [(nolabel, None, Pat.var {txt; loc = emptyLoc}, txt, emptyLoc, None)] - | None -> namedArgList - in - let pluckArg (label, _, _, alias, loc, _) = - let labelString = (match label with | label when isOptional label || isLabelled label -> getLabel label | _ -> "") in - (label, - (match labelString with - | "" -> (Exp.ident ~loc { - txt = (Lident alias); - loc - }) - | labelString -> (Exp.apply ~loc - (Exp.ident ~loc {txt = (Lident "##"); loc }) - [ - (nolabel, Exp.ident ~loc {txt = (Lident props.propsName); loc }); - (nolabel, Exp.ident ~loc { - txt = (Lident labelString); - loc - }) - ] - ) - ) - ) in - let namedTypeList = List.fold_left argToType [] namedArgList in - let loc = emptyLoc in - let externalDecl = makeExternalDecl fnName loc namedArgListWithKeyAndRef namedTypeList in - let innerExpressionArgs = (List.map pluckArg namedArgListWithKeyAndRefForNew) @ - if hasUnit then [(Nolabel, Exp.construct {loc; txt = Lident "()"} None)] else [] in - let innerExpression = Exp.apply (Exp.ident {loc; txt = Lident( - match recFlag with - | Recursive -> internalFnName - | Nonrecursive -> fnName - )}) innerExpressionArgs in - let innerExpressionWithRef = match (forwardRef) with - | Some txt -> - {innerExpression with pexp_desc = Pexp_fun (nolabel, None, { - ppat_desc = Ppat_var { txt; loc = emptyLoc }; - ppat_loc = emptyLoc; - ppat_attributes = []; - }, innerExpression)} - | None -> innerExpression - in - let fullExpression = Exp.fun_ - nolabel - None - { - ppat_desc = Ppat_constraint ( - makePropsName ~loc:emptyLoc props.propsName, - makePropsType ~loc:emptyLoc namedTypeList - ); - ppat_loc = emptyLoc; - ppat_attributes = []; - } - innerExpressionWithRef in - let fullExpression = match (fullModuleName) with - | ("") -> fullExpression - | (txt) -> Exp.let_ - Nonrecursive - [Vb.mk - ~loc:emptyLoc - (Pat.var ~loc:emptyLoc {loc = emptyLoc; txt}) - fullExpression - ] - (Exp.ident ~loc:emptyLoc {loc = emptyLoc; txt = Lident txt}) in - let (bindings, newBinding) = - match recFlag with - | Recursive -> ([bindingWrapper (Exp.let_ - ~loc:(emptyLoc) - Recursive - [ - makeNewBinding binding expression internalFnName; - Vb.mk (Pat.var {loc = emptyLoc; txt = fnName}) fullExpression - ] - (Exp.ident {loc = emptyLoc; txt = Lident fnName}))], None) - | Nonrecursive -> ([{ binding with pvb_expr = expression; pvb_attributes = [] }], Some(bindingWrapper fullExpression)) - in - (Some externalDecl, bindings, newBinding) - else - (None, [binding], None) - in - let structuresAndBinding = List.map mapBinding valueBindings in - let otherStructures (extern, binding, newBinding) (externs, bindings, newBindings) = - let externs = match extern with - | Some extern -> extern :: externs - | None -> externs in - let newBindings = match newBinding with - | Some newBinding -> newBinding :: newBindings - | None -> newBindings in - (externs, binding @ bindings, newBindings) - in - let (externs, bindings, newBindings) = List.fold_right otherStructures structuresAndBinding ([], [], []) in - externs @ [{ - pstr_loc; - pstr_desc = Pstr_value ( - recFlag, - bindings - ) - }] @ (match newBindings with - | [] -> [] - | newBindings -> [{ - pstr_loc = emptyLoc; - pstr_desc = Pstr_value ( - recFlag, - newBindings - ) - }]) @ returnStructures - | structure -> structure :: returnStructures in - - let reactComponentTransform mapper structures = - List.fold_right (transformComponentDefinition mapper) structures [] in - - let transformComponentSignature _mapper signature returnSignatures = match signature with - | ({ - psig_loc; - psig_desc = Psig_value ({ - pval_name = { txt = fnName }; - pval_attributes; - pval_type; - } as psig_desc) - } as psig) -> - (match List.filter hasAttr pval_attributes with - | [] -> signature :: returnSignatures - | [_] -> - let rec getPropTypes types ({ptyp_loc; ptyp_desc} as fullType) = - (match ptyp_desc with - | Ptyp_arrow (name, type_, ({ptyp_desc = Ptyp_arrow _} as rest)) when isOptional name || isLabelled name -> - getPropTypes ((name, ptyp_loc, type_)::types) rest - | Ptyp_arrow (Nolabel, _type, rest) -> - getPropTypes types rest - | Ptyp_arrow (name, type_, returnValue) when isOptional name || isLabelled name -> - (returnValue, (name, returnValue.ptyp_loc, type_)::types) - | _ -> (fullType, types)) - in - let (innerType, propTypes) = getPropTypes [] pval_type in - let namedTypeList = List.fold_left argToConcreteType [] propTypes in - let pluckLabelAndLoc (label, loc, type_) = (label, None, loc, Some type_) in - let retPropsType = makePropsType ~loc:psig_loc namedTypeList in - let externalPropsDecl = makePropsExternalSig fnName psig_loc (( - optional "key", - None, - psig_loc, - Some(keyType psig_loc) - ) :: List.map pluckLabelAndLoc propTypes) retPropsType in - (* can't be an arrow because it will defensively uncurry *) - let newExternalType = Ptyp_constr ( - {loc = psig_loc; txt = Ldot ((Lident "React"), "componentLike")}, - [retPropsType; innerType] - ) in - let newStructure = { - psig with psig_desc = Psig_value { - psig_desc with pval_type = { - pval_type with ptyp_desc = newExternalType; - }; - pval_attributes = List.filter otherAttrsPure pval_attributes; - } - } in - externalPropsDecl :: newStructure :: returnSignatures - | _ -> raise (Invalid_argument "Only one react.component call can exist on a component at one time")) - | signature -> signature :: returnSignatures in - - let reactComponentSignatureTransform mapper signatures = - List.fold_right (transformComponentSignature mapper) signatures [] in - - - let transformJsxCall mapper callExpression callArguments attrs = - (match callExpression.pexp_desc with - | Pexp_ident caller -> - (match caller with - | {txt = Lident "createElement"} -> - raise (Invalid_argument "JSX: `createElement` should be preceeded by a module name.") - - (* Foo.createElement(~prop1=foo, ~prop2=bar, ~children=[], ()) *) - | {loc; txt = Ldot (modulePath, ("createElement" | "make"))} -> - (match !jsxVersion with - | None - | Some 3 -> transformUppercaseCall3 modulePath mapper loc attrs callExpression callArguments - | Some _ -> raise (Invalid_argument "JSX: the JSX version must be 3")) - - (* div(~prop1=foo, ~prop2=bar, ~children=[bla], ()) *) - (* turn that into - ReactDOMRe.createElement(~props=ReactDOMRe.props(~props1=foo, ~props2=bar, ()), [|bla|]) *) - | {loc; txt = Lident id} -> - (match !jsxVersion with - | None - | Some 3 -> transformLowercaseCall3 mapper loc attrs callArguments id - | Some _ -> raise (Invalid_argument "JSX: the JSX version must be 3")) - - | {txt = Ldot (_, anythingNotCreateElementOrMake)} -> - raise ( - Invalid_argument - ("JSX: the JSX attribute should be attached to a `YourModuleName.createElement` or `YourModuleName.make` call. We saw `" - ^ anythingNotCreateElementOrMake - ^ "` instead" - ) - ) - - | {txt = Lapply _} -> - (* don't think there's ever a case where this is reached *) - raise ( - Invalid_argument "JSX: encountered a weird case while processing the code. Please report this!" - ) - ) - | _ -> - raise ( - Invalid_argument "JSX: `createElement` should be preceeded by a simple, direct module name." - ) - ) in - - let signature = - (fun mapper signature -> default_mapper.signature mapper @@ reactComponentSignatureTransform mapper signature) in - - let structure = - (fun mapper structure -> match structure with - | structures -> begin - default_mapper.structure mapper @@ reactComponentTransform mapper structures - end - ) in - - let expr = - (fun mapper expression -> match expression with - (* Does the function application have the @JSX attribute? *) - | { - pexp_desc = Pexp_apply (callExpression, callArguments); - pexp_attributes - } -> - let (jsxAttribute, nonJSXAttributes) = List.partition (fun (attribute, _) -> attribute.txt = "JSX") pexp_attributes in - (match (jsxAttribute, nonJSXAttributes) with - (* no JSX attribute *) - | ([], _) -> default_mapper.expr mapper expression - | (_, nonJSXAttributes) -> transformJsxCall mapper callExpression callArguments nonJSXAttributes) - - (* is it a list with jsx attribute? Reason <>foo desugars to [@JSX][foo]*) - | { - pexp_desc = - Pexp_construct ({txt = Lident "::"; loc}, Some {pexp_desc = Pexp_tuple _}) - | Pexp_construct ({txt = Lident "[]"; loc}, None); - pexp_attributes - } as listItems -> - let (jsxAttribute, nonJSXAttributes) = List.partition (fun (attribute, _) -> attribute.txt = "JSX") pexp_attributes in - (match (jsxAttribute, nonJSXAttributes) with - (* no JSX attribute *) - | ([], _) -> default_mapper.expr mapper expression - | (_, nonJSXAttributes) -> - let fragment = Exp.ident ~loc {loc; txt = Ldot (Lident "ReasonReact", "fragment")} in - let childrenExpr = transformChildrenIfList ~loc ~mapper listItems in - let args = [ - (* "div" *) - (nolabel, fragment); - (* [|moreCreateElementCallsHere|] *) - (nolabel, childrenExpr) - ] in - Exp.apply - ~loc - (* throw away the [@JSX] attribute and keep the others, if any *) - ~attrs:nonJSXAttributes - (* ReactDOMRe.createElement *) - (Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOMRe", "createElement")}) - args - ) - (* Delegate to the default mapper, a deep identity traversal *) - | e -> default_mapper.expr mapper e) in - - let module_binding = - (fun mapper module_binding -> - let _ = nestedModules := module_binding.pmb_name.txt :: !nestedModules in - let mapped = default_mapper.module_binding mapper module_binding in - let _ = nestedModules := List.tl !nestedModules in - mapped - ) in - - { default_mapper with structure; expr; signature; module_binding; } - -let rewrite_implementation (code: Parsetree.structure) : Parsetree.structure = - let mapper = jsxMapper () in - mapper.structure mapper code -let rewrite_signature (code : Parsetree.signature) : Parsetree.signature = - let mapper = jsxMapper () in - mapper.signature mapper code - - end module Ppx_entry = struct diff --git a/lib/4.06.1/unstable/js_refmt_compiler.ml.d b/lib/4.06.1/unstable/js_refmt_compiler.ml.d index ad38a05e5a..4b5d504ebb 100644 --- a/lib/4.06.1/unstable/js_refmt_compiler.ml.d +++ b/lib/4.06.1/unstable/js_refmt_compiler.ml.d @@ -1 +1 @@ -../lib/4.06.1/unstable/js_refmt_compiler.ml: ../ocaml/bytecomp/lambda.ml ../ocaml/bytecomp/lambda.mli ../ocaml/bytecomp/matching.ml ../ocaml/bytecomp/matching.mli ../ocaml/bytecomp/printlambda.ml ../ocaml/bytecomp/printlambda.mli ../ocaml/bytecomp/switch.ml ../ocaml/bytecomp/switch.mli ../ocaml/bytecomp/translattribute.ml ../ocaml/bytecomp/translattribute.mli ../ocaml/bytecomp/translclass.ml ../ocaml/bytecomp/translclass.mli ../ocaml/bytecomp/translcore.ml ../ocaml/bytecomp/translcore.mli ../ocaml/bytecomp/translmod.ml ../ocaml/bytecomp/translmod.mli ../ocaml/bytecomp/translobj.ml ../ocaml/bytecomp/translobj.mli ../ocaml/parsing/ast_helper.ml ../ocaml/parsing/ast_helper.mli ../ocaml/parsing/ast_iterator.ml ../ocaml/parsing/ast_iterator.mli ../ocaml/parsing/ast_mapper.ml ../ocaml/parsing/ast_mapper.mli ../ocaml/parsing/asttypes.mli ../ocaml/parsing/attr_helper.ml ../ocaml/parsing/attr_helper.mli ../ocaml/parsing/builtin_attributes.ml ../ocaml/parsing/builtin_attributes.mli ../ocaml/parsing/docstrings.ml ../ocaml/parsing/docstrings.mli ../ocaml/parsing/lexer.ml ../ocaml/parsing/lexer.mli ../ocaml/parsing/location.ml ../ocaml/parsing/location.mli ../ocaml/parsing/longident.ml ../ocaml/parsing/longident.mli ../ocaml/parsing/parse.ml ../ocaml/parsing/parse.mli ../ocaml/parsing/parser.ml ../ocaml/parsing/parser.mli ../ocaml/parsing/parsetree.mli ../ocaml/parsing/pprintast.ml ../ocaml/parsing/pprintast.mli ../ocaml/parsing/syntaxerr.ml ../ocaml/parsing/syntaxerr.mli ../ocaml/typing/annot.mli ../ocaml/typing/btype.ml ../ocaml/typing/btype.mli ../ocaml/typing/cmi_format.ml ../ocaml/typing/cmi_format.mli ../ocaml/typing/cmt_format.ml ../ocaml/typing/cmt_format.mli ../ocaml/typing/ctype.ml ../ocaml/typing/ctype.mli ../ocaml/typing/datarepr.ml ../ocaml/typing/datarepr.mli ../ocaml/typing/env.ml ../ocaml/typing/env.mli ../ocaml/typing/ident.ml ../ocaml/typing/ident.mli ../ocaml/typing/includeclass.ml ../ocaml/typing/includeclass.mli ../ocaml/typing/includecore.ml ../ocaml/typing/includecore.mli ../ocaml/typing/includemod.ml ../ocaml/typing/includemod.mli ../ocaml/typing/mtype.ml ../ocaml/typing/mtype.mli ../ocaml/typing/oprint.ml ../ocaml/typing/oprint.mli ../ocaml/typing/outcometree.mli ../ocaml/typing/parmatch.ml ../ocaml/typing/parmatch.mli ../ocaml/typing/path.ml ../ocaml/typing/path.mli ../ocaml/typing/predef.ml ../ocaml/typing/predef.mli ../ocaml/typing/primitive.ml ../ocaml/typing/primitive.mli ../ocaml/typing/printtyp.ml ../ocaml/typing/printtyp.mli ../ocaml/typing/stypes.ml ../ocaml/typing/stypes.mli ../ocaml/typing/subst.ml ../ocaml/typing/subst.mli ../ocaml/typing/tast_mapper.ml ../ocaml/typing/tast_mapper.mli ../ocaml/typing/typeclass.ml ../ocaml/typing/typeclass.mli ../ocaml/typing/typecore.ml ../ocaml/typing/typecore.mli ../ocaml/typing/typedecl.ml ../ocaml/typing/typedecl.mli ../ocaml/typing/typedtree.ml ../ocaml/typing/typedtree.mli ../ocaml/typing/typedtreeIter.ml ../ocaml/typing/typedtreeIter.mli ../ocaml/typing/typemod.ml ../ocaml/typing/typemod.mli ../ocaml/typing/typeopt.ml ../ocaml/typing/typeopt.mli ../ocaml/typing/types.ml ../ocaml/typing/types.mli ../ocaml/typing/typetexp.ml ../ocaml/typing/typetexp.mli ../ocaml/typing/untypeast.ml ../ocaml/typing/untypeast.mli ../ocaml/utils/arg_helper.ml ../ocaml/utils/arg_helper.mli ../ocaml/utils/ccomp.ml ../ocaml/utils/ccomp.mli ../ocaml/utils/clflags.ml ../ocaml/utils/clflags.mli ../ocaml/utils/consistbl.ml ../ocaml/utils/consistbl.mli ../ocaml/utils/identifiable.ml ../ocaml/utils/identifiable.mli ../ocaml/utils/misc.ml ../ocaml/utils/misc.mli ../ocaml/utils/numbers.ml ../ocaml/utils/numbers.mli ../ocaml/utils/profile.ml ../ocaml/utils/profile.mli ../ocaml/utils/tbl.ml ../ocaml/utils/tbl.mli ../ocaml/utils/warnings.ml ../ocaml/utils/warnings.mli ./common/bs_loc.ml ./common/bs_loc.mli ./common/bs_version.ml ./common/bs_version.mli ./common/bs_warnings.ml ./common/bs_warnings.mli ./common/ext_log.ml ./common/ext_log.mli ./common/js_config.ml ./common/js_config.mli ./common/lam_methname.ml ./common/lam_methname.mli ./core/bs_cmi_load.ml ./core/bs_conditional_initial.ml ./core/bs_conditional_initial.mli ./core/compile_rec_module.ml ./core/config_util.ml ./core/config_util.mli ./core/config_whole_compiler.ml ./core/config_whole_compiler.mli ./core/j.ml ./core/js_analyzer.ml ./core/js_analyzer.mli ./core/js_arr.ml ./core/js_arr.mli ./core/js_ast_util.ml ./core/js_ast_util.mli ./core/js_block_runtime.ml ./core/js_block_runtime.mli ./core/js_call_info.ml ./core/js_call_info.mli ./core/js_closure.ml ./core/js_closure.mli ./core/js_cmj_format.ml ./core/js_cmj_format.mli ./core/js_cmj_load.ml ./core/js_cmj_load.mli ./core/js_cmj_load_builtin_unit.ml ./core/js_dump.ml ./core/js_dump.mli ./core/js_dump_import_export.ml ./core/js_dump_import_export.mli ./core/js_dump_lit.ml ./core/js_dump_program.ml ./core/js_dump_program.mli ./core/js_dump_property.ml ./core/js_dump_property.mli ./core/js_dump_string.ml ./core/js_dump_string.mli ./core/js_exp_make.ml ./core/js_exp_make.mli ./core/js_fold.ml ./core/js_fold_basic.ml ./core/js_fold_basic.mli ./core/js_fun_env.ml ./core/js_fun_env.mli ./core/js_long.ml ./core/js_long.mli ./core/js_map.ml ./core/js_name_of_module_id.ml ./core/js_name_of_module_id.mli ./core/js_number.ml ./core/js_number.mli ./core/js_of_lam_array.ml ./core/js_of_lam_array.mli ./core/js_of_lam_block.ml ./core/js_of_lam_block.mli ./core/js_of_lam_exception.ml ./core/js_of_lam_exception.mli ./core/js_of_lam_option.ml ./core/js_of_lam_option.mli ./core/js_of_lam_string.ml ./core/js_of_lam_string.mli ./core/js_of_lam_variant.ml ./core/js_of_lam_variant.mli ./core/js_op.ml ./core/js_op_util.ml ./core/js_op_util.mli ./core/js_output.ml ./core/js_output.mli ./core/js_packages_info.ml ./core/js_packages_info.mli ./core/js_packages_state.ml ./core/js_packages_state.mli ./core/js_pass_debug.ml ./core/js_pass_debug.mli ./core/js_pass_flatten.ml ./core/js_pass_flatten.mli ./core/js_pass_flatten_and_mark_dead.ml ./core/js_pass_flatten_and_mark_dead.mli ./core/js_pass_get_used.ml ./core/js_pass_get_used.mli ./core/js_pass_scope.ml ./core/js_pass_scope.mli ./core/js_pass_tailcall_inline.ml ./core/js_pass_tailcall_inline.mli ./core/js_raw_info.ml ./core/js_shake.ml ./core/js_shake.mli ./core/js_stmt_make.ml ./core/js_stmt_make.mli ./core/lam.ml ./core/lam.mli ./core/lam_analysis.ml ./core/lam_analysis.mli ./core/lam_arity.ml ./core/lam_arity.mli ./core/lam_arity_analysis.ml ./core/lam_arity_analysis.mli ./core/lam_beta_reduce.ml ./core/lam_beta_reduce.mli ./core/lam_beta_reduce_util.ml ./core/lam_beta_reduce_util.mli ./core/lam_bounded_vars.ml ./core/lam_bounded_vars.mli ./core/lam_closure.ml ./core/lam_closure.mli ./core/lam_coercion.ml ./core/lam_coercion.mli ./core/lam_compat.ml ./core/lam_compat.mli ./core/lam_compile.ml ./core/lam_compile.mli ./core/lam_compile_const.ml ./core/lam_compile_const.mli ./core/lam_compile_context.ml ./core/lam_compile_context.mli ./core/lam_compile_env.ml ./core/lam_compile_env.mli ./core/lam_compile_external_call.ml ./core/lam_compile_external_call.mli ./core/lam_compile_external_obj.ml ./core/lam_compile_external_obj.mli ./core/lam_compile_main.ml ./core/lam_compile_main.mli ./core/lam_compile_primitive.ml ./core/lam_compile_primitive.mli ./core/lam_compile_util.ml ./core/lam_compile_util.mli ./core/lam_constant.ml ./core/lam_constant.mli ./core/lam_constant_convert.ml ./core/lam_constant_convert.mli ./core/lam_convert.ml ./core/lam_convert.mli ./core/lam_dce.ml ./core/lam_dce.mli ./core/lam_dispatch_primitive.ml ./core/lam_dispatch_primitive.mli ./core/lam_eta_conversion.ml ./core/lam_eta_conversion.mli ./core/lam_exit_code.ml ./core/lam_exit_code.mli ./core/lam_exit_count.ml ./core/lam_exit_count.mli ./core/lam_free_variables.ml ./core/lam_free_variables.mli ./core/lam_group.ml ./core/lam_group.mli ./core/lam_hit.ml ./core/lam_hit.mli ./core/lam_id_kind.ml ./core/lam_id_kind.mli ./core/lam_iter.ml ./core/lam_iter.mli ./core/lam_module_ident.ml ./core/lam_module_ident.mli ./core/lam_pass_alpha_conversion.ml ./core/lam_pass_alpha_conversion.mli ./core/lam_pass_collect.ml ./core/lam_pass_collect.mli ./core/lam_pass_count.ml ./core/lam_pass_count.mli ./core/lam_pass_deep_flatten.ml ./core/lam_pass_deep_flatten.mli ./core/lam_pass_eliminate_ref.ml ./core/lam_pass_eliminate_ref.mli ./core/lam_pass_exits.ml ./core/lam_pass_exits.mli ./core/lam_pass_lets_dce.ml ./core/lam_pass_lets_dce.mli ./core/lam_pass_remove_alias.ml ./core/lam_pass_remove_alias.mli ./core/lam_pointer_info.ml ./core/lam_pointer_info.mli ./core/lam_primitive.ml ./core/lam_primitive.mli ./core/lam_print.ml ./core/lam_print.mli ./core/lam_scc.ml ./core/lam_scc.mli ./core/lam_stats.ml ./core/lam_stats.mli ./core/lam_stats_export.ml ./core/lam_stats_export.mli ./core/lam_subst.ml ./core/lam_subst.mli ./core/lam_tag_info.ml ./core/lam_util.ml ./core/lam_util.mli ./core/lam_var_stats.ml ./core/lam_var_stats.mli ./core/matching_polyfill.ml ./core/matching_polyfill.mli ./core/polyvar_pattern_match.ml ./core/record_attributes_check.ml ./core/res_compmisc.ml ./core/res_compmisc.mli ./core/transl_single_field_record.ml ./depends/bs_exception.ml ./depends/bs_exception.mli ./ext/bsc_args.ml ./ext/bsc_args.mli ./ext/bsc_warnings.ml ./ext/ext_array.ml ./ext/ext_array.mli ./ext/ext_buffer.ml ./ext/ext_buffer.mli ./ext/ext_bytes.ml ./ext/ext_bytes.mli ./ext/ext_char.ml ./ext/ext_char.mli ./ext/ext_digest.ml ./ext/ext_digest.mli ./ext/ext_filename.ml ./ext/ext_filename.mli ./ext/ext_fmt.ml ./ext/ext_ident.ml ./ext/ext_ident.mli ./ext/ext_int.ml ./ext/ext_int.mli ./ext/ext_io.ml ./ext/ext_io.mli ./ext/ext_js_file_kind.ml ./ext/ext_js_suffix.ml ./ext/ext_list.ml ./ext/ext_list.mli ./ext/ext_marshal.ml ./ext/ext_marshal.mli ./ext/ext_modulename.ml ./ext/ext_modulename.mli ./ext/ext_namespace.ml ./ext/ext_namespace.mli ./ext/ext_option.ml ./ext/ext_option.mli ./ext/ext_path.ml ./ext/ext_path.mli ./ext/ext_pervasives.ml ./ext/ext_pervasives.mli ./ext/ext_pp.ml ./ext/ext_pp.mli ./ext/ext_pp_scope.ml ./ext/ext_pp_scope.mli ./ext/ext_ref.ml ./ext/ext_ref.mli ./ext/ext_scc.ml ./ext/ext_scc.mli ./ext/ext_spec.ml ./ext/ext_spec.mli ./ext/ext_string.ml ./ext/ext_string.mli ./ext/ext_string_array.ml ./ext/ext_string_array.mli ./ext/ext_sys.ml ./ext/ext_sys.mli ./ext/ext_utf8.ml ./ext/ext_utf8.mli ./ext/ext_util.ml ./ext/ext_util.mli ./ext/hash.ml ./ext/hash.mli ./ext/hash_gen.ml ./ext/hash_ident.ml ./ext/hash_ident.mli ./ext/hash_int.ml ./ext/hash_int.mli ./ext/hash_set.ml ./ext/hash_set.mli ./ext/hash_set_gen.ml ./ext/hash_set_ident.ml ./ext/hash_set_ident.mli ./ext/hash_set_ident_mask.ml ./ext/hash_set_ident_mask.mli ./ext/hash_set_poly.ml ./ext/hash_set_poly.mli ./ext/hash_set_string.ml ./ext/hash_set_string.mli ./ext/hash_string.ml ./ext/hash_string.mli ./ext/int_vec_util.ml ./ext/int_vec_util.mli ./ext/int_vec_vec.ml ./ext/int_vec_vec.mli ./ext/js_reserved_map.ml ./ext/js_reserved_map.mli ./ext/js_runtime_modules.ml ./ext/literals.ml ./ext/map_gen.ml ./ext/map_gen.mli ./ext/map_ident.ml ./ext/map_ident.mli ./ext/map_int.ml ./ext/map_int.mli ./ext/map_string.ml ./ext/map_string.mli ./ext/ordered_hash_map_gen.ml ./ext/ordered_hash_map_local_ident.ml ./ext/ordered_hash_map_local_ident.mli ./ext/set_gen.ml ./ext/set_gen.mli ./ext/set_ident.ml ./ext/set_ident.mli ./ext/set_string.ml ./ext/set_string.mli ./ext/vec.ml ./ext/vec.mli ./ext/vec_gen.ml ./ext/vec_int.ml ./ext/vec_int.mli ./js_parser/declaration_parser.ml ./js_parser/enum_common.ml ./js_parser/enum_parser.ml ./js_parser/expression_parser.ml ./js_parser/file_key.ml ./js_parser/flow_ast.ml ./js_parser/flow_ast_utils.ml ./js_parser/flow_ast_utils.mli ./js_parser/flow_lexer.ml ./js_parser/flow_lexer.mli ./js_parser/jsx_parser.ml ./js_parser/lex_env.ml ./js_parser/lex_result.ml ./js_parser/loc.ml ./js_parser/loc.mli ./js_parser/object_parser.ml ./js_parser/parse_error.ml ./js_parser/parser_common.ml ./js_parser/parser_env.ml ./js_parser/parser_env.mli ./js_parser/parser_flow.ml ./js_parser/pattern_cover.ml ./js_parser/pattern_parser.ml ./js_parser/sedlexing.ml ./js_parser/sedlexing.mli ./js_parser/statement_parser.ml ./js_parser/token.ml ./js_parser/type_parser.ml ./js_parser/wtf8.ml ./js_parser/wtf8.mli ./main/builtin_cmi_datasets.ml ./main/builtin_cmi_datasets.mli ./main/builtin_cmj_datasets.ml ./main/builtin_cmj_datasets.mli ./main/jsoo_common.ml ./main/jsoo_common.mli ./outcome_printer/outcome_printer_ns.ml ./outcome_printer/outcome_printer_ns.mli ./refmt/jsoo_refmt_main.ml ./refmt/jsoo_refmt_main.mli ./refmt/refmt_api.ml ./stubs/bs_hash_stubs.ml ./super_errors/super_env.ml ./super_errors/super_location.ml ./super_errors/super_location.mli ./super_errors/super_main.ml ./super_errors/super_misc.ml ./super_errors/super_misc.mli ./super_errors/super_pparse.ml ./super_errors/super_typecore.ml ./super_errors/super_typemod.ml ./super_errors/super_typetexp.ml ./syntax/ast_attributes.ml ./syntax/ast_attributes.mli ./syntax/ast_bs_open.ml ./syntax/ast_bs_open.mli ./syntax/ast_comb.ml ./syntax/ast_comb.mli ./syntax/ast_compatible.ml ./syntax/ast_compatible.mli ./syntax/ast_config.ml ./syntax/ast_config.mli ./syntax/ast_core_type.ml ./syntax/ast_core_type.mli ./syntax/ast_core_type_class_type.ml ./syntax/ast_core_type_class_type.mli ./syntax/ast_derive.ml ./syntax/ast_derive.mli ./syntax/ast_derive_abstract.ml ./syntax/ast_derive_abstract.mli ./syntax/ast_derive_js_mapper.ml ./syntax/ast_derive_js_mapper.mli ./syntax/ast_derive_projector.ml ./syntax/ast_derive_projector.mli ./syntax/ast_derive_util.ml ./syntax/ast_derive_util.mli ./syntax/ast_exp.ml ./syntax/ast_exp.mli ./syntax/ast_exp_apply.ml ./syntax/ast_exp_apply.mli ./syntax/ast_exp_extension.ml ./syntax/ast_exp_extension.mli ./syntax/ast_exp_handle_external.ml ./syntax/ast_exp_handle_external.mli ./syntax/ast_external.ml ./syntax/ast_external.mli ./syntax/ast_external_mk.ml ./syntax/ast_external_mk.mli ./syntax/ast_external_process.ml ./syntax/ast_external_process.mli ./syntax/ast_literal.ml ./syntax/ast_literal.mli ./syntax/ast_open_cxt.ml ./syntax/ast_open_cxt.mli ./syntax/ast_pat.ml ./syntax/ast_pat.mli ./syntax/ast_payload.ml ./syntax/ast_payload.mli ./syntax/ast_polyvar.ml ./syntax/ast_polyvar.mli ./syntax/ast_reason_pp.ml ./syntax/ast_reason_pp.mli ./syntax/ast_signature.ml ./syntax/ast_signature.mli ./syntax/ast_structure.ml ./syntax/ast_structure.mli ./syntax/ast_tdcls.ml ./syntax/ast_tdcls.mli ./syntax/ast_tuple_pattern_flatten.ml ./syntax/ast_tuple_pattern_flatten.mli ./syntax/ast_typ_uncurry.ml ./syntax/ast_typ_uncurry.mli ./syntax/ast_uncurry_apply.ml ./syntax/ast_uncurry_apply.mli ./syntax/ast_uncurry_gen.ml ./syntax/ast_uncurry_gen.mli ./syntax/ast_utf8_string.ml ./syntax/ast_utf8_string.mli ./syntax/ast_utf8_string_interp.ml ./syntax/ast_utf8_string_interp.mli ./syntax/ast_util.ml ./syntax/ast_util.mli ./syntax/bs_ast_invariant.ml ./syntax/bs_ast_invariant.mli ./syntax/bs_ast_mapper.ml ./syntax/bs_ast_mapper.mli ./syntax/bs_builtin_ppx.ml ./syntax/bs_builtin_ppx.mli ./syntax/bs_flow_ast_utils.ml ./syntax/bs_flow_ast_utils.mli ./syntax/bs_syntaxerr.ml ./syntax/bs_syntaxerr.mli ./syntax/classify_function.ml ./syntax/classify_function.mli ./syntax/external_arg_spec.ml ./syntax/external_arg_spec.mli ./syntax/external_ffi_types.ml ./syntax/external_ffi_types.mli ./syntax/ppx_entry.ml ./syntax/reactjs_jsx_ppx_v3.ml ./syntax/typemod_hide.ml \ No newline at end of file +../lib/4.06.1/unstable/js_refmt_compiler.ml: ../ocaml/bytecomp/lambda.ml ../ocaml/bytecomp/lambda.mli ../ocaml/bytecomp/matching.ml ../ocaml/bytecomp/matching.mli ../ocaml/bytecomp/printlambda.ml ../ocaml/bytecomp/printlambda.mli ../ocaml/bytecomp/switch.ml ../ocaml/bytecomp/switch.mli ../ocaml/bytecomp/translattribute.ml ../ocaml/bytecomp/translattribute.mli ../ocaml/bytecomp/translclass.ml ../ocaml/bytecomp/translclass.mli ../ocaml/bytecomp/translcore.ml ../ocaml/bytecomp/translcore.mli ../ocaml/bytecomp/translmod.ml ../ocaml/bytecomp/translmod.mli ../ocaml/bytecomp/translobj.ml ../ocaml/bytecomp/translobj.mli ../ocaml/parsing/ast_helper.ml ../ocaml/parsing/ast_helper.mli ../ocaml/parsing/ast_iterator.ml ../ocaml/parsing/ast_iterator.mli ../ocaml/parsing/ast_mapper.ml ../ocaml/parsing/ast_mapper.mli ../ocaml/parsing/asttypes.mli ../ocaml/parsing/attr_helper.ml ../ocaml/parsing/attr_helper.mli ../ocaml/parsing/builtin_attributes.ml ../ocaml/parsing/builtin_attributes.mli ../ocaml/parsing/docstrings.ml ../ocaml/parsing/docstrings.mli ../ocaml/parsing/lexer.ml ../ocaml/parsing/lexer.mli ../ocaml/parsing/location.ml ../ocaml/parsing/location.mli ../ocaml/parsing/longident.ml ../ocaml/parsing/longident.mli ../ocaml/parsing/parse.ml ../ocaml/parsing/parse.mli ../ocaml/parsing/parser.ml ../ocaml/parsing/parser.mli ../ocaml/parsing/parsetree.mli ../ocaml/parsing/pprintast.ml ../ocaml/parsing/pprintast.mli ../ocaml/parsing/syntaxerr.ml ../ocaml/parsing/syntaxerr.mli ../ocaml/typing/annot.mli ../ocaml/typing/btype.ml ../ocaml/typing/btype.mli ../ocaml/typing/cmi_format.ml ../ocaml/typing/cmi_format.mli ../ocaml/typing/cmt_format.ml ../ocaml/typing/cmt_format.mli ../ocaml/typing/ctype.ml ../ocaml/typing/ctype.mli ../ocaml/typing/datarepr.ml ../ocaml/typing/datarepr.mli ../ocaml/typing/env.ml ../ocaml/typing/env.mli ../ocaml/typing/ident.ml ../ocaml/typing/ident.mli ../ocaml/typing/includeclass.ml ../ocaml/typing/includeclass.mli ../ocaml/typing/includecore.ml ../ocaml/typing/includecore.mli ../ocaml/typing/includemod.ml ../ocaml/typing/includemod.mli ../ocaml/typing/mtype.ml ../ocaml/typing/mtype.mli ../ocaml/typing/oprint.ml ../ocaml/typing/oprint.mli ../ocaml/typing/outcometree.mli ../ocaml/typing/parmatch.ml ../ocaml/typing/parmatch.mli ../ocaml/typing/path.ml ../ocaml/typing/path.mli ../ocaml/typing/predef.ml ../ocaml/typing/predef.mli ../ocaml/typing/primitive.ml ../ocaml/typing/primitive.mli ../ocaml/typing/printtyp.ml ../ocaml/typing/printtyp.mli ../ocaml/typing/stypes.ml ../ocaml/typing/stypes.mli ../ocaml/typing/subst.ml ../ocaml/typing/subst.mli ../ocaml/typing/tast_mapper.ml ../ocaml/typing/tast_mapper.mli ../ocaml/typing/typeclass.ml ../ocaml/typing/typeclass.mli ../ocaml/typing/typecore.ml ../ocaml/typing/typecore.mli ../ocaml/typing/typedecl.ml ../ocaml/typing/typedecl.mli ../ocaml/typing/typedtree.ml ../ocaml/typing/typedtree.mli ../ocaml/typing/typedtreeIter.ml ../ocaml/typing/typedtreeIter.mli ../ocaml/typing/typemod.ml ../ocaml/typing/typemod.mli ../ocaml/typing/typeopt.ml ../ocaml/typing/typeopt.mli ../ocaml/typing/types.ml ../ocaml/typing/types.mli ../ocaml/typing/typetexp.ml ../ocaml/typing/typetexp.mli ../ocaml/typing/untypeast.ml ../ocaml/typing/untypeast.mli ../ocaml/utils/arg_helper.ml ../ocaml/utils/arg_helper.mli ../ocaml/utils/ccomp.ml ../ocaml/utils/ccomp.mli ../ocaml/utils/clflags.ml ../ocaml/utils/clflags.mli ../ocaml/utils/consistbl.ml ../ocaml/utils/consistbl.mli ../ocaml/utils/identifiable.ml ../ocaml/utils/identifiable.mli ../ocaml/utils/misc.ml ../ocaml/utils/misc.mli ../ocaml/utils/numbers.ml ../ocaml/utils/numbers.mli ../ocaml/utils/profile.ml ../ocaml/utils/profile.mli ../ocaml/utils/tbl.ml ../ocaml/utils/tbl.mli ../ocaml/utils/warnings.ml ../ocaml/utils/warnings.mli ./common/bs_loc.ml ./common/bs_loc.mli ./common/bs_version.ml ./common/bs_version.mli ./common/bs_warnings.ml ./common/bs_warnings.mli ./common/ext_log.ml ./common/ext_log.mli ./common/js_config.ml ./common/js_config.mli ./common/lam_methname.ml ./common/lam_methname.mli ./core/bs_cmi_load.ml ./core/bs_conditional_initial.ml ./core/bs_conditional_initial.mli ./core/compile_rec_module.ml ./core/config_util.ml ./core/config_util.mli ./core/config_whole_compiler.ml ./core/config_whole_compiler.mli ./core/j.ml ./core/js_analyzer.ml ./core/js_analyzer.mli ./core/js_arr.ml ./core/js_arr.mli ./core/js_ast_util.ml ./core/js_ast_util.mli ./core/js_block_runtime.ml ./core/js_block_runtime.mli ./core/js_call_info.ml ./core/js_call_info.mli ./core/js_closure.ml ./core/js_closure.mli ./core/js_cmj_format.ml ./core/js_cmj_format.mli ./core/js_cmj_load.ml ./core/js_cmj_load.mli ./core/js_cmj_load_builtin_unit.ml ./core/js_dump.ml ./core/js_dump.mli ./core/js_dump_import_export.ml ./core/js_dump_import_export.mli ./core/js_dump_lit.ml ./core/js_dump_program.ml ./core/js_dump_program.mli ./core/js_dump_property.ml ./core/js_dump_property.mli ./core/js_dump_string.ml ./core/js_dump_string.mli ./core/js_exp_make.ml ./core/js_exp_make.mli ./core/js_fold.ml ./core/js_fold_basic.ml ./core/js_fold_basic.mli ./core/js_fun_env.ml ./core/js_fun_env.mli ./core/js_long.ml ./core/js_long.mli ./core/js_map.ml ./core/js_name_of_module_id.ml ./core/js_name_of_module_id.mli ./core/js_number.ml ./core/js_number.mli ./core/js_of_lam_array.ml ./core/js_of_lam_array.mli ./core/js_of_lam_block.ml ./core/js_of_lam_block.mli ./core/js_of_lam_exception.ml ./core/js_of_lam_exception.mli ./core/js_of_lam_option.ml ./core/js_of_lam_option.mli ./core/js_of_lam_string.ml ./core/js_of_lam_string.mli ./core/js_of_lam_variant.ml ./core/js_of_lam_variant.mli ./core/js_op.ml ./core/js_op_util.ml ./core/js_op_util.mli ./core/js_output.ml ./core/js_output.mli ./core/js_packages_info.ml ./core/js_packages_info.mli ./core/js_packages_state.ml ./core/js_packages_state.mli ./core/js_pass_debug.ml ./core/js_pass_debug.mli ./core/js_pass_flatten.ml ./core/js_pass_flatten.mli ./core/js_pass_flatten_and_mark_dead.ml ./core/js_pass_flatten_and_mark_dead.mli ./core/js_pass_get_used.ml ./core/js_pass_get_used.mli ./core/js_pass_scope.ml ./core/js_pass_scope.mli ./core/js_pass_tailcall_inline.ml ./core/js_pass_tailcall_inline.mli ./core/js_raw_info.ml ./core/js_shake.ml ./core/js_shake.mli ./core/js_stmt_make.ml ./core/js_stmt_make.mli ./core/lam.ml ./core/lam.mli ./core/lam_analysis.ml ./core/lam_analysis.mli ./core/lam_arity.ml ./core/lam_arity.mli ./core/lam_arity_analysis.ml ./core/lam_arity_analysis.mli ./core/lam_beta_reduce.ml ./core/lam_beta_reduce.mli ./core/lam_beta_reduce_util.ml ./core/lam_beta_reduce_util.mli ./core/lam_bounded_vars.ml ./core/lam_bounded_vars.mli ./core/lam_closure.ml ./core/lam_closure.mli ./core/lam_coercion.ml ./core/lam_coercion.mli ./core/lam_compat.ml ./core/lam_compat.mli ./core/lam_compile.ml ./core/lam_compile.mli ./core/lam_compile_const.ml ./core/lam_compile_const.mli ./core/lam_compile_context.ml ./core/lam_compile_context.mli ./core/lam_compile_env.ml ./core/lam_compile_env.mli ./core/lam_compile_external_call.ml ./core/lam_compile_external_call.mli ./core/lam_compile_external_obj.ml ./core/lam_compile_external_obj.mli ./core/lam_compile_main.ml ./core/lam_compile_main.mli ./core/lam_compile_primitive.ml ./core/lam_compile_primitive.mli ./core/lam_compile_util.ml ./core/lam_compile_util.mli ./core/lam_constant.ml ./core/lam_constant.mli ./core/lam_constant_convert.ml ./core/lam_constant_convert.mli ./core/lam_convert.ml ./core/lam_convert.mli ./core/lam_dce.ml ./core/lam_dce.mli ./core/lam_dispatch_primitive.ml ./core/lam_dispatch_primitive.mli ./core/lam_eta_conversion.ml ./core/lam_eta_conversion.mli ./core/lam_exit_code.ml ./core/lam_exit_code.mli ./core/lam_exit_count.ml ./core/lam_exit_count.mli ./core/lam_free_variables.ml ./core/lam_free_variables.mli ./core/lam_group.ml ./core/lam_group.mli ./core/lam_hit.ml ./core/lam_hit.mli ./core/lam_id_kind.ml ./core/lam_id_kind.mli ./core/lam_iter.ml ./core/lam_iter.mli ./core/lam_module_ident.ml ./core/lam_module_ident.mli ./core/lam_pass_alpha_conversion.ml ./core/lam_pass_alpha_conversion.mli ./core/lam_pass_collect.ml ./core/lam_pass_collect.mli ./core/lam_pass_count.ml ./core/lam_pass_count.mli ./core/lam_pass_deep_flatten.ml ./core/lam_pass_deep_flatten.mli ./core/lam_pass_eliminate_ref.ml ./core/lam_pass_eliminate_ref.mli ./core/lam_pass_exits.ml ./core/lam_pass_exits.mli ./core/lam_pass_lets_dce.ml ./core/lam_pass_lets_dce.mli ./core/lam_pass_remove_alias.ml ./core/lam_pass_remove_alias.mli ./core/lam_pointer_info.ml ./core/lam_pointer_info.mli ./core/lam_primitive.ml ./core/lam_primitive.mli ./core/lam_print.ml ./core/lam_print.mli ./core/lam_scc.ml ./core/lam_scc.mli ./core/lam_stats.ml ./core/lam_stats.mli ./core/lam_stats_export.ml ./core/lam_stats_export.mli ./core/lam_subst.ml ./core/lam_subst.mli ./core/lam_tag_info.ml ./core/lam_util.ml ./core/lam_util.mli ./core/lam_var_stats.ml ./core/lam_var_stats.mli ./core/matching_polyfill.ml ./core/matching_polyfill.mli ./core/polyvar_pattern_match.ml ./core/record_attributes_check.ml ./core/res_compmisc.ml ./core/res_compmisc.mli ./core/transl_single_field_record.ml ./depends/bs_exception.ml ./depends/bs_exception.mli ./ext/bsc_args.ml ./ext/bsc_args.mli ./ext/bsc_warnings.ml ./ext/ext_array.ml ./ext/ext_array.mli ./ext/ext_buffer.ml ./ext/ext_buffer.mli ./ext/ext_bytes.ml ./ext/ext_bytes.mli ./ext/ext_char.ml ./ext/ext_char.mli ./ext/ext_digest.ml ./ext/ext_digest.mli ./ext/ext_filename.ml ./ext/ext_filename.mli ./ext/ext_fmt.ml ./ext/ext_ident.ml ./ext/ext_ident.mli ./ext/ext_int.ml ./ext/ext_int.mli ./ext/ext_io.ml ./ext/ext_io.mli ./ext/ext_js_file_kind.ml ./ext/ext_js_suffix.ml ./ext/ext_list.ml ./ext/ext_list.mli ./ext/ext_marshal.ml ./ext/ext_marshal.mli ./ext/ext_modulename.ml ./ext/ext_modulename.mli ./ext/ext_namespace.ml ./ext/ext_namespace.mli ./ext/ext_option.ml ./ext/ext_option.mli ./ext/ext_path.ml ./ext/ext_path.mli ./ext/ext_pervasives.ml ./ext/ext_pervasives.mli ./ext/ext_pp.ml ./ext/ext_pp.mli ./ext/ext_pp_scope.ml ./ext/ext_pp_scope.mli ./ext/ext_ref.ml ./ext/ext_ref.mli ./ext/ext_scc.ml ./ext/ext_scc.mli ./ext/ext_spec.ml ./ext/ext_spec.mli ./ext/ext_string.ml ./ext/ext_string.mli ./ext/ext_string_array.ml ./ext/ext_string_array.mli ./ext/ext_sys.ml ./ext/ext_sys.mli ./ext/ext_utf8.ml ./ext/ext_utf8.mli ./ext/ext_util.ml ./ext/ext_util.mli ./ext/hash.ml ./ext/hash.mli ./ext/hash_gen.ml ./ext/hash_ident.ml ./ext/hash_ident.mli ./ext/hash_int.ml ./ext/hash_int.mli ./ext/hash_set.ml ./ext/hash_set.mli ./ext/hash_set_gen.ml ./ext/hash_set_ident.ml ./ext/hash_set_ident.mli ./ext/hash_set_ident_mask.ml ./ext/hash_set_ident_mask.mli ./ext/hash_set_poly.ml ./ext/hash_set_poly.mli ./ext/hash_set_string.ml ./ext/hash_set_string.mli ./ext/hash_string.ml ./ext/hash_string.mli ./ext/int_vec_util.ml ./ext/int_vec_util.mli ./ext/int_vec_vec.ml ./ext/int_vec_vec.mli ./ext/js_reserved_map.ml ./ext/js_reserved_map.mli ./ext/js_runtime_modules.ml ./ext/literals.ml ./ext/map_gen.ml ./ext/map_gen.mli ./ext/map_ident.ml ./ext/map_ident.mli ./ext/map_int.ml ./ext/map_int.mli ./ext/map_string.ml ./ext/map_string.mli ./ext/ordered_hash_map_gen.ml ./ext/ordered_hash_map_local_ident.ml ./ext/ordered_hash_map_local_ident.mli ./ext/set_gen.ml ./ext/set_gen.mli ./ext/set_ident.ml ./ext/set_ident.mli ./ext/set_string.ml ./ext/set_string.mli ./ext/vec.ml ./ext/vec.mli ./ext/vec_gen.ml ./ext/vec_int.ml ./ext/vec_int.mli ./js_parser/declaration_parser.ml ./js_parser/enum_common.ml ./js_parser/enum_parser.ml ./js_parser/expression_parser.ml ./js_parser/file_key.ml ./js_parser/flow_ast.ml ./js_parser/flow_ast_utils.ml ./js_parser/flow_ast_utils.mli ./js_parser/flow_lexer.ml ./js_parser/flow_lexer.mli ./js_parser/jsx_parser.ml ./js_parser/lex_env.ml ./js_parser/lex_result.ml ./js_parser/loc.ml ./js_parser/loc.mli ./js_parser/object_parser.ml ./js_parser/parse_error.ml ./js_parser/parser_common.ml ./js_parser/parser_env.ml ./js_parser/parser_env.mli ./js_parser/parser_flow.ml ./js_parser/pattern_cover.ml ./js_parser/pattern_parser.ml ./js_parser/sedlexing.ml ./js_parser/sedlexing.mli ./js_parser/statement_parser.ml ./js_parser/token.ml ./js_parser/type_parser.ml ./js_parser/wtf8.ml ./js_parser/wtf8.mli ./main/builtin_cmi_datasets.ml ./main/builtin_cmi_datasets.mli ./main/builtin_cmj_datasets.ml ./main/builtin_cmj_datasets.mli ./main/jsoo_common.ml ./main/jsoo_common.mli ./outcome_printer/outcome_printer_ns.ml ./outcome_printer/outcome_printer_ns.mli ./refmt/jsoo_refmt_main.ml ./refmt/jsoo_refmt_main.mli ./refmt/refmt_api.ml ./stubs/bs_hash_stubs.ml ./super_errors/super_env.ml ./super_errors/super_location.ml ./super_errors/super_location.mli ./super_errors/super_main.ml ./super_errors/super_misc.ml ./super_errors/super_misc.mli ./super_errors/super_pparse.ml ./super_errors/super_typecore.ml ./super_errors/super_typemod.ml ./super_errors/super_typetexp.ml ./syntax/ast_attributes.ml ./syntax/ast_attributes.mli ./syntax/ast_bs_open.ml ./syntax/ast_bs_open.mli ./syntax/ast_comb.ml ./syntax/ast_comb.mli ./syntax/ast_compatible.ml ./syntax/ast_compatible.mli ./syntax/ast_config.ml ./syntax/ast_config.mli ./syntax/ast_core_type.ml ./syntax/ast_core_type.mli ./syntax/ast_core_type_class_type.ml ./syntax/ast_core_type_class_type.mli ./syntax/ast_derive.ml ./syntax/ast_derive.mli ./syntax/ast_derive_abstract.ml ./syntax/ast_derive_abstract.mli ./syntax/ast_derive_js_mapper.ml ./syntax/ast_derive_js_mapper.mli ./syntax/ast_derive_projector.ml ./syntax/ast_derive_projector.mli ./syntax/ast_derive_util.ml ./syntax/ast_derive_util.mli ./syntax/ast_exp.ml ./syntax/ast_exp.mli ./syntax/ast_exp_apply.ml ./syntax/ast_exp_apply.mli ./syntax/ast_exp_extension.ml ./syntax/ast_exp_extension.mli ./syntax/ast_exp_handle_external.ml ./syntax/ast_exp_handle_external.mli ./syntax/ast_external.ml ./syntax/ast_external.mli ./syntax/ast_external_mk.ml ./syntax/ast_external_mk.mli ./syntax/ast_external_process.ml ./syntax/ast_external_process.mli ./syntax/ast_literal.ml ./syntax/ast_literal.mli ./syntax/ast_open_cxt.ml ./syntax/ast_open_cxt.mli ./syntax/ast_pat.ml ./syntax/ast_pat.mli ./syntax/ast_payload.ml ./syntax/ast_payload.mli ./syntax/ast_polyvar.ml ./syntax/ast_polyvar.mli ./syntax/ast_reason_pp.ml ./syntax/ast_reason_pp.mli ./syntax/ast_signature.ml ./syntax/ast_signature.mli ./syntax/ast_structure.ml ./syntax/ast_structure.mli ./syntax/ast_tdcls.ml ./syntax/ast_tdcls.mli ./syntax/ast_tuple_pattern_flatten.ml ./syntax/ast_tuple_pattern_flatten.mli ./syntax/ast_typ_uncurry.ml ./syntax/ast_typ_uncurry.mli ./syntax/ast_uncurry_apply.ml ./syntax/ast_uncurry_apply.mli ./syntax/ast_uncurry_gen.ml ./syntax/ast_uncurry_gen.mli ./syntax/ast_utf8_string.ml ./syntax/ast_utf8_string.mli ./syntax/ast_utf8_string_interp.ml ./syntax/ast_utf8_string_interp.mli ./syntax/ast_util.ml ./syntax/ast_util.mli ./syntax/bs_ast_invariant.ml ./syntax/bs_ast_invariant.mli ./syntax/bs_ast_mapper.ml ./syntax/bs_ast_mapper.mli ./syntax/bs_builtin_ppx.ml ./syntax/bs_builtin_ppx.mli ./syntax/bs_flow_ast_utils.ml ./syntax/bs_flow_ast_utils.mli ./syntax/bs_syntaxerr.ml ./syntax/bs_syntaxerr.mli ./syntax/classify_function.ml ./syntax/classify_function.mli ./syntax/external_arg_spec.ml ./syntax/external_arg_spec.mli ./syntax/external_ffi_types.ml ./syntax/external_ffi_types.mli ./syntax/ppx_entry.ml ./syntax/typemod_hide.ml \ No newline at end of file diff --git a/lib/4.06.1/whole_compiler.ml b/lib/4.06.1/whole_compiler.ml index 44894a571a..9fb532eb16 100644 --- a/lib/4.06.1/whole_compiler.ml +++ b/lib/4.06.1/whole_compiler.ml @@ -411165,16 +411165,14 @@ let mapper : mapper = end -module Reactjs_jsx_ppx_v3 -= struct -#1 "reactjs_jsx_ppx_v3.ml" -# 1 "syntax/reactjs_jsx_ppx.cppo.ml" +module Reactjs_jsx_ppx_v3 : sig +#1 "reactjs_jsx_ppx_v3.mli" (* - This is the file that handles turning Reason JSX' agnostic function call into + This is the module that handles turning Reason JSX' agnostic function call into a ReasonReact-specific function call. Aka, this is a macro, using OCaml's ppx facilities; https://whitequark.org/blog/2014/04/16/a-guide-to-extension- points-in-ocaml/ - You wouldn't use this file directly; it's used by BuckleScript's + You wouldn't use this file directly; it's used by ReScript's bsconfig.json. Specifically, there's a field called `react-jsx` inside the field `reason`, which enables this ppx through some internal call in bsb *) @@ -411205,49 +411203,46 @@ module Reactjs_jsx_ppx_v3 `ReactDOMRe.createElement(ReasonReact.fragment, [|foo|])` *) +val rewrite_implementation : Parsetree.structure -> Parsetree.structure + +val rewrite_signature : Parsetree.signature -> Parsetree.signature + +end = struct +#1 "reactjs_jsx_ppx_v3.ml" open Ast_helper open Ast_mapper open Asttypes open Parsetree open Longident -let rec find_opt p = function - | [] -> None - | x :: l -> if p x then Some x else find_opt p l - - +let rec find_opt p = function [] -> None | x :: l -> if p x then Some x else find_opt p l let nolabel = Nolabel + let labelled str = Labelled str + let optional str = Optional str -let isOptional str = match str with -| Optional _ -> true -| _ -> false -let isLabelled str = match str with -| Labelled _ -> true -| _ -> false -let getLabel str = match str with -| Optional str | Labelled str -> str -| Nolabel -> "" + +let isOptional str = match str with Optional _ -> true | _ -> false + +let isLabelled str = match str with Labelled _ -> true | _ -> false + +let getLabel str = match str with Optional str | Labelled str -> str | Nolabel -> "" + let optionIdent = Lident "option" -let argIsKeyRef = function - | (Labelled ("key" | "ref"), _) | (Optional ("key" | "ref"), _) -> true - | _ -> false let constantString ~loc str = Ast_helper.Exp.constant ~loc (Pconst_string (str, None)) - let safeTypeFromValue valueStr = -let valueStr = getLabel valueStr in -match String.sub valueStr 0 1 with -| "_" -> "T" ^ valueStr -| _ -> valueStr -let keyType loc = Typ.constr ~loc {loc; txt=optionIdent} [Typ.constr ~loc {loc; txt=Lident "string"} []] - -type 'a children = | ListLiteral of 'a | Exact of 'a -type componentConfig = { - propsName: string; -} + let valueStr = getLabel valueStr in + match String.sub valueStr 0 1 with "_" -> "T" ^ valueStr | _ -> valueStr + [@@raises Invalid_argument] + +let keyType loc = Typ.constr ~loc { loc; txt = optionIdent } [ Typ.constr ~loc { loc; txt = Lident "string" } [] ] + +type 'a children = ListLiteral of 'a | Exact of 'a + +type componentConfig = { propsName : string } (* if children is a list, convert it to an array while mapping each element. If not, just map over it, as usual *) let transformChildrenIfListUpper ~loc ~mapper theList = @@ -411255,16 +411250,12 @@ let transformChildrenIfListUpper ~loc ~mapper theList = (* not in the sense of converting a list to an array; convert the AST reprensentation of a list to the AST reprensentation of an array *) match theList with - | {pexp_desc = Pexp_construct ({txt = Lident "[]"}, None)} -> begin - match accum with - | [singleElement] -> Exact singleElement - | accum -> ListLiteral (List.rev accum |> Exp.array ~loc) - end - | {pexp_desc = Pexp_construct ( - {txt = Lident "::"}, - Some {pexp_desc = Pexp_tuple (v::acc::[])} - )} -> - transformChildren_ acc ((mapper.expr mapper v)::accum) + | { pexp_desc = Pexp_construct ({ txt = Lident "[]" }, None) } -> ( + match accum with + | [ singleElement ] -> Exact singleElement + | accum -> ListLiteral (Exp.array ~loc (List.rev accum)) ) + | { pexp_desc = Pexp_construct ({ txt = Lident "::" }, Some { pexp_desc = Pexp_tuple [ v; acc ] }) } -> + transformChildren_ acc (mapper.expr mapper v :: accum) | notAList -> Exact (mapper.expr mapper notAList) in transformChildren_ theList [] @@ -411274,114 +411265,103 @@ let transformChildrenIfList ~loc ~mapper theList = (* not in the sense of converting a list to an array; convert the AST reprensentation of a list to the AST reprensentation of an array *) match theList with - | {pexp_desc = Pexp_construct ({txt = Lident "[]"}, None)} -> - List.rev accum |> Exp.array ~loc - | {pexp_desc = Pexp_construct ( - {txt = Lident "::"}, - Some {pexp_desc = Pexp_tuple (v::acc::[])} - )} -> - transformChildren_ acc ((mapper.expr mapper v)::accum) + | { pexp_desc = Pexp_construct ({ txt = Lident "[]" }, None) } -> Exp.array ~loc (List.rev accum) + | { pexp_desc = Pexp_construct ({ txt = Lident "::" }, Some { pexp_desc = Pexp_tuple [ v; acc ] }) } -> + transformChildren_ acc (mapper.expr mapper v :: accum) | notAList -> mapper.expr mapper notAList in transformChildren_ theList [] -let extractChildren ?(removeLastPositionUnit=false) ~loc propsAndChildren = - let rec allButLast_ lst acc = match lst with +let extractChildren ?(removeLastPositionUnit = false) ~loc propsAndChildren = + let rec allButLast_ lst acc = + match lst with | [] -> [] - | (Nolabel, {pexp_desc = Pexp_construct ({txt = Lident "()"}, None)})::[] -> acc + | [ (Nolabel, { pexp_desc = Pexp_construct ({ txt = Lident "()" }, None) }) ] -> acc | (Nolabel, _) :: _rest -> raise (Invalid_argument "JSX: found non-labelled argument before the last position") - | arg::rest -> allButLast_ rest (arg::acc) + | arg :: rest -> allButLast_ rest (arg :: acc) + [@@raises Invalid_argument] in - let allButLast lst = allButLast_ lst [] |> List.rev in - match (List.partition (fun (label, _) -> label = labelled "children") propsAndChildren) with - | ([], props) -> - (* no children provided? Place a placeholder list *) - (Exp.construct ~loc {loc; txt = Lident "[]"} None, if removeLastPositionUnit then allButLast props else props) - | ([(_, childrenExpr)], props) -> - (childrenExpr, if removeLastPositionUnit then allButLast props else props) + let allButLast lst = allButLast_ lst [] |> List.rev [@@raises Invalid_argument] in + match List.partition (fun (label, _) -> label = labelled "children") propsAndChildren with + | [], props -> + (* no children provided? Place a placeholder list *) + (Exp.construct ~loc { loc; txt = Lident "[]" } None, if removeLastPositionUnit then allButLast props else props) + | [ (_, childrenExpr) ], props -> (childrenExpr, if removeLastPositionUnit then allButLast props else props) | _ -> raise (Invalid_argument "JSX: somehow there's more than one `children` label") + [@@raises Invalid_argument] -let unerasableIgnore loc = ({loc; txt = "warning"}, (PStr [Str.eval (Exp.constant (Pconst_string ("-16", None)))])) -let merlinFocus = ({loc = Location.none; txt = "merlin.focus"}, (PStr [])) +let unerasableIgnore loc = ({ loc; txt = "warning" }, PStr [ Str.eval (Exp.constant (Pconst_string ("-16", None))) ]) + +let merlinFocus = ({ loc = Location.none; txt = "merlin.focus" }, PStr []) (* Helper method to look up the [@react.component] attribute *) -let hasAttr (loc, _) = - loc.txt = "react.component" +let hasAttr (loc, _) = loc.txt = "react.component" (* Helper method to filter out any attribute that isn't [@react.component] *) -let otherAttrsPure (loc, _) = - loc.txt <> "react.component" +let otherAttrsPure (loc, _) = loc.txt <> "react.component" (* Iterate over the attributes and try to find the [@react.component] attribute *) -let hasAttrOnBinding {pvb_attributes} = find_opt hasAttr pvb_attributes <> None - -(* Filter the [@react.component] attribute and immutably replace them on the binding *) -let filterAttrOnBinding binding = {binding with pvb_attributes = List.filter otherAttrsPure binding.pvb_attributes} +let hasAttrOnBinding { pvb_attributes } = find_opt hasAttr pvb_attributes <> None (* Finds the name of the variable the binding is assigned to, otherwise raises Invalid_argument *) let getFnName binding = match binding with - | {pvb_pat = { - ppat_desc = Ppat_var {txt} - }} -> txt + | { pvb_pat = { ppat_desc = Ppat_var { txt } } } -> txt | _ -> raise (Invalid_argument "react.component calls cannot be destructured.") + [@@raises Invalid_argument] let makeNewBinding binding expression newName = match binding with - | {pvb_pat = { - ppat_desc = Ppat_var ( ppat_var) - } as pvb_pat} ->{ binding with pvb_pat = { - pvb_pat with - ppat_desc = Ppat_var {ppat_var with txt = newName}; - }; - pvb_expr = expression; - pvb_attributes = [merlinFocus]; - } + | { pvb_pat = { ppat_desc = Ppat_var ppat_var } as pvb_pat } -> + { + binding with + pvb_pat = { pvb_pat with ppat_desc = Ppat_var { ppat_var with txt = newName } }; + pvb_expr = expression; + pvb_attributes = [ merlinFocus ]; + } | _ -> raise (Invalid_argument "react.component calls cannot be destructured.") + [@@raises Invalid_argument] (* Lookup the value of `props` otherwise raise Invalid_argument error *) let getPropsNameValue _acc (loc, exp) = - match (loc, exp) with - | ({ txt = Lident "props" }, { pexp_desc = Pexp_ident {txt = Lident str} }) -> { propsName = str } - | ({ txt }, _) -> raise (Invalid_argument ("react.component only accepts props as an option, given: " ^ Longident.last txt)) + match (loc, exp) with + | { txt = Lident "props" }, { pexp_desc = Pexp_ident { txt = Lident str } } -> { propsName = str } + | { txt }, _ -> + raise (Invalid_argument ("react.component only accepts props as an option, given: " ^ Longident.last txt)) + [@@raises Invalid_argument] (* Lookup the `props` record or string as part of [@react.component] and store the name for use when rewriting *) let getPropsAttr payload = - let defaultProps = {propsName = "Props"} in + let defaultProps = { propsName = "Props" } in match payload with - | Some(PStr( - {pstr_desc = Pstr_eval ({ - pexp_desc = Pexp_record (recordFields, None) - }, _)}::_rest - )) -> + | Some (PStr ({ pstr_desc = Pstr_eval ({ pexp_desc = Pexp_record (recordFields, None) }, _) } :: _rest)) -> List.fold_left getPropsNameValue defaultProps recordFields - | Some(PStr({pstr_desc = Pstr_eval ({pexp_desc = Pexp_ident {txt = Lident "props"}}, _)}::_rest)) -> {propsName = "props"} - | Some(PStr({pstr_desc = Pstr_eval (_, _)}::_rest)) -> raise (Invalid_argument ("react.component accepts a record config with props as an options.")) + | Some (PStr ({ pstr_desc = Pstr_eval ({ pexp_desc = Pexp_ident { txt = Lident "props" } }, _) } :: _rest)) -> + { propsName = "props" } + | Some (PStr ({ pstr_desc = Pstr_eval (_, _) } :: _rest)) -> + raise (Invalid_argument "react.component accepts a record config with props as an options.") | _ -> defaultProps + [@@raises Invalid_argument] (* Plucks the label, loc, and type_ from an AST node *) let pluckLabelDefaultLocType (label, default, _, _, loc, type_) = (label, default, loc, type_) (* Lookup the filename from the location information on the AST node and turn it into a valid module identifier *) -let filenameFromLoc (pstr_loc: Location.t) = - let fileName = match pstr_loc.loc_start.pos_fname with - | "" -> !Location.input_name - | fileName -> fileName - in - let fileName = try - Filename.chop_extension (Filename.basename fileName) - with | Invalid_argument _-> fileName in +let filenameFromLoc (pstr_loc : Location.t) = + let fileName = match pstr_loc.loc_start.pos_fname with "" -> !Location.input_name | fileName -> fileName in + let fileName = try Filename.chop_extension (Filename.basename fileName) with Invalid_argument _ -> fileName in let fileName = String.capitalize_ascii fileName in fileName (* Build a string representation of a module name with segments separated by $ *) let makeModuleName fileName nestedModules fnName = - let fullModuleName = match (fileName, nestedModules, fnName) with - (* TODO: is this even reachable? It seems like the fileName always exists *) - | ("", nestedModules, "make") -> nestedModules - | ("", nestedModules, fnName) -> List.rev (fnName :: nestedModules) - | (fileName, nestedModules, "make") -> fileName :: (List.rev nestedModules) - | (fileName, nestedModules, fnName) -> fileName :: (List.rev (fnName :: nestedModules)) + let fullModuleName = + match (fileName, nestedModules, fnName) with + (* TODO: is this even reachable? It seems like the fileName always exists *) + | "", nestedModules, "make" -> nestedModules + | "", nestedModules, fnName -> List.rev (fnName :: nestedModules) + | fileName, nestedModules, "make" -> fileName :: List.rev nestedModules + | fileName, nestedModules, fnName -> fileName :: List.rev (fnName :: nestedModules) in let fullModuleName = String.concat "$" fullModuleName in fullModuleName @@ -411395,202 +411375,167 @@ let makeModuleName fileName nestedModules fnName = (* Build an AST node representing all named args for the `external` definition for a component's props *) let rec recursivelyMakeNamedArgsForExternal list args = match list with - | (label, default, loc, interiorType)::tl -> - recursivelyMakeNamedArgsForExternal tl (Typ.arrow - ~loc - label - (match (label, interiorType, default) with - (* ~foo=1 *) - | (label, None, Some _) -> - { - ptyp_desc = Ptyp_var (safeTypeFromValue label); - ptyp_loc = loc; - ptyp_attributes = []; - } - (* ~foo: int=1 *) - | (_label, Some type_, Some _) -> - type_ - - (* ~foo: option(int)=? *) - | (label, Some ({ptyp_desc = Ptyp_constr ({txt=(Lident "option")}, [type_])}), _) - | (label, Some ({ptyp_desc = Ptyp_constr ({txt=(Ldot (Lident "*predef*", "option"))}, [type_])}), _) - (* ~foo: int=? - note this isnt valid. but we want to get a type error *) - | (label, Some type_, _) when isOptional label -> - type_ - (* ~foo=? *) - | (label, None, _) when isOptional label -> - { - ptyp_desc = Ptyp_var (safeTypeFromValue label); - ptyp_loc = loc; - ptyp_attributes = []; - } - - (* ~foo *) - | (label, None, _) -> - { - ptyp_desc = Ptyp_var (safeTypeFromValue label); - ptyp_loc = loc; - ptyp_attributes = []; - } - | (_label, Some type_, _) -> - type_ - ) - args) + | (label, default, loc, interiorType) :: tl -> + recursivelyMakeNamedArgsForExternal tl + (Typ.arrow ~loc label + ( match (label, interiorType, default) with + (* ~foo=1 *) + | label, None, Some _ -> + { ptyp_desc = Ptyp_var (safeTypeFromValue label); ptyp_loc = loc; ptyp_attributes = [] } + (* ~foo: int=1 *) + | _label, Some type_, Some _ -> type_ + (* ~foo: option(int)=? *) + | label, Some { ptyp_desc = Ptyp_constr ({ txt = Lident "option" }, [ type_ ]) }, _ + | label, Some { ptyp_desc = Ptyp_constr ({ txt = Ldot (Lident "*predef*", "option") }, [ type_ ]) }, _ + (* ~foo: int=? - note this isnt valid. but we want to get a type error *) + | label, Some type_, _ + when isOptional label -> + type_ + (* ~foo=? *) + | label, None, _ when isOptional label -> + { ptyp_desc = Ptyp_var (safeTypeFromValue label); ptyp_loc = loc; ptyp_attributes = [] } + (* ~foo *) + | label, None, _ -> { ptyp_desc = Ptyp_var (safeTypeFromValue label); ptyp_loc = loc; ptyp_attributes = [] } + | _label, Some type_, _ -> type_ ) + args) | [] -> args + [@@raises Invalid_argument] (* Build an AST node for the [@bs.obj] representing props for a component *) let makePropsValue fnName loc namedArgListWithKeyAndRef propsType = - let propsName = fnName ^ "Props" in { - pval_name = {txt = propsName; loc}; - pval_type = - recursivelyMakeNamedArgsForExternal - namedArgListWithKeyAndRef - (Typ.arrow - nolabel - { - ptyp_desc = Ptyp_constr ({txt= Lident("unit"); loc}, []); - ptyp_loc = loc; - ptyp_attributes = []; - } - propsType - ); - pval_prim = [""]; - pval_attributes = [({txt = "bs.obj"; loc = loc}, PStr [])]; - pval_loc = loc; -} + let propsName = fnName ^ "Props" in + { + pval_name = { txt = propsName; loc }; + pval_type = + recursivelyMakeNamedArgsForExternal namedArgListWithKeyAndRef + (Typ.arrow nolabel + { ptyp_desc = Ptyp_constr ({ txt = Lident "unit"; loc }, []); ptyp_loc = loc; ptyp_attributes = [] } + propsType); + pval_prim = [ "" ]; + pval_attributes = [ ({ txt = "bs.obj"; loc }, PStr []) ]; + pval_loc = loc; + } + [@@raises Invalid_argument] (* Build an AST node representing an `external` with the definition of the [@bs.obj] *) let makePropsExternal fnName loc namedArgListWithKeyAndRef propsType = - { - pstr_loc = loc; - pstr_desc = Pstr_primitive (makePropsValue fnName loc namedArgListWithKeyAndRef propsType) - } + { pstr_loc = loc; pstr_desc = Pstr_primitive (makePropsValue fnName loc namedArgListWithKeyAndRef propsType) } + [@@raises Invalid_argument] (* Build an AST node for the signature of the `external` definition *) let makePropsExternalSig fnName loc namedArgListWithKeyAndRef propsType = - { - psig_loc = loc; - psig_desc = Psig_value (makePropsValue fnName loc namedArgListWithKeyAndRef propsType) - } + { psig_loc = loc; psig_desc = Psig_value (makePropsValue fnName loc namedArgListWithKeyAndRef propsType) } + [@@raises Invalid_argument] (* Build an AST node for the props name when converted to a Js.t inside the function signature *) -let makePropsName ~loc name = - { - ppat_desc = Ppat_var {txt = name; loc}; - ppat_loc = loc; - ppat_attributes = []; - } - - -let makeObjectField loc (str, attrs, type_) = - Otag ({ loc; txt = str }, attrs, type_) +let makePropsName ~loc name = { ppat_desc = Ppat_var { txt = name; loc }; ppat_loc = loc; ppat_attributes = [] } +let makeObjectField loc (str, attrs, type_) = Otag ({ loc; txt = str }, attrs, type_) (* Build an AST node representing a "closed" Js.t object representing a component's props *) let makePropsType ~loc namedTypeList = - Typ.mk ~loc ( - Ptyp_constr({txt= Ldot (Lident("Js"), "t"); loc}, [{ - ptyp_desc = Ptyp_object( - List.map (makeObjectField loc) namedTypeList, - Closed - ); - ptyp_loc = loc; - ptyp_attributes = []; - }]) - ) + Typ.mk ~loc + (Ptyp_constr + ( { txt = Ldot (Lident "Js", "t"); loc }, + [ + { + ptyp_desc = Ptyp_object (List.map (makeObjectField loc) namedTypeList, Closed); + ptyp_loc = loc; + ptyp_attributes = []; + }; + ] )) (* Builds an AST node for the entire `external` definition of props *) let makeExternalDecl fnName loc namedArgListWithKeyAndRef namedTypeList = - makePropsExternal - fnName - loc + makePropsExternal fnName loc (List.map pluckLabelDefaultLocType namedArgListWithKeyAndRef) (makePropsType ~loc namedTypeList) + [@@raises Invalid_argument] (* TODO: some line number might still be wrong *) let jsxMapper () = - let jsxVersion = ref None in let transformUppercaseCall3 modulePath mapper loc attrs _ callArguments = - let (children, argsWithLabels) = extractChildren ~loc ~removeLastPositionUnit:true callArguments in + let children, argsWithLabels = extractChildren ~loc ~removeLastPositionUnit:true callArguments in let argsForMake = argsWithLabels in let childrenExpr = transformChildrenIfListUpper ~loc ~mapper children in - let recursivelyTransformedArgsForMake = argsForMake |> List.map (fun (label, expression) -> (label, mapper.expr mapper expression)) in + let recursivelyTransformedArgsForMake = + argsForMake |> List.map (fun (label, expression) -> (label, mapper.expr mapper expression)) + in let childrenArg = ref None in - let args = recursivelyTransformedArgsForMake - @ (match childrenExpr with - | Exact children -> [(labelled "children", children)] - | ListLiteral ({ pexp_desc = Pexp_array list }) when list = [] -> [] + let args = + recursivelyTransformedArgsForMake + @ ( match childrenExpr with + | Exact children -> [ (labelled "children", children) ] + | ListLiteral { pexp_desc = Pexp_array list } when list = [] -> [] | ListLiteral expression -> - (* this is a hack to support react components that introspect into their children *) - (childrenArg := Some expression; - [(labelled "children", Exp.ident ~loc {loc; txt = Ldot (Lident "React", "null")})])) - @ [(nolabel, Exp.construct ~loc {loc; txt = Lident "()"} None)] in - let isCap str = let first = String.sub str 0 1 in - let capped = String.uppercase_ascii first in first = capped in - let ident = match modulePath with - | Lident _ -> Ldot (modulePath, "make") - | (Ldot (_modulePath, value) as fullPath) when isCap value -> Ldot (fullPath, "make") - | modulePath -> modulePath in - let propsIdent = match ident with - | Lident path -> Lident (path ^ "Props") - | Ldot(ident, path) -> Ldot (ident, path ^ "Props") - | _ -> raise (Invalid_argument "JSX name can't be the result of function applications") in - let props = - Exp.apply ~attrs ~loc (Exp.ident ~loc {loc; txt = propsIdent}) args in + (* this is a hack to support react components that introspect into their children *) + childrenArg := Some expression; + [ (labelled "children", Exp.ident ~loc { loc; txt = Ldot (Lident "React", "null") }) ] ) + @ [ (nolabel, Exp.construct ~loc { loc; txt = Lident "()" } None) ] + in + let isCap str = + let first = String.sub str 0 1 [@@raises Invalid_argument] in + let capped = String.uppercase_ascii first in + first = capped + [@@raises Invalid_argument] + in + let ident = + match modulePath with + | Lident _ -> Ldot (modulePath, "make") + | Ldot (_modulePath, value) as fullPath when isCap value -> Ldot (fullPath, "make") + | modulePath -> modulePath + in + let propsIdent = + match ident with + | Lident path -> Lident (path ^ "Props") + | Ldot (ident, path) -> Ldot (ident, path ^ "Props") + | _ -> raise (Invalid_argument "JSX name can't be the result of function applications") + in + let props = Exp.apply ~attrs ~loc (Exp.ident ~loc { loc; txt = propsIdent }) args in (* handle key, ref, children *) - (* React.createElement(Component.make, props, ...children) *) - match (!childrenArg) with + (* React.createElement(Component.make, props, ...children) *) + match !childrenArg with | None -> - (Exp.apply - ~loc - ~attrs - (Exp.ident ~loc {loc; txt = Ldot (Lident "React", "createElement")}) - ([ - (nolabel, Exp.ident ~loc {txt = ident; loc}); - (nolabel, props) - ])) - | Some children -> - (Exp.apply - ~loc - ~attrs - (Exp.ident ~loc {loc; txt = Ldot (Lident "React", "createElementVariadic")}) - ([ - (nolabel, Exp.ident ~loc {txt = ident; loc}); - (nolabel, props); - (nolabel, children) - ])) - in + Exp.apply ~loc ~attrs + (Exp.ident ~loc { loc; txt = Ldot (Lident "React", "createElement") }) + [ (nolabel, Exp.ident ~loc { txt = ident; loc }); (nolabel, props) ] + | Some children -> + Exp.apply ~loc ~attrs + (Exp.ident ~loc { loc; txt = Ldot (Lident "React", "createElementVariadic") }) + [ (nolabel, Exp.ident ~loc { txt = ident; loc }); (nolabel, props); (nolabel, children) ] + [@@raises Invalid_argument] + in - let transformLowercaseCall3 mapper loc attrs callArguments id = - let (children, nonChildrenProps) = extractChildren ~loc callArguments in - let componentNameExpr = constantString ~loc id in - let childrenExpr = transformChildrenIfList ~loc ~mapper children in - let createElementCall = match children with - (* [@JSX] div(~children=[a]), coming from
a
*) - | { - pexp_desc = - Pexp_construct ({txt = Lident "::"}, Some {pexp_desc = Pexp_tuple _ }) - | Pexp_construct ({txt = Lident "[]"}, None) - } -> "createDOMElementVariadic" - (* [@JSX] div(~children= value), coming from
...(value)
*) - | _ -> raise (Invalid_argument "A spread as a DOM element's \ - children don't make sense written together. You can simply remove the spread.") - in - let args = match nonChildrenProps with - | [_justTheUnitArgumentAtEnd] -> - [ - (* "div" *) - (nolabel, componentNameExpr); - (* [|moreCreateElementCallsHere|] *) - (nolabel, childrenExpr) - ] - | nonEmptyProps -> + let transformLowercaseCall3 mapper loc attrs callArguments id = + let children, nonChildrenProps = extractChildren ~loc callArguments in + let componentNameExpr = constantString ~loc id in + let childrenExpr = transformChildrenIfList ~loc ~mapper children in + let createElementCall = + match children with + (* [@JSX] div(~children=[a]), coming from
a
*) + | { + pexp_desc = + ( Pexp_construct ({ txt = Lident "::" }, Some { pexp_desc = Pexp_tuple _ }) + | Pexp_construct ({ txt = Lident "[]" }, None) ); + } -> + "createDOMElementVariadic" + (* [@JSX] div(~children= value), coming from
...(value)
*) + | _ -> + raise + (Invalid_argument + "A spread as a DOM element's children don't make sense written together. You can simply remove the \ + spread.") + in + let args = + match nonChildrenProps with + | [ _justTheUnitArgumentAtEnd ] -> + [ (* "div" *) (nolabel, componentNameExpr); (* [|moreCreateElementCallsHere|] *) (nolabel, childrenExpr) ] + | nonEmptyProps -> let propsCall = - Exp.apply - ~loc - (Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOMRe", "domProps")}) + Exp.apply ~loc + (Exp.ident ~loc { loc; txt = Ldot (Lident "ReactDOMRe", "domProps") }) (nonEmptyProps |> List.map (fun (label, expression) -> (label, mapper.expr mapper expression))) in [ @@ -411599,547 +411544,551 @@ let jsxMapper () = (* ReactDOMRe.props(~className=blabla, ~foo=bar, ()) *) (labelled "props", propsCall); (* [|moreCreateElementCallsHere|] *) - (nolabel, childrenExpr) - ] in - Exp.apply - ~loc - (* throw away the [@JSX] attribute and keep the others, if any *) - ~attrs - (* ReactDOMRe.createElement *) - (Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOMRe", createElementCall)}) - args + (nolabel, childrenExpr); + ] in - - - + Exp.apply ~loc (* throw away the [@JSX] attribute and keep the others, if any *) ~attrs + (* ReactDOMRe.createElement *) + (Exp.ident ~loc { loc; txt = Ldot (Lident "ReactDOMRe", createElementCall) }) + args + [@@raises Invalid_argument] + in let rec recursivelyTransformNamedArgsForMake mapper expr list = let expr = mapper.expr mapper expr in match expr.pexp_desc with (* TODO: make this show up with a loc. *) - | Pexp_fun (Labelled "key", _, _, _) - | Pexp_fun (Optional "key", _, _, _) -> raise (Invalid_argument "Key cannot be accessed inside of a component. Don't worry - you can always key a component from its parent!") - | Pexp_fun (Labelled "ref", _, _, _) - | Pexp_fun (Optional "ref", _, _, _) -> raise (Invalid_argument "Ref cannot be passed as a normal prop. Please use `forwardRef` API instead.") + | Pexp_fun (Labelled "key", _, _, _) | Pexp_fun (Optional "key", _, _, _) -> + raise + (Invalid_argument + "Key cannot be accessed inside of a component. Don't worry - you can always key a component from its \ + parent!") + | Pexp_fun (Labelled "ref", _, _, _) | Pexp_fun (Optional "ref", _, _, _) -> + raise (Invalid_argument "Ref cannot be passed as a normal prop. Please use `forwardRef` API instead.") | Pexp_fun (arg, default, pattern, expression) when isOptional arg || isLabelled arg -> - let () = - (match (isOptional arg, pattern, default) with - | (true, { ppat_desc = Ppat_constraint (_, { ptyp_desc })}, None) -> - (match ptyp_desc with - | Ptyp_constr({txt=(Lident "option")}, [_]) -> () - | _ -> - let currentType = (match ptyp_desc with - | Ptyp_constr({txt}, []) -> String.concat "." (Longident.flatten txt) - | Ptyp_constr({txt}, _innerTypeArgs) -> String.concat "." (Longident.flatten txt) ^ "(...)" - | _ -> "...") - in - Location.prerr_warning pattern.ppat_loc - (Preprocessor - (Printf.sprintf "ReasonReact: optional argument annotations must have explicit `option`. Did you mean `option(%s)=?`?" currentType))) - | _ -> ()) in - let alias = (match pattern with - | {ppat_desc = Ppat_alias (_, {txt}) | Ppat_var {txt}} -> txt - | {ppat_desc = Ppat_any} -> "_" - | _ -> getLabel arg) in - let type_ = (match pattern with - | {ppat_desc = Ppat_constraint (_, type_)} -> Some type_ - | _ -> None) in - - recursivelyTransformNamedArgsForMake mapper expression ((arg, default, pattern, alias, pattern.ppat_loc, type_) :: list) - | Pexp_fun (Nolabel, _, { ppat_desc = (Ppat_construct ({txt = Lident "()"}, _) | Ppat_any)}, _expression) -> + let () = + match (isOptional arg, pattern, default) with + | true, { ppat_desc = Ppat_constraint (_, { ptyp_desc }) }, None -> ( + match ptyp_desc with + | Ptyp_constr ({ txt = Lident "option" }, [ _ ]) -> () + | _ -> + let currentType = + match ptyp_desc with + | Ptyp_constr ({ txt }, []) -> String.concat "." (Longident.flatten txt) + | Ptyp_constr ({ txt }, _innerTypeArgs) -> String.concat "." (Longident.flatten txt) ^ "(...)" + | _ -> "..." + in + Location.prerr_warning pattern.ppat_loc + (Preprocessor + (Printf.sprintf + "ReasonReact: optional argument annotations must have explicit `option`. Did you mean \ + `option(%s)=?`?" + currentType)) ) + | _ -> () + in + let alias = + match pattern with + | { ppat_desc = Ppat_alias (_, { txt }) | Ppat_var { txt } } -> txt + | { ppat_desc = Ppat_any } -> "_" + | _ -> getLabel arg + in + let type_ = match pattern with { ppat_desc = Ppat_constraint (_, type_) } -> Some type_ | _ -> None in + + recursivelyTransformNamedArgsForMake mapper expression + ((arg, default, pattern, alias, pattern.ppat_loc, type_) :: list) + | Pexp_fun (Nolabel, _, { ppat_desc = Ppat_construct ({ txt = Lident "()" }, _) | Ppat_any }, _expression) -> (list, None) - | Pexp_fun (Nolabel, _, { ppat_desc = Ppat_var ({txt}) | Ppat_constraint ({ ppat_desc = Ppat_var ({txt})}, _)}, _expression) -> + | Pexp_fun + ( Nolabel, + _, + { ppat_desc = Ppat_var { txt } | Ppat_constraint ({ ppat_desc = Ppat_var { txt } }, _) }, + _expression ) -> (list, Some txt) | Pexp_fun (Nolabel, _, pattern, _expression) -> - Location.raise_errorf ~loc:pattern.ppat_loc "ReasonReact: react.component refs only support plain arguments and type annotations." + Location.raise_errorf ~loc:pattern.ppat_loc + "ReasonReact: react.component refs only support plain arguments and type annotations." | _ -> (list, None) + [@@raises Invalid_argument] in - - let argToType types (name, default, _noLabelName, _alias, loc, type_) = match (type_, name, default) with - | (Some ({ptyp_desc = Ptyp_constr ({txt=(Lident "option")}, [type_])}), name, _) when isOptional name -> - (getLabel name, [], { - type_ with - ptyp_desc = Ptyp_constr ({loc=type_.ptyp_loc; txt=optionIdent}, [type_]); - }) :: types - | (Some type_, name, Some _default) -> - (getLabel name, [], { - ptyp_desc = Ptyp_constr ({loc; txt=optionIdent}, [type_]); - ptyp_loc = loc; - ptyp_attributes = []; - }) :: types - | (Some type_, name, _) -> - (getLabel name, [], type_) :: types - | (None, name, _) when isOptional name -> - (getLabel name, [], { - ptyp_desc = Ptyp_constr ({loc; txt=optionIdent}, [{ - ptyp_desc = Ptyp_var (safeTypeFromValue name); - ptyp_loc = loc; - ptyp_attributes = []; - }]); - ptyp_loc = loc; - ptyp_attributes = []; - }) :: types - | (None, name, _) when isLabelled name -> - (getLabel name, [], { - ptyp_desc = Ptyp_var (safeTypeFromValue name); - ptyp_loc = loc; - ptyp_attributes = []; - }) :: types + let argToType types (name, default, _noLabelName, _alias, loc, type_) = + match (type_, name, default) with + | Some { ptyp_desc = Ptyp_constr ({ txt = Lident "option" }, [ type_ ]) }, name, _ when isOptional name -> + ( getLabel name, + [], + { type_ with ptyp_desc = Ptyp_constr ({ loc = type_.ptyp_loc; txt = optionIdent }, [ type_ ]) } ) + :: types + | Some type_, name, Some _default -> + ( getLabel name, + [], + { ptyp_desc = Ptyp_constr ({ loc; txt = optionIdent }, [ type_ ]); ptyp_loc = loc; ptyp_attributes = [] } ) + :: types + | Some type_, name, _ -> (getLabel name, [], type_) :: types + | None, name, _ when isOptional name -> + ( getLabel name, + [], + { + ptyp_desc = + Ptyp_constr + ( { loc; txt = optionIdent }, + [ { ptyp_desc = Ptyp_var (safeTypeFromValue name); ptyp_loc = loc; ptyp_attributes = [] } ] ); + ptyp_loc = loc; + ptyp_attributes = []; + } ) + :: types + | None, name, _ when isLabelled name -> + (getLabel name, [], { ptyp_desc = Ptyp_var (safeTypeFromValue name); ptyp_loc = loc; ptyp_attributes = [] }) + :: types | _ -> types + [@@raises Invalid_argument] in - let argToConcreteType types (name, loc, type_) = match name with - | name when isLabelled name -> - (getLabel name, [], type_) :: types - | name when isOptional name -> - (getLabel name, [], Typ.constr ~loc {loc; txt=optionIdent} [type_]) :: types + let argToConcreteType types (name, loc, type_) = + match name with + | name when isLabelled name -> (getLabel name, [], type_) :: types + | name when isOptional name -> (getLabel name, [], Typ.constr ~loc { loc; txt = optionIdent } [ type_ ]) :: types | _ -> types in - let nestedModules = ref([]) in - let transformComponentDefinition mapper structure returnStructures = match structure with - (* external *) - | ({ - pstr_loc; - pstr_desc = Pstr_primitive ({ - pval_name = { txt = fnName }; - pval_attributes; - pval_type; - } as value_description) - } as pstr) -> - (match List.filter hasAttr pval_attributes with - | [] -> structure :: returnStructures - | [_] -> - let rec getPropTypes types ({ptyp_loc; ptyp_desc} as fullType) = - (match ptyp_desc with - | Ptyp_arrow (name, type_, ({ptyp_desc = Ptyp_arrow _} as rest)) when isLabelled name || isOptional name -> - getPropTypes ((name, ptyp_loc, type_)::types) rest - | Ptyp_arrow (Nolabel, _type, rest) -> - getPropTypes types rest - | Ptyp_arrow (name, type_, returnValue) when isLabelled name || isOptional name -> - (returnValue, (name, returnValue.ptyp_loc, type_)::types) - | _ -> (fullType, types)) - in - let (innerType, propTypes) = getPropTypes [] pval_type in - let namedTypeList = List.fold_left argToConcreteType [] propTypes in - let pluckLabelAndLoc (label, loc, type_) = (label, None (* default *), loc, Some type_) in - let retPropsType = makePropsType ~loc:pstr_loc namedTypeList in - let externalPropsDecl = makePropsExternal fnName pstr_loc (( - optional "key", - None, - pstr_loc, - Some(keyType pstr_loc) - ) :: List.map pluckLabelAndLoc propTypes) retPropsType in - (* can't be an arrow because it will defensively uncurry *) - let newExternalType = Ptyp_constr ( - {loc = pstr_loc; txt = Ldot ((Lident "React"), "componentLike")}, - [retPropsType; innerType] - ) in - let newStructure = { - pstr with pstr_desc = Pstr_primitive { - value_description with pval_type = { - pval_type with ptyp_desc = newExternalType; - }; - pval_attributes = List.filter otherAttrsPure pval_attributes; - } - } in - externalPropsDecl :: newStructure :: returnStructures - | _ -> raise (Invalid_argument "Only one react.component call can exist on a component at one time")) - (* let component = ... *) - | { - pstr_loc; - pstr_desc = Pstr_value ( - recFlag, - valueBindings - ) - } -> - let fileName = filenameFromLoc pstr_loc in - let emptyLoc = Location.in_file fileName in - let mapBinding binding = if (hasAttrOnBinding binding) then - let bindingLoc = binding.pvb_loc in - let bindingPatLoc = binding.pvb_pat.ppat_loc in - let binding = { binding with pvb_pat = { binding.pvb_pat with ppat_loc = emptyLoc}; pvb_loc = emptyLoc} in - let fnName = getFnName binding in - let internalFnName = fnName ^ "$Internal" in - let fullModuleName = makeModuleName fileName !nestedModules fnName in - let modifiedBindingOld binding = - let expression = binding.pvb_expr in - (* TODO: there is a long-tail of unsupported features inside of blocks - Pexp_letmodule , Pexp_letexception , Pexp_ifthenelse *) - let rec spelunkForFunExpression expression = (match expression with - (* let make = (~prop) => ... *) - | { - pexp_desc = Pexp_fun _ - } -> expression - (* let make = {let foo = bar in (~prop) => ...} *) - | { - pexp_desc = Pexp_let (_recursive, _vbs, returnExpression) - } -> - (* here's where we spelunk! *) - spelunkForFunExpression returnExpression - (* let make = React.forwardRef((~prop) => ...) *) - - | { pexp_desc = Pexp_apply (_wrapperExpression, [(Nolabel, innerFunctionExpression)]) } -> - spelunkForFunExpression innerFunctionExpression - | { - pexp_desc = Pexp_sequence (_wrapperExpression, innerFunctionExpression) - } -> - spelunkForFunExpression innerFunctionExpression - | _ -> raise (Invalid_argument "react.component calls can only be on function definitions or component wrappers (forwardRef, memo).") - ) in - spelunkForFunExpression expression - in - let modifiedBinding binding = - let hasApplication = ref(false) in - let wrapExpressionWithBinding expressionFn expression = - Vb.mk - ~loc:bindingLoc - ~attrs:(List.filter otherAttrsPure binding.pvb_attributes) - (Pat.var ~loc:bindingPatLoc {loc = bindingPatLoc; txt = fnName}) (expressionFn expression) in - let expression = binding.pvb_expr in - let unerasableIgnoreExp exp = { exp with pexp_attributes = (unerasableIgnore emptyLoc) :: exp.pexp_attributes } in - (* TODO: there is a long-tail of unsupported features inside of blocks - Pexp_letmodule , Pexp_letexception , Pexp_ifthenelse *) - let rec spelunkForFunExpression expression = (match expression with - (* let make = (~prop) => ... with no final unit *) - | { - pexp_desc = Pexp_fun ((Labelled(_) | Optional(_) as label), default, pattern, ({pexp_desc = Pexp_fun _} as internalExpression)) - } -> - let (wrap, hasUnit, exp) = spelunkForFunExpression internalExpression in - (wrap, hasUnit, unerasableIgnoreExp {expression with pexp_desc = Pexp_fun (label, default, pattern, exp)}) - (* let make = (()) => ... *) - (* let make = (_) => ... *) - | { - pexp_desc = Pexp_fun (Nolabel, _default, { ppat_desc = Ppat_construct ({txt = Lident "()"}, _) | Ppat_any}, _internalExpression) - } -> ((fun a -> a), true, expression) - (* let make = (~prop) => ... *) - | { - pexp_desc = Pexp_fun ((Labelled(_) | Optional(_)), _default, _pattern, _internalExpression) - } -> ((fun a -> a), false, unerasableIgnoreExp expression) - (* let make = (prop) => ... *) - | { - pexp_desc = Pexp_fun (_nolabel, _default, pattern, _internalExpression) - } -> - if (hasApplication.contents) then - ((fun a -> a), false, unerasableIgnoreExp expression) - else - Location.raise_errorf ~loc:pattern.ppat_loc "ReasonReact: props need to be labelled arguments.\n If you are working with refs be sure to wrap with React.forwardRef.\n If your component doesn't have any props use () or _ instead of a name." - (* let make = {let foo = bar in (~prop) => ...} *) - | { - pexp_desc = Pexp_let (recursive, vbs, internalExpression) - } -> - (* here's where we spelunk! *) - let (wrap, hasUnit, exp) = spelunkForFunExpression internalExpression in - (wrap, hasUnit, {expression with pexp_desc = Pexp_let (recursive, vbs, exp)}) - (* let make = React.forwardRef((~prop) => ...) *) - | { pexp_desc = Pexp_apply (wrapperExpression, [(Nolabel, internalExpression)]) } -> - let () = hasApplication := true in - let (_, hasUnit, exp) = spelunkForFunExpression internalExpression in - ((fun exp -> Exp.apply wrapperExpression [(nolabel, exp)]), hasUnit, exp) - | { - pexp_desc = Pexp_sequence (wrapperExpression, internalExpression) - } -> - let (wrap, hasUnit, exp) = spelunkForFunExpression internalExpression in - (wrap, hasUnit, {expression with pexp_desc = Pexp_sequence (wrapperExpression, exp)}) - | e -> ((fun a -> a), false, e) - ) in - let (wrapExpression, hasUnit, expression) = spelunkForFunExpression expression in - (wrapExpressionWithBinding wrapExpression, hasUnit, expression) - in - let (bindingWrapper, hasUnit, expression) = modifiedBinding binding in - let reactComponentAttribute = try - Some(List.find hasAttr binding.pvb_attributes) - with | Not_found -> None in - let (_attr_loc, payload) = match reactComponentAttribute with - | Some (loc, payload) -> (loc.loc, Some payload) - | None -> (emptyLoc, None) in - let props = getPropsAttr payload in - (* do stuff here! *) - let (namedArgList, forwardRef) = recursivelyTransformNamedArgsForMake mapper (modifiedBindingOld binding) [] in - let namedArgListWithKeyAndRef = (optional("key"), None, Pat.var {txt = "key"; loc = emptyLoc}, "key", emptyLoc, Some(keyType emptyLoc)) :: namedArgList in - let namedArgListWithKeyAndRef = match forwardRef with - | Some(_) -> (optional("ref"), None, Pat.var {txt = "key"; loc = emptyLoc}, "ref", emptyLoc, None) :: namedArgListWithKeyAndRef - | None -> namedArgListWithKeyAndRef - in - let namedArgListWithKeyAndRefForNew = match forwardRef with - | Some(txt) -> namedArgList @ [(nolabel, None, Pat.var {txt; loc = emptyLoc}, txt, emptyLoc, None)] - | None -> namedArgList + let nestedModules = ref [] in + let transformComponentDefinition mapper structure returnStructures = + match structure with + (* external *) + | { + pstr_loc; + pstr_desc = Pstr_primitive ({ pval_name = { txt = fnName }; pval_attributes; pval_type } as value_description); + } as pstr -> ( + match List.filter hasAttr pval_attributes with + | [] -> structure :: returnStructures + | [ _ ] -> + let rec getPropTypes types ({ ptyp_loc; ptyp_desc } as fullType) = + match ptyp_desc with + | Ptyp_arrow (name, type_, ({ ptyp_desc = Ptyp_arrow _ } as rest)) when isLabelled name || isOptional name + -> + getPropTypes ((name, ptyp_loc, type_) :: types) rest + | Ptyp_arrow (Nolabel, _type, rest) -> getPropTypes types rest + | Ptyp_arrow (name, type_, returnValue) when isLabelled name || isOptional name -> + (returnValue, (name, returnValue.ptyp_loc, type_) :: types) + | _ -> (fullType, types) + in + let innerType, propTypes = getPropTypes [] pval_type in + let namedTypeList = List.fold_left argToConcreteType [] propTypes in + let pluckLabelAndLoc (label, loc, type_) = (label, None (* default *), loc, Some type_) in + let retPropsType = makePropsType ~loc:pstr_loc namedTypeList in + let externalPropsDecl = + makePropsExternal fnName pstr_loc + ((optional "key", None, pstr_loc, Some (keyType pstr_loc)) :: List.map pluckLabelAndLoc propTypes) + retPropsType + in + (* can't be an arrow because it will defensively uncurry *) + let newExternalType = + Ptyp_constr ({ loc = pstr_loc; txt = Ldot (Lident "React", "componentLike") }, [ retPropsType; innerType ]) + in + let newStructure = + { + pstr with + pstr_desc = + Pstr_primitive + { + value_description with + pval_type = { pval_type with ptyp_desc = newExternalType }; + pval_attributes = List.filter otherAttrsPure pval_attributes; + }; + } + in + externalPropsDecl :: newStructure :: returnStructures + | _ -> raise (Invalid_argument "Only one react.component call can exist on a component at one time") ) + (* let component = ... *) + | { pstr_loc; pstr_desc = Pstr_value (recFlag, valueBindings) } -> + let fileName = filenameFromLoc pstr_loc in + let emptyLoc = Location.in_file fileName in + let mapBinding binding = + if hasAttrOnBinding binding then + let bindingLoc = binding.pvb_loc in + let bindingPatLoc = binding.pvb_pat.ppat_loc in + let binding = { binding with pvb_pat = { binding.pvb_pat with ppat_loc = emptyLoc }; pvb_loc = emptyLoc } in + let fnName = getFnName binding in + let internalFnName = fnName ^ "$Internal" in + let fullModuleName = makeModuleName fileName !nestedModules fnName in + let modifiedBindingOld binding = + let expression = binding.pvb_expr in + (* TODO: there is a long-tail of unsupported features inside of blocks - Pexp_letmodule , Pexp_letexception , Pexp_ifthenelse *) + let rec spelunkForFunExpression expression = + match expression with + (* let make = (~prop) => ... *) + | { pexp_desc = Pexp_fun _ } -> expression + (* let make = {let foo = bar in (~prop) => ...} *) + | { pexp_desc = Pexp_let (_recursive, _vbs, returnExpression) } -> + (* here's where we spelunk! *) + spelunkForFunExpression returnExpression + (* let make = React.forwardRef((~prop) => ...) *) + | { pexp_desc = Pexp_apply (_wrapperExpression, [ (Nolabel, innerFunctionExpression) ]) } -> + spelunkForFunExpression innerFunctionExpression + | { pexp_desc = Pexp_sequence (_wrapperExpression, innerFunctionExpression) } -> + spelunkForFunExpression innerFunctionExpression + | _ -> + raise + (Invalid_argument + "react.component calls can only be on function definitions or component wrappers (forwardRef, \ + memo).") + [@@raises Invalid_argument] + in + spelunkForFunExpression expression + in + let modifiedBinding binding = + let hasApplication = ref false in + let wrapExpressionWithBinding expressionFn expression = + Vb.mk ~loc:bindingLoc + ~attrs:(List.filter otherAttrsPure binding.pvb_attributes) + (Pat.var ~loc:bindingPatLoc { loc = bindingPatLoc; txt = fnName }) + (expressionFn expression) + in + let expression = binding.pvb_expr in + let unerasableIgnoreExp exp = + { exp with pexp_attributes = unerasableIgnore emptyLoc :: exp.pexp_attributes } + in + (* TODO: there is a long-tail of unsupported features inside of blocks - Pexp_letmodule , Pexp_letexception , Pexp_ifthenelse *) + let rec spelunkForFunExpression expression = + match expression with + (* let make = (~prop) => ... with no final unit *) + | { + pexp_desc = + Pexp_fun + ( ((Labelled _ | Optional _) as label), + default, + pattern, + ({ pexp_desc = Pexp_fun _ } as internalExpression) ); + } -> + let wrap, hasUnit, exp = spelunkForFunExpression internalExpression in + ( wrap, + hasUnit, + unerasableIgnoreExp { expression with pexp_desc = Pexp_fun (label, default, pattern, exp) } ) + (* let make = (()) => ... *) + (* let make = (_) => ... *) + | { + pexp_desc = + Pexp_fun + ( Nolabel, + _default, + { ppat_desc = Ppat_construct ({ txt = Lident "()" }, _) | Ppat_any }, + _internalExpression ); + } -> + ((fun a -> a), true, expression) + (* let make = (~prop) => ... *) + | { pexp_desc = Pexp_fun ((Labelled _ | Optional _), _default, _pattern, _internalExpression) } -> + ((fun a -> a), false, unerasableIgnoreExp expression) + (* let make = (prop) => ... *) + | { pexp_desc = Pexp_fun (_nolabel, _default, pattern, _internalExpression) } -> + if hasApplication.contents then ((fun a -> a), false, unerasableIgnoreExp expression) + else + Location.raise_errorf ~loc:pattern.ppat_loc + "ReasonReact: props need to be labelled arguments.\n\ + \ If you are working with refs be sure to wrap with React.forwardRef.\n\ + \ If your component doesn't have any props use () or _ instead of a name." + (* let make = {let foo = bar in (~prop) => ...} *) + | { pexp_desc = Pexp_let (recursive, vbs, internalExpression) } -> + (* here's where we spelunk! *) + let wrap, hasUnit, exp = spelunkForFunExpression internalExpression in + (wrap, hasUnit, { expression with pexp_desc = Pexp_let (recursive, vbs, exp) }) + (* let make = React.forwardRef((~prop) => ...) *) + | { pexp_desc = Pexp_apply (wrapperExpression, [ (Nolabel, internalExpression) ]) } -> + let () = hasApplication := true in + let _, hasUnit, exp = spelunkForFunExpression internalExpression in + ((fun exp -> Exp.apply wrapperExpression [ (nolabel, exp) ]), hasUnit, exp) + | { pexp_desc = Pexp_sequence (wrapperExpression, internalExpression) } -> + let wrap, hasUnit, exp = spelunkForFunExpression internalExpression in + (wrap, hasUnit, { expression with pexp_desc = Pexp_sequence (wrapperExpression, exp) }) + | e -> ((fun a -> a), false, e) + in + let wrapExpression, hasUnit, expression = spelunkForFunExpression expression in + (wrapExpressionWithBinding wrapExpression, hasUnit, expression) + in + let bindingWrapper, hasUnit, expression = modifiedBinding binding in + let reactComponentAttribute = + try Some (List.find hasAttr binding.pvb_attributes) with Not_found -> None + in + let _attr_loc, payload = + match reactComponentAttribute with + | Some (loc, payload) -> (loc.loc, Some payload) + | None -> (emptyLoc, None) + in + let props = getPropsAttr payload in + (* do stuff here! *) + let namedArgList, forwardRef = + recursivelyTransformNamedArgsForMake mapper (modifiedBindingOld binding) [] + in + let namedArgListWithKeyAndRef = + (optional "key", None, Pat.var { txt = "key"; loc = emptyLoc }, "key", emptyLoc, Some (keyType emptyLoc)) + :: namedArgList + in + let namedArgListWithKeyAndRef = + match forwardRef with + | Some _ -> + (optional "ref", None, Pat.var { txt = "key"; loc = emptyLoc }, "ref", emptyLoc, None) + :: namedArgListWithKeyAndRef + | None -> namedArgListWithKeyAndRef + in + let namedArgListWithKeyAndRefForNew = + match forwardRef with + | Some txt -> namedArgList @ [ (nolabel, None, Pat.var { txt; loc = emptyLoc }, txt, emptyLoc, None) ] + | None -> namedArgList + in + let pluckArg (label, _, _, alias, loc, _) = + let labelString = + match label with label when isOptional label || isLabelled label -> getLabel label | _ -> "" + in + ( label, + match labelString with + | "" -> Exp.ident ~loc { txt = Lident alias; loc } + | labelString -> + Exp.apply ~loc + (Exp.ident ~loc { txt = Lident "##"; loc }) + [ + (nolabel, Exp.ident ~loc { txt = Lident props.propsName; loc }); + (nolabel, Exp.ident ~loc { txt = Lident labelString; loc }); + ] ) + in + let namedTypeList = List.fold_left argToType [] namedArgList in + let loc = emptyLoc in + let externalDecl = makeExternalDecl fnName loc namedArgListWithKeyAndRef namedTypeList in + let innerExpressionArgs = + List.map pluckArg namedArgListWithKeyAndRefForNew + @ if hasUnit then [ (Nolabel, Exp.construct { loc; txt = Lident "()" } None) ] else [] + in + let innerExpression = + Exp.apply + (Exp.ident + { loc; txt = Lident (match recFlag with Recursive -> internalFnName | Nonrecursive -> fnName) }) + innerExpressionArgs + in + let innerExpressionWithRef = + match forwardRef with + | Some txt -> + { + innerExpression with + pexp_desc = + Pexp_fun + ( nolabel, + None, + { ppat_desc = Ppat_var { txt; loc = emptyLoc }; ppat_loc = emptyLoc; ppat_attributes = [] }, + innerExpression ); + } + | None -> innerExpression + in + let fullExpression = + Exp.fun_ nolabel None + { + ppat_desc = + Ppat_constraint + (makePropsName ~loc:emptyLoc props.propsName, makePropsType ~loc:emptyLoc namedTypeList); + ppat_loc = emptyLoc; + ppat_attributes = []; + } + innerExpressionWithRef + in + let fullExpression = + match fullModuleName with + | "" -> fullExpression + | txt -> + Exp.let_ Nonrecursive + [ Vb.mk ~loc:emptyLoc (Pat.var ~loc:emptyLoc { loc = emptyLoc; txt }) fullExpression ] + (Exp.ident ~loc:emptyLoc { loc = emptyLoc; txt = Lident txt }) + in + let bindings, newBinding = + match recFlag with + | Recursive -> + ( [ + bindingWrapper + (Exp.let_ ~loc:emptyLoc Recursive + [ + makeNewBinding binding expression internalFnName; + Vb.mk (Pat.var { loc = emptyLoc; txt = fnName }) fullExpression; + ] + (Exp.ident { loc = emptyLoc; txt = Lident fnName })); + ], + None ) + | Nonrecursive -> + ([ { binding with pvb_expr = expression; pvb_attributes = [] } ], Some (bindingWrapper fullExpression)) + in + (Some externalDecl, bindings, newBinding) + else (None, [ binding ], None) + [@@raises Invalid_argument] in - let pluckArg (label, _, _, alias, loc, _) = - let labelString = (match label with | label when isOptional label || isLabelled label -> getLabel label | _ -> "") in - (label, - (match labelString with - | "" -> (Exp.ident ~loc { - txt = (Lident alias); - loc - }) - | labelString -> (Exp.apply ~loc - (Exp.ident ~loc {txt = (Lident "##"); loc }) - [ - (nolabel, Exp.ident ~loc {txt = (Lident props.propsName); loc }); - (nolabel, Exp.ident ~loc { - txt = (Lident labelString); - loc - }) - ] - ) - ) - ) in - let namedTypeList = List.fold_left argToType [] namedArgList in - let loc = emptyLoc in - let externalDecl = makeExternalDecl fnName loc namedArgListWithKeyAndRef namedTypeList in - let innerExpressionArgs = (List.map pluckArg namedArgListWithKeyAndRefForNew) @ - if hasUnit then [(Nolabel, Exp.construct {loc; txt = Lident "()"} None)] else [] in - let innerExpression = Exp.apply (Exp.ident {loc; txt = Lident( - match recFlag with - | Recursive -> internalFnName - | Nonrecursive -> fnName - )}) innerExpressionArgs in - let innerExpressionWithRef = match (forwardRef) with - | Some txt -> - {innerExpression with pexp_desc = Pexp_fun (nolabel, None, { - ppat_desc = Ppat_var { txt; loc = emptyLoc }; - ppat_loc = emptyLoc; - ppat_attributes = []; - }, innerExpression)} - | None -> innerExpression + let structuresAndBinding = List.map mapBinding valueBindings in + let otherStructures (extern, binding, newBinding) (externs, bindings, newBindings) = + let externs = match extern with Some extern -> extern :: externs | None -> externs in + let newBindings = + match newBinding with Some newBinding -> newBinding :: newBindings | None -> newBindings + in + (externs, binding @ bindings, newBindings) in - let fullExpression = Exp.fun_ - nolabel - None - { - ppat_desc = Ppat_constraint ( - makePropsName ~loc:emptyLoc props.propsName, - makePropsType ~loc:emptyLoc namedTypeList - ); - ppat_loc = emptyLoc; - ppat_attributes = []; - } - innerExpressionWithRef in - let fullExpression = match (fullModuleName) with - | ("") -> fullExpression - | (txt) -> Exp.let_ - Nonrecursive - [Vb.mk - ~loc:emptyLoc - (Pat.var ~loc:emptyLoc {loc = emptyLoc; txt}) - fullExpression - ] - (Exp.ident ~loc:emptyLoc {loc = emptyLoc; txt = Lident txt}) in - let (bindings, newBinding) = - match recFlag with - | Recursive -> ([bindingWrapper (Exp.let_ - ~loc:(emptyLoc) - Recursive - [ - makeNewBinding binding expression internalFnName; - Vb.mk (Pat.var {loc = emptyLoc; txt = fnName}) fullExpression - ] - (Exp.ident {loc = emptyLoc; txt = Lident fnName}))], None) - | Nonrecursive -> ([{ binding with pvb_expr = expression; pvb_attributes = [] }], Some(bindingWrapper fullExpression)) - in - (Some externalDecl, bindings, newBinding) - else - (None, [binding], None) - in - let structuresAndBinding = List.map mapBinding valueBindings in - let otherStructures (extern, binding, newBinding) (externs, bindings, newBindings) = - let externs = match extern with - | Some extern -> extern :: externs - | None -> externs in - let newBindings = match newBinding with - | Some newBinding -> newBinding :: newBindings - | None -> newBindings in - (externs, binding @ bindings, newBindings) - in - let (externs, bindings, newBindings) = List.fold_right otherStructures structuresAndBinding ([], [], []) in - externs @ [{ - pstr_loc; - pstr_desc = Pstr_value ( - recFlag, - bindings - ) - }] @ (match newBindings with - | [] -> [] - | newBindings -> [{ - pstr_loc = emptyLoc; - pstr_desc = Pstr_value ( - recFlag, - newBindings - ) - }]) @ returnStructures - | structure -> structure :: returnStructures in + let externs, bindings, newBindings = List.fold_right otherStructures structuresAndBinding ([], [], []) in + externs + @ [ { pstr_loc; pstr_desc = Pstr_value (recFlag, bindings) } ] + @ ( match newBindings with + | [] -> [] + | newBindings -> [ { pstr_loc = emptyLoc; pstr_desc = Pstr_value (recFlag, newBindings) } ] ) + @ returnStructures + | structure -> structure :: returnStructures + [@@raises Invalid_argument] + in let reactComponentTransform mapper structures = - List.fold_right (transformComponentDefinition mapper) structures [] in - - let transformComponentSignature _mapper signature returnSignatures = match signature with - | ({ - psig_loc; - psig_desc = Psig_value ({ - pval_name = { txt = fnName }; - pval_attributes; - pval_type; - } as psig_desc) - } as psig) -> - (match List.filter hasAttr pval_attributes with - | [] -> signature :: returnSignatures - | [_] -> - let rec getPropTypes types ({ptyp_loc; ptyp_desc} as fullType) = - (match ptyp_desc with - | Ptyp_arrow (name, type_, ({ptyp_desc = Ptyp_arrow _} as rest)) when isOptional name || isLabelled name -> - getPropTypes ((name, ptyp_loc, type_)::types) rest - | Ptyp_arrow (Nolabel, _type, rest) -> - getPropTypes types rest - | Ptyp_arrow (name, type_, returnValue) when isOptional name || isLabelled name -> - (returnValue, (name, returnValue.ptyp_loc, type_)::types) - | _ -> (fullType, types)) - in - let (innerType, propTypes) = getPropTypes [] pval_type in - let namedTypeList = List.fold_left argToConcreteType [] propTypes in - let pluckLabelAndLoc (label, loc, type_) = (label, None, loc, Some type_) in - let retPropsType = makePropsType ~loc:psig_loc namedTypeList in - let externalPropsDecl = makePropsExternalSig fnName psig_loc (( - optional "key", - None, - psig_loc, - Some(keyType psig_loc) - ) :: List.map pluckLabelAndLoc propTypes) retPropsType in - (* can't be an arrow because it will defensively uncurry *) - let newExternalType = Ptyp_constr ( - {loc = psig_loc; txt = Ldot ((Lident "React"), "componentLike")}, - [retPropsType; innerType] - ) in - let newStructure = { - psig with psig_desc = Psig_value { - psig_desc with pval_type = { - pval_type with ptyp_desc = newExternalType; - }; - pval_attributes = List.filter otherAttrsPure pval_attributes; - } - } in - externalPropsDecl :: newStructure :: returnSignatures - | _ -> raise (Invalid_argument "Only one react.component call can exist on a component at one time")) - | signature -> signature :: returnSignatures in + List.fold_right (transformComponentDefinition mapper) structures [] + [@@raises Invalid_argument] + in - let reactComponentSignatureTransform mapper signatures = - List.fold_right (transformComponentSignature mapper) signatures [] in + let transformComponentSignature _mapper signature returnSignatures = + match signature with + | { psig_loc; psig_desc = Psig_value ({ pval_name = { txt = fnName }; pval_attributes; pval_type } as psig_desc) } + as psig -> ( + match List.filter hasAttr pval_attributes with + | [] -> signature :: returnSignatures + | [ _ ] -> + let rec getPropTypes types ({ ptyp_loc; ptyp_desc } as fullType) = + match ptyp_desc with + | Ptyp_arrow (name, type_, ({ ptyp_desc = Ptyp_arrow _ } as rest)) when isOptional name || isLabelled name + -> + getPropTypes ((name, ptyp_loc, type_) :: types) rest + | Ptyp_arrow (Nolabel, _type, rest) -> getPropTypes types rest + | Ptyp_arrow (name, type_, returnValue) when isOptional name || isLabelled name -> + (returnValue, (name, returnValue.ptyp_loc, type_) :: types) + | _ -> (fullType, types) + in + let innerType, propTypes = getPropTypes [] pval_type in + let namedTypeList = List.fold_left argToConcreteType [] propTypes in + let pluckLabelAndLoc (label, loc, type_) = (label, None, loc, Some type_) in + let retPropsType = makePropsType ~loc:psig_loc namedTypeList in + let externalPropsDecl = + makePropsExternalSig fnName psig_loc + ((optional "key", None, psig_loc, Some (keyType psig_loc)) :: List.map pluckLabelAndLoc propTypes) + retPropsType + in + (* can't be an arrow because it will defensively uncurry *) + let newExternalType = + Ptyp_constr ({ loc = psig_loc; txt = Ldot (Lident "React", "componentLike") }, [ retPropsType; innerType ]) + in + let newStructure = + { + psig with + psig_desc = + Psig_value + { + psig_desc with + pval_type = { pval_type with ptyp_desc = newExternalType }; + pval_attributes = List.filter otherAttrsPure pval_attributes; + }; + } + in + externalPropsDecl :: newStructure :: returnSignatures + | _ -> raise (Invalid_argument "Only one react.component call can exist on a component at one time") ) + | signature -> signature :: returnSignatures + [@@raises Invalid_argument] + in + let reactComponentSignatureTransform mapper signatures = + List.fold_right (transformComponentSignature mapper) signatures [] + [@@raises Invalid_argument] + in let transformJsxCall mapper callExpression callArguments attrs = - (match callExpression.pexp_desc with - | Pexp_ident caller -> - (match caller with - | {txt = Lident "createElement"} -> - raise (Invalid_argument "JSX: `createElement` should be preceeded by a module name.") - + match callExpression.pexp_desc with + | Pexp_ident caller -> ( + match caller with + | { txt = Lident "createElement" } -> + raise (Invalid_argument "JSX: `createElement` should be preceeded by a module name.") (* Foo.createElement(~prop1=foo, ~prop2=bar, ~children=[], ()) *) - | {loc; txt = Ldot (modulePath, ("createElement" | "make"))} -> - (match !jsxVersion with - | None - | Some 3 -> transformUppercaseCall3 modulePath mapper loc attrs callExpression callArguments - | Some _ -> raise (Invalid_argument "JSX: the JSX version must be 3")) - + | { loc; txt = Ldot (modulePath, ("createElement" | "make")) } -> ( + match !jsxVersion with + | None | Some 3 -> transformUppercaseCall3 modulePath mapper loc attrs callExpression callArguments + | Some _ -> raise (Invalid_argument "JSX: the JSX version must be 3") ) (* div(~prop1=foo, ~prop2=bar, ~children=[bla], ()) *) (* turn that into - ReactDOMRe.createElement(~props=ReactDOMRe.props(~props1=foo, ~props2=bar, ()), [|bla|]) *) - | {loc; txt = Lident id} -> - (match !jsxVersion with - | None - | Some 3 -> transformLowercaseCall3 mapper loc attrs callArguments id - | Some _ -> raise (Invalid_argument "JSX: the JSX version must be 3")) - - | {txt = Ldot (_, anythingNotCreateElementOrMake)} -> - raise ( - Invalid_argument - ("JSX: the JSX attribute should be attached to a `YourModuleName.createElement` or `YourModuleName.make` call. We saw `" - ^ anythingNotCreateElementOrMake - ^ "` instead" - ) - ) - - | {txt = Lapply _} -> - (* don't think there's ever a case where this is reached *) - raise ( - Invalid_argument "JSX: encountered a weird case while processing the code. Please report this!" - ) - ) - | _ -> - raise ( - Invalid_argument "JSX: `createElement` should be preceeded by a simple, direct module name." - ) - ) in + ReactDOMRe.createElement(~props=ReactDOMRe.props(~props1=foo, ~props2=bar, ()), [|bla|]) *) + | { loc; txt = Lident id } -> ( + match !jsxVersion with + | None | Some 3 -> transformLowercaseCall3 mapper loc attrs callArguments id + | Some _ -> raise (Invalid_argument "JSX: the JSX version must be 3") ) + | { txt = Ldot (_, anythingNotCreateElementOrMake) } -> + raise + (Invalid_argument + ( "JSX: the JSX attribute should be attached to a `YourModuleName.createElement` or \ + `YourModuleName.make` call. We saw `" ^ anythingNotCreateElementOrMake ^ "` instead" )) + | { txt = Lapply _ } -> + (* don't think there's ever a case where this is reached *) + raise (Invalid_argument "JSX: encountered a weird case while processing the code. Please report this!") ) + | _ -> raise (Invalid_argument "JSX: `createElement` should be preceeded by a simple, direct module name.") + [@@raises Invalid_argument] + in - let signature = - (fun mapper signature -> default_mapper.signature mapper @@ reactComponentSignatureTransform mapper signature) in + let signature mapper signature = + default_mapper.signature mapper @@ reactComponentSignatureTransform mapper signature + [@@raises Invalid_argument] + in - let structure = - (fun mapper structure -> match structure with - | structures -> begin - default_mapper.structure mapper @@ reactComponentTransform mapper structures - end - ) in + let structure mapper structure = + match structure with structures -> default_mapper.structure mapper @@ reactComponentTransform mapper structures + [@@raises Invalid_argument] + in - let expr = - (fun mapper expression -> match expression with - (* Does the function application have the @JSX attribute? *) - | { - pexp_desc = Pexp_apply (callExpression, callArguments); - pexp_attributes - } -> - let (jsxAttribute, nonJSXAttributes) = List.partition (fun (attribute, _) -> attribute.txt = "JSX") pexp_attributes in - (match (jsxAttribute, nonJSXAttributes) with - (* no JSX attribute *) - | ([], _) -> default_mapper.expr mapper expression - | (_, nonJSXAttributes) -> transformJsxCall mapper callExpression callArguments nonJSXAttributes) - - (* is it a list with jsx attribute? Reason <>foo desugars to [@JSX][foo]*) - | { - pexp_desc = - Pexp_construct ({txt = Lident "::"; loc}, Some {pexp_desc = Pexp_tuple _}) - | Pexp_construct ({txt = Lident "[]"; loc}, None); - pexp_attributes - } as listItems -> - let (jsxAttribute, nonJSXAttributes) = List.partition (fun (attribute, _) -> attribute.txt = "JSX") pexp_attributes in - (match (jsxAttribute, nonJSXAttributes) with - (* no JSX attribute *) - | ([], _) -> default_mapper.expr mapper expression - | (_, nonJSXAttributes) -> - let fragment = Exp.ident ~loc {loc; txt = Ldot (Lident "ReasonReact", "fragment")} in + let expr mapper expression = + match expression with + (* Does the function application have the @JSX attribute? *) + | { pexp_desc = Pexp_apply (callExpression, callArguments); pexp_attributes } -> ( + let jsxAttribute, nonJSXAttributes = + List.partition (fun (attribute, _) -> attribute.txt = "JSX") pexp_attributes + in + match (jsxAttribute, nonJSXAttributes) with + (* no JSX attribute *) + | [], _ -> default_mapper.expr mapper expression + | _, nonJSXAttributes -> transformJsxCall mapper callExpression callArguments nonJSXAttributes ) + (* is it a list with jsx attribute? Reason <>foo desugars to [@JSX][foo]*) + | { + pexp_desc = + ( Pexp_construct ({ txt = Lident "::"; loc }, Some { pexp_desc = Pexp_tuple _ }) + | Pexp_construct ({ txt = Lident "[]"; loc }, None) ); + pexp_attributes; + } as listItems -> ( + let jsxAttribute, nonJSXAttributes = + List.partition (fun (attribute, _) -> attribute.txt = "JSX") pexp_attributes + in + match (jsxAttribute, nonJSXAttributes) with + (* no JSX attribute *) + | [], _ -> default_mapper.expr mapper expression + | _, nonJSXAttributes -> + let fragment = Exp.ident ~loc { loc; txt = Ldot (Lident "ReasonReact", "fragment") } in let childrenExpr = transformChildrenIfList ~loc ~mapper listItems in - let args = [ - (* "div" *) - (nolabel, fragment); - (* [|moreCreateElementCallsHere|] *) - (nolabel, childrenExpr) - ] in - Exp.apply - ~loc - (* throw away the [@JSX] attribute and keep the others, if any *) - ~attrs:nonJSXAttributes + let args = + [ (* "div" *) (nolabel, fragment); (* [|moreCreateElementCallsHere|] *) (nolabel, childrenExpr) ] + in + Exp.apply ~loc (* throw away the [@JSX] attribute and keep the others, if any *) ~attrs:nonJSXAttributes (* ReactDOMRe.createElement *) - (Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOMRe", "createElement")}) - args - ) - (* Delegate to the default mapper, a deep identity traversal *) - | e -> default_mapper.expr mapper e) in - - let module_binding = - (fun mapper module_binding -> - let _ = nestedModules := module_binding.pmb_name.txt :: !nestedModules in - let mapped = default_mapper.module_binding mapper module_binding in - let _ = nestedModules := List.tl !nestedModules in - mapped - ) in + (Exp.ident ~loc { loc; txt = Ldot (Lident "ReactDOMRe", "createElement") }) + args ) + (* Delegate to the default mapper, a deep identity traversal *) + | e -> default_mapper.expr mapper e + [@@raises Invalid_argument] + in - { default_mapper with structure; expr; signature; module_binding; } + let module_binding mapper module_binding = + let _ = nestedModules := module_binding.pmb_name.txt :: !nestedModules in + let mapped = default_mapper.module_binding mapper module_binding in + let _ = nestedModules := List.tl !nestedModules in + mapped + [@@raises Failure] + in + { default_mapper with structure; expr; signature; module_binding } + [@@raises Invalid_argument, Failure] -let rewrite_implementation (code: Parsetree.structure) : Parsetree.structure = +let rewrite_implementation (code : Parsetree.structure) : Parsetree.structure = let mapper = jsxMapper () in mapper.structure mapper code + [@@raises Invalid_argument, Failure] + let rewrite_signature (code : Parsetree.signature) : Parsetree.signature = let mapper = jsxMapper () in mapper.signature mapper code - + [@@raises Invalid_argument, Failure] end module Ppx_entry @@ -417499,6 +417448,12 @@ let rec isBlockExpr expr = | Pexp_setfield (expr, _, _) when isBlockExpr expr -> true | _ -> false +let isIfThenElseExpr expr = + let open Parsetree in + match expr.pexp_desc with + | Pexp_ifthenelse _ -> true + | _ -> false + let rec walkStructure s t comments = match s with | _ when comments = [] -> () @@ -418285,7 +418240,7 @@ let rec walkStructure s t comments = begin match elseExpr with | None -> () | Some expr -> - if isBlockExpr expr then + if isBlockExpr expr || isIfThenElseExpr expr then walkExpr expr t comments else ( let (leading, inside, trailing) = partitionByLoc comments expr.pexp_loc in @@ -419614,7 +419569,7 @@ type t = let toString = function | OpenDescription -> "an open description" - | ModuleLongIdent -> "a module identifier" + | ModuleLongIdent -> "a module path" | Ternary -> "a ternary expression" | Es6ArrowExpr -> "an es6 arrow function" | Jsx -> "a jsx expression" @@ -419999,7 +419954,7 @@ let explain t = let token = Token.toString t in "`" ^ token ^ "` is a reserved keyword." | _ -> - "At this point, I'm looking for an uppercased identifier like `Belt` or `Array`" + "At this point, I'm looking for an uppercased name like `Belt` or `Array`" end | Lident currentToken -> begin match currentToken with @@ -420012,7 +419967,7 @@ let explain t = | Underscore -> "`_` isn't a valid name." | _ -> - "I'm expecting an lowercased identifier like `name` or `age`" + "I'm expecting a lowercase name like `user or `age`" end | Message txt -> txt | UnclosedString -> @@ -420060,7 +420015,7 @@ let explain t = "Did you forget to write an expression here?" | (Grammar.LetBinding, _)::_, _ -> "This let-binding misses an expression" - | _::_, (Rbracket | Rbrace) -> + | _::_, (Rbracket | Rbrace | Eof) -> "Missing expression" | _ -> "I'm not sure what to parse here when looking at \"" ^ name ^ "\"." @@ -421288,6 +421243,9 @@ val bracedExpr: Parsetree.expression -> bool val callExpr: Parsetree.expression -> kind val includeModExpr : Parsetree.module_expr -> bool + +val arrowReturnTypExpr: Parsetree.core_type -> bool + end = struct #1 "res_parens.ml" module ParsetreeViewer = Res_parsetree_viewer @@ -421695,6 +421653,10 @@ type kind = Parenthesized | Braced of Location.t | Nothing | Parsetree.Pmod_constraint _ -> true | _ -> false +let arrowReturnTypExpr typExpr = match typExpr.Parsetree.ptyp_desc with + | Parsetree.Ptyp_arrow _ -> true + | _ -> false + end module Res_printer : sig #1 "res_printer.mli" @@ -424005,7 +423967,12 @@ and printPattern (p : Parsetree.pattern) cmtTbl = | _ -> patternDoc ] ) orChain in - Doc.group (Doc.concat docs) + let isSpreadOverMultipleLines = match (orChain, List.rev orChain) with + | first::_, last::_ -> + first.ppat_loc.loc_start.pos_lnum < last.ppat_loc.loc_end.pos_lnum + | _ -> false + in + Doc.breakableGroup ~forceBreak:isSpreadOverMultipleLines (Doc.concat docs) | Ppat_extension ext -> printExtension ~atModuleLvl:false ext cmtTbl | Ppat_lazy p -> @@ -424683,7 +424650,6 @@ and printExpression (e : Parsetree.expression) cmtTbl = | Pexp_let _ -> printExpressionBlock ~braces:true e cmtTbl | Pexp_fun (Nolabel, None, {ppat_desc = Ppat_var {txt="__x"}}, ({pexp_desc = Pexp_apply _})) -> - (* (__x) => f(a, __x, c) -----> f(a, _, c) *) printExpressionWithComments (ParsetreeViewer.rewriteUnderscoreApply e) cmtTbl | Pexp_fun _ | Pexp_newtype _ -> @@ -424754,7 +424720,15 @@ and printExpression (e : Parsetree.expression) cmtTbl = ) in let typConstraintDoc = match typConstraint with - | Some(typ) -> Doc.concat [Doc.text ": "; printTypExpr typ cmtTbl] + | Some(typ) -> + let typDoc = + let doc = printTypExpr typ cmtTbl in + if Parens.arrowReturnTypExpr typ then + addParens doc + else + doc + in + Doc.concat [Doc.text ": "; typDoc] | _ -> Doc.nil in let attrs = printAttributes attrs cmtTbl in @@ -426758,8 +426732,6 @@ let mkLoc startLoc endLoc = Location.{ } module Recover = struct - (* type action = unit option None is abort, Some () is retry *) - let defaultExpr () = let id = Location.mknoloc "rescript.exprhole" in Ast_helper.Exp.mk (Pexp_extension (id, PStr [])) @@ -426776,6 +426748,10 @@ module Recover = struct let defaultModuleExpr () = Ast_helper.Mod.structure [] let defaultModuleType () = Ast_helper.Mty.signature [] + let defaultSignatureItem = + let id = Location.mknoloc "rescript.sigitemhole" in + Ast_helper.Sig.extension (id, PStr []) + let recoverEqualGreater p = Parser.expect EqualGreater p; match p.Parser.token with @@ -426836,6 +426812,13 @@ Solution: directly use `concat`." let typeParam = "A type param consists of a singlequote followed by a name like `'a` or `'A`" let typeVar = "A type variable consists of a singlequote followed by a name like `'a` or `'A`" + + let attributeWithoutNode (attr : Parsetree.attribute) = + let ({Asttypes.txt = attrName}, _) = attr in + "Did you forget to attach `" ^ attrName ^ "` to an item?\n Standalone attributes start with `@@` like: `@@" ^ attrName ^"`" + + let typeDeclarationNameLongident longident = + "A type declaration's name cannot contain a module access. Did you mean `" ^ (Longident.last longident) ^"`?" end @@ -428711,7 +428694,7 @@ and parsePrimaryExpr ~operand ?(noCall=false) p = ~startPos:expr.pexp_loc.loc_start ~endPos:expr.pexp_loc.loc_end p - (Diagnostics.message "Tagged template literals are currently restricted to identifiers like: json`null`."); + (Diagnostics.message "Tagged template literals are currently restricted to names like: json`null`."); parseTemplateExpr p end | _ -> expr @@ -429168,7 +429151,7 @@ and parseJsxName p = let longident = parseModuleLongIdent ~lowercase:true p in Location.mkloc (Longident.Ldot (longident.txt, "createElement")) longident.loc | _ -> - let msg = "A jsx name should start with a lowercase or uppercase identifier, like: div in
or Navbar in " + let msg = "A jsx name must be a lowercase or uppercase name, like: div in
or Navbar in " in Parser.err p (Diagnostics.message msg); Location.mknoloc (Longident.Lident "_") @@ -429320,7 +429303,7 @@ and parseJsxProp p = | _ -> let attrExpr = Ast_helper.Exp.ident ~loc ~attrs:[propLocAttr] - (Location.mknoloc (Longident.Lident name)) in + (Location.mkloc (Longident.Lident name) loc) in let label = if optional then Asttypes.Optional name else Asttypes.Labelled name in @@ -431687,6 +431670,13 @@ and parseTypeDefinitionOrExtension ~attrs p = | PlusEqual -> TypeExt(parseTypeExtension ~params ~attrs ~name p) | _ -> + (* shape of type name should be Lident, i.e. `t` is accepted. `User.t` not *) + let () = match name.Location.txt with + | Lident _ -> () + | longident -> + Parser.err ~startPos:name.loc.loc_start ~endPos:name.loc.loc_end p + (longident |> ErrorMessages.typeDeclarationNameLongident |> Diagnostics.message) + in let typeDefs = parseTypeDefinitions ~attrs ~name ~params ~startPos p in TypeDef {recFlag; types = typeDefs} @@ -431837,9 +431827,11 @@ and parseStructureItemRegion p = let loc = mkLoc startPos p.prevEndPos in Some {structureItem with pstr_loc = loc} | Module -> + Parser.beginRegion p; let structureItem = parseModuleOrModuleTypeImplOrPackExpr ~attrs p in parseNewlineOrSemicolonStructure p; let loc = mkLoc startPos p.prevEndPos in + Parser.endRegion p; Some {structureItem with pstr_loc = loc} | AtAt -> let attr = parseStandaloneAttribute p in @@ -431857,7 +431849,19 @@ and parseStructureItemRegion p = parseNewlineOrSemicolonStructure p; let loc = mkLoc startPos p.prevEndPos in Parser.checkProgress ~prevEndPos ~result:(Ast_helper.Str.eval ~loc ~attrs exp) p - | _ -> None + | _ -> + begin match attrs with + | (({Asttypes.loc = attrLoc}, _) as attr)::_ -> + Parser.err + ~startPos:attrLoc.loc_start + ~endPos:attrLoc.loc_end + p + (Diagnostics.message (ErrorMessages.attributeWithoutNode attr)); + let expr = parseExpr p in + Some (Ast_helper.Str.eval ~loc:(mkLoc p.startPos p.prevEndPos) ~attrs expr) + | _ -> + None + end and parseJsImport ~startPos ~attrs p = Parser.expect Token.Import p; @@ -432558,24 +432562,30 @@ and parseSignatureItemRegion p = let loc = mkLoc startPos p.prevEndPos in Some (Ast_helper.Sig.include_ ~loc includeDescription) | Module -> + Parser.beginRegion p; Parser.next p; begin match p.Parser.token with | Uident _ -> let modDecl = parseModuleDeclarationOrAlias ~attrs p in parseNewlineOrSemicolonSignature p; let loc = mkLoc startPos p.prevEndPos in + Parser.endRegion p; Some (Ast_helper.Sig.module_ ~loc modDecl) | Rec -> let recModule = parseRecModuleSpec ~attrs ~startPos p in parseNewlineOrSemicolonSignature p; let loc = mkLoc startPos p.prevEndPos in + Parser.endRegion p; Some (Ast_helper.Sig.rec_module ~loc recModule) | Typ -> - Some (parseModuleTypeDeclaration ~attrs ~startPos p) + let modTypeDecl = parseModuleTypeDeclaration ~attrs ~startPos p in + Parser.endRegion p; + Some modTypeDecl | _t -> let modDecl = parseModuleDeclarationOrAlias ~attrs p in parseNewlineOrSemicolonSignature p; let loc = mkLoc startPos p.prevEndPos in + Parser.endRegion p; Some (Ast_helper.Sig.module_ ~loc modDecl) end | AtAt -> @@ -432592,7 +432602,17 @@ and parseSignatureItemRegion p = Parser.next p; parseSignatureItemRegion p | _ -> - None + begin match attrs with + | (({Asttypes.loc = attrLoc}, _) as attr)::_ -> + Parser.err + ~startPos:attrLoc.loc_start + ~endPos:attrLoc.loc_end + p + (Diagnostics.message (ErrorMessages.attributeWithoutNode attr)); + Some Recover.defaultSignatureItem + | _ -> + None + end (* module rec module-name : module-type { and module-name: module-type } *) and parseRecModuleSpec ~attrs ~startPos p = @@ -432695,8 +432715,7 @@ and parseSignLetDesc ~attrs p = (* attr-id ::= lowercase-ident ∣ capitalized-ident ∣ attr-id . attr-id *) -and parseAttributeId p = - let startPos = p.Parser.startPos in +and parseAttributeId ~startPos p = let rec loop p acc = match p.Parser.token with | Lident ident | Uident ident -> @@ -432779,8 +432798,9 @@ and parsePayload p = and parseAttribute p = match p.Parser.token with | At -> + let startPos = p.startPos in Parser.next p; - let attrId = parseAttributeId p in + let attrId = parseAttributeId ~startPos p in let payload = parsePayload p in Some(attrId, payload) | _ -> None @@ -432796,8 +432816,9 @@ and parseAttributes p = * | @@ attribute-id ( structure-item ) *) and parseStandaloneAttribute p = + let startPos = p.startPos in Parser.expect AtAt p; - let attrId = parseAttributeId p in + let attrId = parseAttributeId ~startPos p in let payload = parsePayload p in (attrId, payload) @@ -432835,11 +432856,12 @@ and parseStandaloneAttribute p = * ~moduleLanguage represents whether we're on the module level or not *) and parseExtension ?(moduleLanguage=false) p = + let startPos = p.Parser.startPos in if moduleLanguage then Parser.expect PercentPercent p else Parser.expect Percent p; - let attrId = parseAttributeId p in + let attrId = parseAttributeId ~startPos p in let payload = parsePayload p in (attrId, payload) @@ -433533,7 +433555,7 @@ let normalize = structure_item = begin fun mapper structureItem -> match structureItem.pstr_desc with (* heuristic: if we have multiple type declarations, mark them recursive *) - | Pstr_type (recFlag, typeDeclarations) -> + | Pstr_type (Recursive as recFlag, typeDeclarations) -> let flag = match typeDeclarations with | [td] -> if looksLikeRecursiveTypeDeclaration td then Asttypes.Recursive @@ -433551,7 +433573,7 @@ let normalize = signature_item = begin fun mapper signatureItem -> match signatureItem.psig_desc with (* heuristic: if we have multiple type declarations, mark them recursive *) - | Psig_type (recFlag, typeDeclarations) -> + | Psig_type (Recursive as recFlag, typeDeclarations) -> let flag = match typeDeclarations with | [td] -> if looksLikeRecursiveTypeDeclaration td then Asttypes.Recursive diff --git a/lib/4.06.1/whole_compiler.ml.d b/lib/4.06.1/whole_compiler.ml.d index 850e6421a8..3650d5a99d 100644 --- a/lib/4.06.1/whole_compiler.ml.d +++ b/lib/4.06.1/whole_compiler.ml.d @@ -1 +1 @@ -../lib/4.06.1/whole_compiler.ml: ../ocaml/bytecomp/lambda.ml ../ocaml/bytecomp/lambda.mli ../ocaml/bytecomp/matching.ml ../ocaml/bytecomp/matching.mli ../ocaml/bytecomp/printlambda.ml ../ocaml/bytecomp/printlambda.mli ../ocaml/bytecomp/switch.ml ../ocaml/bytecomp/switch.mli ../ocaml/bytecomp/translattribute.ml ../ocaml/bytecomp/translattribute.mli ../ocaml/bytecomp/translclass.ml ../ocaml/bytecomp/translclass.mli ../ocaml/bytecomp/translcore.ml ../ocaml/bytecomp/translcore.mli ../ocaml/bytecomp/translmod.ml ../ocaml/bytecomp/translmod.mli ../ocaml/bytecomp/translobj.ml ../ocaml/bytecomp/translobj.mli ../ocaml/parsing/ast_helper.ml ../ocaml/parsing/ast_helper.mli ../ocaml/parsing/ast_iterator.ml ../ocaml/parsing/ast_iterator.mli ../ocaml/parsing/ast_mapper.ml ../ocaml/parsing/ast_mapper.mli ../ocaml/parsing/asttypes.mli ../ocaml/parsing/attr_helper.ml ../ocaml/parsing/attr_helper.mli ../ocaml/parsing/builtin_attributes.ml ../ocaml/parsing/builtin_attributes.mli ../ocaml/parsing/depend.ml ../ocaml/parsing/depend.mli ../ocaml/parsing/docstrings.ml ../ocaml/parsing/docstrings.mli ../ocaml/parsing/lexer.ml ../ocaml/parsing/lexer.mli ../ocaml/parsing/location.ml ../ocaml/parsing/location.mli ../ocaml/parsing/longident.ml ../ocaml/parsing/longident.mli ../ocaml/parsing/parse.ml ../ocaml/parsing/parse.mli ../ocaml/parsing/parser.ml ../ocaml/parsing/parser.mli ../ocaml/parsing/parsetree.mli ../ocaml/parsing/pprintast.ml ../ocaml/parsing/pprintast.mli ../ocaml/parsing/printast.ml ../ocaml/parsing/printast.mli ../ocaml/parsing/syntaxerr.ml ../ocaml/parsing/syntaxerr.mli ../ocaml/typing/annot.mli ../ocaml/typing/btype.ml ../ocaml/typing/btype.mli ../ocaml/typing/cmi_format.ml ../ocaml/typing/cmi_format.mli ../ocaml/typing/cmt_format.ml ../ocaml/typing/cmt_format.mli ../ocaml/typing/ctype.ml ../ocaml/typing/ctype.mli ../ocaml/typing/datarepr.ml ../ocaml/typing/datarepr.mli ../ocaml/typing/env.ml ../ocaml/typing/env.mli ../ocaml/typing/ident.ml ../ocaml/typing/ident.mli ../ocaml/typing/includeclass.ml ../ocaml/typing/includeclass.mli ../ocaml/typing/includecore.ml ../ocaml/typing/includecore.mli ../ocaml/typing/includemod.ml ../ocaml/typing/includemod.mli ../ocaml/typing/mtype.ml ../ocaml/typing/mtype.mli ../ocaml/typing/oprint.ml ../ocaml/typing/oprint.mli ../ocaml/typing/outcometree.mli ../ocaml/typing/parmatch.ml ../ocaml/typing/parmatch.mli ../ocaml/typing/path.ml ../ocaml/typing/path.mli ../ocaml/typing/predef.ml ../ocaml/typing/predef.mli ../ocaml/typing/primitive.ml ../ocaml/typing/primitive.mli ../ocaml/typing/printtyp.ml ../ocaml/typing/printtyp.mli ../ocaml/typing/printtyped.ml ../ocaml/typing/printtyped.mli ../ocaml/typing/stypes.ml ../ocaml/typing/stypes.mli ../ocaml/typing/subst.ml ../ocaml/typing/subst.mli ../ocaml/typing/tast_mapper.ml ../ocaml/typing/tast_mapper.mli ../ocaml/typing/typeclass.ml ../ocaml/typing/typeclass.mli ../ocaml/typing/typecore.ml ../ocaml/typing/typecore.mli ../ocaml/typing/typedecl.ml ../ocaml/typing/typedecl.mli ../ocaml/typing/typedtree.ml ../ocaml/typing/typedtree.mli ../ocaml/typing/typedtreeIter.ml ../ocaml/typing/typedtreeIter.mli ../ocaml/typing/typemod.ml ../ocaml/typing/typemod.mli ../ocaml/typing/typeopt.ml ../ocaml/typing/typeopt.mli ../ocaml/typing/types.ml ../ocaml/typing/types.mli ../ocaml/typing/typetexp.ml ../ocaml/typing/typetexp.mli ../ocaml/typing/untypeast.ml ../ocaml/typing/untypeast.mli ../ocaml/utils/arg_helper.ml ../ocaml/utils/arg_helper.mli ../ocaml/utils/ccomp.ml ../ocaml/utils/ccomp.mli ../ocaml/utils/clflags.ml ../ocaml/utils/clflags.mli ../ocaml/utils/consistbl.ml ../ocaml/utils/consistbl.mli ../ocaml/utils/identifiable.ml ../ocaml/utils/identifiable.mli ../ocaml/utils/misc.ml ../ocaml/utils/misc.mli ../ocaml/utils/numbers.ml ../ocaml/utils/numbers.mli ../ocaml/utils/profile.ml ../ocaml/utils/profile.mli ../ocaml/utils/tbl.ml ../ocaml/utils/tbl.mli ../ocaml/utils/warnings.ml ../ocaml/utils/warnings.mli ./common/bs_loc.ml ./common/bs_loc.mli ./common/bs_version.ml ./common/bs_version.mli ./common/bs_warnings.ml ./common/bs_warnings.mli ./common/ext_log.ml ./common/ext_log.mli ./common/js_config.ml ./common/js_config.mli ./common/lam_methname.ml ./common/lam_methname.mli ./common/ml_binary.ml ./common/ml_binary.mli ./core/bs_cmi_load.ml ./core/bs_conditional_initial.ml ./core/bs_conditional_initial.mli ./core/cmd_ast_exception.ml ./core/cmd_ppx_apply.ml ./core/compile_rec_module.ml ./core/config_util.ml ./core/config_util.mli ./core/config_whole_compiler.ml ./core/config_whole_compiler.mli ./core/j.ml ./core/js_analyzer.ml ./core/js_analyzer.mli ./core/js_arr.ml ./core/js_arr.mli ./core/js_ast_util.ml ./core/js_ast_util.mli ./core/js_block_runtime.ml ./core/js_block_runtime.mli ./core/js_call_info.ml ./core/js_call_info.mli ./core/js_closure.ml ./core/js_closure.mli ./core/js_cmj_format.ml ./core/js_cmj_format.mli ./core/js_cmj_load.ml ./core/js_cmj_load.mli ./core/js_cmj_load_builtin_unit.ml ./core/js_dump.ml ./core/js_dump.mli ./core/js_dump_import_export.ml ./core/js_dump_import_export.mli ./core/js_dump_lit.ml ./core/js_dump_program.ml ./core/js_dump_program.mli ./core/js_dump_property.ml ./core/js_dump_property.mli ./core/js_dump_string.ml ./core/js_dump_string.mli ./core/js_exp_make.ml ./core/js_exp_make.mli ./core/js_fold.ml ./core/js_fold_basic.ml ./core/js_fold_basic.mli ./core/js_fun_env.ml ./core/js_fun_env.mli ./core/js_implementation.ml ./core/js_implementation.mli ./core/js_long.ml ./core/js_long.mli ./core/js_map.ml ./core/js_name_of_module_id.ml ./core/js_name_of_module_id.mli ./core/js_number.ml ./core/js_number.mli ./core/js_of_lam_array.ml ./core/js_of_lam_array.mli ./core/js_of_lam_block.ml ./core/js_of_lam_block.mli ./core/js_of_lam_exception.ml ./core/js_of_lam_exception.mli ./core/js_of_lam_option.ml ./core/js_of_lam_option.mli ./core/js_of_lam_string.ml ./core/js_of_lam_string.mli ./core/js_of_lam_variant.ml ./core/js_of_lam_variant.mli ./core/js_op.ml ./core/js_op_util.ml ./core/js_op_util.mli ./core/js_output.ml ./core/js_output.mli ./core/js_packages_info.ml ./core/js_packages_info.mli ./core/js_packages_state.ml ./core/js_packages_state.mli ./core/js_pass_debug.ml ./core/js_pass_debug.mli ./core/js_pass_flatten.ml ./core/js_pass_flatten.mli ./core/js_pass_flatten_and_mark_dead.ml ./core/js_pass_flatten_and_mark_dead.mli ./core/js_pass_get_used.ml ./core/js_pass_get_used.mli ./core/js_pass_scope.ml ./core/js_pass_scope.mli ./core/js_pass_tailcall_inline.ml ./core/js_pass_tailcall_inline.mli ./core/js_raw_info.ml ./core/js_shake.ml ./core/js_shake.mli ./core/js_stmt_make.ml ./core/js_stmt_make.mli ./core/lam.ml ./core/lam.mli ./core/lam_analysis.ml ./core/lam_analysis.mli ./core/lam_arity.ml ./core/lam_arity.mli ./core/lam_arity_analysis.ml ./core/lam_arity_analysis.mli ./core/lam_beta_reduce.ml ./core/lam_beta_reduce.mli ./core/lam_beta_reduce_util.ml ./core/lam_beta_reduce_util.mli ./core/lam_bounded_vars.ml ./core/lam_bounded_vars.mli ./core/lam_closure.ml ./core/lam_closure.mli ./core/lam_coercion.ml ./core/lam_coercion.mli ./core/lam_compat.ml ./core/lam_compat.mli ./core/lam_compile.ml ./core/lam_compile.mli ./core/lam_compile_const.ml ./core/lam_compile_const.mli ./core/lam_compile_context.ml ./core/lam_compile_context.mli ./core/lam_compile_env.ml ./core/lam_compile_env.mli ./core/lam_compile_external_call.ml ./core/lam_compile_external_call.mli ./core/lam_compile_external_obj.ml ./core/lam_compile_external_obj.mli ./core/lam_compile_main.ml ./core/lam_compile_main.mli ./core/lam_compile_primitive.ml ./core/lam_compile_primitive.mli ./core/lam_compile_util.ml ./core/lam_compile_util.mli ./core/lam_constant.ml ./core/lam_constant.mli ./core/lam_constant_convert.ml ./core/lam_constant_convert.mli ./core/lam_convert.ml ./core/lam_convert.mli ./core/lam_dce.ml ./core/lam_dce.mli ./core/lam_dispatch_primitive.ml ./core/lam_dispatch_primitive.mli ./core/lam_eta_conversion.ml ./core/lam_eta_conversion.mli ./core/lam_exit_code.ml ./core/lam_exit_code.mli ./core/lam_exit_count.ml ./core/lam_exit_count.mli ./core/lam_free_variables.ml ./core/lam_free_variables.mli ./core/lam_group.ml ./core/lam_group.mli ./core/lam_hit.ml ./core/lam_hit.mli ./core/lam_id_kind.ml ./core/lam_id_kind.mli ./core/lam_iter.ml ./core/lam_iter.mli ./core/lam_module_ident.ml ./core/lam_module_ident.mli ./core/lam_pass_alpha_conversion.ml ./core/lam_pass_alpha_conversion.mli ./core/lam_pass_collect.ml ./core/lam_pass_collect.mli ./core/lam_pass_count.ml ./core/lam_pass_count.mli ./core/lam_pass_deep_flatten.ml ./core/lam_pass_deep_flatten.mli ./core/lam_pass_eliminate_ref.ml ./core/lam_pass_eliminate_ref.mli ./core/lam_pass_exits.ml ./core/lam_pass_exits.mli ./core/lam_pass_lets_dce.ml ./core/lam_pass_lets_dce.mli ./core/lam_pass_remove_alias.ml ./core/lam_pass_remove_alias.mli ./core/lam_pointer_info.ml ./core/lam_pointer_info.mli ./core/lam_primitive.ml ./core/lam_primitive.mli ./core/lam_print.ml ./core/lam_print.mli ./core/lam_scc.ml ./core/lam_scc.mli ./core/lam_stats.ml ./core/lam_stats.mli ./core/lam_stats_export.ml ./core/lam_stats_export.mli ./core/lam_subst.ml ./core/lam_subst.mli ./core/lam_tag_info.ml ./core/lam_util.ml ./core/lam_util.mli ./core/lam_var_stats.ml ./core/lam_var_stats.mli ./core/matching_polyfill.ml ./core/matching_polyfill.mli ./core/polyvar_pattern_match.ml ./core/pparse_driver.ml ./core/pparse_driver.mli ./core/record_attributes_check.ml ./core/res_compmisc.ml ./core/res_compmisc.mli ./core/transl_single_field_record.ml ./depends/ast_extract.ml ./depends/ast_extract.mli ./depends/binary_ast.ml ./depends/binary_ast.mli ./depends/bs_exception.ml ./depends/bs_exception.mli ./ext/bsc_args.ml ./ext/bsc_args.mli ./ext/bsc_warnings.ml ./ext/ext_array.ml ./ext/ext_array.mli ./ext/ext_buffer.ml ./ext/ext_buffer.mli ./ext/ext_bytes.ml ./ext/ext_bytes.mli ./ext/ext_char.ml ./ext/ext_char.mli ./ext/ext_digest.ml ./ext/ext_digest.mli ./ext/ext_file_extensions.ml ./ext/ext_filename.ml ./ext/ext_filename.mli ./ext/ext_fmt.ml ./ext/ext_ident.ml ./ext/ext_ident.mli ./ext/ext_int.ml ./ext/ext_int.mli ./ext/ext_io.ml ./ext/ext_io.mli ./ext/ext_js_file_kind.ml ./ext/ext_js_suffix.ml ./ext/ext_list.ml ./ext/ext_list.mli ./ext/ext_marshal.ml ./ext/ext_marshal.mli ./ext/ext_modulename.ml ./ext/ext_modulename.mli ./ext/ext_namespace.ml ./ext/ext_namespace.mli ./ext/ext_namespace_encode.ml ./ext/ext_namespace_encode.mli ./ext/ext_option.ml ./ext/ext_option.mli ./ext/ext_path.ml ./ext/ext_path.mli ./ext/ext_pervasives.ml ./ext/ext_pervasives.mli ./ext/ext_pp.ml ./ext/ext_pp.mli ./ext/ext_pp_scope.ml ./ext/ext_pp_scope.mli ./ext/ext_ref.ml ./ext/ext_ref.mli ./ext/ext_scc.ml ./ext/ext_scc.mli ./ext/ext_spec.ml ./ext/ext_spec.mli ./ext/ext_string.ml ./ext/ext_string.mli ./ext/ext_string_array.ml ./ext/ext_string_array.mli ./ext/ext_sys.ml ./ext/ext_sys.mli ./ext/ext_utf8.ml ./ext/ext_utf8.mli ./ext/ext_util.ml ./ext/ext_util.mli ./ext/hash.ml ./ext/hash.mli ./ext/hash_gen.ml ./ext/hash_ident.ml ./ext/hash_ident.mli ./ext/hash_int.ml ./ext/hash_int.mli ./ext/hash_set.ml ./ext/hash_set.mli ./ext/hash_set_gen.ml ./ext/hash_set_ident.ml ./ext/hash_set_ident.mli ./ext/hash_set_ident_mask.ml ./ext/hash_set_ident_mask.mli ./ext/hash_set_poly.ml ./ext/hash_set_poly.mli ./ext/hash_set_string.ml ./ext/hash_set_string.mli ./ext/hash_string.ml ./ext/hash_string.mli ./ext/int_vec_util.ml ./ext/int_vec_util.mli ./ext/int_vec_vec.ml ./ext/int_vec_vec.mli ./ext/js_reserved_map.ml ./ext/js_reserved_map.mli ./ext/js_runtime_modules.ml ./ext/literals.ml ./ext/map_gen.ml ./ext/map_gen.mli ./ext/map_ident.ml ./ext/map_ident.mli ./ext/map_int.ml ./ext/map_int.mli ./ext/map_string.ml ./ext/map_string.mli ./ext/ordered_hash_map_gen.ml ./ext/ordered_hash_map_local_ident.ml ./ext/ordered_hash_map_local_ident.mli ./ext/set_gen.ml ./ext/set_gen.mli ./ext/set_ident.ml ./ext/set_ident.mli ./ext/set_string.ml ./ext/set_string.mli ./ext/vec.ml ./ext/vec.mli ./ext/vec_gen.ml ./ext/vec_int.ml ./ext/vec_int.mli ./js_parser/declaration_parser.ml ./js_parser/enum_common.ml ./js_parser/enum_parser.ml ./js_parser/expression_parser.ml ./js_parser/file_key.ml ./js_parser/flow_ast.ml ./js_parser/flow_ast_utils.ml ./js_parser/flow_ast_utils.mli ./js_parser/flow_lexer.ml ./js_parser/flow_lexer.mli ./js_parser/jsx_parser.ml ./js_parser/lex_env.ml ./js_parser/lex_result.ml ./js_parser/loc.ml ./js_parser/loc.mli ./js_parser/object_parser.ml ./js_parser/parse_error.ml ./js_parser/parser_common.ml ./js_parser/parser_env.ml ./js_parser/parser_env.mli ./js_parser/parser_flow.ml ./js_parser/pattern_cover.ml ./js_parser/pattern_parser.ml ./js_parser/sedlexing.ml ./js_parser/sedlexing.mli ./js_parser/statement_parser.ml ./js_parser/token.ml ./js_parser/type_parser.ml ./js_parser/wtf8.ml ./js_parser/wtf8.mli ./main/builtin_cmi_datasets.ml ./main/builtin_cmi_datasets.mli ./main/builtin_cmj_datasets.ml ./main/builtin_cmj_datasets.mli ./main/js_main.ml ./main/js_main.mli ./napkin/res_ast_conversion.ml ./napkin/res_ast_conversion.mli ./napkin/res_character_codes.ml ./napkin/res_comment.ml ./napkin/res_comment.mli ./napkin/res_comments_table.ml ./napkin/res_core.ml ./napkin/res_core.mli ./napkin/res_diagnostics.ml ./napkin/res_diagnostics.mli ./napkin/res_diagnostics_printing_utils.ml ./napkin/res_doc.ml ./napkin/res_doc.mli ./napkin/res_driver.ml ./napkin/res_driver.mli ./napkin/res_driver_ml_parser.ml ./napkin/res_driver_ml_parser.mli ./napkin/res_driver_reason_binary.ml ./napkin/res_driver_reason_binary.mli ./napkin/res_grammar.ml ./napkin/res_io.ml ./napkin/res_io.mli ./napkin/res_js_ffi.ml ./napkin/res_minibuffer.ml ./napkin/res_minibuffer.mli ./napkin/res_multi_printer.ml ./napkin/res_multi_printer.mli ./napkin/res_outcome_printer.ml ./napkin/res_outcome_printer.mli ./napkin/res_parens.ml ./napkin/res_parens.mli ./napkin/res_parser.ml ./napkin/res_parser.mli ./napkin/res_parsetree_viewer.ml ./napkin/res_parsetree_viewer.mli ./napkin/res_printer.ml ./napkin/res_printer.mli ./napkin/res_reporting.ml ./napkin/res_scanner.ml ./napkin/res_scanner.mli ./napkin/res_token.ml ./outcome_printer/outcome_printer_ns.ml ./outcome_printer/outcome_printer_ns.mli ./outcome_printer/reason_outcome_printer_main.ml ./outcome_printer/reason_syntax_util.ml ./outcome_printer/reason_syntax_util.mli ./outcome_printer/tweaked_reason_oprint.ml ./stubs/bs_hash_stubs.ml ./super_errors/super_env.ml ./super_errors/super_location.ml ./super_errors/super_location.mli ./super_errors/super_main.ml ./super_errors/super_misc.ml ./super_errors/super_misc.mli ./super_errors/super_pparse.ml ./super_errors/super_typecore.ml ./super_errors/super_typemod.ml ./super_errors/super_typetexp.ml ./syntax/ast_attributes.ml ./syntax/ast_attributes.mli ./syntax/ast_bs_open.ml ./syntax/ast_bs_open.mli ./syntax/ast_comb.ml ./syntax/ast_comb.mli ./syntax/ast_compatible.ml ./syntax/ast_compatible.mli ./syntax/ast_config.ml ./syntax/ast_config.mli ./syntax/ast_core_type.ml ./syntax/ast_core_type.mli ./syntax/ast_core_type_class_type.ml ./syntax/ast_core_type_class_type.mli ./syntax/ast_derive.ml ./syntax/ast_derive.mli ./syntax/ast_derive_abstract.ml ./syntax/ast_derive_abstract.mli ./syntax/ast_derive_js_mapper.ml ./syntax/ast_derive_js_mapper.mli ./syntax/ast_derive_projector.ml ./syntax/ast_derive_projector.mli ./syntax/ast_derive_util.ml ./syntax/ast_derive_util.mli ./syntax/ast_exp.ml ./syntax/ast_exp.mli ./syntax/ast_exp_apply.ml ./syntax/ast_exp_apply.mli ./syntax/ast_exp_extension.ml ./syntax/ast_exp_extension.mli ./syntax/ast_exp_handle_external.ml ./syntax/ast_exp_handle_external.mli ./syntax/ast_external.ml ./syntax/ast_external.mli ./syntax/ast_external_mk.ml ./syntax/ast_external_mk.mli ./syntax/ast_external_process.ml ./syntax/ast_external_process.mli ./syntax/ast_literal.ml ./syntax/ast_literal.mli ./syntax/ast_open_cxt.ml ./syntax/ast_open_cxt.mli ./syntax/ast_pat.ml ./syntax/ast_pat.mli ./syntax/ast_payload.ml ./syntax/ast_payload.mli ./syntax/ast_polyvar.ml ./syntax/ast_polyvar.mli ./syntax/ast_reason_pp.ml ./syntax/ast_reason_pp.mli ./syntax/ast_signature.ml ./syntax/ast_signature.mli ./syntax/ast_structure.ml ./syntax/ast_structure.mli ./syntax/ast_tdcls.ml ./syntax/ast_tdcls.mli ./syntax/ast_tuple_pattern_flatten.ml ./syntax/ast_tuple_pattern_flatten.mli ./syntax/ast_typ_uncurry.ml ./syntax/ast_typ_uncurry.mli ./syntax/ast_uncurry_apply.ml ./syntax/ast_uncurry_apply.mli ./syntax/ast_uncurry_gen.ml ./syntax/ast_uncurry_gen.mli ./syntax/ast_utf8_string.ml ./syntax/ast_utf8_string.mli ./syntax/ast_utf8_string_interp.ml ./syntax/ast_utf8_string_interp.mli ./syntax/ast_util.ml ./syntax/ast_util.mli ./syntax/bs_ast_invariant.ml ./syntax/bs_ast_invariant.mli ./syntax/bs_ast_mapper.ml ./syntax/bs_ast_mapper.mli ./syntax/bs_builtin_ppx.ml ./syntax/bs_builtin_ppx.mli ./syntax/bs_flow_ast_utils.ml ./syntax/bs_flow_ast_utils.mli ./syntax/bs_syntaxerr.ml ./syntax/bs_syntaxerr.mli ./syntax/classify_function.ml ./syntax/classify_function.mli ./syntax/external_arg_spec.ml ./syntax/external_arg_spec.mli ./syntax/external_ffi_types.ml ./syntax/external_ffi_types.mli ./syntax/ppx_apply.ml ./syntax/ppx_entry.ml ./syntax/reactjs_jsx_ppx_v3.ml ./syntax/typemod_hide.ml \ No newline at end of file +../lib/4.06.1/whole_compiler.ml: ../ocaml/bytecomp/lambda.ml ../ocaml/bytecomp/lambda.mli ../ocaml/bytecomp/matching.ml ../ocaml/bytecomp/matching.mli ../ocaml/bytecomp/printlambda.ml ../ocaml/bytecomp/printlambda.mli ../ocaml/bytecomp/switch.ml ../ocaml/bytecomp/switch.mli ../ocaml/bytecomp/translattribute.ml ../ocaml/bytecomp/translattribute.mli ../ocaml/bytecomp/translclass.ml ../ocaml/bytecomp/translclass.mli ../ocaml/bytecomp/translcore.ml ../ocaml/bytecomp/translcore.mli ../ocaml/bytecomp/translmod.ml ../ocaml/bytecomp/translmod.mli ../ocaml/bytecomp/translobj.ml ../ocaml/bytecomp/translobj.mli ../ocaml/parsing/ast_helper.ml ../ocaml/parsing/ast_helper.mli ../ocaml/parsing/ast_iterator.ml ../ocaml/parsing/ast_iterator.mli ../ocaml/parsing/ast_mapper.ml ../ocaml/parsing/ast_mapper.mli ../ocaml/parsing/asttypes.mli ../ocaml/parsing/attr_helper.ml ../ocaml/parsing/attr_helper.mli ../ocaml/parsing/builtin_attributes.ml ../ocaml/parsing/builtin_attributes.mli ../ocaml/parsing/depend.ml ../ocaml/parsing/depend.mli ../ocaml/parsing/docstrings.ml ../ocaml/parsing/docstrings.mli ../ocaml/parsing/lexer.ml ../ocaml/parsing/lexer.mli ../ocaml/parsing/location.ml ../ocaml/parsing/location.mli ../ocaml/parsing/longident.ml ../ocaml/parsing/longident.mli ../ocaml/parsing/parse.ml ../ocaml/parsing/parse.mli ../ocaml/parsing/parser.ml ../ocaml/parsing/parser.mli ../ocaml/parsing/parsetree.mli ../ocaml/parsing/pprintast.ml ../ocaml/parsing/pprintast.mli ../ocaml/parsing/printast.ml ../ocaml/parsing/printast.mli ../ocaml/parsing/syntaxerr.ml ../ocaml/parsing/syntaxerr.mli ../ocaml/typing/annot.mli ../ocaml/typing/btype.ml ../ocaml/typing/btype.mli ../ocaml/typing/cmi_format.ml ../ocaml/typing/cmi_format.mli ../ocaml/typing/cmt_format.ml ../ocaml/typing/cmt_format.mli ../ocaml/typing/ctype.ml ../ocaml/typing/ctype.mli ../ocaml/typing/datarepr.ml ../ocaml/typing/datarepr.mli ../ocaml/typing/env.ml ../ocaml/typing/env.mli ../ocaml/typing/ident.ml ../ocaml/typing/ident.mli ../ocaml/typing/includeclass.ml ../ocaml/typing/includeclass.mli ../ocaml/typing/includecore.ml ../ocaml/typing/includecore.mli ../ocaml/typing/includemod.ml ../ocaml/typing/includemod.mli ../ocaml/typing/mtype.ml ../ocaml/typing/mtype.mli ../ocaml/typing/oprint.ml ../ocaml/typing/oprint.mli ../ocaml/typing/outcometree.mli ../ocaml/typing/parmatch.ml ../ocaml/typing/parmatch.mli ../ocaml/typing/path.ml ../ocaml/typing/path.mli ../ocaml/typing/predef.ml ../ocaml/typing/predef.mli ../ocaml/typing/primitive.ml ../ocaml/typing/primitive.mli ../ocaml/typing/printtyp.ml ../ocaml/typing/printtyp.mli ../ocaml/typing/printtyped.ml ../ocaml/typing/printtyped.mli ../ocaml/typing/stypes.ml ../ocaml/typing/stypes.mli ../ocaml/typing/subst.ml ../ocaml/typing/subst.mli ../ocaml/typing/tast_mapper.ml ../ocaml/typing/tast_mapper.mli ../ocaml/typing/typeclass.ml ../ocaml/typing/typeclass.mli ../ocaml/typing/typecore.ml ../ocaml/typing/typecore.mli ../ocaml/typing/typedecl.ml ../ocaml/typing/typedecl.mli ../ocaml/typing/typedtree.ml ../ocaml/typing/typedtree.mli ../ocaml/typing/typedtreeIter.ml ../ocaml/typing/typedtreeIter.mli ../ocaml/typing/typemod.ml ../ocaml/typing/typemod.mli ../ocaml/typing/typeopt.ml ../ocaml/typing/typeopt.mli ../ocaml/typing/types.ml ../ocaml/typing/types.mli ../ocaml/typing/typetexp.ml ../ocaml/typing/typetexp.mli ../ocaml/typing/untypeast.ml ../ocaml/typing/untypeast.mli ../ocaml/utils/arg_helper.ml ../ocaml/utils/arg_helper.mli ../ocaml/utils/ccomp.ml ../ocaml/utils/ccomp.mli ../ocaml/utils/clflags.ml ../ocaml/utils/clflags.mli ../ocaml/utils/consistbl.ml ../ocaml/utils/consistbl.mli ../ocaml/utils/identifiable.ml ../ocaml/utils/identifiable.mli ../ocaml/utils/misc.ml ../ocaml/utils/misc.mli ../ocaml/utils/numbers.ml ../ocaml/utils/numbers.mli ../ocaml/utils/profile.ml ../ocaml/utils/profile.mli ../ocaml/utils/tbl.ml ../ocaml/utils/tbl.mli ../ocaml/utils/warnings.ml ../ocaml/utils/warnings.mli ./common/bs_loc.ml ./common/bs_loc.mli ./common/bs_version.ml ./common/bs_version.mli ./common/bs_warnings.ml ./common/bs_warnings.mli ./common/ext_log.ml ./common/ext_log.mli ./common/js_config.ml ./common/js_config.mli ./common/lam_methname.ml ./common/lam_methname.mli ./common/ml_binary.ml ./common/ml_binary.mli ./core/bs_cmi_load.ml ./core/bs_conditional_initial.ml ./core/bs_conditional_initial.mli ./core/cmd_ast_exception.ml ./core/cmd_ppx_apply.ml ./core/compile_rec_module.ml ./core/config_util.ml ./core/config_util.mli ./core/config_whole_compiler.ml ./core/config_whole_compiler.mli ./core/j.ml ./core/js_analyzer.ml ./core/js_analyzer.mli ./core/js_arr.ml ./core/js_arr.mli ./core/js_ast_util.ml ./core/js_ast_util.mli ./core/js_block_runtime.ml ./core/js_block_runtime.mli ./core/js_call_info.ml ./core/js_call_info.mli ./core/js_closure.ml ./core/js_closure.mli ./core/js_cmj_format.ml ./core/js_cmj_format.mli ./core/js_cmj_load.ml ./core/js_cmj_load.mli ./core/js_cmj_load_builtin_unit.ml ./core/js_dump.ml ./core/js_dump.mli ./core/js_dump_import_export.ml ./core/js_dump_import_export.mli ./core/js_dump_lit.ml ./core/js_dump_program.ml ./core/js_dump_program.mli ./core/js_dump_property.ml ./core/js_dump_property.mli ./core/js_dump_string.ml ./core/js_dump_string.mli ./core/js_exp_make.ml ./core/js_exp_make.mli ./core/js_fold.ml ./core/js_fold_basic.ml ./core/js_fold_basic.mli ./core/js_fun_env.ml ./core/js_fun_env.mli ./core/js_implementation.ml ./core/js_implementation.mli ./core/js_long.ml ./core/js_long.mli ./core/js_map.ml ./core/js_name_of_module_id.ml ./core/js_name_of_module_id.mli ./core/js_number.ml ./core/js_number.mli ./core/js_of_lam_array.ml ./core/js_of_lam_array.mli ./core/js_of_lam_block.ml ./core/js_of_lam_block.mli ./core/js_of_lam_exception.ml ./core/js_of_lam_exception.mli ./core/js_of_lam_option.ml ./core/js_of_lam_option.mli ./core/js_of_lam_string.ml ./core/js_of_lam_string.mli ./core/js_of_lam_variant.ml ./core/js_of_lam_variant.mli ./core/js_op.ml ./core/js_op_util.ml ./core/js_op_util.mli ./core/js_output.ml ./core/js_output.mli ./core/js_packages_info.ml ./core/js_packages_info.mli ./core/js_packages_state.ml ./core/js_packages_state.mli ./core/js_pass_debug.ml ./core/js_pass_debug.mli ./core/js_pass_flatten.ml ./core/js_pass_flatten.mli ./core/js_pass_flatten_and_mark_dead.ml ./core/js_pass_flatten_and_mark_dead.mli ./core/js_pass_get_used.ml ./core/js_pass_get_used.mli ./core/js_pass_scope.ml ./core/js_pass_scope.mli ./core/js_pass_tailcall_inline.ml ./core/js_pass_tailcall_inline.mli ./core/js_raw_info.ml ./core/js_shake.ml ./core/js_shake.mli ./core/js_stmt_make.ml ./core/js_stmt_make.mli ./core/lam.ml ./core/lam.mli ./core/lam_analysis.ml ./core/lam_analysis.mli ./core/lam_arity.ml ./core/lam_arity.mli ./core/lam_arity_analysis.ml ./core/lam_arity_analysis.mli ./core/lam_beta_reduce.ml ./core/lam_beta_reduce.mli ./core/lam_beta_reduce_util.ml ./core/lam_beta_reduce_util.mli ./core/lam_bounded_vars.ml ./core/lam_bounded_vars.mli ./core/lam_closure.ml ./core/lam_closure.mli ./core/lam_coercion.ml ./core/lam_coercion.mli ./core/lam_compat.ml ./core/lam_compat.mli ./core/lam_compile.ml ./core/lam_compile.mli ./core/lam_compile_const.ml ./core/lam_compile_const.mli ./core/lam_compile_context.ml ./core/lam_compile_context.mli ./core/lam_compile_env.ml ./core/lam_compile_env.mli ./core/lam_compile_external_call.ml ./core/lam_compile_external_call.mli ./core/lam_compile_external_obj.ml ./core/lam_compile_external_obj.mli ./core/lam_compile_main.ml ./core/lam_compile_main.mli ./core/lam_compile_primitive.ml ./core/lam_compile_primitive.mli ./core/lam_compile_util.ml ./core/lam_compile_util.mli ./core/lam_constant.ml ./core/lam_constant.mli ./core/lam_constant_convert.ml ./core/lam_constant_convert.mli ./core/lam_convert.ml ./core/lam_convert.mli ./core/lam_dce.ml ./core/lam_dce.mli ./core/lam_dispatch_primitive.ml ./core/lam_dispatch_primitive.mli ./core/lam_eta_conversion.ml ./core/lam_eta_conversion.mli ./core/lam_exit_code.ml ./core/lam_exit_code.mli ./core/lam_exit_count.ml ./core/lam_exit_count.mli ./core/lam_free_variables.ml ./core/lam_free_variables.mli ./core/lam_group.ml ./core/lam_group.mli ./core/lam_hit.ml ./core/lam_hit.mli ./core/lam_id_kind.ml ./core/lam_id_kind.mli ./core/lam_iter.ml ./core/lam_iter.mli ./core/lam_module_ident.ml ./core/lam_module_ident.mli ./core/lam_pass_alpha_conversion.ml ./core/lam_pass_alpha_conversion.mli ./core/lam_pass_collect.ml ./core/lam_pass_collect.mli ./core/lam_pass_count.ml ./core/lam_pass_count.mli ./core/lam_pass_deep_flatten.ml ./core/lam_pass_deep_flatten.mli ./core/lam_pass_eliminate_ref.ml ./core/lam_pass_eliminate_ref.mli ./core/lam_pass_exits.ml ./core/lam_pass_exits.mli ./core/lam_pass_lets_dce.ml ./core/lam_pass_lets_dce.mli ./core/lam_pass_remove_alias.ml ./core/lam_pass_remove_alias.mli ./core/lam_pointer_info.ml ./core/lam_pointer_info.mli ./core/lam_primitive.ml ./core/lam_primitive.mli ./core/lam_print.ml ./core/lam_print.mli ./core/lam_scc.ml ./core/lam_scc.mli ./core/lam_stats.ml ./core/lam_stats.mli ./core/lam_stats_export.ml ./core/lam_stats_export.mli ./core/lam_subst.ml ./core/lam_subst.mli ./core/lam_tag_info.ml ./core/lam_util.ml ./core/lam_util.mli ./core/lam_var_stats.ml ./core/lam_var_stats.mli ./core/matching_polyfill.ml ./core/matching_polyfill.mli ./core/polyvar_pattern_match.ml ./core/pparse_driver.ml ./core/pparse_driver.mli ./core/record_attributes_check.ml ./core/res_compmisc.ml ./core/res_compmisc.mli ./core/transl_single_field_record.ml ./depends/ast_extract.ml ./depends/ast_extract.mli ./depends/binary_ast.ml ./depends/binary_ast.mli ./depends/bs_exception.ml ./depends/bs_exception.mli ./ext/bsc_args.ml ./ext/bsc_args.mli ./ext/bsc_warnings.ml ./ext/ext_array.ml ./ext/ext_array.mli ./ext/ext_buffer.ml ./ext/ext_buffer.mli ./ext/ext_bytes.ml ./ext/ext_bytes.mli ./ext/ext_char.ml ./ext/ext_char.mli ./ext/ext_digest.ml ./ext/ext_digest.mli ./ext/ext_file_extensions.ml ./ext/ext_filename.ml ./ext/ext_filename.mli ./ext/ext_fmt.ml ./ext/ext_ident.ml ./ext/ext_ident.mli ./ext/ext_int.ml ./ext/ext_int.mli ./ext/ext_io.ml ./ext/ext_io.mli ./ext/ext_js_file_kind.ml ./ext/ext_js_suffix.ml ./ext/ext_list.ml ./ext/ext_list.mli ./ext/ext_marshal.ml ./ext/ext_marshal.mli ./ext/ext_modulename.ml ./ext/ext_modulename.mli ./ext/ext_namespace.ml ./ext/ext_namespace.mli ./ext/ext_namespace_encode.ml ./ext/ext_namespace_encode.mli ./ext/ext_option.ml ./ext/ext_option.mli ./ext/ext_path.ml ./ext/ext_path.mli ./ext/ext_pervasives.ml ./ext/ext_pervasives.mli ./ext/ext_pp.ml ./ext/ext_pp.mli ./ext/ext_pp_scope.ml ./ext/ext_pp_scope.mli ./ext/ext_ref.ml ./ext/ext_ref.mli ./ext/ext_scc.ml ./ext/ext_scc.mli ./ext/ext_spec.ml ./ext/ext_spec.mli ./ext/ext_string.ml ./ext/ext_string.mli ./ext/ext_string_array.ml ./ext/ext_string_array.mli ./ext/ext_sys.ml ./ext/ext_sys.mli ./ext/ext_utf8.ml ./ext/ext_utf8.mli ./ext/ext_util.ml ./ext/ext_util.mli ./ext/hash.ml ./ext/hash.mli ./ext/hash_gen.ml ./ext/hash_ident.ml ./ext/hash_ident.mli ./ext/hash_int.ml ./ext/hash_int.mli ./ext/hash_set.ml ./ext/hash_set.mli ./ext/hash_set_gen.ml ./ext/hash_set_ident.ml ./ext/hash_set_ident.mli ./ext/hash_set_ident_mask.ml ./ext/hash_set_ident_mask.mli ./ext/hash_set_poly.ml ./ext/hash_set_poly.mli ./ext/hash_set_string.ml ./ext/hash_set_string.mli ./ext/hash_string.ml ./ext/hash_string.mli ./ext/int_vec_util.ml ./ext/int_vec_util.mli ./ext/int_vec_vec.ml ./ext/int_vec_vec.mli ./ext/js_reserved_map.ml ./ext/js_reserved_map.mli ./ext/js_runtime_modules.ml ./ext/literals.ml ./ext/map_gen.ml ./ext/map_gen.mli ./ext/map_ident.ml ./ext/map_ident.mli ./ext/map_int.ml ./ext/map_int.mli ./ext/map_string.ml ./ext/map_string.mli ./ext/ordered_hash_map_gen.ml ./ext/ordered_hash_map_local_ident.ml ./ext/ordered_hash_map_local_ident.mli ./ext/set_gen.ml ./ext/set_gen.mli ./ext/set_ident.ml ./ext/set_ident.mli ./ext/set_string.ml ./ext/set_string.mli ./ext/vec.ml ./ext/vec.mli ./ext/vec_gen.ml ./ext/vec_int.ml ./ext/vec_int.mli ./js_parser/declaration_parser.ml ./js_parser/enum_common.ml ./js_parser/enum_parser.ml ./js_parser/expression_parser.ml ./js_parser/file_key.ml ./js_parser/flow_ast.ml ./js_parser/flow_ast_utils.ml ./js_parser/flow_ast_utils.mli ./js_parser/flow_lexer.ml ./js_parser/flow_lexer.mli ./js_parser/jsx_parser.ml ./js_parser/lex_env.ml ./js_parser/lex_result.ml ./js_parser/loc.ml ./js_parser/loc.mli ./js_parser/object_parser.ml ./js_parser/parse_error.ml ./js_parser/parser_common.ml ./js_parser/parser_env.ml ./js_parser/parser_env.mli ./js_parser/parser_flow.ml ./js_parser/pattern_cover.ml ./js_parser/pattern_parser.ml ./js_parser/sedlexing.ml ./js_parser/sedlexing.mli ./js_parser/statement_parser.ml ./js_parser/token.ml ./js_parser/type_parser.ml ./js_parser/wtf8.ml ./js_parser/wtf8.mli ./main/builtin_cmi_datasets.ml ./main/builtin_cmi_datasets.mli ./main/builtin_cmj_datasets.ml ./main/builtin_cmj_datasets.mli ./main/js_main.ml ./main/js_main.mli ./napkin/reactjs_jsx_ppx_v3.ml ./napkin/reactjs_jsx_ppx_v3.mli ./napkin/res_ast_conversion.ml ./napkin/res_ast_conversion.mli ./napkin/res_character_codes.ml ./napkin/res_comment.ml ./napkin/res_comment.mli ./napkin/res_comments_table.ml ./napkin/res_core.ml ./napkin/res_core.mli ./napkin/res_diagnostics.ml ./napkin/res_diagnostics.mli ./napkin/res_diagnostics_printing_utils.ml ./napkin/res_doc.ml ./napkin/res_doc.mli ./napkin/res_driver.ml ./napkin/res_driver.mli ./napkin/res_driver_ml_parser.ml ./napkin/res_driver_ml_parser.mli ./napkin/res_driver_reason_binary.ml ./napkin/res_driver_reason_binary.mli ./napkin/res_grammar.ml ./napkin/res_io.ml ./napkin/res_io.mli ./napkin/res_js_ffi.ml ./napkin/res_minibuffer.ml ./napkin/res_minibuffer.mli ./napkin/res_multi_printer.ml ./napkin/res_multi_printer.mli ./napkin/res_outcome_printer.ml ./napkin/res_outcome_printer.mli ./napkin/res_parens.ml ./napkin/res_parens.mli ./napkin/res_parser.ml ./napkin/res_parser.mli ./napkin/res_parsetree_viewer.ml ./napkin/res_parsetree_viewer.mli ./napkin/res_printer.ml ./napkin/res_printer.mli ./napkin/res_reporting.ml ./napkin/res_scanner.ml ./napkin/res_scanner.mli ./napkin/res_token.ml ./outcome_printer/outcome_printer_ns.ml ./outcome_printer/outcome_printer_ns.mli ./outcome_printer/reason_outcome_printer_main.ml ./outcome_printer/reason_syntax_util.ml ./outcome_printer/reason_syntax_util.mli ./outcome_printer/tweaked_reason_oprint.ml ./stubs/bs_hash_stubs.ml ./super_errors/super_env.ml ./super_errors/super_location.ml ./super_errors/super_location.mli ./super_errors/super_main.ml ./super_errors/super_misc.ml ./super_errors/super_misc.mli ./super_errors/super_pparse.ml ./super_errors/super_typecore.ml ./super_errors/super_typemod.ml ./super_errors/super_typetexp.ml ./syntax/ast_attributes.ml ./syntax/ast_attributes.mli ./syntax/ast_bs_open.ml ./syntax/ast_bs_open.mli ./syntax/ast_comb.ml ./syntax/ast_comb.mli ./syntax/ast_compatible.ml ./syntax/ast_compatible.mli ./syntax/ast_config.ml ./syntax/ast_config.mli ./syntax/ast_core_type.ml ./syntax/ast_core_type.mli ./syntax/ast_core_type_class_type.ml ./syntax/ast_core_type_class_type.mli ./syntax/ast_derive.ml ./syntax/ast_derive.mli ./syntax/ast_derive_abstract.ml ./syntax/ast_derive_abstract.mli ./syntax/ast_derive_js_mapper.ml ./syntax/ast_derive_js_mapper.mli ./syntax/ast_derive_projector.ml ./syntax/ast_derive_projector.mli ./syntax/ast_derive_util.ml ./syntax/ast_derive_util.mli ./syntax/ast_exp.ml ./syntax/ast_exp.mli ./syntax/ast_exp_apply.ml ./syntax/ast_exp_apply.mli ./syntax/ast_exp_extension.ml ./syntax/ast_exp_extension.mli ./syntax/ast_exp_handle_external.ml ./syntax/ast_exp_handle_external.mli ./syntax/ast_external.ml ./syntax/ast_external.mli ./syntax/ast_external_mk.ml ./syntax/ast_external_mk.mli ./syntax/ast_external_process.ml ./syntax/ast_external_process.mli ./syntax/ast_literal.ml ./syntax/ast_literal.mli ./syntax/ast_open_cxt.ml ./syntax/ast_open_cxt.mli ./syntax/ast_pat.ml ./syntax/ast_pat.mli ./syntax/ast_payload.ml ./syntax/ast_payload.mli ./syntax/ast_polyvar.ml ./syntax/ast_polyvar.mli ./syntax/ast_reason_pp.ml ./syntax/ast_reason_pp.mli ./syntax/ast_signature.ml ./syntax/ast_signature.mli ./syntax/ast_structure.ml ./syntax/ast_structure.mli ./syntax/ast_tdcls.ml ./syntax/ast_tdcls.mli ./syntax/ast_tuple_pattern_flatten.ml ./syntax/ast_tuple_pattern_flatten.mli ./syntax/ast_typ_uncurry.ml ./syntax/ast_typ_uncurry.mli ./syntax/ast_uncurry_apply.ml ./syntax/ast_uncurry_apply.mli ./syntax/ast_uncurry_gen.ml ./syntax/ast_uncurry_gen.mli ./syntax/ast_utf8_string.ml ./syntax/ast_utf8_string.mli ./syntax/ast_utf8_string_interp.ml ./syntax/ast_utf8_string_interp.mli ./syntax/ast_util.ml ./syntax/ast_util.mli ./syntax/bs_ast_invariant.ml ./syntax/bs_ast_invariant.mli ./syntax/bs_ast_mapper.ml ./syntax/bs_ast_mapper.mli ./syntax/bs_builtin_ppx.ml ./syntax/bs_builtin_ppx.mli ./syntax/bs_flow_ast_utils.ml ./syntax/bs_flow_ast_utils.mli ./syntax/bs_syntaxerr.ml ./syntax/bs_syntaxerr.mli ./syntax/classify_function.ml ./syntax/classify_function.mli ./syntax/external_arg_spec.ml ./syntax/external_arg_spec.mli ./syntax/external_ffi_types.ml ./syntax/external_ffi_types.mli ./syntax/ppx_apply.ml ./syntax/ppx_entry.ml ./syntax/typemod_hide.ml \ No newline at end of file diff --git a/syntax b/syntax index b82cabc71e..de8eb1dcf9 160000 --- a/syntax +++ b/syntax @@ -1 +1 @@ -Subproject commit b82cabc71e76bb6885dad3a254cdc581eea80784 +Subproject commit de8eb1dcf9376bd934fb3b23f8211bb0b06f370f From 9069f7ce9a359e6b978a481856d15ad613c60d1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Cha=CC=81varri?= Date: Sat, 24 Oct 2020 09:32:20 +0200 Subject: [PATCH 3/4] add napkin as deps for compiler --- jscomp/snapshot.ninja | 4 +- lib/4.06.1/unstable/js_compiler.ml | 926 +++++++++++++++++++++ lib/4.06.1/unstable/js_compiler.ml.d | 2 +- lib/4.06.1/unstable/js_refmt_compiler.ml | 926 +++++++++++++++++++++ lib/4.06.1/unstable/js_refmt_compiler.ml.d | 2 +- 5 files changed, 1856 insertions(+), 4 deletions(-) diff --git a/jscomp/snapshot.ninja b/jscomp/snapshot.ninja index cd3200e6b9..48ae2a6cb9 100644 --- a/jscomp/snapshot.ninja +++ b/jscomp/snapshot.ninja @@ -47,11 +47,11 @@ o $SNAP/unstable/bspack.ml: bspack | ./bin/bspack.exe $LTO main = Bspack_main o $SNAP/unstable/js_compiler.ml: bspack | ./bin/bspack.exe $LTO - flags = -D BS_BROWSER=true -bs-MD -module-alias Config=Config_whole_compiler -bs-exclude-I config -I $OCAML_SRC_UTILS -I $OCAML_SRC_PARSING -I $OCAML_SRC_TYPING -I $OCAML_SRC_BYTECOMP -I $OCAML_SRC_DRIVER -I stubs -I ext -I syntax -I depends -I common -I core -I super_errors -I bsb -I outcome_printer -I js_parser -I main + flags = -D BS_BROWSER=true -bs-MD -module-alias Config=Config_whole_compiler -bs-exclude-I config -I $OCAML_SRC_UTILS -I $OCAML_SRC_PARSING -I $OCAML_SRC_TYPING -I $OCAML_SRC_BYTECOMP -I $OCAML_SRC_DRIVER -I stubs -I ext -I napkin -I syntax -I depends -I common -I core -I super_errors -I bsb -I outcome_printer -I js_parser -I main main = Jsoo_main o $SNAP/unstable/js_refmt_compiler.ml: bspack | ./bin/bspack.exe $LTO - flags = -D BS_BROWSER=true -bs-MD -module-alias Config=Config_whole_compiler -bs-exclude-I config -I $OCAML_SRC_UTILS -I $OCAML_SRC_PARSING -I $OCAML_SRC_TYPING -I $OCAML_SRC_BYTECOMP -I $OCAML_SRC_DRIVER -I js_parser -I stubs -I ext -I syntax -I depends -I common -I core -I super_errors -I bsb -I outcome_printer -I js_parser -I main -I refmt + flags = -D BS_BROWSER=true -bs-MD -module-alias Config=Config_whole_compiler -bs-exclude-I config -I $OCAML_SRC_UTILS -I $OCAML_SRC_PARSING -I $OCAML_SRC_TYPING -I $OCAML_SRC_BYTECOMP -I $OCAML_SRC_DRIVER -I js_parser -I stubs -I ext -I napkin -I syntax -I depends -I common -I core -I super_errors -I bsb -I outcome_printer -I js_parser -I main -I refmt main = Jsoo_refmt_main subninja build.ninja diff --git a/lib/4.06.1/unstable/js_compiler.ml b/lib/4.06.1/unstable/js_compiler.ml index 3edbf175c8..2c7c8b7c22 100644 --- a/lib/4.06.1/unstable/js_compiler.ml +++ b/lib/4.06.1/unstable/js_compiler.ml @@ -408271,6 +408271,932 @@ let mapper : mapper = +end +module Reactjs_jsx_ppx_v3 : sig +#1 "reactjs_jsx_ppx_v3.mli" +(* + This is the module that handles turning Reason JSX' agnostic function call into + a ReasonReact-specific function call. Aka, this is a macro, using OCaml's ppx + facilities; https://whitequark.org/blog/2014/04/16/a-guide-to-extension- + points-in-ocaml/ + You wouldn't use this file directly; it's used by ReScript's + bsconfig.json. Specifically, there's a field called `react-jsx` inside the + field `reason`, which enables this ppx through some internal call in bsb +*) + +(* + There are two different transforms that can be selected in this file (v2 and v3): + v2: + transform `[@JSX] div(~props1=a, ~props2=b, ~children=[foo, bar], ())` into + `ReactDOMRe.createElement("div", ~props={"props1": 1, "props2": b}, [|foo, + bar|])`. + transform `[@JSX] div(~props1=a, ~props2=b, ~children=foo, ())` into + `ReactDOMRe.createElementVariadic("div", ~props={"props1": 1, "props2": b}, foo)`. + transform the upper-cased case + `[@JSX] Foo.createElement(~key=a, ~ref=b, ~foo=bar, ~children=[], ())` into + `ReasonReact.element(~key=a, ~ref=b, Foo.make(~foo=bar, [||]))` + transform `[@JSX] [foo]` into + `ReactDOMRe.createElement(ReasonReact.fragment, [|foo|])` + v3: + transform `[@JSX] div(~props1=a, ~props2=b, ~children=[foo, bar], ())` into + `ReactDOMRe.createDOMElementVariadic("div", ReactDOMRe.domProps(~props1=1, ~props2=b), [|foo, bar|])`. + transform the upper-cased case + `[@JSX] Foo.createElement(~key=a, ~ref=b, ~foo=bar, ~children=[], ())` into + `React.createElement(Foo.make, Foo.makeProps(~key=a, ~ref=b, ~foo=bar, ()))` + transform the upper-cased case + `[@JSX] Foo.createElement(~foo=bar, ~children=[foo, bar], ())` into + `React.createElementVariadic(Foo.make, Foo.makeProps(~foo=bar, ~children=React.null, ()), [|foo, bar|])` + transform `[@JSX] [foo]` into + `ReactDOMRe.createElement(ReasonReact.fragment, [|foo|])` +*) + +val rewrite_implementation : Parsetree.structure -> Parsetree.structure + +val rewrite_signature : Parsetree.signature -> Parsetree.signature + +end = struct +#1 "reactjs_jsx_ppx_v3.ml" +open Ast_helper +open Ast_mapper +open Asttypes +open Parsetree +open Longident + +let rec find_opt p = function [] -> None | x :: l -> if p x then Some x else find_opt p l + +let nolabel = Nolabel + +let labelled str = Labelled str + +let optional str = Optional str + +let isOptional str = match str with Optional _ -> true | _ -> false + +let isLabelled str = match str with Labelled _ -> true | _ -> false + +let getLabel str = match str with Optional str | Labelled str -> str | Nolabel -> "" + +let optionIdent = Lident "option" + +let constantString ~loc str = Ast_helper.Exp.constant ~loc (Pconst_string (str, None)) + +let safeTypeFromValue valueStr = + let valueStr = getLabel valueStr in + match String.sub valueStr 0 1 with "_" -> "T" ^ valueStr | _ -> valueStr + [@@raises Invalid_argument] + +let keyType loc = Typ.constr ~loc { loc; txt = optionIdent } [ Typ.constr ~loc { loc; txt = Lident "string" } [] ] + +type 'a children = ListLiteral of 'a | Exact of 'a + +type componentConfig = { propsName : string } + +(* if children is a list, convert it to an array while mapping each element. If not, just map over it, as usual *) +let transformChildrenIfListUpper ~loc ~mapper theList = + let rec transformChildren_ theList accum = + (* not in the sense of converting a list to an array; convert the AST + reprensentation of a list to the AST reprensentation of an array *) + match theList with + | { pexp_desc = Pexp_construct ({ txt = Lident "[]" }, None) } -> ( + match accum with + | [ singleElement ] -> Exact singleElement + | accum -> ListLiteral (Exp.array ~loc (List.rev accum)) ) + | { pexp_desc = Pexp_construct ({ txt = Lident "::" }, Some { pexp_desc = Pexp_tuple [ v; acc ] }) } -> + transformChildren_ acc (mapper.expr mapper v :: accum) + | notAList -> Exact (mapper.expr mapper notAList) + in + transformChildren_ theList [] + +let transformChildrenIfList ~loc ~mapper theList = + let rec transformChildren_ theList accum = + (* not in the sense of converting a list to an array; convert the AST + reprensentation of a list to the AST reprensentation of an array *) + match theList with + | { pexp_desc = Pexp_construct ({ txt = Lident "[]" }, None) } -> Exp.array ~loc (List.rev accum) + | { pexp_desc = Pexp_construct ({ txt = Lident "::" }, Some { pexp_desc = Pexp_tuple [ v; acc ] }) } -> + transformChildren_ acc (mapper.expr mapper v :: accum) + | notAList -> mapper.expr mapper notAList + in + transformChildren_ theList [] + +let extractChildren ?(removeLastPositionUnit = false) ~loc propsAndChildren = + let rec allButLast_ lst acc = + match lst with + | [] -> [] + | [ (Nolabel, { pexp_desc = Pexp_construct ({ txt = Lident "()" }, None) }) ] -> acc + | (Nolabel, _) :: _rest -> raise (Invalid_argument "JSX: found non-labelled argument before the last position") + | arg :: rest -> allButLast_ rest (arg :: acc) + [@@raises Invalid_argument] + in + let allButLast lst = allButLast_ lst [] |> List.rev [@@raises Invalid_argument] in + match List.partition (fun (label, _) -> label = labelled "children") propsAndChildren with + | [], props -> + (* no children provided? Place a placeholder list *) + (Exp.construct ~loc { loc; txt = Lident "[]" } None, if removeLastPositionUnit then allButLast props else props) + | [ (_, childrenExpr) ], props -> (childrenExpr, if removeLastPositionUnit then allButLast props else props) + | _ -> raise (Invalid_argument "JSX: somehow there's more than one `children` label") + [@@raises Invalid_argument] + +let unerasableIgnore loc = ({ loc; txt = "warning" }, PStr [ Str.eval (Exp.constant (Pconst_string ("-16", None))) ]) + +let merlinFocus = ({ loc = Location.none; txt = "merlin.focus" }, PStr []) + +(* Helper method to look up the [@react.component] attribute *) +let hasAttr (loc, _) = loc.txt = "react.component" + +(* Helper method to filter out any attribute that isn't [@react.component] *) +let otherAttrsPure (loc, _) = loc.txt <> "react.component" + +(* Iterate over the attributes and try to find the [@react.component] attribute *) +let hasAttrOnBinding { pvb_attributes } = find_opt hasAttr pvb_attributes <> None + +(* Finds the name of the variable the binding is assigned to, otherwise raises Invalid_argument *) +let getFnName binding = + match binding with + | { pvb_pat = { ppat_desc = Ppat_var { txt } } } -> txt + | _ -> raise (Invalid_argument "react.component calls cannot be destructured.") + [@@raises Invalid_argument] + +let makeNewBinding binding expression newName = + match binding with + | { pvb_pat = { ppat_desc = Ppat_var ppat_var } as pvb_pat } -> + { + binding with + pvb_pat = { pvb_pat with ppat_desc = Ppat_var { ppat_var with txt = newName } }; + pvb_expr = expression; + pvb_attributes = [ merlinFocus ]; + } + | _ -> raise (Invalid_argument "react.component calls cannot be destructured.") + [@@raises Invalid_argument] + +(* Lookup the value of `props` otherwise raise Invalid_argument error *) +let getPropsNameValue _acc (loc, exp) = + match (loc, exp) with + | { txt = Lident "props" }, { pexp_desc = Pexp_ident { txt = Lident str } } -> { propsName = str } + | { txt }, _ -> + raise (Invalid_argument ("react.component only accepts props as an option, given: " ^ Longident.last txt)) + [@@raises Invalid_argument] + +(* Lookup the `props` record or string as part of [@react.component] and store the name for use when rewriting *) +let getPropsAttr payload = + let defaultProps = { propsName = "Props" } in + match payload with + | Some (PStr ({ pstr_desc = Pstr_eval ({ pexp_desc = Pexp_record (recordFields, None) }, _) } :: _rest)) -> + List.fold_left getPropsNameValue defaultProps recordFields + | Some (PStr ({ pstr_desc = Pstr_eval ({ pexp_desc = Pexp_ident { txt = Lident "props" } }, _) } :: _rest)) -> + { propsName = "props" } + | Some (PStr ({ pstr_desc = Pstr_eval (_, _) } :: _rest)) -> + raise (Invalid_argument "react.component accepts a record config with props as an options.") + | _ -> defaultProps + [@@raises Invalid_argument] + +(* Plucks the label, loc, and type_ from an AST node *) +let pluckLabelDefaultLocType (label, default, _, _, loc, type_) = (label, default, loc, type_) + +(* Lookup the filename from the location information on the AST node and turn it into a valid module identifier *) +let filenameFromLoc (pstr_loc : Location.t) = + let fileName = match pstr_loc.loc_start.pos_fname with "" -> !Location.input_name | fileName -> fileName in + let fileName = try Filename.chop_extension (Filename.basename fileName) with Invalid_argument _ -> fileName in + let fileName = String.capitalize_ascii fileName in + fileName + +(* Build a string representation of a module name with segments separated by $ *) +let makeModuleName fileName nestedModules fnName = + let fullModuleName = + match (fileName, nestedModules, fnName) with + (* TODO: is this even reachable? It seems like the fileName always exists *) + | "", nestedModules, "make" -> nestedModules + | "", nestedModules, fnName -> List.rev (fnName :: nestedModules) + | fileName, nestedModules, "make" -> fileName :: List.rev nestedModules + | fileName, nestedModules, fnName -> fileName :: List.rev (fnName :: nestedModules) + in + let fullModuleName = String.concat "$" fullModuleName in + fullModuleName + +(* + AST node builders + These functions help us build AST nodes that are needed when transforming a [@react.component] into a + constructor and a props external +*) + +(* Build an AST node representing all named args for the `external` definition for a component's props *) +let rec recursivelyMakeNamedArgsForExternal list args = + match list with + | (label, default, loc, interiorType) :: tl -> + recursivelyMakeNamedArgsForExternal tl + (Typ.arrow ~loc label + ( match (label, interiorType, default) with + (* ~foo=1 *) + | label, None, Some _ -> + { ptyp_desc = Ptyp_var (safeTypeFromValue label); ptyp_loc = loc; ptyp_attributes = [] } + (* ~foo: int=1 *) + | _label, Some type_, Some _ -> type_ + (* ~foo: option(int)=? *) + | label, Some { ptyp_desc = Ptyp_constr ({ txt = Lident "option" }, [ type_ ]) }, _ + | label, Some { ptyp_desc = Ptyp_constr ({ txt = Ldot (Lident "*predef*", "option") }, [ type_ ]) }, _ + (* ~foo: int=? - note this isnt valid. but we want to get a type error *) + | label, Some type_, _ + when isOptional label -> + type_ + (* ~foo=? *) + | label, None, _ when isOptional label -> + { ptyp_desc = Ptyp_var (safeTypeFromValue label); ptyp_loc = loc; ptyp_attributes = [] } + (* ~foo *) + | label, None, _ -> { ptyp_desc = Ptyp_var (safeTypeFromValue label); ptyp_loc = loc; ptyp_attributes = [] } + | _label, Some type_, _ -> type_ ) + args) + | [] -> args + [@@raises Invalid_argument] + +(* Build an AST node for the [@bs.obj] representing props for a component *) +let makePropsValue fnName loc namedArgListWithKeyAndRef propsType = + let propsName = fnName ^ "Props" in + { + pval_name = { txt = propsName; loc }; + pval_type = + recursivelyMakeNamedArgsForExternal namedArgListWithKeyAndRef + (Typ.arrow nolabel + { ptyp_desc = Ptyp_constr ({ txt = Lident "unit"; loc }, []); ptyp_loc = loc; ptyp_attributes = [] } + propsType); + pval_prim = [ "" ]; + pval_attributes = [ ({ txt = "bs.obj"; loc }, PStr []) ]; + pval_loc = loc; + } + [@@raises Invalid_argument] + +(* Build an AST node representing an `external` with the definition of the [@bs.obj] *) +let makePropsExternal fnName loc namedArgListWithKeyAndRef propsType = + { pstr_loc = loc; pstr_desc = Pstr_primitive (makePropsValue fnName loc namedArgListWithKeyAndRef propsType) } + [@@raises Invalid_argument] + +(* Build an AST node for the signature of the `external` definition *) +let makePropsExternalSig fnName loc namedArgListWithKeyAndRef propsType = + { psig_loc = loc; psig_desc = Psig_value (makePropsValue fnName loc namedArgListWithKeyAndRef propsType) } + [@@raises Invalid_argument] + +(* Build an AST node for the props name when converted to a Js.t inside the function signature *) +let makePropsName ~loc name = { ppat_desc = Ppat_var { txt = name; loc }; ppat_loc = loc; ppat_attributes = [] } + +let makeObjectField loc (str, attrs, type_) = Otag ({ loc; txt = str }, attrs, type_) + +(* Build an AST node representing a "closed" Js.t object representing a component's props *) +let makePropsType ~loc namedTypeList = + Typ.mk ~loc + (Ptyp_constr + ( { txt = Ldot (Lident "Js", "t"); loc }, + [ + { + ptyp_desc = Ptyp_object (List.map (makeObjectField loc) namedTypeList, Closed); + ptyp_loc = loc; + ptyp_attributes = []; + }; + ] )) + +(* Builds an AST node for the entire `external` definition of props *) +let makeExternalDecl fnName loc namedArgListWithKeyAndRef namedTypeList = + makePropsExternal fnName loc + (List.map pluckLabelDefaultLocType namedArgListWithKeyAndRef) + (makePropsType ~loc namedTypeList) + [@@raises Invalid_argument] + +(* TODO: some line number might still be wrong *) +let jsxMapper () = + let jsxVersion = ref None in + + let transformUppercaseCall3 modulePath mapper loc attrs _ callArguments = + let children, argsWithLabels = extractChildren ~loc ~removeLastPositionUnit:true callArguments in + let argsForMake = argsWithLabels in + let childrenExpr = transformChildrenIfListUpper ~loc ~mapper children in + let recursivelyTransformedArgsForMake = + argsForMake |> List.map (fun (label, expression) -> (label, mapper.expr mapper expression)) + in + let childrenArg = ref None in + let args = + recursivelyTransformedArgsForMake + @ ( match childrenExpr with + | Exact children -> [ (labelled "children", children) ] + | ListLiteral { pexp_desc = Pexp_array list } when list = [] -> [] + | ListLiteral expression -> + (* this is a hack to support react components that introspect into their children *) + childrenArg := Some expression; + [ (labelled "children", Exp.ident ~loc { loc; txt = Ldot (Lident "React", "null") }) ] ) + @ [ (nolabel, Exp.construct ~loc { loc; txt = Lident "()" } None) ] + in + let isCap str = + let first = String.sub str 0 1 [@@raises Invalid_argument] in + let capped = String.uppercase_ascii first in + first = capped + [@@raises Invalid_argument] + in + let ident = + match modulePath with + | Lident _ -> Ldot (modulePath, "make") + | Ldot (_modulePath, value) as fullPath when isCap value -> Ldot (fullPath, "make") + | modulePath -> modulePath + in + let propsIdent = + match ident with + | Lident path -> Lident (path ^ "Props") + | Ldot (ident, path) -> Ldot (ident, path ^ "Props") + | _ -> raise (Invalid_argument "JSX name can't be the result of function applications") + in + let props = Exp.apply ~attrs ~loc (Exp.ident ~loc { loc; txt = propsIdent }) args in + (* handle key, ref, children *) + (* React.createElement(Component.make, props, ...children) *) + match !childrenArg with + | None -> + Exp.apply ~loc ~attrs + (Exp.ident ~loc { loc; txt = Ldot (Lident "React", "createElement") }) + [ (nolabel, Exp.ident ~loc { txt = ident; loc }); (nolabel, props) ] + | Some children -> + Exp.apply ~loc ~attrs + (Exp.ident ~loc { loc; txt = Ldot (Lident "React", "createElementVariadic") }) + [ (nolabel, Exp.ident ~loc { txt = ident; loc }); (nolabel, props); (nolabel, children) ] + [@@raises Invalid_argument] + in + + let transformLowercaseCall3 mapper loc attrs callArguments id = + let children, nonChildrenProps = extractChildren ~loc callArguments in + let componentNameExpr = constantString ~loc id in + let childrenExpr = transformChildrenIfList ~loc ~mapper children in + let createElementCall = + match children with + (* [@JSX] div(~children=[a]), coming from
a
*) + | { + pexp_desc = + ( Pexp_construct ({ txt = Lident "::" }, Some { pexp_desc = Pexp_tuple _ }) + | Pexp_construct ({ txt = Lident "[]" }, None) ); + } -> + "createDOMElementVariadic" + (* [@JSX] div(~children= value), coming from
...(value)
*) + | _ -> + raise + (Invalid_argument + "A spread as a DOM element's children don't make sense written together. You can simply remove the \ + spread.") + in + let args = + match nonChildrenProps with + | [ _justTheUnitArgumentAtEnd ] -> + [ (* "div" *) (nolabel, componentNameExpr); (* [|moreCreateElementCallsHere|] *) (nolabel, childrenExpr) ] + | nonEmptyProps -> + let propsCall = + Exp.apply ~loc + (Exp.ident ~loc { loc; txt = Ldot (Lident "ReactDOMRe", "domProps") }) + (nonEmptyProps |> List.map (fun (label, expression) -> (label, mapper.expr mapper expression))) + in + [ + (* "div" *) + (nolabel, componentNameExpr); + (* ReactDOMRe.props(~className=blabla, ~foo=bar, ()) *) + (labelled "props", propsCall); + (* [|moreCreateElementCallsHere|] *) + (nolabel, childrenExpr); + ] + in + Exp.apply ~loc (* throw away the [@JSX] attribute and keep the others, if any *) ~attrs + (* ReactDOMRe.createElement *) + (Exp.ident ~loc { loc; txt = Ldot (Lident "ReactDOMRe", createElementCall) }) + args + [@@raises Invalid_argument] + in + + let rec recursivelyTransformNamedArgsForMake mapper expr list = + let expr = mapper.expr mapper expr in + match expr.pexp_desc with + (* TODO: make this show up with a loc. *) + | Pexp_fun (Labelled "key", _, _, _) | Pexp_fun (Optional "key", _, _, _) -> + raise + (Invalid_argument + "Key cannot be accessed inside of a component. Don't worry - you can always key a component from its \ + parent!") + | Pexp_fun (Labelled "ref", _, _, _) | Pexp_fun (Optional "ref", _, _, _) -> + raise (Invalid_argument "Ref cannot be passed as a normal prop. Please use `forwardRef` API instead.") + | Pexp_fun (arg, default, pattern, expression) when isOptional arg || isLabelled arg -> + let () = + match (isOptional arg, pattern, default) with + | true, { ppat_desc = Ppat_constraint (_, { ptyp_desc }) }, None -> ( + match ptyp_desc with + | Ptyp_constr ({ txt = Lident "option" }, [ _ ]) -> () + | _ -> + let currentType = + match ptyp_desc with + | Ptyp_constr ({ txt }, []) -> String.concat "." (Longident.flatten txt) + | Ptyp_constr ({ txt }, _innerTypeArgs) -> String.concat "." (Longident.flatten txt) ^ "(...)" + | _ -> "..." + in + Location.prerr_warning pattern.ppat_loc + (Preprocessor + (Printf.sprintf + "ReasonReact: optional argument annotations must have explicit `option`. Did you mean \ + `option(%s)=?`?" + currentType)) ) + | _ -> () + in + let alias = + match pattern with + | { ppat_desc = Ppat_alias (_, { txt }) | Ppat_var { txt } } -> txt + | { ppat_desc = Ppat_any } -> "_" + | _ -> getLabel arg + in + let type_ = match pattern with { ppat_desc = Ppat_constraint (_, type_) } -> Some type_ | _ -> None in + + recursivelyTransformNamedArgsForMake mapper expression + ((arg, default, pattern, alias, pattern.ppat_loc, type_) :: list) + | Pexp_fun (Nolabel, _, { ppat_desc = Ppat_construct ({ txt = Lident "()" }, _) | Ppat_any }, _expression) -> + (list, None) + | Pexp_fun + ( Nolabel, + _, + { ppat_desc = Ppat_var { txt } | Ppat_constraint ({ ppat_desc = Ppat_var { txt } }, _) }, + _expression ) -> + (list, Some txt) + | Pexp_fun (Nolabel, _, pattern, _expression) -> + Location.raise_errorf ~loc:pattern.ppat_loc + "ReasonReact: react.component refs only support plain arguments and type annotations." + | _ -> (list, None) + [@@raises Invalid_argument] + in + + let argToType types (name, default, _noLabelName, _alias, loc, type_) = + match (type_, name, default) with + | Some { ptyp_desc = Ptyp_constr ({ txt = Lident "option" }, [ type_ ]) }, name, _ when isOptional name -> + ( getLabel name, + [], + { type_ with ptyp_desc = Ptyp_constr ({ loc = type_.ptyp_loc; txt = optionIdent }, [ type_ ]) } ) + :: types + | Some type_, name, Some _default -> + ( getLabel name, + [], + { ptyp_desc = Ptyp_constr ({ loc; txt = optionIdent }, [ type_ ]); ptyp_loc = loc; ptyp_attributes = [] } ) + :: types + | Some type_, name, _ -> (getLabel name, [], type_) :: types + | None, name, _ when isOptional name -> + ( getLabel name, + [], + { + ptyp_desc = + Ptyp_constr + ( { loc; txt = optionIdent }, + [ { ptyp_desc = Ptyp_var (safeTypeFromValue name); ptyp_loc = loc; ptyp_attributes = [] } ] ); + ptyp_loc = loc; + ptyp_attributes = []; + } ) + :: types + | None, name, _ when isLabelled name -> + (getLabel name, [], { ptyp_desc = Ptyp_var (safeTypeFromValue name); ptyp_loc = loc; ptyp_attributes = [] }) + :: types + | _ -> types + [@@raises Invalid_argument] + in + + let argToConcreteType types (name, loc, type_) = + match name with + | name when isLabelled name -> (getLabel name, [], type_) :: types + | name when isOptional name -> (getLabel name, [], Typ.constr ~loc { loc; txt = optionIdent } [ type_ ]) :: types + | _ -> types + in + + let nestedModules = ref [] in + let transformComponentDefinition mapper structure returnStructures = + match structure with + (* external *) + | { + pstr_loc; + pstr_desc = Pstr_primitive ({ pval_name = { txt = fnName }; pval_attributes; pval_type } as value_description); + } as pstr -> ( + match List.filter hasAttr pval_attributes with + | [] -> structure :: returnStructures + | [ _ ] -> + let rec getPropTypes types ({ ptyp_loc; ptyp_desc } as fullType) = + match ptyp_desc with + | Ptyp_arrow (name, type_, ({ ptyp_desc = Ptyp_arrow _ } as rest)) when isLabelled name || isOptional name + -> + getPropTypes ((name, ptyp_loc, type_) :: types) rest + | Ptyp_arrow (Nolabel, _type, rest) -> getPropTypes types rest + | Ptyp_arrow (name, type_, returnValue) when isLabelled name || isOptional name -> + (returnValue, (name, returnValue.ptyp_loc, type_) :: types) + | _ -> (fullType, types) + in + let innerType, propTypes = getPropTypes [] pval_type in + let namedTypeList = List.fold_left argToConcreteType [] propTypes in + let pluckLabelAndLoc (label, loc, type_) = (label, None (* default *), loc, Some type_) in + let retPropsType = makePropsType ~loc:pstr_loc namedTypeList in + let externalPropsDecl = + makePropsExternal fnName pstr_loc + ((optional "key", None, pstr_loc, Some (keyType pstr_loc)) :: List.map pluckLabelAndLoc propTypes) + retPropsType + in + (* can't be an arrow because it will defensively uncurry *) + let newExternalType = + Ptyp_constr ({ loc = pstr_loc; txt = Ldot (Lident "React", "componentLike") }, [ retPropsType; innerType ]) + in + let newStructure = + { + pstr with + pstr_desc = + Pstr_primitive + { + value_description with + pval_type = { pval_type with ptyp_desc = newExternalType }; + pval_attributes = List.filter otherAttrsPure pval_attributes; + }; + } + in + externalPropsDecl :: newStructure :: returnStructures + | _ -> raise (Invalid_argument "Only one react.component call can exist on a component at one time") ) + (* let component = ... *) + | { pstr_loc; pstr_desc = Pstr_value (recFlag, valueBindings) } -> + let fileName = filenameFromLoc pstr_loc in + let emptyLoc = Location.in_file fileName in + let mapBinding binding = + if hasAttrOnBinding binding then + let bindingLoc = binding.pvb_loc in + let bindingPatLoc = binding.pvb_pat.ppat_loc in + let binding = { binding with pvb_pat = { binding.pvb_pat with ppat_loc = emptyLoc }; pvb_loc = emptyLoc } in + let fnName = getFnName binding in + let internalFnName = fnName ^ "$Internal" in + let fullModuleName = makeModuleName fileName !nestedModules fnName in + let modifiedBindingOld binding = + let expression = binding.pvb_expr in + (* TODO: there is a long-tail of unsupported features inside of blocks - Pexp_letmodule , Pexp_letexception , Pexp_ifthenelse *) + let rec spelunkForFunExpression expression = + match expression with + (* let make = (~prop) => ... *) + | { pexp_desc = Pexp_fun _ } -> expression + (* let make = {let foo = bar in (~prop) => ...} *) + | { pexp_desc = Pexp_let (_recursive, _vbs, returnExpression) } -> + (* here's where we spelunk! *) + spelunkForFunExpression returnExpression + (* let make = React.forwardRef((~prop) => ...) *) + | { pexp_desc = Pexp_apply (_wrapperExpression, [ (Nolabel, innerFunctionExpression) ]) } -> + spelunkForFunExpression innerFunctionExpression + | { pexp_desc = Pexp_sequence (_wrapperExpression, innerFunctionExpression) } -> + spelunkForFunExpression innerFunctionExpression + | _ -> + raise + (Invalid_argument + "react.component calls can only be on function definitions or component wrappers (forwardRef, \ + memo).") + [@@raises Invalid_argument] + in + spelunkForFunExpression expression + in + let modifiedBinding binding = + let hasApplication = ref false in + let wrapExpressionWithBinding expressionFn expression = + Vb.mk ~loc:bindingLoc + ~attrs:(List.filter otherAttrsPure binding.pvb_attributes) + (Pat.var ~loc:bindingPatLoc { loc = bindingPatLoc; txt = fnName }) + (expressionFn expression) + in + let expression = binding.pvb_expr in + let unerasableIgnoreExp exp = + { exp with pexp_attributes = unerasableIgnore emptyLoc :: exp.pexp_attributes } + in + (* TODO: there is a long-tail of unsupported features inside of blocks - Pexp_letmodule , Pexp_letexception , Pexp_ifthenelse *) + let rec spelunkForFunExpression expression = + match expression with + (* let make = (~prop) => ... with no final unit *) + | { + pexp_desc = + Pexp_fun + ( ((Labelled _ | Optional _) as label), + default, + pattern, + ({ pexp_desc = Pexp_fun _ } as internalExpression) ); + } -> + let wrap, hasUnit, exp = spelunkForFunExpression internalExpression in + ( wrap, + hasUnit, + unerasableIgnoreExp { expression with pexp_desc = Pexp_fun (label, default, pattern, exp) } ) + (* let make = (()) => ... *) + (* let make = (_) => ... *) + | { + pexp_desc = + Pexp_fun + ( Nolabel, + _default, + { ppat_desc = Ppat_construct ({ txt = Lident "()" }, _) | Ppat_any }, + _internalExpression ); + } -> + ((fun a -> a), true, expression) + (* let make = (~prop) => ... *) + | { pexp_desc = Pexp_fun ((Labelled _ | Optional _), _default, _pattern, _internalExpression) } -> + ((fun a -> a), false, unerasableIgnoreExp expression) + (* let make = (prop) => ... *) + | { pexp_desc = Pexp_fun (_nolabel, _default, pattern, _internalExpression) } -> + if hasApplication.contents then ((fun a -> a), false, unerasableIgnoreExp expression) + else + Location.raise_errorf ~loc:pattern.ppat_loc + "ReasonReact: props need to be labelled arguments.\n\ + \ If you are working with refs be sure to wrap with React.forwardRef.\n\ + \ If your component doesn't have any props use () or _ instead of a name." + (* let make = {let foo = bar in (~prop) => ...} *) + | { pexp_desc = Pexp_let (recursive, vbs, internalExpression) } -> + (* here's where we spelunk! *) + let wrap, hasUnit, exp = spelunkForFunExpression internalExpression in + (wrap, hasUnit, { expression with pexp_desc = Pexp_let (recursive, vbs, exp) }) + (* let make = React.forwardRef((~prop) => ...) *) + | { pexp_desc = Pexp_apply (wrapperExpression, [ (Nolabel, internalExpression) ]) } -> + let () = hasApplication := true in + let _, hasUnit, exp = spelunkForFunExpression internalExpression in + ((fun exp -> Exp.apply wrapperExpression [ (nolabel, exp) ]), hasUnit, exp) + | { pexp_desc = Pexp_sequence (wrapperExpression, internalExpression) } -> + let wrap, hasUnit, exp = spelunkForFunExpression internalExpression in + (wrap, hasUnit, { expression with pexp_desc = Pexp_sequence (wrapperExpression, exp) }) + | e -> ((fun a -> a), false, e) + in + let wrapExpression, hasUnit, expression = spelunkForFunExpression expression in + (wrapExpressionWithBinding wrapExpression, hasUnit, expression) + in + let bindingWrapper, hasUnit, expression = modifiedBinding binding in + let reactComponentAttribute = + try Some (List.find hasAttr binding.pvb_attributes) with Not_found -> None + in + let _attr_loc, payload = + match reactComponentAttribute with + | Some (loc, payload) -> (loc.loc, Some payload) + | None -> (emptyLoc, None) + in + let props = getPropsAttr payload in + (* do stuff here! *) + let namedArgList, forwardRef = + recursivelyTransformNamedArgsForMake mapper (modifiedBindingOld binding) [] + in + let namedArgListWithKeyAndRef = + (optional "key", None, Pat.var { txt = "key"; loc = emptyLoc }, "key", emptyLoc, Some (keyType emptyLoc)) + :: namedArgList + in + let namedArgListWithKeyAndRef = + match forwardRef with + | Some _ -> + (optional "ref", None, Pat.var { txt = "key"; loc = emptyLoc }, "ref", emptyLoc, None) + :: namedArgListWithKeyAndRef + | None -> namedArgListWithKeyAndRef + in + let namedArgListWithKeyAndRefForNew = + match forwardRef with + | Some txt -> namedArgList @ [ (nolabel, None, Pat.var { txt; loc = emptyLoc }, txt, emptyLoc, None) ] + | None -> namedArgList + in + let pluckArg (label, _, _, alias, loc, _) = + let labelString = + match label with label when isOptional label || isLabelled label -> getLabel label | _ -> "" + in + ( label, + match labelString with + | "" -> Exp.ident ~loc { txt = Lident alias; loc } + | labelString -> + Exp.apply ~loc + (Exp.ident ~loc { txt = Lident "##"; loc }) + [ + (nolabel, Exp.ident ~loc { txt = Lident props.propsName; loc }); + (nolabel, Exp.ident ~loc { txt = Lident labelString; loc }); + ] ) + in + let namedTypeList = List.fold_left argToType [] namedArgList in + let loc = emptyLoc in + let externalDecl = makeExternalDecl fnName loc namedArgListWithKeyAndRef namedTypeList in + let innerExpressionArgs = + List.map pluckArg namedArgListWithKeyAndRefForNew + @ if hasUnit then [ (Nolabel, Exp.construct { loc; txt = Lident "()" } None) ] else [] + in + let innerExpression = + Exp.apply + (Exp.ident + { loc; txt = Lident (match recFlag with Recursive -> internalFnName | Nonrecursive -> fnName) }) + innerExpressionArgs + in + let innerExpressionWithRef = + match forwardRef with + | Some txt -> + { + innerExpression with + pexp_desc = + Pexp_fun + ( nolabel, + None, + { ppat_desc = Ppat_var { txt; loc = emptyLoc }; ppat_loc = emptyLoc; ppat_attributes = [] }, + innerExpression ); + } + | None -> innerExpression + in + let fullExpression = + Exp.fun_ nolabel None + { + ppat_desc = + Ppat_constraint + (makePropsName ~loc:emptyLoc props.propsName, makePropsType ~loc:emptyLoc namedTypeList); + ppat_loc = emptyLoc; + ppat_attributes = []; + } + innerExpressionWithRef + in + let fullExpression = + match fullModuleName with + | "" -> fullExpression + | txt -> + Exp.let_ Nonrecursive + [ Vb.mk ~loc:emptyLoc (Pat.var ~loc:emptyLoc { loc = emptyLoc; txt }) fullExpression ] + (Exp.ident ~loc:emptyLoc { loc = emptyLoc; txt = Lident txt }) + in + let bindings, newBinding = + match recFlag with + | Recursive -> + ( [ + bindingWrapper + (Exp.let_ ~loc:emptyLoc Recursive + [ + makeNewBinding binding expression internalFnName; + Vb.mk (Pat.var { loc = emptyLoc; txt = fnName }) fullExpression; + ] + (Exp.ident { loc = emptyLoc; txt = Lident fnName })); + ], + None ) + | Nonrecursive -> + ([ { binding with pvb_expr = expression; pvb_attributes = [] } ], Some (bindingWrapper fullExpression)) + in + (Some externalDecl, bindings, newBinding) + else (None, [ binding ], None) + [@@raises Invalid_argument] + in + let structuresAndBinding = List.map mapBinding valueBindings in + let otherStructures (extern, binding, newBinding) (externs, bindings, newBindings) = + let externs = match extern with Some extern -> extern :: externs | None -> externs in + let newBindings = + match newBinding with Some newBinding -> newBinding :: newBindings | None -> newBindings + in + (externs, binding @ bindings, newBindings) + in + let externs, bindings, newBindings = List.fold_right otherStructures structuresAndBinding ([], [], []) in + externs + @ [ { pstr_loc; pstr_desc = Pstr_value (recFlag, bindings) } ] + @ ( match newBindings with + | [] -> [] + | newBindings -> [ { pstr_loc = emptyLoc; pstr_desc = Pstr_value (recFlag, newBindings) } ] ) + @ returnStructures + | structure -> structure :: returnStructures + [@@raises Invalid_argument] + in + + let reactComponentTransform mapper structures = + List.fold_right (transformComponentDefinition mapper) structures [] + [@@raises Invalid_argument] + in + + let transformComponentSignature _mapper signature returnSignatures = + match signature with + | { psig_loc; psig_desc = Psig_value ({ pval_name = { txt = fnName }; pval_attributes; pval_type } as psig_desc) } + as psig -> ( + match List.filter hasAttr pval_attributes with + | [] -> signature :: returnSignatures + | [ _ ] -> + let rec getPropTypes types ({ ptyp_loc; ptyp_desc } as fullType) = + match ptyp_desc with + | Ptyp_arrow (name, type_, ({ ptyp_desc = Ptyp_arrow _ } as rest)) when isOptional name || isLabelled name + -> + getPropTypes ((name, ptyp_loc, type_) :: types) rest + | Ptyp_arrow (Nolabel, _type, rest) -> getPropTypes types rest + | Ptyp_arrow (name, type_, returnValue) when isOptional name || isLabelled name -> + (returnValue, (name, returnValue.ptyp_loc, type_) :: types) + | _ -> (fullType, types) + in + let innerType, propTypes = getPropTypes [] pval_type in + let namedTypeList = List.fold_left argToConcreteType [] propTypes in + let pluckLabelAndLoc (label, loc, type_) = (label, None, loc, Some type_) in + let retPropsType = makePropsType ~loc:psig_loc namedTypeList in + let externalPropsDecl = + makePropsExternalSig fnName psig_loc + ((optional "key", None, psig_loc, Some (keyType psig_loc)) :: List.map pluckLabelAndLoc propTypes) + retPropsType + in + (* can't be an arrow because it will defensively uncurry *) + let newExternalType = + Ptyp_constr ({ loc = psig_loc; txt = Ldot (Lident "React", "componentLike") }, [ retPropsType; innerType ]) + in + let newStructure = + { + psig with + psig_desc = + Psig_value + { + psig_desc with + pval_type = { pval_type with ptyp_desc = newExternalType }; + pval_attributes = List.filter otherAttrsPure pval_attributes; + }; + } + in + externalPropsDecl :: newStructure :: returnSignatures + | _ -> raise (Invalid_argument "Only one react.component call can exist on a component at one time") ) + | signature -> signature :: returnSignatures + [@@raises Invalid_argument] + in + + let reactComponentSignatureTransform mapper signatures = + List.fold_right (transformComponentSignature mapper) signatures [] + [@@raises Invalid_argument] + in + + let transformJsxCall mapper callExpression callArguments attrs = + match callExpression.pexp_desc with + | Pexp_ident caller -> ( + match caller with + | { txt = Lident "createElement" } -> + raise (Invalid_argument "JSX: `createElement` should be preceeded by a module name.") + (* Foo.createElement(~prop1=foo, ~prop2=bar, ~children=[], ()) *) + | { loc; txt = Ldot (modulePath, ("createElement" | "make")) } -> ( + match !jsxVersion with + | None | Some 3 -> transformUppercaseCall3 modulePath mapper loc attrs callExpression callArguments + | Some _ -> raise (Invalid_argument "JSX: the JSX version must be 3") ) + (* div(~prop1=foo, ~prop2=bar, ~children=[bla], ()) *) + (* turn that into + ReactDOMRe.createElement(~props=ReactDOMRe.props(~props1=foo, ~props2=bar, ()), [|bla|]) *) + | { loc; txt = Lident id } -> ( + match !jsxVersion with + | None | Some 3 -> transformLowercaseCall3 mapper loc attrs callArguments id + | Some _ -> raise (Invalid_argument "JSX: the JSX version must be 3") ) + | { txt = Ldot (_, anythingNotCreateElementOrMake) } -> + raise + (Invalid_argument + ( "JSX: the JSX attribute should be attached to a `YourModuleName.createElement` or \ + `YourModuleName.make` call. We saw `" ^ anythingNotCreateElementOrMake ^ "` instead" )) + | { txt = Lapply _ } -> + (* don't think there's ever a case where this is reached *) + raise (Invalid_argument "JSX: encountered a weird case while processing the code. Please report this!") ) + | _ -> raise (Invalid_argument "JSX: `createElement` should be preceeded by a simple, direct module name.") + [@@raises Invalid_argument] + in + + let signature mapper signature = + default_mapper.signature mapper @@ reactComponentSignatureTransform mapper signature + [@@raises Invalid_argument] + in + + let structure mapper structure = + match structure with structures -> default_mapper.structure mapper @@ reactComponentTransform mapper structures + [@@raises Invalid_argument] + in + + let expr mapper expression = + match expression with + (* Does the function application have the @JSX attribute? *) + | { pexp_desc = Pexp_apply (callExpression, callArguments); pexp_attributes } -> ( + let jsxAttribute, nonJSXAttributes = + List.partition (fun (attribute, _) -> attribute.txt = "JSX") pexp_attributes + in + match (jsxAttribute, nonJSXAttributes) with + (* no JSX attribute *) + | [], _ -> default_mapper.expr mapper expression + | _, nonJSXAttributes -> transformJsxCall mapper callExpression callArguments nonJSXAttributes ) + (* is it a list with jsx attribute? Reason <>foo desugars to [@JSX][foo]*) + | { + pexp_desc = + ( Pexp_construct ({ txt = Lident "::"; loc }, Some { pexp_desc = Pexp_tuple _ }) + | Pexp_construct ({ txt = Lident "[]"; loc }, None) ); + pexp_attributes; + } as listItems -> ( + let jsxAttribute, nonJSXAttributes = + List.partition (fun (attribute, _) -> attribute.txt = "JSX") pexp_attributes + in + match (jsxAttribute, nonJSXAttributes) with + (* no JSX attribute *) + | [], _ -> default_mapper.expr mapper expression + | _, nonJSXAttributes -> + let fragment = Exp.ident ~loc { loc; txt = Ldot (Lident "ReasonReact", "fragment") } in + let childrenExpr = transformChildrenIfList ~loc ~mapper listItems in + let args = + [ (* "div" *) (nolabel, fragment); (* [|moreCreateElementCallsHere|] *) (nolabel, childrenExpr) ] + in + Exp.apply ~loc (* throw away the [@JSX] attribute and keep the others, if any *) ~attrs:nonJSXAttributes + (* ReactDOMRe.createElement *) + (Exp.ident ~loc { loc; txt = Ldot (Lident "ReactDOMRe", "createElement") }) + args ) + (* Delegate to the default mapper, a deep identity traversal *) + | e -> default_mapper.expr mapper e + [@@raises Invalid_argument] + in + + let module_binding mapper module_binding = + let _ = nestedModules := module_binding.pmb_name.txt :: !nestedModules in + let mapped = default_mapper.module_binding mapper module_binding in + let _ = nestedModules := List.tl !nestedModules in + mapped + [@@raises Failure] + in + { default_mapper with structure; expr; signature; module_binding } + [@@raises Invalid_argument, Failure] + +let rewrite_implementation (code : Parsetree.structure) : Parsetree.structure = + let mapper = jsxMapper () in + mapper.structure mapper code + [@@raises Invalid_argument, Failure] + +let rewrite_signature (code : Parsetree.signature) : Parsetree.signature = + let mapper = jsxMapper () in + mapper.signature mapper code + [@@raises Invalid_argument, Failure] + end module Ppx_entry = struct diff --git a/lib/4.06.1/unstable/js_compiler.ml.d b/lib/4.06.1/unstable/js_compiler.ml.d index 20398afb0e..bed82fe89b 100644 --- a/lib/4.06.1/unstable/js_compiler.ml.d +++ b/lib/4.06.1/unstable/js_compiler.ml.d @@ -1 +1 @@ -../lib/4.06.1/unstable/js_compiler.ml: ../ocaml/bytecomp/lambda.ml ../ocaml/bytecomp/lambda.mli ../ocaml/bytecomp/matching.ml ../ocaml/bytecomp/matching.mli ../ocaml/bytecomp/printlambda.ml ../ocaml/bytecomp/printlambda.mli ../ocaml/bytecomp/switch.ml ../ocaml/bytecomp/switch.mli ../ocaml/bytecomp/translattribute.ml ../ocaml/bytecomp/translattribute.mli ../ocaml/bytecomp/translclass.ml ../ocaml/bytecomp/translclass.mli ../ocaml/bytecomp/translcore.ml ../ocaml/bytecomp/translcore.mli ../ocaml/bytecomp/translmod.ml ../ocaml/bytecomp/translmod.mli ../ocaml/bytecomp/translobj.ml ../ocaml/bytecomp/translobj.mli ../ocaml/parsing/ast_helper.ml ../ocaml/parsing/ast_helper.mli ../ocaml/parsing/ast_iterator.ml ../ocaml/parsing/ast_iterator.mli ../ocaml/parsing/ast_mapper.ml ../ocaml/parsing/ast_mapper.mli ../ocaml/parsing/asttypes.mli ../ocaml/parsing/attr_helper.ml ../ocaml/parsing/attr_helper.mli ../ocaml/parsing/builtin_attributes.ml ../ocaml/parsing/builtin_attributes.mli ../ocaml/parsing/docstrings.ml ../ocaml/parsing/docstrings.mli ../ocaml/parsing/lexer.ml ../ocaml/parsing/lexer.mli ../ocaml/parsing/location.ml ../ocaml/parsing/location.mli ../ocaml/parsing/longident.ml ../ocaml/parsing/longident.mli ../ocaml/parsing/parse.ml ../ocaml/parsing/parse.mli ../ocaml/parsing/parser.ml ../ocaml/parsing/parser.mli ../ocaml/parsing/parsetree.mli ../ocaml/parsing/syntaxerr.ml ../ocaml/parsing/syntaxerr.mli ../ocaml/typing/annot.mli ../ocaml/typing/btype.ml ../ocaml/typing/btype.mli ../ocaml/typing/cmi_format.ml ../ocaml/typing/cmi_format.mli ../ocaml/typing/cmt_format.ml ../ocaml/typing/cmt_format.mli ../ocaml/typing/ctype.ml ../ocaml/typing/ctype.mli ../ocaml/typing/datarepr.ml ../ocaml/typing/datarepr.mli ../ocaml/typing/env.ml ../ocaml/typing/env.mli ../ocaml/typing/ident.ml ../ocaml/typing/ident.mli ../ocaml/typing/includeclass.ml ../ocaml/typing/includeclass.mli ../ocaml/typing/includecore.ml ../ocaml/typing/includecore.mli ../ocaml/typing/includemod.ml ../ocaml/typing/includemod.mli ../ocaml/typing/mtype.ml ../ocaml/typing/mtype.mli ../ocaml/typing/oprint.ml ../ocaml/typing/oprint.mli ../ocaml/typing/outcometree.mli ../ocaml/typing/parmatch.ml ../ocaml/typing/parmatch.mli ../ocaml/typing/path.ml ../ocaml/typing/path.mli ../ocaml/typing/predef.ml ../ocaml/typing/predef.mli ../ocaml/typing/primitive.ml ../ocaml/typing/primitive.mli ../ocaml/typing/printtyp.ml ../ocaml/typing/printtyp.mli ../ocaml/typing/stypes.ml ../ocaml/typing/stypes.mli ../ocaml/typing/subst.ml ../ocaml/typing/subst.mli ../ocaml/typing/tast_mapper.ml ../ocaml/typing/tast_mapper.mli ../ocaml/typing/typeclass.ml ../ocaml/typing/typeclass.mli ../ocaml/typing/typecore.ml ../ocaml/typing/typecore.mli ../ocaml/typing/typedecl.ml ../ocaml/typing/typedecl.mli ../ocaml/typing/typedtree.ml ../ocaml/typing/typedtree.mli ../ocaml/typing/typedtreeIter.ml ../ocaml/typing/typedtreeIter.mli ../ocaml/typing/typemod.ml ../ocaml/typing/typemod.mli ../ocaml/typing/typeopt.ml ../ocaml/typing/typeopt.mli ../ocaml/typing/types.ml ../ocaml/typing/types.mli ../ocaml/typing/typetexp.ml ../ocaml/typing/typetexp.mli ../ocaml/typing/untypeast.ml ../ocaml/typing/untypeast.mli ../ocaml/utils/arg_helper.ml ../ocaml/utils/arg_helper.mli ../ocaml/utils/ccomp.ml ../ocaml/utils/ccomp.mli ../ocaml/utils/clflags.ml ../ocaml/utils/clflags.mli ../ocaml/utils/consistbl.ml ../ocaml/utils/consistbl.mli ../ocaml/utils/identifiable.ml ../ocaml/utils/identifiable.mli ../ocaml/utils/misc.ml ../ocaml/utils/misc.mli ../ocaml/utils/numbers.ml ../ocaml/utils/numbers.mli ../ocaml/utils/profile.ml ../ocaml/utils/profile.mli ../ocaml/utils/tbl.ml ../ocaml/utils/tbl.mli ../ocaml/utils/warnings.ml ../ocaml/utils/warnings.mli ./common/bs_loc.ml ./common/bs_loc.mli ./common/bs_version.ml ./common/bs_version.mli ./common/bs_warnings.ml ./common/bs_warnings.mli ./common/ext_log.ml ./common/ext_log.mli ./common/js_config.ml ./common/js_config.mli ./common/lam_methname.ml ./common/lam_methname.mli ./core/bs_cmi_load.ml ./core/bs_conditional_initial.ml ./core/bs_conditional_initial.mli ./core/compile_rec_module.ml ./core/config_util.ml ./core/config_util.mli ./core/config_whole_compiler.ml ./core/config_whole_compiler.mli ./core/j.ml ./core/js_analyzer.ml ./core/js_analyzer.mli ./core/js_arr.ml ./core/js_arr.mli ./core/js_ast_util.ml ./core/js_ast_util.mli ./core/js_block_runtime.ml ./core/js_block_runtime.mli ./core/js_call_info.ml ./core/js_call_info.mli ./core/js_closure.ml ./core/js_closure.mli ./core/js_cmj_format.ml ./core/js_cmj_format.mli ./core/js_cmj_load.ml ./core/js_cmj_load.mli ./core/js_cmj_load_builtin_unit.ml ./core/js_dump.ml ./core/js_dump.mli ./core/js_dump_import_export.ml ./core/js_dump_import_export.mli ./core/js_dump_lit.ml ./core/js_dump_program.ml ./core/js_dump_program.mli ./core/js_dump_property.ml ./core/js_dump_property.mli ./core/js_dump_string.ml ./core/js_dump_string.mli ./core/js_exp_make.ml ./core/js_exp_make.mli ./core/js_fold.ml ./core/js_fold_basic.ml ./core/js_fold_basic.mli ./core/js_fun_env.ml ./core/js_fun_env.mli ./core/js_long.ml ./core/js_long.mli ./core/js_map.ml ./core/js_name_of_module_id.ml ./core/js_name_of_module_id.mli ./core/js_number.ml ./core/js_number.mli ./core/js_of_lam_array.ml ./core/js_of_lam_array.mli ./core/js_of_lam_block.ml ./core/js_of_lam_block.mli ./core/js_of_lam_exception.ml ./core/js_of_lam_exception.mli ./core/js_of_lam_option.ml ./core/js_of_lam_option.mli ./core/js_of_lam_string.ml ./core/js_of_lam_string.mli ./core/js_of_lam_variant.ml ./core/js_of_lam_variant.mli ./core/js_op.ml ./core/js_op_util.ml ./core/js_op_util.mli ./core/js_output.ml ./core/js_output.mli ./core/js_packages_info.ml ./core/js_packages_info.mli ./core/js_packages_state.ml ./core/js_packages_state.mli ./core/js_pass_debug.ml ./core/js_pass_debug.mli ./core/js_pass_flatten.ml ./core/js_pass_flatten.mli ./core/js_pass_flatten_and_mark_dead.ml ./core/js_pass_flatten_and_mark_dead.mli ./core/js_pass_get_used.ml ./core/js_pass_get_used.mli ./core/js_pass_scope.ml ./core/js_pass_scope.mli ./core/js_pass_tailcall_inline.ml ./core/js_pass_tailcall_inline.mli ./core/js_raw_info.ml ./core/js_shake.ml ./core/js_shake.mli ./core/js_stmt_make.ml ./core/js_stmt_make.mli ./core/lam.ml ./core/lam.mli ./core/lam_analysis.ml ./core/lam_analysis.mli ./core/lam_arity.ml ./core/lam_arity.mli ./core/lam_arity_analysis.ml ./core/lam_arity_analysis.mli ./core/lam_beta_reduce.ml ./core/lam_beta_reduce.mli ./core/lam_beta_reduce_util.ml ./core/lam_beta_reduce_util.mli ./core/lam_bounded_vars.ml ./core/lam_bounded_vars.mli ./core/lam_closure.ml ./core/lam_closure.mli ./core/lam_coercion.ml ./core/lam_coercion.mli ./core/lam_compat.ml ./core/lam_compat.mli ./core/lam_compile.ml ./core/lam_compile.mli ./core/lam_compile_const.ml ./core/lam_compile_const.mli ./core/lam_compile_context.ml ./core/lam_compile_context.mli ./core/lam_compile_env.ml ./core/lam_compile_env.mli ./core/lam_compile_external_call.ml ./core/lam_compile_external_call.mli ./core/lam_compile_external_obj.ml ./core/lam_compile_external_obj.mli ./core/lam_compile_main.ml ./core/lam_compile_main.mli ./core/lam_compile_primitive.ml ./core/lam_compile_primitive.mli ./core/lam_compile_util.ml ./core/lam_compile_util.mli ./core/lam_constant.ml ./core/lam_constant.mli ./core/lam_constant_convert.ml ./core/lam_constant_convert.mli ./core/lam_convert.ml ./core/lam_convert.mli ./core/lam_dce.ml ./core/lam_dce.mli ./core/lam_dispatch_primitive.ml ./core/lam_dispatch_primitive.mli ./core/lam_eta_conversion.ml ./core/lam_eta_conversion.mli ./core/lam_exit_code.ml ./core/lam_exit_code.mli ./core/lam_exit_count.ml ./core/lam_exit_count.mli ./core/lam_free_variables.ml ./core/lam_free_variables.mli ./core/lam_group.ml ./core/lam_group.mli ./core/lam_hit.ml ./core/lam_hit.mli ./core/lam_id_kind.ml ./core/lam_id_kind.mli ./core/lam_iter.ml ./core/lam_iter.mli ./core/lam_module_ident.ml ./core/lam_module_ident.mli ./core/lam_pass_alpha_conversion.ml ./core/lam_pass_alpha_conversion.mli ./core/lam_pass_collect.ml ./core/lam_pass_collect.mli ./core/lam_pass_count.ml ./core/lam_pass_count.mli ./core/lam_pass_deep_flatten.ml ./core/lam_pass_deep_flatten.mli ./core/lam_pass_eliminate_ref.ml ./core/lam_pass_eliminate_ref.mli ./core/lam_pass_exits.ml ./core/lam_pass_exits.mli ./core/lam_pass_lets_dce.ml ./core/lam_pass_lets_dce.mli ./core/lam_pass_remove_alias.ml ./core/lam_pass_remove_alias.mli ./core/lam_pointer_info.ml ./core/lam_pointer_info.mli ./core/lam_primitive.ml ./core/lam_primitive.mli ./core/lam_print.ml ./core/lam_print.mli ./core/lam_scc.ml ./core/lam_scc.mli ./core/lam_stats.ml ./core/lam_stats.mli ./core/lam_stats_export.ml ./core/lam_stats_export.mli ./core/lam_subst.ml ./core/lam_subst.mli ./core/lam_tag_info.ml ./core/lam_util.ml ./core/lam_util.mli ./core/lam_var_stats.ml ./core/lam_var_stats.mli ./core/matching_polyfill.ml ./core/matching_polyfill.mli ./core/polyvar_pattern_match.ml ./core/record_attributes_check.ml ./core/res_compmisc.ml ./core/res_compmisc.mli ./core/transl_single_field_record.ml ./depends/bs_exception.ml ./depends/bs_exception.mli ./ext/bsc_args.ml ./ext/bsc_args.mli ./ext/bsc_warnings.ml ./ext/ext_array.ml ./ext/ext_array.mli ./ext/ext_buffer.ml ./ext/ext_buffer.mli ./ext/ext_bytes.ml ./ext/ext_bytes.mli ./ext/ext_char.ml ./ext/ext_char.mli ./ext/ext_digest.ml ./ext/ext_digest.mli ./ext/ext_filename.ml ./ext/ext_filename.mli ./ext/ext_fmt.ml ./ext/ext_ident.ml ./ext/ext_ident.mli ./ext/ext_int.ml ./ext/ext_int.mli ./ext/ext_io.ml ./ext/ext_io.mli ./ext/ext_js_file_kind.ml ./ext/ext_js_suffix.ml ./ext/ext_list.ml ./ext/ext_list.mli ./ext/ext_marshal.ml ./ext/ext_marshal.mli ./ext/ext_modulename.ml ./ext/ext_modulename.mli ./ext/ext_namespace.ml ./ext/ext_namespace.mli ./ext/ext_option.ml ./ext/ext_option.mli ./ext/ext_path.ml ./ext/ext_path.mli ./ext/ext_pervasives.ml ./ext/ext_pervasives.mli ./ext/ext_pp.ml ./ext/ext_pp.mli ./ext/ext_pp_scope.ml ./ext/ext_pp_scope.mli ./ext/ext_ref.ml ./ext/ext_ref.mli ./ext/ext_scc.ml ./ext/ext_scc.mli ./ext/ext_spec.ml ./ext/ext_spec.mli ./ext/ext_string.ml ./ext/ext_string.mli ./ext/ext_string_array.ml ./ext/ext_string_array.mli ./ext/ext_sys.ml ./ext/ext_sys.mli ./ext/ext_utf8.ml ./ext/ext_utf8.mli ./ext/ext_util.ml ./ext/ext_util.mli ./ext/hash.ml ./ext/hash.mli ./ext/hash_gen.ml ./ext/hash_ident.ml ./ext/hash_ident.mli ./ext/hash_int.ml ./ext/hash_int.mli ./ext/hash_set.ml ./ext/hash_set.mli ./ext/hash_set_gen.ml ./ext/hash_set_ident.ml ./ext/hash_set_ident.mli ./ext/hash_set_ident_mask.ml ./ext/hash_set_ident_mask.mli ./ext/hash_set_poly.ml ./ext/hash_set_poly.mli ./ext/hash_set_string.ml ./ext/hash_set_string.mli ./ext/hash_string.ml ./ext/hash_string.mli ./ext/int_vec_util.ml ./ext/int_vec_util.mli ./ext/int_vec_vec.ml ./ext/int_vec_vec.mli ./ext/js_reserved_map.ml ./ext/js_reserved_map.mli ./ext/js_runtime_modules.ml ./ext/literals.ml ./ext/map_gen.ml ./ext/map_gen.mli ./ext/map_ident.ml ./ext/map_ident.mli ./ext/map_int.ml ./ext/map_int.mli ./ext/map_string.ml ./ext/map_string.mli ./ext/ordered_hash_map_gen.ml ./ext/ordered_hash_map_local_ident.ml ./ext/ordered_hash_map_local_ident.mli ./ext/set_gen.ml ./ext/set_gen.mli ./ext/set_ident.ml ./ext/set_ident.mli ./ext/set_string.ml ./ext/set_string.mli ./ext/vec.ml ./ext/vec.mli ./ext/vec_gen.ml ./ext/vec_int.ml ./ext/vec_int.mli ./js_parser/declaration_parser.ml ./js_parser/enum_common.ml ./js_parser/enum_parser.ml ./js_parser/expression_parser.ml ./js_parser/file_key.ml ./js_parser/flow_ast.ml ./js_parser/flow_ast_utils.ml ./js_parser/flow_ast_utils.mli ./js_parser/flow_lexer.ml ./js_parser/flow_lexer.mli ./js_parser/jsx_parser.ml ./js_parser/lex_env.ml ./js_parser/lex_result.ml ./js_parser/loc.ml ./js_parser/loc.mli ./js_parser/object_parser.ml ./js_parser/parse_error.ml ./js_parser/parser_common.ml ./js_parser/parser_env.ml ./js_parser/parser_env.mli ./js_parser/parser_flow.ml ./js_parser/pattern_cover.ml ./js_parser/pattern_parser.ml ./js_parser/sedlexing.ml ./js_parser/sedlexing.mli ./js_parser/statement_parser.ml ./js_parser/token.ml ./js_parser/type_parser.ml ./js_parser/wtf8.ml ./js_parser/wtf8.mli ./main/builtin_cmi_datasets.ml ./main/builtin_cmi_datasets.mli ./main/builtin_cmj_datasets.ml ./main/builtin_cmj_datasets.mli ./main/jsoo_common.ml ./main/jsoo_common.mli ./main/jsoo_main.ml ./main/jsoo_main.mli ./outcome_printer/outcome_printer_ns.ml ./outcome_printer/outcome_printer_ns.mli ./stubs/bs_hash_stubs.ml ./super_errors/super_env.ml ./super_errors/super_location.ml ./super_errors/super_location.mli ./super_errors/super_main.ml ./super_errors/super_misc.ml ./super_errors/super_misc.mli ./super_errors/super_pparse.ml ./super_errors/super_typecore.ml ./super_errors/super_typemod.ml ./super_errors/super_typetexp.ml ./syntax/ast_attributes.ml ./syntax/ast_attributes.mli ./syntax/ast_bs_open.ml ./syntax/ast_bs_open.mli ./syntax/ast_comb.ml ./syntax/ast_comb.mli ./syntax/ast_compatible.ml ./syntax/ast_compatible.mli ./syntax/ast_config.ml ./syntax/ast_config.mli ./syntax/ast_core_type.ml ./syntax/ast_core_type.mli ./syntax/ast_core_type_class_type.ml ./syntax/ast_core_type_class_type.mli ./syntax/ast_derive.ml ./syntax/ast_derive.mli ./syntax/ast_derive_abstract.ml ./syntax/ast_derive_abstract.mli ./syntax/ast_derive_js_mapper.ml ./syntax/ast_derive_js_mapper.mli ./syntax/ast_derive_projector.ml ./syntax/ast_derive_projector.mli ./syntax/ast_derive_util.ml ./syntax/ast_derive_util.mli ./syntax/ast_exp.ml ./syntax/ast_exp.mli ./syntax/ast_exp_apply.ml ./syntax/ast_exp_apply.mli ./syntax/ast_exp_extension.ml ./syntax/ast_exp_extension.mli ./syntax/ast_exp_handle_external.ml ./syntax/ast_exp_handle_external.mli ./syntax/ast_external.ml ./syntax/ast_external.mli ./syntax/ast_external_mk.ml ./syntax/ast_external_mk.mli ./syntax/ast_external_process.ml ./syntax/ast_external_process.mli ./syntax/ast_literal.ml ./syntax/ast_literal.mli ./syntax/ast_open_cxt.ml ./syntax/ast_open_cxt.mli ./syntax/ast_pat.ml ./syntax/ast_pat.mli ./syntax/ast_payload.ml ./syntax/ast_payload.mli ./syntax/ast_polyvar.ml ./syntax/ast_polyvar.mli ./syntax/ast_reason_pp.ml ./syntax/ast_reason_pp.mli ./syntax/ast_signature.ml ./syntax/ast_signature.mli ./syntax/ast_structure.ml ./syntax/ast_structure.mli ./syntax/ast_tdcls.ml ./syntax/ast_tdcls.mli ./syntax/ast_tuple_pattern_flatten.ml ./syntax/ast_tuple_pattern_flatten.mli ./syntax/ast_typ_uncurry.ml ./syntax/ast_typ_uncurry.mli ./syntax/ast_uncurry_apply.ml ./syntax/ast_uncurry_apply.mli ./syntax/ast_uncurry_gen.ml ./syntax/ast_uncurry_gen.mli ./syntax/ast_utf8_string.ml ./syntax/ast_utf8_string.mli ./syntax/ast_utf8_string_interp.ml ./syntax/ast_utf8_string_interp.mli ./syntax/ast_util.ml ./syntax/ast_util.mli ./syntax/bs_ast_invariant.ml ./syntax/bs_ast_invariant.mli ./syntax/bs_ast_mapper.ml ./syntax/bs_ast_mapper.mli ./syntax/bs_builtin_ppx.ml ./syntax/bs_builtin_ppx.mli ./syntax/bs_flow_ast_utils.ml ./syntax/bs_flow_ast_utils.mli ./syntax/bs_syntaxerr.ml ./syntax/bs_syntaxerr.mli ./syntax/classify_function.ml ./syntax/classify_function.mli ./syntax/external_arg_spec.ml ./syntax/external_arg_spec.mli ./syntax/external_ffi_types.ml ./syntax/external_ffi_types.mli ./syntax/ppx_entry.ml ./syntax/typemod_hide.ml \ No newline at end of file +../lib/4.06.1/unstable/js_compiler.ml: ../ocaml/bytecomp/lambda.ml ../ocaml/bytecomp/lambda.mli ../ocaml/bytecomp/matching.ml ../ocaml/bytecomp/matching.mli ../ocaml/bytecomp/printlambda.ml ../ocaml/bytecomp/printlambda.mli ../ocaml/bytecomp/switch.ml ../ocaml/bytecomp/switch.mli ../ocaml/bytecomp/translattribute.ml ../ocaml/bytecomp/translattribute.mli ../ocaml/bytecomp/translclass.ml ../ocaml/bytecomp/translclass.mli ../ocaml/bytecomp/translcore.ml ../ocaml/bytecomp/translcore.mli ../ocaml/bytecomp/translmod.ml ../ocaml/bytecomp/translmod.mli ../ocaml/bytecomp/translobj.ml ../ocaml/bytecomp/translobj.mli ../ocaml/parsing/ast_helper.ml ../ocaml/parsing/ast_helper.mli ../ocaml/parsing/ast_iterator.ml ../ocaml/parsing/ast_iterator.mli ../ocaml/parsing/ast_mapper.ml ../ocaml/parsing/ast_mapper.mli ../ocaml/parsing/asttypes.mli ../ocaml/parsing/attr_helper.ml ../ocaml/parsing/attr_helper.mli ../ocaml/parsing/builtin_attributes.ml ../ocaml/parsing/builtin_attributes.mli ../ocaml/parsing/docstrings.ml ../ocaml/parsing/docstrings.mli ../ocaml/parsing/lexer.ml ../ocaml/parsing/lexer.mli ../ocaml/parsing/location.ml ../ocaml/parsing/location.mli ../ocaml/parsing/longident.ml ../ocaml/parsing/longident.mli ../ocaml/parsing/parse.ml ../ocaml/parsing/parse.mli ../ocaml/parsing/parser.ml ../ocaml/parsing/parser.mli ../ocaml/parsing/parsetree.mli ../ocaml/parsing/syntaxerr.ml ../ocaml/parsing/syntaxerr.mli ../ocaml/typing/annot.mli ../ocaml/typing/btype.ml ../ocaml/typing/btype.mli ../ocaml/typing/cmi_format.ml ../ocaml/typing/cmi_format.mli ../ocaml/typing/cmt_format.ml ../ocaml/typing/cmt_format.mli ../ocaml/typing/ctype.ml ../ocaml/typing/ctype.mli ../ocaml/typing/datarepr.ml ../ocaml/typing/datarepr.mli ../ocaml/typing/env.ml ../ocaml/typing/env.mli ../ocaml/typing/ident.ml ../ocaml/typing/ident.mli ../ocaml/typing/includeclass.ml ../ocaml/typing/includeclass.mli ../ocaml/typing/includecore.ml ../ocaml/typing/includecore.mli ../ocaml/typing/includemod.ml ../ocaml/typing/includemod.mli ../ocaml/typing/mtype.ml ../ocaml/typing/mtype.mli ../ocaml/typing/oprint.ml ../ocaml/typing/oprint.mli ../ocaml/typing/outcometree.mli ../ocaml/typing/parmatch.ml ../ocaml/typing/parmatch.mli ../ocaml/typing/path.ml ../ocaml/typing/path.mli ../ocaml/typing/predef.ml ../ocaml/typing/predef.mli ../ocaml/typing/primitive.ml ../ocaml/typing/primitive.mli ../ocaml/typing/printtyp.ml ../ocaml/typing/printtyp.mli ../ocaml/typing/stypes.ml ../ocaml/typing/stypes.mli ../ocaml/typing/subst.ml ../ocaml/typing/subst.mli ../ocaml/typing/tast_mapper.ml ../ocaml/typing/tast_mapper.mli ../ocaml/typing/typeclass.ml ../ocaml/typing/typeclass.mli ../ocaml/typing/typecore.ml ../ocaml/typing/typecore.mli ../ocaml/typing/typedecl.ml ../ocaml/typing/typedecl.mli ../ocaml/typing/typedtree.ml ../ocaml/typing/typedtree.mli ../ocaml/typing/typedtreeIter.ml ../ocaml/typing/typedtreeIter.mli ../ocaml/typing/typemod.ml ../ocaml/typing/typemod.mli ../ocaml/typing/typeopt.ml ../ocaml/typing/typeopt.mli ../ocaml/typing/types.ml ../ocaml/typing/types.mli ../ocaml/typing/typetexp.ml ../ocaml/typing/typetexp.mli ../ocaml/typing/untypeast.ml ../ocaml/typing/untypeast.mli ../ocaml/utils/arg_helper.ml ../ocaml/utils/arg_helper.mli ../ocaml/utils/ccomp.ml ../ocaml/utils/ccomp.mli ../ocaml/utils/clflags.ml ../ocaml/utils/clflags.mli ../ocaml/utils/consistbl.ml ../ocaml/utils/consistbl.mli ../ocaml/utils/identifiable.ml ../ocaml/utils/identifiable.mli ../ocaml/utils/misc.ml ../ocaml/utils/misc.mli ../ocaml/utils/numbers.ml ../ocaml/utils/numbers.mli ../ocaml/utils/profile.ml ../ocaml/utils/profile.mli ../ocaml/utils/tbl.ml ../ocaml/utils/tbl.mli ../ocaml/utils/warnings.ml ../ocaml/utils/warnings.mli ./common/bs_loc.ml ./common/bs_loc.mli ./common/bs_version.ml ./common/bs_version.mli ./common/bs_warnings.ml ./common/bs_warnings.mli ./common/ext_log.ml ./common/ext_log.mli ./common/js_config.ml ./common/js_config.mli ./common/lam_methname.ml ./common/lam_methname.mli ./core/bs_cmi_load.ml ./core/bs_conditional_initial.ml ./core/bs_conditional_initial.mli ./core/compile_rec_module.ml ./core/config_util.ml ./core/config_util.mli ./core/config_whole_compiler.ml ./core/config_whole_compiler.mli ./core/j.ml ./core/js_analyzer.ml ./core/js_analyzer.mli ./core/js_arr.ml ./core/js_arr.mli ./core/js_ast_util.ml ./core/js_ast_util.mli ./core/js_block_runtime.ml ./core/js_block_runtime.mli ./core/js_call_info.ml ./core/js_call_info.mli ./core/js_closure.ml ./core/js_closure.mli ./core/js_cmj_format.ml ./core/js_cmj_format.mli ./core/js_cmj_load.ml ./core/js_cmj_load.mli ./core/js_cmj_load_builtin_unit.ml ./core/js_dump.ml ./core/js_dump.mli ./core/js_dump_import_export.ml ./core/js_dump_import_export.mli ./core/js_dump_lit.ml ./core/js_dump_program.ml ./core/js_dump_program.mli ./core/js_dump_property.ml ./core/js_dump_property.mli ./core/js_dump_string.ml ./core/js_dump_string.mli ./core/js_exp_make.ml ./core/js_exp_make.mli ./core/js_fold.ml ./core/js_fold_basic.ml ./core/js_fold_basic.mli ./core/js_fun_env.ml ./core/js_fun_env.mli ./core/js_long.ml ./core/js_long.mli ./core/js_map.ml ./core/js_name_of_module_id.ml ./core/js_name_of_module_id.mli ./core/js_number.ml ./core/js_number.mli ./core/js_of_lam_array.ml ./core/js_of_lam_array.mli ./core/js_of_lam_block.ml ./core/js_of_lam_block.mli ./core/js_of_lam_exception.ml ./core/js_of_lam_exception.mli ./core/js_of_lam_option.ml ./core/js_of_lam_option.mli ./core/js_of_lam_string.ml ./core/js_of_lam_string.mli ./core/js_of_lam_variant.ml ./core/js_of_lam_variant.mli ./core/js_op.ml ./core/js_op_util.ml ./core/js_op_util.mli ./core/js_output.ml ./core/js_output.mli ./core/js_packages_info.ml ./core/js_packages_info.mli ./core/js_packages_state.ml ./core/js_packages_state.mli ./core/js_pass_debug.ml ./core/js_pass_debug.mli ./core/js_pass_flatten.ml ./core/js_pass_flatten.mli ./core/js_pass_flatten_and_mark_dead.ml ./core/js_pass_flatten_and_mark_dead.mli ./core/js_pass_get_used.ml ./core/js_pass_get_used.mli ./core/js_pass_scope.ml ./core/js_pass_scope.mli ./core/js_pass_tailcall_inline.ml ./core/js_pass_tailcall_inline.mli ./core/js_raw_info.ml ./core/js_shake.ml ./core/js_shake.mli ./core/js_stmt_make.ml ./core/js_stmt_make.mli ./core/lam.ml ./core/lam.mli ./core/lam_analysis.ml ./core/lam_analysis.mli ./core/lam_arity.ml ./core/lam_arity.mli ./core/lam_arity_analysis.ml ./core/lam_arity_analysis.mli ./core/lam_beta_reduce.ml ./core/lam_beta_reduce.mli ./core/lam_beta_reduce_util.ml ./core/lam_beta_reduce_util.mli ./core/lam_bounded_vars.ml ./core/lam_bounded_vars.mli ./core/lam_closure.ml ./core/lam_closure.mli ./core/lam_coercion.ml ./core/lam_coercion.mli ./core/lam_compat.ml ./core/lam_compat.mli ./core/lam_compile.ml ./core/lam_compile.mli ./core/lam_compile_const.ml ./core/lam_compile_const.mli ./core/lam_compile_context.ml ./core/lam_compile_context.mli ./core/lam_compile_env.ml ./core/lam_compile_env.mli ./core/lam_compile_external_call.ml ./core/lam_compile_external_call.mli ./core/lam_compile_external_obj.ml ./core/lam_compile_external_obj.mli ./core/lam_compile_main.ml ./core/lam_compile_main.mli ./core/lam_compile_primitive.ml ./core/lam_compile_primitive.mli ./core/lam_compile_util.ml ./core/lam_compile_util.mli ./core/lam_constant.ml ./core/lam_constant.mli ./core/lam_constant_convert.ml ./core/lam_constant_convert.mli ./core/lam_convert.ml ./core/lam_convert.mli ./core/lam_dce.ml ./core/lam_dce.mli ./core/lam_dispatch_primitive.ml ./core/lam_dispatch_primitive.mli ./core/lam_eta_conversion.ml ./core/lam_eta_conversion.mli ./core/lam_exit_code.ml ./core/lam_exit_code.mli ./core/lam_exit_count.ml ./core/lam_exit_count.mli ./core/lam_free_variables.ml ./core/lam_free_variables.mli ./core/lam_group.ml ./core/lam_group.mli ./core/lam_hit.ml ./core/lam_hit.mli ./core/lam_id_kind.ml ./core/lam_id_kind.mli ./core/lam_iter.ml ./core/lam_iter.mli ./core/lam_module_ident.ml ./core/lam_module_ident.mli ./core/lam_pass_alpha_conversion.ml ./core/lam_pass_alpha_conversion.mli ./core/lam_pass_collect.ml ./core/lam_pass_collect.mli ./core/lam_pass_count.ml ./core/lam_pass_count.mli ./core/lam_pass_deep_flatten.ml ./core/lam_pass_deep_flatten.mli ./core/lam_pass_eliminate_ref.ml ./core/lam_pass_eliminate_ref.mli ./core/lam_pass_exits.ml ./core/lam_pass_exits.mli ./core/lam_pass_lets_dce.ml ./core/lam_pass_lets_dce.mli ./core/lam_pass_remove_alias.ml ./core/lam_pass_remove_alias.mli ./core/lam_pointer_info.ml ./core/lam_pointer_info.mli ./core/lam_primitive.ml ./core/lam_primitive.mli ./core/lam_print.ml ./core/lam_print.mli ./core/lam_scc.ml ./core/lam_scc.mli ./core/lam_stats.ml ./core/lam_stats.mli ./core/lam_stats_export.ml ./core/lam_stats_export.mli ./core/lam_subst.ml ./core/lam_subst.mli ./core/lam_tag_info.ml ./core/lam_util.ml ./core/lam_util.mli ./core/lam_var_stats.ml ./core/lam_var_stats.mli ./core/matching_polyfill.ml ./core/matching_polyfill.mli ./core/polyvar_pattern_match.ml ./core/record_attributes_check.ml ./core/res_compmisc.ml ./core/res_compmisc.mli ./core/transl_single_field_record.ml ./depends/bs_exception.ml ./depends/bs_exception.mli ./ext/bsc_args.ml ./ext/bsc_args.mli ./ext/bsc_warnings.ml ./ext/ext_array.ml ./ext/ext_array.mli ./ext/ext_buffer.ml ./ext/ext_buffer.mli ./ext/ext_bytes.ml ./ext/ext_bytes.mli ./ext/ext_char.ml ./ext/ext_char.mli ./ext/ext_digest.ml ./ext/ext_digest.mli ./ext/ext_filename.ml ./ext/ext_filename.mli ./ext/ext_fmt.ml ./ext/ext_ident.ml ./ext/ext_ident.mli ./ext/ext_int.ml ./ext/ext_int.mli ./ext/ext_io.ml ./ext/ext_io.mli ./ext/ext_js_file_kind.ml ./ext/ext_js_suffix.ml ./ext/ext_list.ml ./ext/ext_list.mli ./ext/ext_marshal.ml ./ext/ext_marshal.mli ./ext/ext_modulename.ml ./ext/ext_modulename.mli ./ext/ext_namespace.ml ./ext/ext_namespace.mli ./ext/ext_option.ml ./ext/ext_option.mli ./ext/ext_path.ml ./ext/ext_path.mli ./ext/ext_pervasives.ml ./ext/ext_pervasives.mli ./ext/ext_pp.ml ./ext/ext_pp.mli ./ext/ext_pp_scope.ml ./ext/ext_pp_scope.mli ./ext/ext_ref.ml ./ext/ext_ref.mli ./ext/ext_scc.ml ./ext/ext_scc.mli ./ext/ext_spec.ml ./ext/ext_spec.mli ./ext/ext_string.ml ./ext/ext_string.mli ./ext/ext_string_array.ml ./ext/ext_string_array.mli ./ext/ext_sys.ml ./ext/ext_sys.mli ./ext/ext_utf8.ml ./ext/ext_utf8.mli ./ext/ext_util.ml ./ext/ext_util.mli ./ext/hash.ml ./ext/hash.mli ./ext/hash_gen.ml ./ext/hash_ident.ml ./ext/hash_ident.mli ./ext/hash_int.ml ./ext/hash_int.mli ./ext/hash_set.ml ./ext/hash_set.mli ./ext/hash_set_gen.ml ./ext/hash_set_ident.ml ./ext/hash_set_ident.mli ./ext/hash_set_ident_mask.ml ./ext/hash_set_ident_mask.mli ./ext/hash_set_poly.ml ./ext/hash_set_poly.mli ./ext/hash_set_string.ml ./ext/hash_set_string.mli ./ext/hash_string.ml ./ext/hash_string.mli ./ext/int_vec_util.ml ./ext/int_vec_util.mli ./ext/int_vec_vec.ml ./ext/int_vec_vec.mli ./ext/js_reserved_map.ml ./ext/js_reserved_map.mli ./ext/js_runtime_modules.ml ./ext/literals.ml ./ext/map_gen.ml ./ext/map_gen.mli ./ext/map_ident.ml ./ext/map_ident.mli ./ext/map_int.ml ./ext/map_int.mli ./ext/map_string.ml ./ext/map_string.mli ./ext/ordered_hash_map_gen.ml ./ext/ordered_hash_map_local_ident.ml ./ext/ordered_hash_map_local_ident.mli ./ext/set_gen.ml ./ext/set_gen.mli ./ext/set_ident.ml ./ext/set_ident.mli ./ext/set_string.ml ./ext/set_string.mli ./ext/vec.ml ./ext/vec.mli ./ext/vec_gen.ml ./ext/vec_int.ml ./ext/vec_int.mli ./js_parser/declaration_parser.ml ./js_parser/enum_common.ml ./js_parser/enum_parser.ml ./js_parser/expression_parser.ml ./js_parser/file_key.ml ./js_parser/flow_ast.ml ./js_parser/flow_ast_utils.ml ./js_parser/flow_ast_utils.mli ./js_parser/flow_lexer.ml ./js_parser/flow_lexer.mli ./js_parser/jsx_parser.ml ./js_parser/lex_env.ml ./js_parser/lex_result.ml ./js_parser/loc.ml ./js_parser/loc.mli ./js_parser/object_parser.ml ./js_parser/parse_error.ml ./js_parser/parser_common.ml ./js_parser/parser_env.ml ./js_parser/parser_env.mli ./js_parser/parser_flow.ml ./js_parser/pattern_cover.ml ./js_parser/pattern_parser.ml ./js_parser/sedlexing.ml ./js_parser/sedlexing.mli ./js_parser/statement_parser.ml ./js_parser/token.ml ./js_parser/type_parser.ml ./js_parser/wtf8.ml ./js_parser/wtf8.mli ./main/builtin_cmi_datasets.ml ./main/builtin_cmi_datasets.mli ./main/builtin_cmj_datasets.ml ./main/builtin_cmj_datasets.mli ./main/jsoo_common.ml ./main/jsoo_common.mli ./main/jsoo_main.ml ./main/jsoo_main.mli ./napkin/reactjs_jsx_ppx_v3.ml ./napkin/reactjs_jsx_ppx_v3.mli ./outcome_printer/outcome_printer_ns.ml ./outcome_printer/outcome_printer_ns.mli ./stubs/bs_hash_stubs.ml ./super_errors/super_env.ml ./super_errors/super_location.ml ./super_errors/super_location.mli ./super_errors/super_main.ml ./super_errors/super_misc.ml ./super_errors/super_misc.mli ./super_errors/super_pparse.ml ./super_errors/super_typecore.ml ./super_errors/super_typemod.ml ./super_errors/super_typetexp.ml ./syntax/ast_attributes.ml ./syntax/ast_attributes.mli ./syntax/ast_bs_open.ml ./syntax/ast_bs_open.mli ./syntax/ast_comb.ml ./syntax/ast_comb.mli ./syntax/ast_compatible.ml ./syntax/ast_compatible.mli ./syntax/ast_config.ml ./syntax/ast_config.mli ./syntax/ast_core_type.ml ./syntax/ast_core_type.mli ./syntax/ast_core_type_class_type.ml ./syntax/ast_core_type_class_type.mli ./syntax/ast_derive.ml ./syntax/ast_derive.mli ./syntax/ast_derive_abstract.ml ./syntax/ast_derive_abstract.mli ./syntax/ast_derive_js_mapper.ml ./syntax/ast_derive_js_mapper.mli ./syntax/ast_derive_projector.ml ./syntax/ast_derive_projector.mli ./syntax/ast_derive_util.ml ./syntax/ast_derive_util.mli ./syntax/ast_exp.ml ./syntax/ast_exp.mli ./syntax/ast_exp_apply.ml ./syntax/ast_exp_apply.mli ./syntax/ast_exp_extension.ml ./syntax/ast_exp_extension.mli ./syntax/ast_exp_handle_external.ml ./syntax/ast_exp_handle_external.mli ./syntax/ast_external.ml ./syntax/ast_external.mli ./syntax/ast_external_mk.ml ./syntax/ast_external_mk.mli ./syntax/ast_external_process.ml ./syntax/ast_external_process.mli ./syntax/ast_literal.ml ./syntax/ast_literal.mli ./syntax/ast_open_cxt.ml ./syntax/ast_open_cxt.mli ./syntax/ast_pat.ml ./syntax/ast_pat.mli ./syntax/ast_payload.ml ./syntax/ast_payload.mli ./syntax/ast_polyvar.ml ./syntax/ast_polyvar.mli ./syntax/ast_reason_pp.ml ./syntax/ast_reason_pp.mli ./syntax/ast_signature.ml ./syntax/ast_signature.mli ./syntax/ast_structure.ml ./syntax/ast_structure.mli ./syntax/ast_tdcls.ml ./syntax/ast_tdcls.mli ./syntax/ast_tuple_pattern_flatten.ml ./syntax/ast_tuple_pattern_flatten.mli ./syntax/ast_typ_uncurry.ml ./syntax/ast_typ_uncurry.mli ./syntax/ast_uncurry_apply.ml ./syntax/ast_uncurry_apply.mli ./syntax/ast_uncurry_gen.ml ./syntax/ast_uncurry_gen.mli ./syntax/ast_utf8_string.ml ./syntax/ast_utf8_string.mli ./syntax/ast_utf8_string_interp.ml ./syntax/ast_utf8_string_interp.mli ./syntax/ast_util.ml ./syntax/ast_util.mli ./syntax/bs_ast_invariant.ml ./syntax/bs_ast_invariant.mli ./syntax/bs_ast_mapper.ml ./syntax/bs_ast_mapper.mli ./syntax/bs_builtin_ppx.ml ./syntax/bs_builtin_ppx.mli ./syntax/bs_flow_ast_utils.ml ./syntax/bs_flow_ast_utils.mli ./syntax/bs_syntaxerr.ml ./syntax/bs_syntaxerr.mli ./syntax/classify_function.ml ./syntax/classify_function.mli ./syntax/external_arg_spec.ml ./syntax/external_arg_spec.mli ./syntax/external_ffi_types.ml ./syntax/external_ffi_types.mli ./syntax/ppx_entry.ml ./syntax/typemod_hide.ml \ No newline at end of file diff --git a/lib/4.06.1/unstable/js_refmt_compiler.ml b/lib/4.06.1/unstable/js_refmt_compiler.ml index 360eea346f..f03d85762a 100644 --- a/lib/4.06.1/unstable/js_refmt_compiler.ml +++ b/lib/4.06.1/unstable/js_refmt_compiler.ml @@ -408271,6 +408271,932 @@ let mapper : mapper = +end +module Reactjs_jsx_ppx_v3 : sig +#1 "reactjs_jsx_ppx_v3.mli" +(* + This is the module that handles turning Reason JSX' agnostic function call into + a ReasonReact-specific function call. Aka, this is a macro, using OCaml's ppx + facilities; https://whitequark.org/blog/2014/04/16/a-guide-to-extension- + points-in-ocaml/ + You wouldn't use this file directly; it's used by ReScript's + bsconfig.json. Specifically, there's a field called `react-jsx` inside the + field `reason`, which enables this ppx through some internal call in bsb +*) + +(* + There are two different transforms that can be selected in this file (v2 and v3): + v2: + transform `[@JSX] div(~props1=a, ~props2=b, ~children=[foo, bar], ())` into + `ReactDOMRe.createElement("div", ~props={"props1": 1, "props2": b}, [|foo, + bar|])`. + transform `[@JSX] div(~props1=a, ~props2=b, ~children=foo, ())` into + `ReactDOMRe.createElementVariadic("div", ~props={"props1": 1, "props2": b}, foo)`. + transform the upper-cased case + `[@JSX] Foo.createElement(~key=a, ~ref=b, ~foo=bar, ~children=[], ())` into + `ReasonReact.element(~key=a, ~ref=b, Foo.make(~foo=bar, [||]))` + transform `[@JSX] [foo]` into + `ReactDOMRe.createElement(ReasonReact.fragment, [|foo|])` + v3: + transform `[@JSX] div(~props1=a, ~props2=b, ~children=[foo, bar], ())` into + `ReactDOMRe.createDOMElementVariadic("div", ReactDOMRe.domProps(~props1=1, ~props2=b), [|foo, bar|])`. + transform the upper-cased case + `[@JSX] Foo.createElement(~key=a, ~ref=b, ~foo=bar, ~children=[], ())` into + `React.createElement(Foo.make, Foo.makeProps(~key=a, ~ref=b, ~foo=bar, ()))` + transform the upper-cased case + `[@JSX] Foo.createElement(~foo=bar, ~children=[foo, bar], ())` into + `React.createElementVariadic(Foo.make, Foo.makeProps(~foo=bar, ~children=React.null, ()), [|foo, bar|])` + transform `[@JSX] [foo]` into + `ReactDOMRe.createElement(ReasonReact.fragment, [|foo|])` +*) + +val rewrite_implementation : Parsetree.structure -> Parsetree.structure + +val rewrite_signature : Parsetree.signature -> Parsetree.signature + +end = struct +#1 "reactjs_jsx_ppx_v3.ml" +open Ast_helper +open Ast_mapper +open Asttypes +open Parsetree +open Longident + +let rec find_opt p = function [] -> None | x :: l -> if p x then Some x else find_opt p l + +let nolabel = Nolabel + +let labelled str = Labelled str + +let optional str = Optional str + +let isOptional str = match str with Optional _ -> true | _ -> false + +let isLabelled str = match str with Labelled _ -> true | _ -> false + +let getLabel str = match str with Optional str | Labelled str -> str | Nolabel -> "" + +let optionIdent = Lident "option" + +let constantString ~loc str = Ast_helper.Exp.constant ~loc (Pconst_string (str, None)) + +let safeTypeFromValue valueStr = + let valueStr = getLabel valueStr in + match String.sub valueStr 0 1 with "_" -> "T" ^ valueStr | _ -> valueStr + [@@raises Invalid_argument] + +let keyType loc = Typ.constr ~loc { loc; txt = optionIdent } [ Typ.constr ~loc { loc; txt = Lident "string" } [] ] + +type 'a children = ListLiteral of 'a | Exact of 'a + +type componentConfig = { propsName : string } + +(* if children is a list, convert it to an array while mapping each element. If not, just map over it, as usual *) +let transformChildrenIfListUpper ~loc ~mapper theList = + let rec transformChildren_ theList accum = + (* not in the sense of converting a list to an array; convert the AST + reprensentation of a list to the AST reprensentation of an array *) + match theList with + | { pexp_desc = Pexp_construct ({ txt = Lident "[]" }, None) } -> ( + match accum with + | [ singleElement ] -> Exact singleElement + | accum -> ListLiteral (Exp.array ~loc (List.rev accum)) ) + | { pexp_desc = Pexp_construct ({ txt = Lident "::" }, Some { pexp_desc = Pexp_tuple [ v; acc ] }) } -> + transformChildren_ acc (mapper.expr mapper v :: accum) + | notAList -> Exact (mapper.expr mapper notAList) + in + transformChildren_ theList [] + +let transformChildrenIfList ~loc ~mapper theList = + let rec transformChildren_ theList accum = + (* not in the sense of converting a list to an array; convert the AST + reprensentation of a list to the AST reprensentation of an array *) + match theList with + | { pexp_desc = Pexp_construct ({ txt = Lident "[]" }, None) } -> Exp.array ~loc (List.rev accum) + | { pexp_desc = Pexp_construct ({ txt = Lident "::" }, Some { pexp_desc = Pexp_tuple [ v; acc ] }) } -> + transformChildren_ acc (mapper.expr mapper v :: accum) + | notAList -> mapper.expr mapper notAList + in + transformChildren_ theList [] + +let extractChildren ?(removeLastPositionUnit = false) ~loc propsAndChildren = + let rec allButLast_ lst acc = + match lst with + | [] -> [] + | [ (Nolabel, { pexp_desc = Pexp_construct ({ txt = Lident "()" }, None) }) ] -> acc + | (Nolabel, _) :: _rest -> raise (Invalid_argument "JSX: found non-labelled argument before the last position") + | arg :: rest -> allButLast_ rest (arg :: acc) + [@@raises Invalid_argument] + in + let allButLast lst = allButLast_ lst [] |> List.rev [@@raises Invalid_argument] in + match List.partition (fun (label, _) -> label = labelled "children") propsAndChildren with + | [], props -> + (* no children provided? Place a placeholder list *) + (Exp.construct ~loc { loc; txt = Lident "[]" } None, if removeLastPositionUnit then allButLast props else props) + | [ (_, childrenExpr) ], props -> (childrenExpr, if removeLastPositionUnit then allButLast props else props) + | _ -> raise (Invalid_argument "JSX: somehow there's more than one `children` label") + [@@raises Invalid_argument] + +let unerasableIgnore loc = ({ loc; txt = "warning" }, PStr [ Str.eval (Exp.constant (Pconst_string ("-16", None))) ]) + +let merlinFocus = ({ loc = Location.none; txt = "merlin.focus" }, PStr []) + +(* Helper method to look up the [@react.component] attribute *) +let hasAttr (loc, _) = loc.txt = "react.component" + +(* Helper method to filter out any attribute that isn't [@react.component] *) +let otherAttrsPure (loc, _) = loc.txt <> "react.component" + +(* Iterate over the attributes and try to find the [@react.component] attribute *) +let hasAttrOnBinding { pvb_attributes } = find_opt hasAttr pvb_attributes <> None + +(* Finds the name of the variable the binding is assigned to, otherwise raises Invalid_argument *) +let getFnName binding = + match binding with + | { pvb_pat = { ppat_desc = Ppat_var { txt } } } -> txt + | _ -> raise (Invalid_argument "react.component calls cannot be destructured.") + [@@raises Invalid_argument] + +let makeNewBinding binding expression newName = + match binding with + | { pvb_pat = { ppat_desc = Ppat_var ppat_var } as pvb_pat } -> + { + binding with + pvb_pat = { pvb_pat with ppat_desc = Ppat_var { ppat_var with txt = newName } }; + pvb_expr = expression; + pvb_attributes = [ merlinFocus ]; + } + | _ -> raise (Invalid_argument "react.component calls cannot be destructured.") + [@@raises Invalid_argument] + +(* Lookup the value of `props` otherwise raise Invalid_argument error *) +let getPropsNameValue _acc (loc, exp) = + match (loc, exp) with + | { txt = Lident "props" }, { pexp_desc = Pexp_ident { txt = Lident str } } -> { propsName = str } + | { txt }, _ -> + raise (Invalid_argument ("react.component only accepts props as an option, given: " ^ Longident.last txt)) + [@@raises Invalid_argument] + +(* Lookup the `props` record or string as part of [@react.component] and store the name for use when rewriting *) +let getPropsAttr payload = + let defaultProps = { propsName = "Props" } in + match payload with + | Some (PStr ({ pstr_desc = Pstr_eval ({ pexp_desc = Pexp_record (recordFields, None) }, _) } :: _rest)) -> + List.fold_left getPropsNameValue defaultProps recordFields + | Some (PStr ({ pstr_desc = Pstr_eval ({ pexp_desc = Pexp_ident { txt = Lident "props" } }, _) } :: _rest)) -> + { propsName = "props" } + | Some (PStr ({ pstr_desc = Pstr_eval (_, _) } :: _rest)) -> + raise (Invalid_argument "react.component accepts a record config with props as an options.") + | _ -> defaultProps + [@@raises Invalid_argument] + +(* Plucks the label, loc, and type_ from an AST node *) +let pluckLabelDefaultLocType (label, default, _, _, loc, type_) = (label, default, loc, type_) + +(* Lookup the filename from the location information on the AST node and turn it into a valid module identifier *) +let filenameFromLoc (pstr_loc : Location.t) = + let fileName = match pstr_loc.loc_start.pos_fname with "" -> !Location.input_name | fileName -> fileName in + let fileName = try Filename.chop_extension (Filename.basename fileName) with Invalid_argument _ -> fileName in + let fileName = String.capitalize_ascii fileName in + fileName + +(* Build a string representation of a module name with segments separated by $ *) +let makeModuleName fileName nestedModules fnName = + let fullModuleName = + match (fileName, nestedModules, fnName) with + (* TODO: is this even reachable? It seems like the fileName always exists *) + | "", nestedModules, "make" -> nestedModules + | "", nestedModules, fnName -> List.rev (fnName :: nestedModules) + | fileName, nestedModules, "make" -> fileName :: List.rev nestedModules + | fileName, nestedModules, fnName -> fileName :: List.rev (fnName :: nestedModules) + in + let fullModuleName = String.concat "$" fullModuleName in + fullModuleName + +(* + AST node builders + These functions help us build AST nodes that are needed when transforming a [@react.component] into a + constructor and a props external +*) + +(* Build an AST node representing all named args for the `external` definition for a component's props *) +let rec recursivelyMakeNamedArgsForExternal list args = + match list with + | (label, default, loc, interiorType) :: tl -> + recursivelyMakeNamedArgsForExternal tl + (Typ.arrow ~loc label + ( match (label, interiorType, default) with + (* ~foo=1 *) + | label, None, Some _ -> + { ptyp_desc = Ptyp_var (safeTypeFromValue label); ptyp_loc = loc; ptyp_attributes = [] } + (* ~foo: int=1 *) + | _label, Some type_, Some _ -> type_ + (* ~foo: option(int)=? *) + | label, Some { ptyp_desc = Ptyp_constr ({ txt = Lident "option" }, [ type_ ]) }, _ + | label, Some { ptyp_desc = Ptyp_constr ({ txt = Ldot (Lident "*predef*", "option") }, [ type_ ]) }, _ + (* ~foo: int=? - note this isnt valid. but we want to get a type error *) + | label, Some type_, _ + when isOptional label -> + type_ + (* ~foo=? *) + | label, None, _ when isOptional label -> + { ptyp_desc = Ptyp_var (safeTypeFromValue label); ptyp_loc = loc; ptyp_attributes = [] } + (* ~foo *) + | label, None, _ -> { ptyp_desc = Ptyp_var (safeTypeFromValue label); ptyp_loc = loc; ptyp_attributes = [] } + | _label, Some type_, _ -> type_ ) + args) + | [] -> args + [@@raises Invalid_argument] + +(* Build an AST node for the [@bs.obj] representing props for a component *) +let makePropsValue fnName loc namedArgListWithKeyAndRef propsType = + let propsName = fnName ^ "Props" in + { + pval_name = { txt = propsName; loc }; + pval_type = + recursivelyMakeNamedArgsForExternal namedArgListWithKeyAndRef + (Typ.arrow nolabel + { ptyp_desc = Ptyp_constr ({ txt = Lident "unit"; loc }, []); ptyp_loc = loc; ptyp_attributes = [] } + propsType); + pval_prim = [ "" ]; + pval_attributes = [ ({ txt = "bs.obj"; loc }, PStr []) ]; + pval_loc = loc; + } + [@@raises Invalid_argument] + +(* Build an AST node representing an `external` with the definition of the [@bs.obj] *) +let makePropsExternal fnName loc namedArgListWithKeyAndRef propsType = + { pstr_loc = loc; pstr_desc = Pstr_primitive (makePropsValue fnName loc namedArgListWithKeyAndRef propsType) } + [@@raises Invalid_argument] + +(* Build an AST node for the signature of the `external` definition *) +let makePropsExternalSig fnName loc namedArgListWithKeyAndRef propsType = + { psig_loc = loc; psig_desc = Psig_value (makePropsValue fnName loc namedArgListWithKeyAndRef propsType) } + [@@raises Invalid_argument] + +(* Build an AST node for the props name when converted to a Js.t inside the function signature *) +let makePropsName ~loc name = { ppat_desc = Ppat_var { txt = name; loc }; ppat_loc = loc; ppat_attributes = [] } + +let makeObjectField loc (str, attrs, type_) = Otag ({ loc; txt = str }, attrs, type_) + +(* Build an AST node representing a "closed" Js.t object representing a component's props *) +let makePropsType ~loc namedTypeList = + Typ.mk ~loc + (Ptyp_constr + ( { txt = Ldot (Lident "Js", "t"); loc }, + [ + { + ptyp_desc = Ptyp_object (List.map (makeObjectField loc) namedTypeList, Closed); + ptyp_loc = loc; + ptyp_attributes = []; + }; + ] )) + +(* Builds an AST node for the entire `external` definition of props *) +let makeExternalDecl fnName loc namedArgListWithKeyAndRef namedTypeList = + makePropsExternal fnName loc + (List.map pluckLabelDefaultLocType namedArgListWithKeyAndRef) + (makePropsType ~loc namedTypeList) + [@@raises Invalid_argument] + +(* TODO: some line number might still be wrong *) +let jsxMapper () = + let jsxVersion = ref None in + + let transformUppercaseCall3 modulePath mapper loc attrs _ callArguments = + let children, argsWithLabels = extractChildren ~loc ~removeLastPositionUnit:true callArguments in + let argsForMake = argsWithLabels in + let childrenExpr = transformChildrenIfListUpper ~loc ~mapper children in + let recursivelyTransformedArgsForMake = + argsForMake |> List.map (fun (label, expression) -> (label, mapper.expr mapper expression)) + in + let childrenArg = ref None in + let args = + recursivelyTransformedArgsForMake + @ ( match childrenExpr with + | Exact children -> [ (labelled "children", children) ] + | ListLiteral { pexp_desc = Pexp_array list } when list = [] -> [] + | ListLiteral expression -> + (* this is a hack to support react components that introspect into their children *) + childrenArg := Some expression; + [ (labelled "children", Exp.ident ~loc { loc; txt = Ldot (Lident "React", "null") }) ] ) + @ [ (nolabel, Exp.construct ~loc { loc; txt = Lident "()" } None) ] + in + let isCap str = + let first = String.sub str 0 1 [@@raises Invalid_argument] in + let capped = String.uppercase_ascii first in + first = capped + [@@raises Invalid_argument] + in + let ident = + match modulePath with + | Lident _ -> Ldot (modulePath, "make") + | Ldot (_modulePath, value) as fullPath when isCap value -> Ldot (fullPath, "make") + | modulePath -> modulePath + in + let propsIdent = + match ident with + | Lident path -> Lident (path ^ "Props") + | Ldot (ident, path) -> Ldot (ident, path ^ "Props") + | _ -> raise (Invalid_argument "JSX name can't be the result of function applications") + in + let props = Exp.apply ~attrs ~loc (Exp.ident ~loc { loc; txt = propsIdent }) args in + (* handle key, ref, children *) + (* React.createElement(Component.make, props, ...children) *) + match !childrenArg with + | None -> + Exp.apply ~loc ~attrs + (Exp.ident ~loc { loc; txt = Ldot (Lident "React", "createElement") }) + [ (nolabel, Exp.ident ~loc { txt = ident; loc }); (nolabel, props) ] + | Some children -> + Exp.apply ~loc ~attrs + (Exp.ident ~loc { loc; txt = Ldot (Lident "React", "createElementVariadic") }) + [ (nolabel, Exp.ident ~loc { txt = ident; loc }); (nolabel, props); (nolabel, children) ] + [@@raises Invalid_argument] + in + + let transformLowercaseCall3 mapper loc attrs callArguments id = + let children, nonChildrenProps = extractChildren ~loc callArguments in + let componentNameExpr = constantString ~loc id in + let childrenExpr = transformChildrenIfList ~loc ~mapper children in + let createElementCall = + match children with + (* [@JSX] div(~children=[a]), coming from
a
*) + | { + pexp_desc = + ( Pexp_construct ({ txt = Lident "::" }, Some { pexp_desc = Pexp_tuple _ }) + | Pexp_construct ({ txt = Lident "[]" }, None) ); + } -> + "createDOMElementVariadic" + (* [@JSX] div(~children= value), coming from
...(value)
*) + | _ -> + raise + (Invalid_argument + "A spread as a DOM element's children don't make sense written together. You can simply remove the \ + spread.") + in + let args = + match nonChildrenProps with + | [ _justTheUnitArgumentAtEnd ] -> + [ (* "div" *) (nolabel, componentNameExpr); (* [|moreCreateElementCallsHere|] *) (nolabel, childrenExpr) ] + | nonEmptyProps -> + let propsCall = + Exp.apply ~loc + (Exp.ident ~loc { loc; txt = Ldot (Lident "ReactDOMRe", "domProps") }) + (nonEmptyProps |> List.map (fun (label, expression) -> (label, mapper.expr mapper expression))) + in + [ + (* "div" *) + (nolabel, componentNameExpr); + (* ReactDOMRe.props(~className=blabla, ~foo=bar, ()) *) + (labelled "props", propsCall); + (* [|moreCreateElementCallsHere|] *) + (nolabel, childrenExpr); + ] + in + Exp.apply ~loc (* throw away the [@JSX] attribute and keep the others, if any *) ~attrs + (* ReactDOMRe.createElement *) + (Exp.ident ~loc { loc; txt = Ldot (Lident "ReactDOMRe", createElementCall) }) + args + [@@raises Invalid_argument] + in + + let rec recursivelyTransformNamedArgsForMake mapper expr list = + let expr = mapper.expr mapper expr in + match expr.pexp_desc with + (* TODO: make this show up with a loc. *) + | Pexp_fun (Labelled "key", _, _, _) | Pexp_fun (Optional "key", _, _, _) -> + raise + (Invalid_argument + "Key cannot be accessed inside of a component. Don't worry - you can always key a component from its \ + parent!") + | Pexp_fun (Labelled "ref", _, _, _) | Pexp_fun (Optional "ref", _, _, _) -> + raise (Invalid_argument "Ref cannot be passed as a normal prop. Please use `forwardRef` API instead.") + | Pexp_fun (arg, default, pattern, expression) when isOptional arg || isLabelled arg -> + let () = + match (isOptional arg, pattern, default) with + | true, { ppat_desc = Ppat_constraint (_, { ptyp_desc }) }, None -> ( + match ptyp_desc with + | Ptyp_constr ({ txt = Lident "option" }, [ _ ]) -> () + | _ -> + let currentType = + match ptyp_desc with + | Ptyp_constr ({ txt }, []) -> String.concat "." (Longident.flatten txt) + | Ptyp_constr ({ txt }, _innerTypeArgs) -> String.concat "." (Longident.flatten txt) ^ "(...)" + | _ -> "..." + in + Location.prerr_warning pattern.ppat_loc + (Preprocessor + (Printf.sprintf + "ReasonReact: optional argument annotations must have explicit `option`. Did you mean \ + `option(%s)=?`?" + currentType)) ) + | _ -> () + in + let alias = + match pattern with + | { ppat_desc = Ppat_alias (_, { txt }) | Ppat_var { txt } } -> txt + | { ppat_desc = Ppat_any } -> "_" + | _ -> getLabel arg + in + let type_ = match pattern with { ppat_desc = Ppat_constraint (_, type_) } -> Some type_ | _ -> None in + + recursivelyTransformNamedArgsForMake mapper expression + ((arg, default, pattern, alias, pattern.ppat_loc, type_) :: list) + | Pexp_fun (Nolabel, _, { ppat_desc = Ppat_construct ({ txt = Lident "()" }, _) | Ppat_any }, _expression) -> + (list, None) + | Pexp_fun + ( Nolabel, + _, + { ppat_desc = Ppat_var { txt } | Ppat_constraint ({ ppat_desc = Ppat_var { txt } }, _) }, + _expression ) -> + (list, Some txt) + | Pexp_fun (Nolabel, _, pattern, _expression) -> + Location.raise_errorf ~loc:pattern.ppat_loc + "ReasonReact: react.component refs only support plain arguments and type annotations." + | _ -> (list, None) + [@@raises Invalid_argument] + in + + let argToType types (name, default, _noLabelName, _alias, loc, type_) = + match (type_, name, default) with + | Some { ptyp_desc = Ptyp_constr ({ txt = Lident "option" }, [ type_ ]) }, name, _ when isOptional name -> + ( getLabel name, + [], + { type_ with ptyp_desc = Ptyp_constr ({ loc = type_.ptyp_loc; txt = optionIdent }, [ type_ ]) } ) + :: types + | Some type_, name, Some _default -> + ( getLabel name, + [], + { ptyp_desc = Ptyp_constr ({ loc; txt = optionIdent }, [ type_ ]); ptyp_loc = loc; ptyp_attributes = [] } ) + :: types + | Some type_, name, _ -> (getLabel name, [], type_) :: types + | None, name, _ when isOptional name -> + ( getLabel name, + [], + { + ptyp_desc = + Ptyp_constr + ( { loc; txt = optionIdent }, + [ { ptyp_desc = Ptyp_var (safeTypeFromValue name); ptyp_loc = loc; ptyp_attributes = [] } ] ); + ptyp_loc = loc; + ptyp_attributes = []; + } ) + :: types + | None, name, _ when isLabelled name -> + (getLabel name, [], { ptyp_desc = Ptyp_var (safeTypeFromValue name); ptyp_loc = loc; ptyp_attributes = [] }) + :: types + | _ -> types + [@@raises Invalid_argument] + in + + let argToConcreteType types (name, loc, type_) = + match name with + | name when isLabelled name -> (getLabel name, [], type_) :: types + | name when isOptional name -> (getLabel name, [], Typ.constr ~loc { loc; txt = optionIdent } [ type_ ]) :: types + | _ -> types + in + + let nestedModules = ref [] in + let transformComponentDefinition mapper structure returnStructures = + match structure with + (* external *) + | { + pstr_loc; + pstr_desc = Pstr_primitive ({ pval_name = { txt = fnName }; pval_attributes; pval_type } as value_description); + } as pstr -> ( + match List.filter hasAttr pval_attributes with + | [] -> structure :: returnStructures + | [ _ ] -> + let rec getPropTypes types ({ ptyp_loc; ptyp_desc } as fullType) = + match ptyp_desc with + | Ptyp_arrow (name, type_, ({ ptyp_desc = Ptyp_arrow _ } as rest)) when isLabelled name || isOptional name + -> + getPropTypes ((name, ptyp_loc, type_) :: types) rest + | Ptyp_arrow (Nolabel, _type, rest) -> getPropTypes types rest + | Ptyp_arrow (name, type_, returnValue) when isLabelled name || isOptional name -> + (returnValue, (name, returnValue.ptyp_loc, type_) :: types) + | _ -> (fullType, types) + in + let innerType, propTypes = getPropTypes [] pval_type in + let namedTypeList = List.fold_left argToConcreteType [] propTypes in + let pluckLabelAndLoc (label, loc, type_) = (label, None (* default *), loc, Some type_) in + let retPropsType = makePropsType ~loc:pstr_loc namedTypeList in + let externalPropsDecl = + makePropsExternal fnName pstr_loc + ((optional "key", None, pstr_loc, Some (keyType pstr_loc)) :: List.map pluckLabelAndLoc propTypes) + retPropsType + in + (* can't be an arrow because it will defensively uncurry *) + let newExternalType = + Ptyp_constr ({ loc = pstr_loc; txt = Ldot (Lident "React", "componentLike") }, [ retPropsType; innerType ]) + in + let newStructure = + { + pstr with + pstr_desc = + Pstr_primitive + { + value_description with + pval_type = { pval_type with ptyp_desc = newExternalType }; + pval_attributes = List.filter otherAttrsPure pval_attributes; + }; + } + in + externalPropsDecl :: newStructure :: returnStructures + | _ -> raise (Invalid_argument "Only one react.component call can exist on a component at one time") ) + (* let component = ... *) + | { pstr_loc; pstr_desc = Pstr_value (recFlag, valueBindings) } -> + let fileName = filenameFromLoc pstr_loc in + let emptyLoc = Location.in_file fileName in + let mapBinding binding = + if hasAttrOnBinding binding then + let bindingLoc = binding.pvb_loc in + let bindingPatLoc = binding.pvb_pat.ppat_loc in + let binding = { binding with pvb_pat = { binding.pvb_pat with ppat_loc = emptyLoc }; pvb_loc = emptyLoc } in + let fnName = getFnName binding in + let internalFnName = fnName ^ "$Internal" in + let fullModuleName = makeModuleName fileName !nestedModules fnName in + let modifiedBindingOld binding = + let expression = binding.pvb_expr in + (* TODO: there is a long-tail of unsupported features inside of blocks - Pexp_letmodule , Pexp_letexception , Pexp_ifthenelse *) + let rec spelunkForFunExpression expression = + match expression with + (* let make = (~prop) => ... *) + | { pexp_desc = Pexp_fun _ } -> expression + (* let make = {let foo = bar in (~prop) => ...} *) + | { pexp_desc = Pexp_let (_recursive, _vbs, returnExpression) } -> + (* here's where we spelunk! *) + spelunkForFunExpression returnExpression + (* let make = React.forwardRef((~prop) => ...) *) + | { pexp_desc = Pexp_apply (_wrapperExpression, [ (Nolabel, innerFunctionExpression) ]) } -> + spelunkForFunExpression innerFunctionExpression + | { pexp_desc = Pexp_sequence (_wrapperExpression, innerFunctionExpression) } -> + spelunkForFunExpression innerFunctionExpression + | _ -> + raise + (Invalid_argument + "react.component calls can only be on function definitions or component wrappers (forwardRef, \ + memo).") + [@@raises Invalid_argument] + in + spelunkForFunExpression expression + in + let modifiedBinding binding = + let hasApplication = ref false in + let wrapExpressionWithBinding expressionFn expression = + Vb.mk ~loc:bindingLoc + ~attrs:(List.filter otherAttrsPure binding.pvb_attributes) + (Pat.var ~loc:bindingPatLoc { loc = bindingPatLoc; txt = fnName }) + (expressionFn expression) + in + let expression = binding.pvb_expr in + let unerasableIgnoreExp exp = + { exp with pexp_attributes = unerasableIgnore emptyLoc :: exp.pexp_attributes } + in + (* TODO: there is a long-tail of unsupported features inside of blocks - Pexp_letmodule , Pexp_letexception , Pexp_ifthenelse *) + let rec spelunkForFunExpression expression = + match expression with + (* let make = (~prop) => ... with no final unit *) + | { + pexp_desc = + Pexp_fun + ( ((Labelled _ | Optional _) as label), + default, + pattern, + ({ pexp_desc = Pexp_fun _ } as internalExpression) ); + } -> + let wrap, hasUnit, exp = spelunkForFunExpression internalExpression in + ( wrap, + hasUnit, + unerasableIgnoreExp { expression with pexp_desc = Pexp_fun (label, default, pattern, exp) } ) + (* let make = (()) => ... *) + (* let make = (_) => ... *) + | { + pexp_desc = + Pexp_fun + ( Nolabel, + _default, + { ppat_desc = Ppat_construct ({ txt = Lident "()" }, _) | Ppat_any }, + _internalExpression ); + } -> + ((fun a -> a), true, expression) + (* let make = (~prop) => ... *) + | { pexp_desc = Pexp_fun ((Labelled _ | Optional _), _default, _pattern, _internalExpression) } -> + ((fun a -> a), false, unerasableIgnoreExp expression) + (* let make = (prop) => ... *) + | { pexp_desc = Pexp_fun (_nolabel, _default, pattern, _internalExpression) } -> + if hasApplication.contents then ((fun a -> a), false, unerasableIgnoreExp expression) + else + Location.raise_errorf ~loc:pattern.ppat_loc + "ReasonReact: props need to be labelled arguments.\n\ + \ If you are working with refs be sure to wrap with React.forwardRef.\n\ + \ If your component doesn't have any props use () or _ instead of a name." + (* let make = {let foo = bar in (~prop) => ...} *) + | { pexp_desc = Pexp_let (recursive, vbs, internalExpression) } -> + (* here's where we spelunk! *) + let wrap, hasUnit, exp = spelunkForFunExpression internalExpression in + (wrap, hasUnit, { expression with pexp_desc = Pexp_let (recursive, vbs, exp) }) + (* let make = React.forwardRef((~prop) => ...) *) + | { pexp_desc = Pexp_apply (wrapperExpression, [ (Nolabel, internalExpression) ]) } -> + let () = hasApplication := true in + let _, hasUnit, exp = spelunkForFunExpression internalExpression in + ((fun exp -> Exp.apply wrapperExpression [ (nolabel, exp) ]), hasUnit, exp) + | { pexp_desc = Pexp_sequence (wrapperExpression, internalExpression) } -> + let wrap, hasUnit, exp = spelunkForFunExpression internalExpression in + (wrap, hasUnit, { expression with pexp_desc = Pexp_sequence (wrapperExpression, exp) }) + | e -> ((fun a -> a), false, e) + in + let wrapExpression, hasUnit, expression = spelunkForFunExpression expression in + (wrapExpressionWithBinding wrapExpression, hasUnit, expression) + in + let bindingWrapper, hasUnit, expression = modifiedBinding binding in + let reactComponentAttribute = + try Some (List.find hasAttr binding.pvb_attributes) with Not_found -> None + in + let _attr_loc, payload = + match reactComponentAttribute with + | Some (loc, payload) -> (loc.loc, Some payload) + | None -> (emptyLoc, None) + in + let props = getPropsAttr payload in + (* do stuff here! *) + let namedArgList, forwardRef = + recursivelyTransformNamedArgsForMake mapper (modifiedBindingOld binding) [] + in + let namedArgListWithKeyAndRef = + (optional "key", None, Pat.var { txt = "key"; loc = emptyLoc }, "key", emptyLoc, Some (keyType emptyLoc)) + :: namedArgList + in + let namedArgListWithKeyAndRef = + match forwardRef with + | Some _ -> + (optional "ref", None, Pat.var { txt = "key"; loc = emptyLoc }, "ref", emptyLoc, None) + :: namedArgListWithKeyAndRef + | None -> namedArgListWithKeyAndRef + in + let namedArgListWithKeyAndRefForNew = + match forwardRef with + | Some txt -> namedArgList @ [ (nolabel, None, Pat.var { txt; loc = emptyLoc }, txt, emptyLoc, None) ] + | None -> namedArgList + in + let pluckArg (label, _, _, alias, loc, _) = + let labelString = + match label with label when isOptional label || isLabelled label -> getLabel label | _ -> "" + in + ( label, + match labelString with + | "" -> Exp.ident ~loc { txt = Lident alias; loc } + | labelString -> + Exp.apply ~loc + (Exp.ident ~loc { txt = Lident "##"; loc }) + [ + (nolabel, Exp.ident ~loc { txt = Lident props.propsName; loc }); + (nolabel, Exp.ident ~loc { txt = Lident labelString; loc }); + ] ) + in + let namedTypeList = List.fold_left argToType [] namedArgList in + let loc = emptyLoc in + let externalDecl = makeExternalDecl fnName loc namedArgListWithKeyAndRef namedTypeList in + let innerExpressionArgs = + List.map pluckArg namedArgListWithKeyAndRefForNew + @ if hasUnit then [ (Nolabel, Exp.construct { loc; txt = Lident "()" } None) ] else [] + in + let innerExpression = + Exp.apply + (Exp.ident + { loc; txt = Lident (match recFlag with Recursive -> internalFnName | Nonrecursive -> fnName) }) + innerExpressionArgs + in + let innerExpressionWithRef = + match forwardRef with + | Some txt -> + { + innerExpression with + pexp_desc = + Pexp_fun + ( nolabel, + None, + { ppat_desc = Ppat_var { txt; loc = emptyLoc }; ppat_loc = emptyLoc; ppat_attributes = [] }, + innerExpression ); + } + | None -> innerExpression + in + let fullExpression = + Exp.fun_ nolabel None + { + ppat_desc = + Ppat_constraint + (makePropsName ~loc:emptyLoc props.propsName, makePropsType ~loc:emptyLoc namedTypeList); + ppat_loc = emptyLoc; + ppat_attributes = []; + } + innerExpressionWithRef + in + let fullExpression = + match fullModuleName with + | "" -> fullExpression + | txt -> + Exp.let_ Nonrecursive + [ Vb.mk ~loc:emptyLoc (Pat.var ~loc:emptyLoc { loc = emptyLoc; txt }) fullExpression ] + (Exp.ident ~loc:emptyLoc { loc = emptyLoc; txt = Lident txt }) + in + let bindings, newBinding = + match recFlag with + | Recursive -> + ( [ + bindingWrapper + (Exp.let_ ~loc:emptyLoc Recursive + [ + makeNewBinding binding expression internalFnName; + Vb.mk (Pat.var { loc = emptyLoc; txt = fnName }) fullExpression; + ] + (Exp.ident { loc = emptyLoc; txt = Lident fnName })); + ], + None ) + | Nonrecursive -> + ([ { binding with pvb_expr = expression; pvb_attributes = [] } ], Some (bindingWrapper fullExpression)) + in + (Some externalDecl, bindings, newBinding) + else (None, [ binding ], None) + [@@raises Invalid_argument] + in + let structuresAndBinding = List.map mapBinding valueBindings in + let otherStructures (extern, binding, newBinding) (externs, bindings, newBindings) = + let externs = match extern with Some extern -> extern :: externs | None -> externs in + let newBindings = + match newBinding with Some newBinding -> newBinding :: newBindings | None -> newBindings + in + (externs, binding @ bindings, newBindings) + in + let externs, bindings, newBindings = List.fold_right otherStructures structuresAndBinding ([], [], []) in + externs + @ [ { pstr_loc; pstr_desc = Pstr_value (recFlag, bindings) } ] + @ ( match newBindings with + | [] -> [] + | newBindings -> [ { pstr_loc = emptyLoc; pstr_desc = Pstr_value (recFlag, newBindings) } ] ) + @ returnStructures + | structure -> structure :: returnStructures + [@@raises Invalid_argument] + in + + let reactComponentTransform mapper structures = + List.fold_right (transformComponentDefinition mapper) structures [] + [@@raises Invalid_argument] + in + + let transformComponentSignature _mapper signature returnSignatures = + match signature with + | { psig_loc; psig_desc = Psig_value ({ pval_name = { txt = fnName }; pval_attributes; pval_type } as psig_desc) } + as psig -> ( + match List.filter hasAttr pval_attributes with + | [] -> signature :: returnSignatures + | [ _ ] -> + let rec getPropTypes types ({ ptyp_loc; ptyp_desc } as fullType) = + match ptyp_desc with + | Ptyp_arrow (name, type_, ({ ptyp_desc = Ptyp_arrow _ } as rest)) when isOptional name || isLabelled name + -> + getPropTypes ((name, ptyp_loc, type_) :: types) rest + | Ptyp_arrow (Nolabel, _type, rest) -> getPropTypes types rest + | Ptyp_arrow (name, type_, returnValue) when isOptional name || isLabelled name -> + (returnValue, (name, returnValue.ptyp_loc, type_) :: types) + | _ -> (fullType, types) + in + let innerType, propTypes = getPropTypes [] pval_type in + let namedTypeList = List.fold_left argToConcreteType [] propTypes in + let pluckLabelAndLoc (label, loc, type_) = (label, None, loc, Some type_) in + let retPropsType = makePropsType ~loc:psig_loc namedTypeList in + let externalPropsDecl = + makePropsExternalSig fnName psig_loc + ((optional "key", None, psig_loc, Some (keyType psig_loc)) :: List.map pluckLabelAndLoc propTypes) + retPropsType + in + (* can't be an arrow because it will defensively uncurry *) + let newExternalType = + Ptyp_constr ({ loc = psig_loc; txt = Ldot (Lident "React", "componentLike") }, [ retPropsType; innerType ]) + in + let newStructure = + { + psig with + psig_desc = + Psig_value + { + psig_desc with + pval_type = { pval_type with ptyp_desc = newExternalType }; + pval_attributes = List.filter otherAttrsPure pval_attributes; + }; + } + in + externalPropsDecl :: newStructure :: returnSignatures + | _ -> raise (Invalid_argument "Only one react.component call can exist on a component at one time") ) + | signature -> signature :: returnSignatures + [@@raises Invalid_argument] + in + + let reactComponentSignatureTransform mapper signatures = + List.fold_right (transformComponentSignature mapper) signatures [] + [@@raises Invalid_argument] + in + + let transformJsxCall mapper callExpression callArguments attrs = + match callExpression.pexp_desc with + | Pexp_ident caller -> ( + match caller with + | { txt = Lident "createElement" } -> + raise (Invalid_argument "JSX: `createElement` should be preceeded by a module name.") + (* Foo.createElement(~prop1=foo, ~prop2=bar, ~children=[], ()) *) + | { loc; txt = Ldot (modulePath, ("createElement" | "make")) } -> ( + match !jsxVersion with + | None | Some 3 -> transformUppercaseCall3 modulePath mapper loc attrs callExpression callArguments + | Some _ -> raise (Invalid_argument "JSX: the JSX version must be 3") ) + (* div(~prop1=foo, ~prop2=bar, ~children=[bla], ()) *) + (* turn that into + ReactDOMRe.createElement(~props=ReactDOMRe.props(~props1=foo, ~props2=bar, ()), [|bla|]) *) + | { loc; txt = Lident id } -> ( + match !jsxVersion with + | None | Some 3 -> transformLowercaseCall3 mapper loc attrs callArguments id + | Some _ -> raise (Invalid_argument "JSX: the JSX version must be 3") ) + | { txt = Ldot (_, anythingNotCreateElementOrMake) } -> + raise + (Invalid_argument + ( "JSX: the JSX attribute should be attached to a `YourModuleName.createElement` or \ + `YourModuleName.make` call. We saw `" ^ anythingNotCreateElementOrMake ^ "` instead" )) + | { txt = Lapply _ } -> + (* don't think there's ever a case where this is reached *) + raise (Invalid_argument "JSX: encountered a weird case while processing the code. Please report this!") ) + | _ -> raise (Invalid_argument "JSX: `createElement` should be preceeded by a simple, direct module name.") + [@@raises Invalid_argument] + in + + let signature mapper signature = + default_mapper.signature mapper @@ reactComponentSignatureTransform mapper signature + [@@raises Invalid_argument] + in + + let structure mapper structure = + match structure with structures -> default_mapper.structure mapper @@ reactComponentTransform mapper structures + [@@raises Invalid_argument] + in + + let expr mapper expression = + match expression with + (* Does the function application have the @JSX attribute? *) + | { pexp_desc = Pexp_apply (callExpression, callArguments); pexp_attributes } -> ( + let jsxAttribute, nonJSXAttributes = + List.partition (fun (attribute, _) -> attribute.txt = "JSX") pexp_attributes + in + match (jsxAttribute, nonJSXAttributes) with + (* no JSX attribute *) + | [], _ -> default_mapper.expr mapper expression + | _, nonJSXAttributes -> transformJsxCall mapper callExpression callArguments nonJSXAttributes ) + (* is it a list with jsx attribute? Reason <>foo desugars to [@JSX][foo]*) + | { + pexp_desc = + ( Pexp_construct ({ txt = Lident "::"; loc }, Some { pexp_desc = Pexp_tuple _ }) + | Pexp_construct ({ txt = Lident "[]"; loc }, None) ); + pexp_attributes; + } as listItems -> ( + let jsxAttribute, nonJSXAttributes = + List.partition (fun (attribute, _) -> attribute.txt = "JSX") pexp_attributes + in + match (jsxAttribute, nonJSXAttributes) with + (* no JSX attribute *) + | [], _ -> default_mapper.expr mapper expression + | _, nonJSXAttributes -> + let fragment = Exp.ident ~loc { loc; txt = Ldot (Lident "ReasonReact", "fragment") } in + let childrenExpr = transformChildrenIfList ~loc ~mapper listItems in + let args = + [ (* "div" *) (nolabel, fragment); (* [|moreCreateElementCallsHere|] *) (nolabel, childrenExpr) ] + in + Exp.apply ~loc (* throw away the [@JSX] attribute and keep the others, if any *) ~attrs:nonJSXAttributes + (* ReactDOMRe.createElement *) + (Exp.ident ~loc { loc; txt = Ldot (Lident "ReactDOMRe", "createElement") }) + args ) + (* Delegate to the default mapper, a deep identity traversal *) + | e -> default_mapper.expr mapper e + [@@raises Invalid_argument] + in + + let module_binding mapper module_binding = + let _ = nestedModules := module_binding.pmb_name.txt :: !nestedModules in + let mapped = default_mapper.module_binding mapper module_binding in + let _ = nestedModules := List.tl !nestedModules in + mapped + [@@raises Failure] + in + { default_mapper with structure; expr; signature; module_binding } + [@@raises Invalid_argument, Failure] + +let rewrite_implementation (code : Parsetree.structure) : Parsetree.structure = + let mapper = jsxMapper () in + mapper.structure mapper code + [@@raises Invalid_argument, Failure] + +let rewrite_signature (code : Parsetree.signature) : Parsetree.signature = + let mapper = jsxMapper () in + mapper.signature mapper code + [@@raises Invalid_argument, Failure] + end module Ppx_entry = struct diff --git a/lib/4.06.1/unstable/js_refmt_compiler.ml.d b/lib/4.06.1/unstable/js_refmt_compiler.ml.d index 4b5d504ebb..a4e8c19ac7 100644 --- a/lib/4.06.1/unstable/js_refmt_compiler.ml.d +++ b/lib/4.06.1/unstable/js_refmt_compiler.ml.d @@ -1 +1 @@ -../lib/4.06.1/unstable/js_refmt_compiler.ml: ../ocaml/bytecomp/lambda.ml ../ocaml/bytecomp/lambda.mli ../ocaml/bytecomp/matching.ml ../ocaml/bytecomp/matching.mli ../ocaml/bytecomp/printlambda.ml ../ocaml/bytecomp/printlambda.mli ../ocaml/bytecomp/switch.ml ../ocaml/bytecomp/switch.mli ../ocaml/bytecomp/translattribute.ml ../ocaml/bytecomp/translattribute.mli ../ocaml/bytecomp/translclass.ml ../ocaml/bytecomp/translclass.mli ../ocaml/bytecomp/translcore.ml ../ocaml/bytecomp/translcore.mli ../ocaml/bytecomp/translmod.ml ../ocaml/bytecomp/translmod.mli ../ocaml/bytecomp/translobj.ml ../ocaml/bytecomp/translobj.mli ../ocaml/parsing/ast_helper.ml ../ocaml/parsing/ast_helper.mli ../ocaml/parsing/ast_iterator.ml ../ocaml/parsing/ast_iterator.mli ../ocaml/parsing/ast_mapper.ml ../ocaml/parsing/ast_mapper.mli ../ocaml/parsing/asttypes.mli ../ocaml/parsing/attr_helper.ml ../ocaml/parsing/attr_helper.mli ../ocaml/parsing/builtin_attributes.ml ../ocaml/parsing/builtin_attributes.mli ../ocaml/parsing/docstrings.ml ../ocaml/parsing/docstrings.mli ../ocaml/parsing/lexer.ml ../ocaml/parsing/lexer.mli ../ocaml/parsing/location.ml ../ocaml/parsing/location.mli ../ocaml/parsing/longident.ml ../ocaml/parsing/longident.mli ../ocaml/parsing/parse.ml ../ocaml/parsing/parse.mli ../ocaml/parsing/parser.ml ../ocaml/parsing/parser.mli ../ocaml/parsing/parsetree.mli ../ocaml/parsing/pprintast.ml ../ocaml/parsing/pprintast.mli ../ocaml/parsing/syntaxerr.ml ../ocaml/parsing/syntaxerr.mli ../ocaml/typing/annot.mli ../ocaml/typing/btype.ml ../ocaml/typing/btype.mli ../ocaml/typing/cmi_format.ml ../ocaml/typing/cmi_format.mli ../ocaml/typing/cmt_format.ml ../ocaml/typing/cmt_format.mli ../ocaml/typing/ctype.ml ../ocaml/typing/ctype.mli ../ocaml/typing/datarepr.ml ../ocaml/typing/datarepr.mli ../ocaml/typing/env.ml ../ocaml/typing/env.mli ../ocaml/typing/ident.ml ../ocaml/typing/ident.mli ../ocaml/typing/includeclass.ml ../ocaml/typing/includeclass.mli ../ocaml/typing/includecore.ml ../ocaml/typing/includecore.mli ../ocaml/typing/includemod.ml ../ocaml/typing/includemod.mli ../ocaml/typing/mtype.ml ../ocaml/typing/mtype.mli ../ocaml/typing/oprint.ml ../ocaml/typing/oprint.mli ../ocaml/typing/outcometree.mli ../ocaml/typing/parmatch.ml ../ocaml/typing/parmatch.mli ../ocaml/typing/path.ml ../ocaml/typing/path.mli ../ocaml/typing/predef.ml ../ocaml/typing/predef.mli ../ocaml/typing/primitive.ml ../ocaml/typing/primitive.mli ../ocaml/typing/printtyp.ml ../ocaml/typing/printtyp.mli ../ocaml/typing/stypes.ml ../ocaml/typing/stypes.mli ../ocaml/typing/subst.ml ../ocaml/typing/subst.mli ../ocaml/typing/tast_mapper.ml ../ocaml/typing/tast_mapper.mli ../ocaml/typing/typeclass.ml ../ocaml/typing/typeclass.mli ../ocaml/typing/typecore.ml ../ocaml/typing/typecore.mli ../ocaml/typing/typedecl.ml ../ocaml/typing/typedecl.mli ../ocaml/typing/typedtree.ml ../ocaml/typing/typedtree.mli ../ocaml/typing/typedtreeIter.ml ../ocaml/typing/typedtreeIter.mli ../ocaml/typing/typemod.ml ../ocaml/typing/typemod.mli ../ocaml/typing/typeopt.ml ../ocaml/typing/typeopt.mli ../ocaml/typing/types.ml ../ocaml/typing/types.mli ../ocaml/typing/typetexp.ml ../ocaml/typing/typetexp.mli ../ocaml/typing/untypeast.ml ../ocaml/typing/untypeast.mli ../ocaml/utils/arg_helper.ml ../ocaml/utils/arg_helper.mli ../ocaml/utils/ccomp.ml ../ocaml/utils/ccomp.mli ../ocaml/utils/clflags.ml ../ocaml/utils/clflags.mli ../ocaml/utils/consistbl.ml ../ocaml/utils/consistbl.mli ../ocaml/utils/identifiable.ml ../ocaml/utils/identifiable.mli ../ocaml/utils/misc.ml ../ocaml/utils/misc.mli ../ocaml/utils/numbers.ml ../ocaml/utils/numbers.mli ../ocaml/utils/profile.ml ../ocaml/utils/profile.mli ../ocaml/utils/tbl.ml ../ocaml/utils/tbl.mli ../ocaml/utils/warnings.ml ../ocaml/utils/warnings.mli ./common/bs_loc.ml ./common/bs_loc.mli ./common/bs_version.ml ./common/bs_version.mli ./common/bs_warnings.ml ./common/bs_warnings.mli ./common/ext_log.ml ./common/ext_log.mli ./common/js_config.ml ./common/js_config.mli ./common/lam_methname.ml ./common/lam_methname.mli ./core/bs_cmi_load.ml ./core/bs_conditional_initial.ml ./core/bs_conditional_initial.mli ./core/compile_rec_module.ml ./core/config_util.ml ./core/config_util.mli ./core/config_whole_compiler.ml ./core/config_whole_compiler.mli ./core/j.ml ./core/js_analyzer.ml ./core/js_analyzer.mli ./core/js_arr.ml ./core/js_arr.mli ./core/js_ast_util.ml ./core/js_ast_util.mli ./core/js_block_runtime.ml ./core/js_block_runtime.mli ./core/js_call_info.ml ./core/js_call_info.mli ./core/js_closure.ml ./core/js_closure.mli ./core/js_cmj_format.ml ./core/js_cmj_format.mli ./core/js_cmj_load.ml ./core/js_cmj_load.mli ./core/js_cmj_load_builtin_unit.ml ./core/js_dump.ml ./core/js_dump.mli ./core/js_dump_import_export.ml ./core/js_dump_import_export.mli ./core/js_dump_lit.ml ./core/js_dump_program.ml ./core/js_dump_program.mli ./core/js_dump_property.ml ./core/js_dump_property.mli ./core/js_dump_string.ml ./core/js_dump_string.mli ./core/js_exp_make.ml ./core/js_exp_make.mli ./core/js_fold.ml ./core/js_fold_basic.ml ./core/js_fold_basic.mli ./core/js_fun_env.ml ./core/js_fun_env.mli ./core/js_long.ml ./core/js_long.mli ./core/js_map.ml ./core/js_name_of_module_id.ml ./core/js_name_of_module_id.mli ./core/js_number.ml ./core/js_number.mli ./core/js_of_lam_array.ml ./core/js_of_lam_array.mli ./core/js_of_lam_block.ml ./core/js_of_lam_block.mli ./core/js_of_lam_exception.ml ./core/js_of_lam_exception.mli ./core/js_of_lam_option.ml ./core/js_of_lam_option.mli ./core/js_of_lam_string.ml ./core/js_of_lam_string.mli ./core/js_of_lam_variant.ml ./core/js_of_lam_variant.mli ./core/js_op.ml ./core/js_op_util.ml ./core/js_op_util.mli ./core/js_output.ml ./core/js_output.mli ./core/js_packages_info.ml ./core/js_packages_info.mli ./core/js_packages_state.ml ./core/js_packages_state.mli ./core/js_pass_debug.ml ./core/js_pass_debug.mli ./core/js_pass_flatten.ml ./core/js_pass_flatten.mli ./core/js_pass_flatten_and_mark_dead.ml ./core/js_pass_flatten_and_mark_dead.mli ./core/js_pass_get_used.ml ./core/js_pass_get_used.mli ./core/js_pass_scope.ml ./core/js_pass_scope.mli ./core/js_pass_tailcall_inline.ml ./core/js_pass_tailcall_inline.mli ./core/js_raw_info.ml ./core/js_shake.ml ./core/js_shake.mli ./core/js_stmt_make.ml ./core/js_stmt_make.mli ./core/lam.ml ./core/lam.mli ./core/lam_analysis.ml ./core/lam_analysis.mli ./core/lam_arity.ml ./core/lam_arity.mli ./core/lam_arity_analysis.ml ./core/lam_arity_analysis.mli ./core/lam_beta_reduce.ml ./core/lam_beta_reduce.mli ./core/lam_beta_reduce_util.ml ./core/lam_beta_reduce_util.mli ./core/lam_bounded_vars.ml ./core/lam_bounded_vars.mli ./core/lam_closure.ml ./core/lam_closure.mli ./core/lam_coercion.ml ./core/lam_coercion.mli ./core/lam_compat.ml ./core/lam_compat.mli ./core/lam_compile.ml ./core/lam_compile.mli ./core/lam_compile_const.ml ./core/lam_compile_const.mli ./core/lam_compile_context.ml ./core/lam_compile_context.mli ./core/lam_compile_env.ml ./core/lam_compile_env.mli ./core/lam_compile_external_call.ml ./core/lam_compile_external_call.mli ./core/lam_compile_external_obj.ml ./core/lam_compile_external_obj.mli ./core/lam_compile_main.ml ./core/lam_compile_main.mli ./core/lam_compile_primitive.ml ./core/lam_compile_primitive.mli ./core/lam_compile_util.ml ./core/lam_compile_util.mli ./core/lam_constant.ml ./core/lam_constant.mli ./core/lam_constant_convert.ml ./core/lam_constant_convert.mli ./core/lam_convert.ml ./core/lam_convert.mli ./core/lam_dce.ml ./core/lam_dce.mli ./core/lam_dispatch_primitive.ml ./core/lam_dispatch_primitive.mli ./core/lam_eta_conversion.ml ./core/lam_eta_conversion.mli ./core/lam_exit_code.ml ./core/lam_exit_code.mli ./core/lam_exit_count.ml ./core/lam_exit_count.mli ./core/lam_free_variables.ml ./core/lam_free_variables.mli ./core/lam_group.ml ./core/lam_group.mli ./core/lam_hit.ml ./core/lam_hit.mli ./core/lam_id_kind.ml ./core/lam_id_kind.mli ./core/lam_iter.ml ./core/lam_iter.mli ./core/lam_module_ident.ml ./core/lam_module_ident.mli ./core/lam_pass_alpha_conversion.ml ./core/lam_pass_alpha_conversion.mli ./core/lam_pass_collect.ml ./core/lam_pass_collect.mli ./core/lam_pass_count.ml ./core/lam_pass_count.mli ./core/lam_pass_deep_flatten.ml ./core/lam_pass_deep_flatten.mli ./core/lam_pass_eliminate_ref.ml ./core/lam_pass_eliminate_ref.mli ./core/lam_pass_exits.ml ./core/lam_pass_exits.mli ./core/lam_pass_lets_dce.ml ./core/lam_pass_lets_dce.mli ./core/lam_pass_remove_alias.ml ./core/lam_pass_remove_alias.mli ./core/lam_pointer_info.ml ./core/lam_pointer_info.mli ./core/lam_primitive.ml ./core/lam_primitive.mli ./core/lam_print.ml ./core/lam_print.mli ./core/lam_scc.ml ./core/lam_scc.mli ./core/lam_stats.ml ./core/lam_stats.mli ./core/lam_stats_export.ml ./core/lam_stats_export.mli ./core/lam_subst.ml ./core/lam_subst.mli ./core/lam_tag_info.ml ./core/lam_util.ml ./core/lam_util.mli ./core/lam_var_stats.ml ./core/lam_var_stats.mli ./core/matching_polyfill.ml ./core/matching_polyfill.mli ./core/polyvar_pattern_match.ml ./core/record_attributes_check.ml ./core/res_compmisc.ml ./core/res_compmisc.mli ./core/transl_single_field_record.ml ./depends/bs_exception.ml ./depends/bs_exception.mli ./ext/bsc_args.ml ./ext/bsc_args.mli ./ext/bsc_warnings.ml ./ext/ext_array.ml ./ext/ext_array.mli ./ext/ext_buffer.ml ./ext/ext_buffer.mli ./ext/ext_bytes.ml ./ext/ext_bytes.mli ./ext/ext_char.ml ./ext/ext_char.mli ./ext/ext_digest.ml ./ext/ext_digest.mli ./ext/ext_filename.ml ./ext/ext_filename.mli ./ext/ext_fmt.ml ./ext/ext_ident.ml ./ext/ext_ident.mli ./ext/ext_int.ml ./ext/ext_int.mli ./ext/ext_io.ml ./ext/ext_io.mli ./ext/ext_js_file_kind.ml ./ext/ext_js_suffix.ml ./ext/ext_list.ml ./ext/ext_list.mli ./ext/ext_marshal.ml ./ext/ext_marshal.mli ./ext/ext_modulename.ml ./ext/ext_modulename.mli ./ext/ext_namespace.ml ./ext/ext_namespace.mli ./ext/ext_option.ml ./ext/ext_option.mli ./ext/ext_path.ml ./ext/ext_path.mli ./ext/ext_pervasives.ml ./ext/ext_pervasives.mli ./ext/ext_pp.ml ./ext/ext_pp.mli ./ext/ext_pp_scope.ml ./ext/ext_pp_scope.mli ./ext/ext_ref.ml ./ext/ext_ref.mli ./ext/ext_scc.ml ./ext/ext_scc.mli ./ext/ext_spec.ml ./ext/ext_spec.mli ./ext/ext_string.ml ./ext/ext_string.mli ./ext/ext_string_array.ml ./ext/ext_string_array.mli ./ext/ext_sys.ml ./ext/ext_sys.mli ./ext/ext_utf8.ml ./ext/ext_utf8.mli ./ext/ext_util.ml ./ext/ext_util.mli ./ext/hash.ml ./ext/hash.mli ./ext/hash_gen.ml ./ext/hash_ident.ml ./ext/hash_ident.mli ./ext/hash_int.ml ./ext/hash_int.mli ./ext/hash_set.ml ./ext/hash_set.mli ./ext/hash_set_gen.ml ./ext/hash_set_ident.ml ./ext/hash_set_ident.mli ./ext/hash_set_ident_mask.ml ./ext/hash_set_ident_mask.mli ./ext/hash_set_poly.ml ./ext/hash_set_poly.mli ./ext/hash_set_string.ml ./ext/hash_set_string.mli ./ext/hash_string.ml ./ext/hash_string.mli ./ext/int_vec_util.ml ./ext/int_vec_util.mli ./ext/int_vec_vec.ml ./ext/int_vec_vec.mli ./ext/js_reserved_map.ml ./ext/js_reserved_map.mli ./ext/js_runtime_modules.ml ./ext/literals.ml ./ext/map_gen.ml ./ext/map_gen.mli ./ext/map_ident.ml ./ext/map_ident.mli ./ext/map_int.ml ./ext/map_int.mli ./ext/map_string.ml ./ext/map_string.mli ./ext/ordered_hash_map_gen.ml ./ext/ordered_hash_map_local_ident.ml ./ext/ordered_hash_map_local_ident.mli ./ext/set_gen.ml ./ext/set_gen.mli ./ext/set_ident.ml ./ext/set_ident.mli ./ext/set_string.ml ./ext/set_string.mli ./ext/vec.ml ./ext/vec.mli ./ext/vec_gen.ml ./ext/vec_int.ml ./ext/vec_int.mli ./js_parser/declaration_parser.ml ./js_parser/enum_common.ml ./js_parser/enum_parser.ml ./js_parser/expression_parser.ml ./js_parser/file_key.ml ./js_parser/flow_ast.ml ./js_parser/flow_ast_utils.ml ./js_parser/flow_ast_utils.mli ./js_parser/flow_lexer.ml ./js_parser/flow_lexer.mli ./js_parser/jsx_parser.ml ./js_parser/lex_env.ml ./js_parser/lex_result.ml ./js_parser/loc.ml ./js_parser/loc.mli ./js_parser/object_parser.ml ./js_parser/parse_error.ml ./js_parser/parser_common.ml ./js_parser/parser_env.ml ./js_parser/parser_env.mli ./js_parser/parser_flow.ml ./js_parser/pattern_cover.ml ./js_parser/pattern_parser.ml ./js_parser/sedlexing.ml ./js_parser/sedlexing.mli ./js_parser/statement_parser.ml ./js_parser/token.ml ./js_parser/type_parser.ml ./js_parser/wtf8.ml ./js_parser/wtf8.mli ./main/builtin_cmi_datasets.ml ./main/builtin_cmi_datasets.mli ./main/builtin_cmj_datasets.ml ./main/builtin_cmj_datasets.mli ./main/jsoo_common.ml ./main/jsoo_common.mli ./outcome_printer/outcome_printer_ns.ml ./outcome_printer/outcome_printer_ns.mli ./refmt/jsoo_refmt_main.ml ./refmt/jsoo_refmt_main.mli ./refmt/refmt_api.ml ./stubs/bs_hash_stubs.ml ./super_errors/super_env.ml ./super_errors/super_location.ml ./super_errors/super_location.mli ./super_errors/super_main.ml ./super_errors/super_misc.ml ./super_errors/super_misc.mli ./super_errors/super_pparse.ml ./super_errors/super_typecore.ml ./super_errors/super_typemod.ml ./super_errors/super_typetexp.ml ./syntax/ast_attributes.ml ./syntax/ast_attributes.mli ./syntax/ast_bs_open.ml ./syntax/ast_bs_open.mli ./syntax/ast_comb.ml ./syntax/ast_comb.mli ./syntax/ast_compatible.ml ./syntax/ast_compatible.mli ./syntax/ast_config.ml ./syntax/ast_config.mli ./syntax/ast_core_type.ml ./syntax/ast_core_type.mli ./syntax/ast_core_type_class_type.ml ./syntax/ast_core_type_class_type.mli ./syntax/ast_derive.ml ./syntax/ast_derive.mli ./syntax/ast_derive_abstract.ml ./syntax/ast_derive_abstract.mli ./syntax/ast_derive_js_mapper.ml ./syntax/ast_derive_js_mapper.mli ./syntax/ast_derive_projector.ml ./syntax/ast_derive_projector.mli ./syntax/ast_derive_util.ml ./syntax/ast_derive_util.mli ./syntax/ast_exp.ml ./syntax/ast_exp.mli ./syntax/ast_exp_apply.ml ./syntax/ast_exp_apply.mli ./syntax/ast_exp_extension.ml ./syntax/ast_exp_extension.mli ./syntax/ast_exp_handle_external.ml ./syntax/ast_exp_handle_external.mli ./syntax/ast_external.ml ./syntax/ast_external.mli ./syntax/ast_external_mk.ml ./syntax/ast_external_mk.mli ./syntax/ast_external_process.ml ./syntax/ast_external_process.mli ./syntax/ast_literal.ml ./syntax/ast_literal.mli ./syntax/ast_open_cxt.ml ./syntax/ast_open_cxt.mli ./syntax/ast_pat.ml ./syntax/ast_pat.mli ./syntax/ast_payload.ml ./syntax/ast_payload.mli ./syntax/ast_polyvar.ml ./syntax/ast_polyvar.mli ./syntax/ast_reason_pp.ml ./syntax/ast_reason_pp.mli ./syntax/ast_signature.ml ./syntax/ast_signature.mli ./syntax/ast_structure.ml ./syntax/ast_structure.mli ./syntax/ast_tdcls.ml ./syntax/ast_tdcls.mli ./syntax/ast_tuple_pattern_flatten.ml ./syntax/ast_tuple_pattern_flatten.mli ./syntax/ast_typ_uncurry.ml ./syntax/ast_typ_uncurry.mli ./syntax/ast_uncurry_apply.ml ./syntax/ast_uncurry_apply.mli ./syntax/ast_uncurry_gen.ml ./syntax/ast_uncurry_gen.mli ./syntax/ast_utf8_string.ml ./syntax/ast_utf8_string.mli ./syntax/ast_utf8_string_interp.ml ./syntax/ast_utf8_string_interp.mli ./syntax/ast_util.ml ./syntax/ast_util.mli ./syntax/bs_ast_invariant.ml ./syntax/bs_ast_invariant.mli ./syntax/bs_ast_mapper.ml ./syntax/bs_ast_mapper.mli ./syntax/bs_builtin_ppx.ml ./syntax/bs_builtin_ppx.mli ./syntax/bs_flow_ast_utils.ml ./syntax/bs_flow_ast_utils.mli ./syntax/bs_syntaxerr.ml ./syntax/bs_syntaxerr.mli ./syntax/classify_function.ml ./syntax/classify_function.mli ./syntax/external_arg_spec.ml ./syntax/external_arg_spec.mli ./syntax/external_ffi_types.ml ./syntax/external_ffi_types.mli ./syntax/ppx_entry.ml ./syntax/typemod_hide.ml \ No newline at end of file +../lib/4.06.1/unstable/js_refmt_compiler.ml: ../ocaml/bytecomp/lambda.ml ../ocaml/bytecomp/lambda.mli ../ocaml/bytecomp/matching.ml ../ocaml/bytecomp/matching.mli ../ocaml/bytecomp/printlambda.ml ../ocaml/bytecomp/printlambda.mli ../ocaml/bytecomp/switch.ml ../ocaml/bytecomp/switch.mli ../ocaml/bytecomp/translattribute.ml ../ocaml/bytecomp/translattribute.mli ../ocaml/bytecomp/translclass.ml ../ocaml/bytecomp/translclass.mli ../ocaml/bytecomp/translcore.ml ../ocaml/bytecomp/translcore.mli ../ocaml/bytecomp/translmod.ml ../ocaml/bytecomp/translmod.mli ../ocaml/bytecomp/translobj.ml ../ocaml/bytecomp/translobj.mli ../ocaml/parsing/ast_helper.ml ../ocaml/parsing/ast_helper.mli ../ocaml/parsing/ast_iterator.ml ../ocaml/parsing/ast_iterator.mli ../ocaml/parsing/ast_mapper.ml ../ocaml/parsing/ast_mapper.mli ../ocaml/parsing/asttypes.mli ../ocaml/parsing/attr_helper.ml ../ocaml/parsing/attr_helper.mli ../ocaml/parsing/builtin_attributes.ml ../ocaml/parsing/builtin_attributes.mli ../ocaml/parsing/docstrings.ml ../ocaml/parsing/docstrings.mli ../ocaml/parsing/lexer.ml ../ocaml/parsing/lexer.mli ../ocaml/parsing/location.ml ../ocaml/parsing/location.mli ../ocaml/parsing/longident.ml ../ocaml/parsing/longident.mli ../ocaml/parsing/parse.ml ../ocaml/parsing/parse.mli ../ocaml/parsing/parser.ml ../ocaml/parsing/parser.mli ../ocaml/parsing/parsetree.mli ../ocaml/parsing/pprintast.ml ../ocaml/parsing/pprintast.mli ../ocaml/parsing/syntaxerr.ml ../ocaml/parsing/syntaxerr.mli ../ocaml/typing/annot.mli ../ocaml/typing/btype.ml ../ocaml/typing/btype.mli ../ocaml/typing/cmi_format.ml ../ocaml/typing/cmi_format.mli ../ocaml/typing/cmt_format.ml ../ocaml/typing/cmt_format.mli ../ocaml/typing/ctype.ml ../ocaml/typing/ctype.mli ../ocaml/typing/datarepr.ml ../ocaml/typing/datarepr.mli ../ocaml/typing/env.ml ../ocaml/typing/env.mli ../ocaml/typing/ident.ml ../ocaml/typing/ident.mli ../ocaml/typing/includeclass.ml ../ocaml/typing/includeclass.mli ../ocaml/typing/includecore.ml ../ocaml/typing/includecore.mli ../ocaml/typing/includemod.ml ../ocaml/typing/includemod.mli ../ocaml/typing/mtype.ml ../ocaml/typing/mtype.mli ../ocaml/typing/oprint.ml ../ocaml/typing/oprint.mli ../ocaml/typing/outcometree.mli ../ocaml/typing/parmatch.ml ../ocaml/typing/parmatch.mli ../ocaml/typing/path.ml ../ocaml/typing/path.mli ../ocaml/typing/predef.ml ../ocaml/typing/predef.mli ../ocaml/typing/primitive.ml ../ocaml/typing/primitive.mli ../ocaml/typing/printtyp.ml ../ocaml/typing/printtyp.mli ../ocaml/typing/stypes.ml ../ocaml/typing/stypes.mli ../ocaml/typing/subst.ml ../ocaml/typing/subst.mli ../ocaml/typing/tast_mapper.ml ../ocaml/typing/tast_mapper.mli ../ocaml/typing/typeclass.ml ../ocaml/typing/typeclass.mli ../ocaml/typing/typecore.ml ../ocaml/typing/typecore.mli ../ocaml/typing/typedecl.ml ../ocaml/typing/typedecl.mli ../ocaml/typing/typedtree.ml ../ocaml/typing/typedtree.mli ../ocaml/typing/typedtreeIter.ml ../ocaml/typing/typedtreeIter.mli ../ocaml/typing/typemod.ml ../ocaml/typing/typemod.mli ../ocaml/typing/typeopt.ml ../ocaml/typing/typeopt.mli ../ocaml/typing/types.ml ../ocaml/typing/types.mli ../ocaml/typing/typetexp.ml ../ocaml/typing/typetexp.mli ../ocaml/typing/untypeast.ml ../ocaml/typing/untypeast.mli ../ocaml/utils/arg_helper.ml ../ocaml/utils/arg_helper.mli ../ocaml/utils/ccomp.ml ../ocaml/utils/ccomp.mli ../ocaml/utils/clflags.ml ../ocaml/utils/clflags.mli ../ocaml/utils/consistbl.ml ../ocaml/utils/consistbl.mli ../ocaml/utils/identifiable.ml ../ocaml/utils/identifiable.mli ../ocaml/utils/misc.ml ../ocaml/utils/misc.mli ../ocaml/utils/numbers.ml ../ocaml/utils/numbers.mli ../ocaml/utils/profile.ml ../ocaml/utils/profile.mli ../ocaml/utils/tbl.ml ../ocaml/utils/tbl.mli ../ocaml/utils/warnings.ml ../ocaml/utils/warnings.mli ./common/bs_loc.ml ./common/bs_loc.mli ./common/bs_version.ml ./common/bs_version.mli ./common/bs_warnings.ml ./common/bs_warnings.mli ./common/ext_log.ml ./common/ext_log.mli ./common/js_config.ml ./common/js_config.mli ./common/lam_methname.ml ./common/lam_methname.mli ./core/bs_cmi_load.ml ./core/bs_conditional_initial.ml ./core/bs_conditional_initial.mli ./core/compile_rec_module.ml ./core/config_util.ml ./core/config_util.mli ./core/config_whole_compiler.ml ./core/config_whole_compiler.mli ./core/j.ml ./core/js_analyzer.ml ./core/js_analyzer.mli ./core/js_arr.ml ./core/js_arr.mli ./core/js_ast_util.ml ./core/js_ast_util.mli ./core/js_block_runtime.ml ./core/js_block_runtime.mli ./core/js_call_info.ml ./core/js_call_info.mli ./core/js_closure.ml ./core/js_closure.mli ./core/js_cmj_format.ml ./core/js_cmj_format.mli ./core/js_cmj_load.ml ./core/js_cmj_load.mli ./core/js_cmj_load_builtin_unit.ml ./core/js_dump.ml ./core/js_dump.mli ./core/js_dump_import_export.ml ./core/js_dump_import_export.mli ./core/js_dump_lit.ml ./core/js_dump_program.ml ./core/js_dump_program.mli ./core/js_dump_property.ml ./core/js_dump_property.mli ./core/js_dump_string.ml ./core/js_dump_string.mli ./core/js_exp_make.ml ./core/js_exp_make.mli ./core/js_fold.ml ./core/js_fold_basic.ml ./core/js_fold_basic.mli ./core/js_fun_env.ml ./core/js_fun_env.mli ./core/js_long.ml ./core/js_long.mli ./core/js_map.ml ./core/js_name_of_module_id.ml ./core/js_name_of_module_id.mli ./core/js_number.ml ./core/js_number.mli ./core/js_of_lam_array.ml ./core/js_of_lam_array.mli ./core/js_of_lam_block.ml ./core/js_of_lam_block.mli ./core/js_of_lam_exception.ml ./core/js_of_lam_exception.mli ./core/js_of_lam_option.ml ./core/js_of_lam_option.mli ./core/js_of_lam_string.ml ./core/js_of_lam_string.mli ./core/js_of_lam_variant.ml ./core/js_of_lam_variant.mli ./core/js_op.ml ./core/js_op_util.ml ./core/js_op_util.mli ./core/js_output.ml ./core/js_output.mli ./core/js_packages_info.ml ./core/js_packages_info.mli ./core/js_packages_state.ml ./core/js_packages_state.mli ./core/js_pass_debug.ml ./core/js_pass_debug.mli ./core/js_pass_flatten.ml ./core/js_pass_flatten.mli ./core/js_pass_flatten_and_mark_dead.ml ./core/js_pass_flatten_and_mark_dead.mli ./core/js_pass_get_used.ml ./core/js_pass_get_used.mli ./core/js_pass_scope.ml ./core/js_pass_scope.mli ./core/js_pass_tailcall_inline.ml ./core/js_pass_tailcall_inline.mli ./core/js_raw_info.ml ./core/js_shake.ml ./core/js_shake.mli ./core/js_stmt_make.ml ./core/js_stmt_make.mli ./core/lam.ml ./core/lam.mli ./core/lam_analysis.ml ./core/lam_analysis.mli ./core/lam_arity.ml ./core/lam_arity.mli ./core/lam_arity_analysis.ml ./core/lam_arity_analysis.mli ./core/lam_beta_reduce.ml ./core/lam_beta_reduce.mli ./core/lam_beta_reduce_util.ml ./core/lam_beta_reduce_util.mli ./core/lam_bounded_vars.ml ./core/lam_bounded_vars.mli ./core/lam_closure.ml ./core/lam_closure.mli ./core/lam_coercion.ml ./core/lam_coercion.mli ./core/lam_compat.ml ./core/lam_compat.mli ./core/lam_compile.ml ./core/lam_compile.mli ./core/lam_compile_const.ml ./core/lam_compile_const.mli ./core/lam_compile_context.ml ./core/lam_compile_context.mli ./core/lam_compile_env.ml ./core/lam_compile_env.mli ./core/lam_compile_external_call.ml ./core/lam_compile_external_call.mli ./core/lam_compile_external_obj.ml ./core/lam_compile_external_obj.mli ./core/lam_compile_main.ml ./core/lam_compile_main.mli ./core/lam_compile_primitive.ml ./core/lam_compile_primitive.mli ./core/lam_compile_util.ml ./core/lam_compile_util.mli ./core/lam_constant.ml ./core/lam_constant.mli ./core/lam_constant_convert.ml ./core/lam_constant_convert.mli ./core/lam_convert.ml ./core/lam_convert.mli ./core/lam_dce.ml ./core/lam_dce.mli ./core/lam_dispatch_primitive.ml ./core/lam_dispatch_primitive.mli ./core/lam_eta_conversion.ml ./core/lam_eta_conversion.mli ./core/lam_exit_code.ml ./core/lam_exit_code.mli ./core/lam_exit_count.ml ./core/lam_exit_count.mli ./core/lam_free_variables.ml ./core/lam_free_variables.mli ./core/lam_group.ml ./core/lam_group.mli ./core/lam_hit.ml ./core/lam_hit.mli ./core/lam_id_kind.ml ./core/lam_id_kind.mli ./core/lam_iter.ml ./core/lam_iter.mli ./core/lam_module_ident.ml ./core/lam_module_ident.mli ./core/lam_pass_alpha_conversion.ml ./core/lam_pass_alpha_conversion.mli ./core/lam_pass_collect.ml ./core/lam_pass_collect.mli ./core/lam_pass_count.ml ./core/lam_pass_count.mli ./core/lam_pass_deep_flatten.ml ./core/lam_pass_deep_flatten.mli ./core/lam_pass_eliminate_ref.ml ./core/lam_pass_eliminate_ref.mli ./core/lam_pass_exits.ml ./core/lam_pass_exits.mli ./core/lam_pass_lets_dce.ml ./core/lam_pass_lets_dce.mli ./core/lam_pass_remove_alias.ml ./core/lam_pass_remove_alias.mli ./core/lam_pointer_info.ml ./core/lam_pointer_info.mli ./core/lam_primitive.ml ./core/lam_primitive.mli ./core/lam_print.ml ./core/lam_print.mli ./core/lam_scc.ml ./core/lam_scc.mli ./core/lam_stats.ml ./core/lam_stats.mli ./core/lam_stats_export.ml ./core/lam_stats_export.mli ./core/lam_subst.ml ./core/lam_subst.mli ./core/lam_tag_info.ml ./core/lam_util.ml ./core/lam_util.mli ./core/lam_var_stats.ml ./core/lam_var_stats.mli ./core/matching_polyfill.ml ./core/matching_polyfill.mli ./core/polyvar_pattern_match.ml ./core/record_attributes_check.ml ./core/res_compmisc.ml ./core/res_compmisc.mli ./core/transl_single_field_record.ml ./depends/bs_exception.ml ./depends/bs_exception.mli ./ext/bsc_args.ml ./ext/bsc_args.mli ./ext/bsc_warnings.ml ./ext/ext_array.ml ./ext/ext_array.mli ./ext/ext_buffer.ml ./ext/ext_buffer.mli ./ext/ext_bytes.ml ./ext/ext_bytes.mli ./ext/ext_char.ml ./ext/ext_char.mli ./ext/ext_digest.ml ./ext/ext_digest.mli ./ext/ext_filename.ml ./ext/ext_filename.mli ./ext/ext_fmt.ml ./ext/ext_ident.ml ./ext/ext_ident.mli ./ext/ext_int.ml ./ext/ext_int.mli ./ext/ext_io.ml ./ext/ext_io.mli ./ext/ext_js_file_kind.ml ./ext/ext_js_suffix.ml ./ext/ext_list.ml ./ext/ext_list.mli ./ext/ext_marshal.ml ./ext/ext_marshal.mli ./ext/ext_modulename.ml ./ext/ext_modulename.mli ./ext/ext_namespace.ml ./ext/ext_namespace.mli ./ext/ext_option.ml ./ext/ext_option.mli ./ext/ext_path.ml ./ext/ext_path.mli ./ext/ext_pervasives.ml ./ext/ext_pervasives.mli ./ext/ext_pp.ml ./ext/ext_pp.mli ./ext/ext_pp_scope.ml ./ext/ext_pp_scope.mli ./ext/ext_ref.ml ./ext/ext_ref.mli ./ext/ext_scc.ml ./ext/ext_scc.mli ./ext/ext_spec.ml ./ext/ext_spec.mli ./ext/ext_string.ml ./ext/ext_string.mli ./ext/ext_string_array.ml ./ext/ext_string_array.mli ./ext/ext_sys.ml ./ext/ext_sys.mli ./ext/ext_utf8.ml ./ext/ext_utf8.mli ./ext/ext_util.ml ./ext/ext_util.mli ./ext/hash.ml ./ext/hash.mli ./ext/hash_gen.ml ./ext/hash_ident.ml ./ext/hash_ident.mli ./ext/hash_int.ml ./ext/hash_int.mli ./ext/hash_set.ml ./ext/hash_set.mli ./ext/hash_set_gen.ml ./ext/hash_set_ident.ml ./ext/hash_set_ident.mli ./ext/hash_set_ident_mask.ml ./ext/hash_set_ident_mask.mli ./ext/hash_set_poly.ml ./ext/hash_set_poly.mli ./ext/hash_set_string.ml ./ext/hash_set_string.mli ./ext/hash_string.ml ./ext/hash_string.mli ./ext/int_vec_util.ml ./ext/int_vec_util.mli ./ext/int_vec_vec.ml ./ext/int_vec_vec.mli ./ext/js_reserved_map.ml ./ext/js_reserved_map.mli ./ext/js_runtime_modules.ml ./ext/literals.ml ./ext/map_gen.ml ./ext/map_gen.mli ./ext/map_ident.ml ./ext/map_ident.mli ./ext/map_int.ml ./ext/map_int.mli ./ext/map_string.ml ./ext/map_string.mli ./ext/ordered_hash_map_gen.ml ./ext/ordered_hash_map_local_ident.ml ./ext/ordered_hash_map_local_ident.mli ./ext/set_gen.ml ./ext/set_gen.mli ./ext/set_ident.ml ./ext/set_ident.mli ./ext/set_string.ml ./ext/set_string.mli ./ext/vec.ml ./ext/vec.mli ./ext/vec_gen.ml ./ext/vec_int.ml ./ext/vec_int.mli ./js_parser/declaration_parser.ml ./js_parser/enum_common.ml ./js_parser/enum_parser.ml ./js_parser/expression_parser.ml ./js_parser/file_key.ml ./js_parser/flow_ast.ml ./js_parser/flow_ast_utils.ml ./js_parser/flow_ast_utils.mli ./js_parser/flow_lexer.ml ./js_parser/flow_lexer.mli ./js_parser/jsx_parser.ml ./js_parser/lex_env.ml ./js_parser/lex_result.ml ./js_parser/loc.ml ./js_parser/loc.mli ./js_parser/object_parser.ml ./js_parser/parse_error.ml ./js_parser/parser_common.ml ./js_parser/parser_env.ml ./js_parser/parser_env.mli ./js_parser/parser_flow.ml ./js_parser/pattern_cover.ml ./js_parser/pattern_parser.ml ./js_parser/sedlexing.ml ./js_parser/sedlexing.mli ./js_parser/statement_parser.ml ./js_parser/token.ml ./js_parser/type_parser.ml ./js_parser/wtf8.ml ./js_parser/wtf8.mli ./main/builtin_cmi_datasets.ml ./main/builtin_cmi_datasets.mli ./main/builtin_cmj_datasets.ml ./main/builtin_cmj_datasets.mli ./main/jsoo_common.ml ./main/jsoo_common.mli ./napkin/reactjs_jsx_ppx_v3.ml ./napkin/reactjs_jsx_ppx_v3.mli ./outcome_printer/outcome_printer_ns.ml ./outcome_printer/outcome_printer_ns.mli ./refmt/jsoo_refmt_main.ml ./refmt/jsoo_refmt_main.mli ./refmt/refmt_api.ml ./stubs/bs_hash_stubs.ml ./super_errors/super_env.ml ./super_errors/super_location.ml ./super_errors/super_location.mli ./super_errors/super_main.ml ./super_errors/super_misc.ml ./super_errors/super_misc.mli ./super_errors/super_pparse.ml ./super_errors/super_typecore.ml ./super_errors/super_typemod.ml ./super_errors/super_typetexp.ml ./syntax/ast_attributes.ml ./syntax/ast_attributes.mli ./syntax/ast_bs_open.ml ./syntax/ast_bs_open.mli ./syntax/ast_comb.ml ./syntax/ast_comb.mli ./syntax/ast_compatible.ml ./syntax/ast_compatible.mli ./syntax/ast_config.ml ./syntax/ast_config.mli ./syntax/ast_core_type.ml ./syntax/ast_core_type.mli ./syntax/ast_core_type_class_type.ml ./syntax/ast_core_type_class_type.mli ./syntax/ast_derive.ml ./syntax/ast_derive.mli ./syntax/ast_derive_abstract.ml ./syntax/ast_derive_abstract.mli ./syntax/ast_derive_js_mapper.ml ./syntax/ast_derive_js_mapper.mli ./syntax/ast_derive_projector.ml ./syntax/ast_derive_projector.mli ./syntax/ast_derive_util.ml ./syntax/ast_derive_util.mli ./syntax/ast_exp.ml ./syntax/ast_exp.mli ./syntax/ast_exp_apply.ml ./syntax/ast_exp_apply.mli ./syntax/ast_exp_extension.ml ./syntax/ast_exp_extension.mli ./syntax/ast_exp_handle_external.ml ./syntax/ast_exp_handle_external.mli ./syntax/ast_external.ml ./syntax/ast_external.mli ./syntax/ast_external_mk.ml ./syntax/ast_external_mk.mli ./syntax/ast_external_process.ml ./syntax/ast_external_process.mli ./syntax/ast_literal.ml ./syntax/ast_literal.mli ./syntax/ast_open_cxt.ml ./syntax/ast_open_cxt.mli ./syntax/ast_pat.ml ./syntax/ast_pat.mli ./syntax/ast_payload.ml ./syntax/ast_payload.mli ./syntax/ast_polyvar.ml ./syntax/ast_polyvar.mli ./syntax/ast_reason_pp.ml ./syntax/ast_reason_pp.mli ./syntax/ast_signature.ml ./syntax/ast_signature.mli ./syntax/ast_structure.ml ./syntax/ast_structure.mli ./syntax/ast_tdcls.ml ./syntax/ast_tdcls.mli ./syntax/ast_tuple_pattern_flatten.ml ./syntax/ast_tuple_pattern_flatten.mli ./syntax/ast_typ_uncurry.ml ./syntax/ast_typ_uncurry.mli ./syntax/ast_uncurry_apply.ml ./syntax/ast_uncurry_apply.mli ./syntax/ast_uncurry_gen.ml ./syntax/ast_uncurry_gen.mli ./syntax/ast_utf8_string.ml ./syntax/ast_utf8_string.mli ./syntax/ast_utf8_string_interp.ml ./syntax/ast_utf8_string_interp.mli ./syntax/ast_util.ml ./syntax/ast_util.mli ./syntax/bs_ast_invariant.ml ./syntax/bs_ast_invariant.mli ./syntax/bs_ast_mapper.ml ./syntax/bs_ast_mapper.mli ./syntax/bs_builtin_ppx.ml ./syntax/bs_builtin_ppx.mli ./syntax/bs_flow_ast_utils.ml ./syntax/bs_flow_ast_utils.mli ./syntax/bs_syntaxerr.ml ./syntax/bs_syntaxerr.mli ./syntax/classify_function.ml ./syntax/classify_function.mli ./syntax/external_arg_spec.ml ./syntax/external_arg_spec.mli ./syntax/external_ffi_types.ml ./syntax/external_ffi_types.mli ./syntax/ppx_entry.ml ./syntax/typemod_hide.ml \ No newline at end of file From b967284cb6cd9ad2e021290d8b7af48b9008222a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Cha=CC=81varri?= Date: Sat, 24 Oct 2020 10:02:33 +0200 Subject: [PATCH 4/4] roll back gitmodules change --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 0305793235..6b891b0829 100644 --- a/.gitmodules +++ b/.gitmodules @@ -8,5 +8,5 @@ branch = master [submodule "ninja"] path = ninja - url = https://github.com/rescript-lang/ninja + url = git@github.com:rescript-lang/ninja.git ignore = untracked