From 423933acc8b0c884059ee5a2d723dd879b47db5f Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sat, 13 Jan 2024 18:41:41 +0100 Subject: [PATCH 1/8] rename, config, etc --- jscomp/bsb/bsb_jsx.ml | 8 +- jscomp/bsb/bsb_ninja_rule.ml | 3 +- jscomp/common/js_config.ml | 5 +- jscomp/common/js_config.mli | 2 +- jscomp/frontend/ppx_entry.ml | 4 +- jscomp/syntax/cli/res_cli.ml | 4 +- .../{react_jsx_common.ml => jsx_common.ml} | 0 .../src/{reactjs_jsx_ppx.ml => jsx_ppx.ml} | 10 +-- .../src/{reactjs_jsx_ppx.mli => jsx_ppx.mli} | 0 .../src/{reactjs_jsx_v4.ml => jsx_v4.ml} | 78 +++++++++---------- jscomp/syntax/src/reactjs_jsx_v3.ml | 56 +++++++------ 11 files changed, 83 insertions(+), 87 deletions(-) rename jscomp/syntax/src/{react_jsx_common.ml => jsx_common.ml} (100%) rename jscomp/syntax/src/{reactjs_jsx_ppx.ml => jsx_ppx.ml} (95%) rename jscomp/syntax/src/{reactjs_jsx_ppx.mli => jsx_ppx.mli} (100%) rename jscomp/syntax/src/{reactjs_jsx_v4.ml => jsx_v4.ml} (96%) diff --git a/jscomp/bsb/bsb_jsx.ml b/jscomp/bsb/bsb_jsx.ml index b4a66de189..b9fbd08661 100644 --- a/jscomp/bsb/bsb_jsx.ml +++ b/jscomp/bsb/bsb_jsx.ml @@ -1,5 +1,5 @@ type version = Jsx_v3 | Jsx_v4 -type module_ = React +type module_ = React | Generic of {moduleName: string} type mode = Classic | Automatic type dependencies = string list @@ -15,7 +15,7 @@ let encode_no_nl jsx = | None -> "" | Some Jsx_v3 -> "3" | Some Jsx_v4 -> "4") - ^ (match jsx.module_ with None -> "" | Some React -> "React") + ^ (match jsx.module_ with None -> "" | Some React -> "React" | Some Generic {moduleName} -> moduleName) ^ match jsx.mode with | None -> "" @@ -55,10 +55,10 @@ let from_map map = `Obj (fun m -> match m.?(Bsb_build_schemas.jsx_module) with - | Some (Str { loc; str }) -> ( + | Some (Str { str }) -> ( match str with | "react" -> module_ := Some React - | _ -> Bsb_exception.errorf ~loc "Unsupported jsx module %s" str) + | moduleName -> module_ := Some (Generic {moduleName})) | Some x -> Bsb_exception.config_error x "Unexpected input (jsx module name) for jsx module" diff --git a/jscomp/bsb/bsb_ninja_rule.ml b/jscomp/bsb/bsb_ninja_rule.ml index 829a8f5bfe..1103a3ac4c 100644 --- a/jscomp/bsb/bsb_ninja_rule.ml +++ b/jscomp/bsb/bsb_ninja_rule.ml @@ -169,7 +169,8 @@ let make_custom_rules ~(gentype_config : Bsb_config_types.gentype_config) | None, None -> ()); (match jsx.module_ with | None -> () - | Some React -> Ext_buffer.add_string buf " -bs-jsx-module react"); + | Some React -> Ext_buffer.add_string buf " -bs-jsx-module react" + | Some Generic {moduleName} -> Ext_buffer.add_string buf (" -bs-jsx-module " ^ moduleName)); (match jsx.mode with | None -> () | Some Classic -> Ext_buffer.add_string buf " -bs-jsx-mode classic" diff --git a/jscomp/common/js_config.ml b/jscomp/common/js_config.ml index ef3ad90b60..7602c681e2 100644 --- a/jscomp/common/js_config.ml +++ b/jscomp/common/js_config.ml @@ -25,7 +25,7 @@ (** Browser is not set via command line only for internal use *) type jsx_version = Jsx_v3 | Jsx_v4 -type jsx_module = React +type jsx_module = React | Generic of {moduleName: string} type jsx_mode = Classic | Automatic let no_version_header = ref false @@ -64,6 +64,7 @@ let int_of_jsx_version = function let string_of_jsx_module = function | React -> "react" +| Generic {moduleName} -> moduleName let string_of_jsx_mode = function | Classic -> "classic" @@ -76,7 +77,7 @@ let jsx_version_of_int = function let jsx_module_of_string = function | "react" -> React -| _ -> React +| moduleName -> Generic {moduleName} let jsx_mode_of_string = function | "classic" -> Classic diff --git a/jscomp/common/js_config.mli b/jscomp/common/js_config.mli index f5df0349d3..fd9df5785a 100644 --- a/jscomp/common/js_config.mli +++ b/jscomp/common/js_config.mli @@ -23,7 +23,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) type jsx_version = Jsx_v3 | Jsx_v4 -type jsx_module = React +type jsx_module = React | Generic of {moduleName: string} type jsx_mode = Classic | Automatic (* val get_packages_info : diff --git a/jscomp/frontend/ppx_entry.ml b/jscomp/frontend/ppx_entry.ml index 7f73ef8414..67d50bb61c 100644 --- a/jscomp/frontend/ppx_entry.ml +++ b/jscomp/frontend/ppx_entry.ml @@ -35,7 +35,7 @@ let rewrite_signature (ast : Parsetree.signature) : Parsetree.signature = let jsxVersion = int_of_jsx_version jsxVersion in let jsxModule = string_of_jsx_module !jsx_module in let jsxMode = string_of_jsx_mode !jsx_mode in - Reactjs_jsx_ppx.rewrite_signature ~jsxVersion ~jsxModule ~jsxMode ast + Jsx_ppx.rewrite_signature ~jsxVersion ~jsxModule ~jsxMode ast in if !Js_config.no_builtin_ppx then ast else @@ -55,7 +55,7 @@ let rewrite_implementation (ast : Parsetree.structure) : Parsetree.structure = let jsxVersion = int_of_jsx_version jsxVersion in let jsxModule = string_of_jsx_module !jsx_module in let jsxMode = string_of_jsx_mode !jsx_mode in - Reactjs_jsx_ppx.rewrite_implementation ~jsxVersion ~jsxModule ~jsxMode ast + Jsx_ppx.rewrite_implementation ~jsxVersion ~jsxModule ~jsxMode ast in if !Js_config.no_builtin_ppx then ast else diff --git a/jscomp/syntax/cli/res_cli.ml b/jscomp/syntax/cli/res_cli.ml index bcc4024259..23d9006f35 100644 --- a/jscomp/syntax/cli/res_cli.ml +++ b/jscomp/syntax/cli/res_cli.ml @@ -284,7 +284,7 @@ module CliArgProcessor = struct else exit 1) else let parsetree = - Reactjs_jsx_ppx.rewrite_signature ~jsxVersion ~jsxModule ~jsxMode + Jsx_ppx.rewrite_signature ~jsxVersion ~jsxModule ~jsxMode parseResult.parsetree in printEngine.printInterface ~width ~filename @@ -300,7 +300,7 @@ module CliArgProcessor = struct else exit 1) else let parsetree = - Reactjs_jsx_ppx.rewrite_implementation ~jsxVersion ~jsxModule ~jsxMode + Jsx_ppx.rewrite_implementation ~jsxVersion ~jsxModule ~jsxMode parseResult.parsetree in printEngine.printImplementation ~width ~filename diff --git a/jscomp/syntax/src/react_jsx_common.ml b/jscomp/syntax/src/jsx_common.ml similarity index 100% rename from jscomp/syntax/src/react_jsx_common.ml rename to jscomp/syntax/src/jsx_common.ml diff --git a/jscomp/syntax/src/reactjs_jsx_ppx.ml b/jscomp/syntax/src/jsx_ppx.ml similarity index 95% rename from jscomp/syntax/src/reactjs_jsx_ppx.ml rename to jscomp/syntax/src/jsx_ppx.ml index f6449a6cc1..0f4ea87717 100644 --- a/jscomp/syntax/src/reactjs_jsx_ppx.ml +++ b/jscomp/syntax/src/jsx_ppx.ml @@ -50,7 +50,7 @@ let updateConfig config payload = let fields = getPayloadFields payload in (match getInt ~key:"version" fields with | None -> () - | Some i -> config.React_jsx_common.version <- i); + | Some i -> config.Jsx_common.version <- i); (match getString ~key:"module" fields with | None -> () | Some s -> config.module_ <- s); @@ -68,7 +68,7 @@ let getMapper ~config = Reactjs_jsx_v3.jsxMapper ~config in let expr4, module_binding4, transformSignatureItem4, transformStructureItem4 = - Reactjs_jsx_v4.jsxMapper ~config + Jsx_v4.jsxMapper ~config in let expr mapper e = @@ -93,7 +93,7 @@ let getMapper ~config = } in let restoreConfig oldConfig = - config.version <- oldConfig.React_jsx_common.version; + config.version <- oldConfig.Jsx_common.version; config.module_ <- oldConfig.module_; config.mode <- oldConfig.mode; config.hasReactComponent <- oldConfig.hasReactComponent @@ -143,7 +143,7 @@ let rewrite_implementation ~jsxVersion ~jsxModule ~jsxMode (code : Parsetree.structure) : Parsetree.structure = let config = { - React_jsx_common.version = jsxVersion; + Jsx_common.version = jsxVersion; module_ = jsxModule; mode = jsxMode; nestedModules = []; @@ -157,7 +157,7 @@ let rewrite_signature ~jsxVersion ~jsxModule ~jsxMode (code : Parsetree.signature) : Parsetree.signature = let config = { - React_jsx_common.version = jsxVersion; + Jsx_common.version = jsxVersion; module_ = jsxModule; mode = jsxMode; nestedModules = []; diff --git a/jscomp/syntax/src/reactjs_jsx_ppx.mli b/jscomp/syntax/src/jsx_ppx.mli similarity index 100% rename from jscomp/syntax/src/reactjs_jsx_ppx.mli rename to jscomp/syntax/src/jsx_ppx.mli diff --git a/jscomp/syntax/src/reactjs_jsx_v4.ml b/jscomp/syntax/src/jsx_v4.ml similarity index 96% rename from jscomp/syntax/src/reactjs_jsx_v4.ml rename to jscomp/syntax/src/jsx_v4.ml index e62054d80f..fd6ee2b8c9 100644 --- a/jscomp/syntax/src/reactjs_jsx_v4.ml +++ b/jscomp/syntax/src/jsx_v4.ml @@ -27,7 +27,7 @@ let getLabel str = | Optional str | Labelled str -> str | Nolabel -> "" -let optionalAttrs = [React_jsx_common.optionalAttr] +let optionalAttrs = [Jsx_common.optionalAttr] let constantString ~loc str = Ast_helper.Exp.constant ~loc (Pconst_string (str, None)) @@ -93,7 +93,7 @@ let extractChildren ?(removeLastPositionUnit = false) ~loc propsAndChildren = | [(Nolabel, {pexp_desc = Pexp_construct ({txt = Lident "()"}, None)})] -> acc | (Nolabel, {pexp_loc}) :: _rest -> - React_jsx_common.raiseError ~loc:pexp_loc + Jsx_common.raiseError ~loc:pexp_loc "JSX: found non-labelled argument before the last position" | arg :: rest -> allButLast_ rest (arg :: acc) in @@ -110,7 +110,7 @@ let extractChildren ?(removeLastPositionUnit = false) ~loc propsAndChildren = | [(_, childrenExpr)], props -> (childrenExpr, if removeLastPositionUnit then allButLast props else props) | _ -> - React_jsx_common.raiseError ~loc + Jsx_common.raiseError ~loc "JSX: somehow there's more than one `children` label" let merlinFocus = ({loc = Location.none; txt = "merlin.focus"}, PStr []) @@ -124,7 +124,7 @@ let rec getFnName binding = | {ppat_desc = Ppat_var {txt}} -> txt | {ppat_desc = Ppat_constraint (pat, _)} -> getFnName pat | {ppat_loc} -> - React_jsx_common.raiseError ~loc:ppat_loc + Jsx_common.raiseError ~loc:ppat_loc "react.component calls cannot be destructured." let makeNewBinding binding expression newName = @@ -138,7 +138,7 @@ let makeNewBinding binding expression newName = pvb_attributes = [merlinFocus]; } | {pvb_loc} -> - React_jsx_common.raiseError ~loc:pvb_loc + Jsx_common.raiseError ~loc:pvb_loc "react.component calls cannot be destructured." (* Lookup the filename from the location information on the AST node and turn it into a valid module identifier *) @@ -184,7 +184,7 @@ let recordFromProps ~loc ~removeKey callArguments = | [(Nolabel, {pexp_desc = Pexp_construct ({txt = Lident "()"}, None)})] -> acc | (Nolabel, {pexp_loc}) :: _rest -> - React_jsx_common.raiseError ~loc:pexp_loc + Jsx_common.raiseError ~loc:pexp_loc "JSX: found non-labelled argument before the last position" | ((Labelled txt, {pexp_loc}) as prop) :: rest | ((Optional txt, {pexp_loc}) as prop) :: rest -> @@ -192,7 +192,7 @@ let recordFromProps ~loc ~removeKey callArguments = match acc with | [] -> removeLastPositionUnitAux rest (prop :: acc) | _ -> - React_jsx_common.raiseError ~loc:pexp_loc + Jsx_common.raiseError ~loc:pexp_loc "JSX: use {...p} {x: v} not {x: v} {...p} \n\ \ multiple spreads {...p} {...p} not allowed." else removeLastPositionUnitAux rest (prop :: acc) @@ -297,8 +297,7 @@ let makeLabelDecls namedTypeList = | hd :: tl -> if mem_label hd tl then let _, label, _, loc, _ = hd in - React_jsx_common.raiseError ~loc "JSX: found the duplicated prop `%s`" - label + Jsx_common.raiseError ~loc "JSX: found the duplicated prop `%s`" label else checkDuplicatedLabel tl in let () = namedTypeList |> List.rev |> checkDuplicatedLabel in @@ -374,7 +373,7 @@ let transformUppercaseCall3 ~config modulePath mapper jsxExprLoc callExprLoc | ListLiteral expression -> ( (* this is a hack to support react components that introspect into their children *) childrenArg := Some expression; - match config.React_jsx_common.mode with + match config.Jsx_common.mode with | "automatic" -> [ ( labelled "children", @@ -474,7 +473,7 @@ let transformUppercaseCall3 ~config modulePath mapper jsxExprLoc callExprLoc let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs callArguments id = let componentNameExpr = constantString ~loc:callExprLoc id in - match config.React_jsx_common.mode with + match config.Jsx_common.mode with (* the new jsx transform *) | "automatic" -> let children, nonChildrenProps = @@ -562,7 +561,7 @@ let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs "createDOMElementVariadic" (* [@JSX] div(~children= value), coming from
...(value)
*) | {pexp_loc} -> - React_jsx_common.raiseError ~loc:pexp_loc + Jsx_common.raiseError ~loc:pexp_loc "A spread as a DOM element's children don't make sense written \ together. You can simply remove the spread." in @@ -601,11 +600,11 @@ let rec recursivelyTransformNamedArgsForMake expr args newtypes coreType = match expr.pexp_desc with (* TODO: make this show up with a loc. *) | Pexp_fun (Labelled "key", _, _, _) | Pexp_fun (Optional "key", _, _, _) -> - React_jsx_common.raiseError ~loc:expr.pexp_loc + Jsx_common.raiseError ~loc:expr.pexp_loc "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", _, _, _) -> - React_jsx_common.raiseError ~loc:expr.pexp_loc + Jsx_common.raiseError ~loc:expr.pexp_loc "Ref cannot be passed as a normal prop. Please use `forwardRef` API \ instead." | Pexp_fun (arg, default, pattern, expression) @@ -721,7 +720,7 @@ let argToConcreteType types (name, attrs, loc, type_) = let check_string_int_attribute_iter = let attribute _ ({txt; loc}, _) = if txt = "string" || txt = "int" then - React_jsx_common.raiseError ~loc + Jsx_common.raiseError ~loc "@string and @int attributes not supported. See \ https://github.com/rescript-lang/rescript-compiler/issues/5724" in @@ -730,8 +729,8 @@ let check_string_int_attribute_iter = let checkMultipleReactComponents ~config ~loc = (* If there is another @react.component, throw error *) - if config.React_jsx_common.hasReactComponent then - React_jsx_common.raiseErrorMultipleReactComponent ~loc + if config.Jsx_common.hasReactComponent then + Jsx_common.raiseErrorMultipleReactComponent ~loc else config.hasReactComponent <- true let modifiedBindingOld binding = @@ -757,7 +756,7 @@ let modifiedBindingOld binding = | {pexp_desc = Pexp_constraint (innerFunctionExpression, _typ)} -> spelunkForFunExpression innerFunctionExpression | {pexp_loc} -> - React_jsx_common.raiseError ~loc:pexp_loc + Jsx_common.raiseError ~loc:pexp_loc "react.component calls can only be on function definitions or \ component wrappers (forwardRef, memo)." in @@ -882,15 +881,13 @@ let vbMatchExpr namedArgList expr = aux (List.rev namedArgList) let mapBinding ~config ~emptyLoc ~pstr_loc ~fileName ~recFlag binding = - if React_jsx_common.hasAttrOnBinding binding then ( + if Jsx_common.hasAttrOnBinding binding then ( checkMultipleReactComponents ~config ~loc:pstr_loc; - let binding = React_jsx_common.removeArity binding in - let coreTypeOfAttr = - React_jsx_common.coreTypeOfAttrs binding.pvb_attributes - in + let binding = Jsx_common.removeArity binding in + let coreTypeOfAttr = Jsx_common.coreTypeOfAttrs binding.pvb_attributes in let typVarsOfCoreType = coreTypeOfAttr - |> Option.map React_jsx_common.typVarsOfCoreType + |> Option.map Jsx_common.typVarsOfCoreType |> Option.value ~default:[] in let bindingLoc = binding.pvb_loc in @@ -947,7 +944,7 @@ let mapBinding ~config ~emptyLoc ~pstr_loc ~fileName ~recFlag binding = (Typ.constr (Location.mknoloc @@ Lident "props") [Typ.any ()]) in let innerExpression = - React_jsx_common.async_component ~async:isAsync innerExpression + Jsx_common.async_component ~async:isAsync innerExpression in let fullExpression = (* React component name should start with uppercase letter *) @@ -1129,17 +1126,17 @@ let transformStructureItem ~config item = pstr_desc = Pstr_primitive ({pval_attributes; pval_type} as value_description); } as pstr -> ( - match List.filter React_jsx_common.hasAttr pval_attributes with + match List.filter Jsx_common.hasAttr pval_attributes with | [] -> [item] | [_] -> checkMultipleReactComponents ~config ~loc:pstr_loc; check_string_int_attribute_iter.structure_item check_string_int_attribute_iter item; - let pval_type = React_jsx_common.extractUncurried pval_type in - let coreTypeOfAttr = React_jsx_common.coreTypeOfAttrs pval_attributes in + let pval_type = Jsx_common.extractUncurried pval_type in + let coreTypeOfAttr = Jsx_common.coreTypeOfAttrs pval_attributes in let typVarsOfCoreType = coreTypeOfAttr - |> Option.map React_jsx_common.typVarsOfCoreType + |> Option.map Jsx_common.typVarsOfCoreType |> Option.value ~default:[] in let rec getPropTypes types @@ -1192,7 +1189,7 @@ let transformStructureItem ~config item = in [propsRecordType; newStructure] | _ -> - React_jsx_common.raiseError ~loc:pstr_loc + Jsx_common.raiseError ~loc:pstr_loc "Only one react.component call can exist on a component at one time") (* let component = ... *) | {pstr_loc; pstr_desc = Pstr_value (recFlag, valueBindings)} -> ( @@ -1232,18 +1229,18 @@ let transformSignatureItem ~config item = psig_loc; psig_desc = Psig_value ({pval_attributes; pval_type} as psig_desc); } as psig -> ( - match List.filter React_jsx_common.hasAttr pval_attributes with + match List.filter Jsx_common.hasAttr pval_attributes with | [] -> [item] | [_] -> checkMultipleReactComponents ~config ~loc:psig_loc; - let pval_type = React_jsx_common.extractUncurried pval_type in + let pval_type = Jsx_common.extractUncurried pval_type in check_string_int_attribute_iter.signature_item check_string_int_attribute_iter item; let hasForwardRef = ref false in - let coreTypeOfAttr = React_jsx_common.coreTypeOfAttrs pval_attributes in + let coreTypeOfAttr = Jsx_common.coreTypeOfAttrs pval_attributes in let typVarsOfCoreType = coreTypeOfAttr - |> Option.map React_jsx_common.typVarsOfCoreType + |> Option.map Jsx_common.typVarsOfCoreType |> Option.value ~default:[] in let rec getPropTypes types ({ptyp_loc; ptyp_desc} as fullType) = @@ -1307,7 +1304,7 @@ let transformSignatureItem ~config item = in [propsRecordType; newStructure] | _ -> - React_jsx_common.raiseError ~loc:psig_loc + Jsx_common.raiseError ~loc:psig_loc "Only one react.component call can exist on a component at one time") | _ -> [item] @@ -1317,7 +1314,7 @@ let transformJsxCall ~config mapper callExpression callArguments jsxExprLoc | Pexp_ident caller -> ( match caller with | {txt = Lident "createElement"; loc} -> - React_jsx_common.raiseError ~loc + Jsx_common.raiseError ~loc "JSX: `createElement` should be preceeded by a module name." (* Foo.createElement(~prop1=foo, ~prop2=bar, ~children=[], ()) *) | {loc; txt = Ldot (modulePath, ("createElement" | "make"))} -> @@ -1330,18 +1327,18 @@ let transformJsxCall ~config mapper callExpression callArguments jsxExprLoc transformLowercaseCall3 ~config mapper jsxExprLoc loc attrs callArguments id | {txt = Ldot (_, anythingNotCreateElementOrMake); loc} -> - React_jsx_common.raiseError ~loc + Jsx_common.raiseError ~loc "JSX: the JSX attribute should be attached to a \ `YourModuleName.createElement` or `YourModuleName.make` call. We saw \ `%s` instead" anythingNotCreateElementOrMake | {txt = Lapply _; loc} -> (* don't think there's ever a case where this is reached *) - React_jsx_common.raiseError ~loc + Jsx_common.raiseError ~loc "JSX: encountered a weird case while processing the code. Please \ report this!") | _ -> - React_jsx_common.raiseError ~loc:callExpression.pexp_loc + Jsx_common.raiseError ~loc:callExpression.pexp_loc "JSX: `createElement` should be preceeded by a simple, direct module \ name." @@ -1446,8 +1443,7 @@ let expr ~config mapper expression = (* Delegate to the default mapper, a deep identity traversal *) | e -> default_mapper.expr mapper e -let module_binding ~(config : React_jsx_common.jsxConfig) mapper module_binding - = +let module_binding ~(config : Jsx_common.jsxConfig) mapper module_binding = config.nestedModules <- module_binding.pmb_name.txt :: config.nestedModules; let mapped = default_mapper.module_binding mapper module_binding in let () = diff --git a/jscomp/syntax/src/reactjs_jsx_v3.ml b/jscomp/syntax/src/reactjs_jsx_v3.ml index 0ecbb4cf43..83316c9d5c 100644 --- a/jscomp/syntax/src/reactjs_jsx_v3.ml +++ b/jscomp/syntax/src/reactjs_jsx_v3.ml @@ -87,7 +87,7 @@ let extractChildren ?(removeLastPositionUnit = false) ~loc propsAndChildren = | [(Nolabel, {pexp_desc = Pexp_construct ({txt = Lident "()"}, None)})] -> acc | (Nolabel, {pexp_loc}) :: _rest -> - React_jsx_common.raiseError ~loc:pexp_loc + Jsx_common.raiseError ~loc:pexp_loc "JSX: found non-labelled argument before the last position" | arg :: rest -> allButLast_ rest (arg :: acc) in @@ -104,7 +104,7 @@ let extractChildren ?(removeLastPositionUnit = false) ~loc propsAndChildren = | [(_, childrenExpr)], props -> (childrenExpr, if removeLastPositionUnit then allButLast props else props) | _ -> - React_jsx_common.raiseError ~loc + Jsx_common.raiseError ~loc "JSX: somehow there's more than one `children` label" let unerasableIgnore loc = @@ -122,7 +122,7 @@ let rec getFnName binding = | {ppat_desc = Ppat_var {txt}} -> txt | {ppat_desc = Ppat_constraint (pat, _)} -> getFnName pat | {ppat_loc} -> - React_jsx_common.raiseError ~loc:ppat_loc + Jsx_common.raiseError ~loc:ppat_loc "react.component calls cannot be destructured." let makeNewBinding binding expression newName = @@ -136,7 +136,7 @@ let makeNewBinding binding expression newName = pvb_attributes = [merlinFocus]; } | {pvb_loc} -> - React_jsx_common.raiseError ~loc:pvb_loc + Jsx_common.raiseError ~loc:pvb_loc "react.component calls cannot be destructured." (* Lookup the value of `props` otherwise raise Invalid_argument error *) @@ -145,7 +145,7 @@ let getPropsNameValue _acc (loc, exp) = | {txt = Lident "props"}, {pexp_desc = Pexp_ident {txt = Lident str}} -> {propsName = str} | {txt; loc}, _ -> - React_jsx_common.raiseError ~loc + Jsx_common.raiseError ~loc "react.component only accepts props as an option, given: { %s }" (Longident.last txt) @@ -170,7 +170,7 @@ let getPropsAttr payload = :: _rest)) -> {propsName = "props"} | Some (PStr ({pstr_desc = Pstr_eval (_, _); pstr_loc} :: _rest)) -> - React_jsx_common.raiseError ~loc:pstr_loc + Jsx_common.raiseError ~loc:pstr_loc "react.component accepts a record config with props as an options." | _ -> defaultProps @@ -368,7 +368,7 @@ let jsxMapper ~config = | Lident path -> Lident (path ^ "Props") | Ldot (ident, path) -> Ldot (ident, path ^ "Props") | _ -> - React_jsx_common.raiseError ~loc + Jsx_common.raiseError ~loc "JSX name can't be the result of function applications" in let props = @@ -407,7 +407,7 @@ let jsxMapper ~config = "createDOMElementVariadic" (* [@JSX] div(~children= value), coming from
...(value)
*) | {pexp_loc} -> - React_jsx_common.raiseError ~loc:pexp_loc + Jsx_common.raiseError ~loc:pexp_loc "A spread as a DOM element's children don't make sense written \ together. You can simply remove the spread." in @@ -450,11 +450,11 @@ let jsxMapper ~config = match expr.pexp_desc with (* TODO: make this show up with a loc. *) | Pexp_fun (Labelled "key", _, _, _) | Pexp_fun (Optional "key", _, _, _) -> - React_jsx_common.raiseError ~loc:expr.pexp_loc + Jsx_common.raiseError ~loc:expr.pexp_loc "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", _, _, _) -> - React_jsx_common.raiseError ~loc:expr.pexp_loc + Jsx_common.raiseError ~loc:expr.pexp_loc "Ref cannot be passed as a normal prop. Either give the prop a \ different name or use the `forwardRef` API instead." | Pexp_fun (arg, default, pattern, expression) @@ -594,10 +594,10 @@ let jsxMapper ~config = ({pval_name = {txt = fnName}; pval_attributes; pval_type} as value_description); } as pstr -> ( - match List.filter React_jsx_common.hasAttr pval_attributes with + match List.filter Jsx_common.hasAttr pval_attributes with | [] -> [item] | [_] -> - let pval_type = React_jsx_common.extractUncurried pval_type in + let pval_type = Jsx_common.extractUncurried pval_type in let rec getPropTypes types ({ptyp_loc; ptyp_desc} as fullType) = match ptyp_desc with | Ptyp_arrow (name, type_, ({ptyp_desc = Ptyp_arrow _} as rest)) @@ -641,15 +641,15 @@ let jsxMapper ~config = in [externalPropsDecl; newStructure] | _ -> - React_jsx_common.raiseError ~loc:pstr_loc + Jsx_common.raiseError ~loc:pstr_loc "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 React_jsx_common.hasAttrOnBinding binding then - let binding = React_jsx_common.removeArity binding in + if Jsx_common.hasAttrOnBinding binding then + let binding = Jsx_common.removeArity binding in let bindingLoc = binding.pvb_loc in let bindingPatLoc = binding.pvb_pat.ppat_loc in let binding = @@ -689,7 +689,7 @@ let jsxMapper ~config = | {pexp_desc = Pexp_constraint (innerFunctionExpression, _typ)} -> spelunkForFunExpression innerFunctionExpression | {pexp_loc} -> - React_jsx_common.raiseError ~loc:pexp_loc + Jsx_common.raiseError ~loc:pexp_loc "react.component calls can only be on function definitions \ or component wrappers (forwardRef, memo)." in @@ -814,7 +814,7 @@ let jsxMapper ~config = in let bindingWrapper, hasUnit, expression = modifiedBinding binding in let reactComponentAttribute = - try Some (List.find React_jsx_common.hasAttr binding.pvb_attributes) + try Some (List.find Jsx_common.hasAttr binding.pvb_attributes) with Not_found -> None in let _attr_loc, payload = @@ -1037,10 +1037,10 @@ let jsxMapper ~config = ({pval_name = {txt = fnName}; pval_attributes; pval_type} as psig_desc); } as psig -> ( - match List.filter React_jsx_common.hasAttr pval_attributes with + match List.filter Jsx_common.hasAttr pval_attributes with | [] -> [item] | [_] -> - let pval_type = React_jsx_common.extractUncurried pval_type in + let pval_type = Jsx_common.extractUncurried pval_type in let rec getPropTypes types ({ptyp_loc; ptyp_desc} as fullType) = match ptyp_desc with | Ptyp_arrow (name, type_, ({ptyp_desc = Ptyp_arrow _} as rest)) @@ -1084,7 +1084,7 @@ let jsxMapper ~config = in [externalPropsDecl; newStructure] | _ -> - React_jsx_common.raiseError ~loc:psig_loc + Jsx_common.raiseError ~loc:psig_loc "Only one react.component call can exist on a component at one time") | _ -> [item] in @@ -1094,37 +1094,35 @@ let jsxMapper ~config = | Pexp_ident caller -> ( match caller with | {txt = Lident "createElement"; loc} -> - React_jsx_common.raiseError ~loc + Jsx_common.raiseError ~loc "JSX: `createElement` should be preceeded by a module name." (* Foo.createElement(~prop1=foo, ~prop2=bar, ~children=[], ()) *) | {loc; txt = Ldot (modulePath, ("createElement" | "make"))} -> ( - match config.React_jsx_common.version with + match config.Jsx_common.version with | 3 -> transformUppercaseCall3 modulePath mapper loc attrs callExpression callArguments - | _ -> - React_jsx_common.raiseError ~loc "JSX: the JSX version must be 3") + | _ -> Jsx_common.raiseError ~loc "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 config.version with | 3 -> transformLowercaseCall3 mapper loc attrs callArguments id - | _ -> React_jsx_common.raiseError ~loc "JSX: the JSX version must be 3" - ) + | _ -> Jsx_common.raiseError ~loc "JSX: the JSX version must be 3") | {txt = Ldot (_, anythingNotCreateElementOrMake); loc} -> - React_jsx_common.raiseError ~loc + Jsx_common.raiseError ~loc "JSX: the JSX attribute should be attached to a \ `YourModuleName.createElement` or `YourModuleName.make` call. We \ saw `%s` instead" anythingNotCreateElementOrMake | {txt = Lapply _; loc} -> (* don't think there's ever a case where this is reached *) - React_jsx_common.raiseError ~loc + Jsx_common.raiseError ~loc "JSX: encountered a weird case while processing the code. Please \ report this!") | _ -> - React_jsx_common.raiseError ~loc:callExpression.pexp_loc + Jsx_common.raiseError ~loc:callExpression.pexp_loc "JSX: `createElement` should be preceeded by a simple, direct module \ name." in From 11634d89779b7ad708b5537506d683d9a50ce3b7 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sat, 13 Jan 2024 21:28:25 +0100 Subject: [PATCH 2/8] generalize more --- jscomp/bsc/rescript_compiler_main.ml | 1 - jscomp/syntax/src/jsx_common.ml | 19 ++-- jscomp/syntax/src/jsx_ppx.ml | 14 +-- jscomp/syntax/src/jsx_v4.ml | 155 +++++++++++++++++---------- jscomp/syntax/src/reactjs_jsx_v3.ml | 10 +- 5 files changed, 123 insertions(+), 76 deletions(-) diff --git a/jscomp/bsc/rescript_compiler_main.ml b/jscomp/bsc/rescript_compiler_main.ml index 6a4d63173c..0307e1f708 100644 --- a/jscomp/bsc/rescript_compiler_main.ml +++ b/jscomp/bsc/rescript_compiler_main.ml @@ -251,7 +251,6 @@ let buckle_script_flags : (string * Bsc_args.spec * string) array = "*internal* Set jsx version"; "-bs-jsx-module", string_call (fun i -> - (if i <> "react" then Bsc_args.bad_arg (" Not supported jsx-module : " ^ i)); Js_config.jsx_module := Js_config.jsx_module_of_string i), "*internal* Set jsx module"; diff --git a/jscomp/syntax/src/jsx_common.ml b/jscomp/syntax/src/jsx_common.ml index 51c4711032..8f5df68eab 100644 --- a/jscomp/syntax/src/jsx_common.ml +++ b/jscomp/syntax/src/jsx_common.ml @@ -6,21 +6,26 @@ type jsxConfig = { mutable module_: string; mutable mode: string; mutable nestedModules: string list; - mutable hasReactComponent: bool; + mutable hasComponent: bool; } +let mkModuleAccessName config = String.capitalize_ascii config.module_ + +let mkJsxComponentName config = + String.lowercase_ascii config.module_ ^ ".component" + (* Helper method to look up the [@react.component] attribute *) -let hasAttr (loc, _) = loc.txt = "react.component" +let hasAttr ~config (loc, _) = loc.txt = mkJsxComponentName config (* Iterate over the attributes and try to find the [@react.component] attribute *) -let hasAttrOnBinding {pvb_attributes} = - List.find_opt hasAttr pvb_attributes <> None +let hasAttrOnBinding ~config {pvb_attributes} = + List.find_opt (hasAttr ~config) pvb_attributes <> None -let coreTypeOfAttrs attributes = +let coreTypeOfAttrs ~config attributes = List.find_map (fun ({txt}, payload) -> match (txt, payload) with - | "react.component", PTyp coreType -> Some coreType + | txt, PTyp coreType when txt = mkJsxComponentName config -> Some coreType | _ -> None) attributes @@ -37,7 +42,7 @@ let typVarsOfCoreType {ptyp_desc} = let raiseError ~loc msg = Location.raise_errorf ~loc msg -let raiseErrorMultipleReactComponent ~loc = +let raiseErrorMultipleComponent ~loc = raiseError ~loc "Only one component definition is allowed for each module. Move to a \ submodule or other file if necessary." diff --git a/jscomp/syntax/src/jsx_ppx.ml b/jscomp/syntax/src/jsx_ppx.ml index 0f4ea87717..e362a9c0a5 100644 --- a/jscomp/syntax/src/jsx_ppx.ml +++ b/jscomp/syntax/src/jsx_ppx.ml @@ -51,7 +51,7 @@ let updateConfig config payload = (match getInt ~key:"version" fields with | None -> () | Some i -> config.Jsx_common.version <- i); - (match getString ~key:"module" fields with + (match getString ~key:"module_" fields with | None -> () | Some s -> config.module_ <- s); match getString ~key:"mode" fields with @@ -89,18 +89,18 @@ let getMapper ~config = version = config.version; module_ = config.module_; mode = config.mode; - hasReactComponent = config.hasReactComponent; + hasComponent = config.hasComponent; } in let restoreConfig oldConfig = config.version <- oldConfig.Jsx_common.version; config.module_ <- oldConfig.module_; config.mode <- oldConfig.mode; - config.hasReactComponent <- oldConfig.hasReactComponent + config.hasComponent <- oldConfig.hasComponent in let signature mapper items = let oldConfig = saveConfig () in - config.hasReactComponent <- false; + config.hasComponent <- false; let result = List.map (fun item -> @@ -119,7 +119,7 @@ let getMapper ~config = in let structure mapper items = let oldConfig = saveConfig () in - config.hasReactComponent <- false; + config.hasComponent <- false; let result = List.map (fun item -> @@ -147,7 +147,7 @@ let rewrite_implementation ~jsxVersion ~jsxModule ~jsxMode module_ = jsxModule; mode = jsxMode; nestedModules = []; - hasReactComponent = false; + hasComponent = false; } in let mapper = getMapper ~config in @@ -161,7 +161,7 @@ let rewrite_signature ~jsxVersion ~jsxModule ~jsxMode module_ = jsxModule; mode = jsxMode; nestedModules = []; - hasReactComponent = false; + hasComponent = false; } in let mapper = getMapper ~config in diff --git a/jscomp/syntax/src/jsx_v4.ml b/jscomp/syntax/src/jsx_v4.ml index fd6ee2b8c9..8d0210c5e6 100644 --- a/jscomp/syntax/src/jsx_v4.ml +++ b/jscomp/syntax/src/jsx_v4.ml @@ -4,6 +4,9 @@ open Asttypes open Parsetree open Longident +let moduleAccessName = Jsx_common.mkModuleAccessName +let jsxComponentName = Jsx_common.mkJsxComponentName + let nolabel = Nolabel let labelled str = Labelled str @@ -116,7 +119,7 @@ let extractChildren ?(removeLastPositionUnit = false) ~loc propsAndChildren = let merlinFocus = ({loc = Location.none; txt = "merlin.focus"}, PStr []) (* Helper method to filter out any attribute that isn't [@react.component] *) -let otherAttrsPure (loc, _) = loc.txt <> "react.component" +let otherAttrsPure ~config (loc, _) = loc.txt <> jsxComponentName config (* Finds the name of the variable the binding is assigned to, otherwise raises Invalid_argument *) let rec getFnName binding = @@ -125,7 +128,7 @@ let rec getFnName binding = | {ppat_desc = Ppat_constraint (pat, _)} -> getFnName pat | {ppat_loc} -> Jsx_common.raiseError ~loc:ppat_loc - "react.component calls cannot be destructured." + "JSX component calls cannot be destructured." let makeNewBinding binding expression newName = match binding with @@ -139,7 +142,7 @@ let makeNewBinding binding expression newName = } | {pvb_loc} -> Jsx_common.raiseError ~loc:pvb_loc - "react.component calls cannot be destructured." + "JSX component calls cannot be destructured." (* 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) = @@ -379,7 +382,10 @@ let transformUppercaseCall3 ~config modulePath mapper jsxExprLoc callExprLoc ( labelled "children", Exp.apply (Exp.ident - {txt = Ldot (Lident "React", "array"); loc = Location.none}) + { + txt = Ldot (Lident (moduleAccessName config), "array"); + loc = Location.none; + }) [(Nolabel, expression)] ); ] | _ -> @@ -423,16 +429,31 @@ let transformUppercaseCall3 ~config modulePath mapper jsxExprLoc callExprLoc match (!childrenArg, keyProp) with | None, key :: _ -> ( Exp.ident - {loc = Location.none; txt = Ldot (Lident "React", "jsxKeyed")}, + { + loc = Location.none; + txt = Ldot (Lident (moduleAccessName config), "jsxKeyed"); + }, [key; (nolabel, unitExpr ~loc:Location.none)] ) | None, [] -> - (Exp.ident {loc = Location.none; txt = Ldot (Lident "React", "jsx")}, []) + ( Exp.ident + { + loc = Location.none; + txt = Ldot (Lident (moduleAccessName config), "jsx"); + }, + [] ) | Some _, key :: _ -> ( Exp.ident - {loc = Location.none; txt = Ldot (Lident "React", "jsxsKeyed")}, + { + loc = Location.none; + txt = Ldot (Lident (moduleAccessName config), "jsxsKeyed"); + }, [key; (nolabel, unitExpr ~loc:Location.none)] ) | Some _, [] -> - ( Exp.ident {loc = Location.none; txt = Ldot (Lident "React", "jsxs")}, + ( Exp.ident + { + loc = Location.none; + txt = Ldot (Lident (moduleAccessName config), "jsxs"); + }, [] ) in Exp.apply ~loc:jsxExprLoc ~attrs jsxExpr @@ -476,6 +497,12 @@ let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs match config.Jsx_common.mode with (* the new jsx transform *) | "automatic" -> + let domBinding = + match moduleAccessName config with + | "React" -> Lident "ReactDOM" + | generic -> Ldot (Lident generic, "DOM") + in + let children, nonChildrenProps = extractChildren ~removeLastPositionUnit:true ~loc:jsxExprLoc callArguments in @@ -496,10 +523,7 @@ let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs ( labelled "children", Exp.apply ~attrs:optionalAttrs (Exp.ident - { - txt = Ldot (Lident "ReactDOM", "someElement"); - loc = Location.none; - }) + {txt = Ldot (domBinding, "someElement"); loc = Location.none}) [(Nolabel, children)] ); ] | ListLiteral {pexp_desc = Pexp_array list} when list = [] -> [] @@ -510,7 +534,10 @@ let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs ( labelled "children", Exp.apply (Exp.ident - {txt = Ldot (Lident "React", "array"); loc = Location.none}) + { + txt = Ldot (Lident (moduleAccessName config), "array"); + loc = Location.none; + }) [(Nolabel, expression)] ); ] in @@ -529,19 +556,15 @@ let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs let jsxExpr, keyAndUnit = match (!childrenArg, keyProp) with | None, key :: _ -> - ( Exp.ident - {loc = Location.none; txt = Ldot (Lident "ReactDOM", "jsxKeyed")}, + ( Exp.ident {loc = Location.none; txt = Ldot (domBinding, "jsxKeyed")}, [key; (nolabel, unitExpr ~loc:Location.none)] ) | None, [] -> - ( Exp.ident {loc = Location.none; txt = Ldot (Lident "ReactDOM", "jsx")}, - [] ) + (Exp.ident {loc = Location.none; txt = Ldot (domBinding, "jsx")}, []) | Some _, key :: _ -> - ( Exp.ident - {loc = Location.none; txt = Ldot (Lident "ReactDOM", "jsxsKeyed")}, + ( Exp.ident {loc = Location.none; txt = Ldot (domBinding, "jsxsKeyed")}, [key; (nolabel, unitExpr ~loc:Location.none)] ) | Some _, [] -> - ( Exp.ident {loc = Location.none; txt = Ldot (Lident "ReactDOM", "jsxs")}, - [] ) + (Exp.ident {loc = Location.none; txt = Ldot (domBinding, "jsxs")}, []) in Exp.apply ~loc:jsxExprLoc ~attrs jsxExpr ([(nolabel, componentNameExpr); (nolabel, props)] @ keyAndUnit) @@ -727,11 +750,11 @@ let check_string_int_attribute_iter = {Ast_iterator.default_iterator with attribute} -let checkMultipleReactComponents ~config ~loc = - (* If there is another @react.component, throw error *) - if config.Jsx_common.hasReactComponent then - Jsx_common.raiseErrorMultipleReactComponent ~loc - else config.hasReactComponent <- true +let checkMultipleComponents ~config ~loc = + (* If there is another component, throw error *) + if config.Jsx_common.hasComponent then + Jsx_common.raiseErrorMultipleComponent ~loc + else config.hasComponent <- true let modifiedBindingOld binding = let expression = binding.pvb_expr in @@ -757,8 +780,8 @@ let modifiedBindingOld binding = spelunkForFunExpression innerFunctionExpression | {pexp_loc} -> Jsx_common.raiseError ~loc:pexp_loc - "react.component calls can only be on function definitions or \ - component wrappers (forwardRef, memo)." + "JSX component calls can only be on function definitions or component \ + wrappers (forwardRef, memo)." in spelunkForFunExpression expression @@ -881,10 +904,12 @@ let vbMatchExpr namedArgList expr = aux (List.rev namedArgList) let mapBinding ~config ~emptyLoc ~pstr_loc ~fileName ~recFlag binding = - if Jsx_common.hasAttrOnBinding binding then ( - checkMultipleReactComponents ~config ~loc:pstr_loc; + if Jsx_common.hasAttrOnBinding ~config binding then ( + checkMultipleComponents ~config ~loc:pstr_loc; let binding = Jsx_common.removeArity binding in - let coreTypeOfAttr = Jsx_common.coreTypeOfAttrs binding.pvb_attributes in + let coreTypeOfAttr = + Jsx_common.coreTypeOfAttrs ~config binding.pvb_attributes + in let typVarsOfCoreType = coreTypeOfAttr |> Option.map Jsx_common.typVarsOfCoreType @@ -897,7 +922,8 @@ let mapBinding ~config ~emptyLoc ~pstr_loc ~fileName ~recFlag binding = binding with pvb_pat = {binding.pvb_pat with ppat_loc = emptyLoc}; pvb_loc = emptyLoc; - pvb_attributes = binding.pvb_attributes |> List.filter otherAttrsPure; + pvb_attributes = + binding.pvb_attributes |> List.filter (otherAttrsPure ~config); } in let fnName = getFnName binding.pvb_pat in @@ -1126,16 +1152,16 @@ let transformStructureItem ~config item = pstr_desc = Pstr_primitive ({pval_attributes; pval_type} as value_description); } as pstr -> ( - match List.filter Jsx_common.hasAttr pval_attributes with + match List.filter (Jsx_common.hasAttr ~config) pval_attributes with | [] -> [item] | [_] -> - checkMultipleReactComponents ~config ~loc:pstr_loc; + checkMultipleComponents ~config ~loc:pstr_loc; check_string_int_attribute_iter.structure_item check_string_int_attribute_iter item; let pval_type = Jsx_common.extractUncurried pval_type in let coreTypeOfAttr = Jsx_common.coreTypeOfAttrs pval_attributes in let typVarsOfCoreType = - coreTypeOfAttr + coreTypeOfAttr ~config |> Option.map Jsx_common.typVarsOfCoreType |> Option.value ~default:[] in @@ -1157,7 +1183,7 @@ let transformStructureItem ~config item = let retPropsType = Typ.constr ~loc:pstr_loc (Location.mkloc (Lident "props") pstr_loc) - (match coreTypeOfAttr with + (match coreTypeOfAttr ~config with | None -> makePropsTypeParams namedTypeList | Some _ -> ( match typVarsOfCoreType with @@ -1166,13 +1192,16 @@ let transformStructureItem ~config item = in (* type props<'x, 'y> = { x: 'x, y?: 'y, ... } *) let propsRecordType = - makePropsRecordType ~coreTypeOfAttr ~typVarsOfCoreType "props" pstr_loc - namedTypeList + makePropsRecordType ~coreTypeOfAttr:(coreTypeOfAttr ~config) + ~typVarsOfCoreType "props" pstr_loc namedTypeList in (* can't be an arrow because it will defensively uncurry *) let newExternalType = Ptyp_constr - ( {loc = pstr_loc; txt = Ldot (Lident "React", "componentLike")}, + ( { + loc = pstr_loc; + txt = Ldot (Lident (moduleAccessName config), "componentLike"); + }, [retPropsType; innerType] ) in let newStructure = @@ -1183,14 +1212,15 @@ let transformStructureItem ~config item = { value_description with pval_type = {pval_type with ptyp_desc = newExternalType}; - pval_attributes = List.filter otherAttrsPure pval_attributes; + pval_attributes = + List.filter (otherAttrsPure ~config) pval_attributes; }; } in [propsRecordType; newStructure] | _ -> Jsx_common.raiseError ~loc:pstr_loc - "Only one react.component call can exist on a component at one time") + "Only one JSX 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 @@ -1229,17 +1259,17 @@ let transformSignatureItem ~config item = psig_loc; psig_desc = Psig_value ({pval_attributes; pval_type} as psig_desc); } as psig -> ( - match List.filter Jsx_common.hasAttr pval_attributes with + match List.filter (Jsx_common.hasAttr ~config) pval_attributes with | [] -> [item] | [_] -> - checkMultipleReactComponents ~config ~loc:psig_loc; + checkMultipleComponents ~config ~loc:psig_loc; let pval_type = Jsx_common.extractUncurried pval_type in check_string_int_attribute_iter.signature_item check_string_int_attribute_iter item; let hasForwardRef = ref false in let coreTypeOfAttr = Jsx_common.coreTypeOfAttrs pval_attributes in let typVarsOfCoreType = - coreTypeOfAttr + coreTypeOfAttr ~config |> Option.map Jsx_common.typVarsOfCoreType |> Option.value ~default:[] in @@ -1268,7 +1298,7 @@ let transformSignatureItem ~config item = let retPropsType = Typ.constr (Location.mkloc (Lident "props") psig_loc) - (match coreTypeOfAttr with + (match coreTypeOfAttr ~config with | None -> makePropsTypeParams namedTypeList | Some _ -> ( match typVarsOfCoreType with @@ -1276,8 +1306,8 @@ let transformSignatureItem ~config item = | _ -> [Typ.any ()])) in let propsRecordType = - makePropsRecordTypeSig ~coreTypeOfAttr ~typVarsOfCoreType "props" - psig_loc + makePropsRecordTypeSig ~coreTypeOfAttr:(coreTypeOfAttr ~config) + ~typVarsOfCoreType "props" psig_loc ((* If there is Nolabel arg, regard the type as ref in forwardRef *) (if !hasForwardRef then [(true, "ref", [], Location.none, refType Location.none)] @@ -1287,7 +1317,10 @@ let transformSignatureItem ~config item = (* can't be an arrow because it will defensively uncurry *) let newExternalType = Ptyp_constr - ( {loc = psig_loc; txt = Ldot (Lident "React", "componentLike")}, + ( { + loc = psig_loc; + txt = Ldot (Lident (moduleAccessName config), "componentLike"); + }, [retPropsType; innerType] ) in let newStructure = @@ -1298,14 +1331,15 @@ let transformSignatureItem ~config item = { psig_desc with pval_type = {pval_type with ptyp_desc = newExternalType}; - pval_attributes = List.filter otherAttrsPure pval_attributes; + pval_attributes = + List.filter (otherAttrsPure ~config) pval_attributes; }; } in [propsRecordType; newStructure] | _ -> Jsx_common.raiseError ~loc:psig_loc - "Only one react.component call can exist on a component at one time") + "Only one JSX component call can exist on a component at one time") | _ -> [item] let transformJsxCall ~config mapper callExpression callArguments jsxExprLoc @@ -1382,7 +1416,8 @@ let expr ~config mapper expression = let fragment = match config.mode with | "automatic" -> - Exp.ident ~loc {loc; txt = Ldot (Lident "React", "jsxFragment")} + Exp.ident ~loc + {loc; txt = Ldot (Lident (moduleAccessName config), "jsxFragment")} | "classic" | _ -> Exp.ident ~loc {loc; txt = Ldot (Lident "React", "fragment")} in @@ -1390,10 +1425,13 @@ let expr ~config mapper expression = let recordOfChildren children = Exp.record [(Location.mknoloc (Lident "children"), children)] None in - let applyReactArray expr = + let applyJsxArray expr = Exp.apply (Exp.ident - {txt = Ldot (Lident "React", "array"); loc = Location.none}) + { + txt = Ldot (Lident (moduleAccessName config), "array"); + loc = Location.none; + }) [(Nolabel, expr)] in let countOfChildren = function @@ -1408,11 +1446,11 @@ let expr ~config mapper expression = | [child] -> recordOfChildren child | _ -> ( match config.mode with - | "automatic" -> recordOfChildren @@ applyReactArray childrenExpr + | "automatic" -> recordOfChildren @@ applyJsxArray childrenExpr | "classic" | _ -> emptyRecord ~loc:Location.none)) | _ -> ( match config.mode with - | "automatic" -> recordOfChildren @@ applyReactArray childrenExpr + | "automatic" -> recordOfChildren @@ applyJsxArray childrenExpr | "classic" | _ -> emptyRecord ~loc:Location.none) in let args = @@ -1431,8 +1469,11 @@ let expr ~config mapper expression = (match config.mode with | "automatic" -> if countOfChildren childrenExpr > 1 then - Exp.ident ~loc {loc; txt = Ldot (Lident "React", "jsxs")} - else Exp.ident ~loc {loc; txt = Ldot (Lident "React", "jsx")} + Exp.ident ~loc + {loc; txt = Ldot (Lident (moduleAccessName config), "jsxs")} + else + Exp.ident ~loc + {loc; txt = Ldot (Lident (moduleAccessName config), "jsx")} | "classic" | _ -> if countOfChildren childrenExpr > 1 then Exp.ident ~loc diff --git a/jscomp/syntax/src/reactjs_jsx_v3.ml b/jscomp/syntax/src/reactjs_jsx_v3.ml index 83316c9d5c..355279a812 100644 --- a/jscomp/syntax/src/reactjs_jsx_v3.ml +++ b/jscomp/syntax/src/reactjs_jsx_v3.ml @@ -594,7 +594,7 @@ let jsxMapper ~config = ({pval_name = {txt = fnName}; pval_attributes; pval_type} as value_description); } as pstr -> ( - match List.filter Jsx_common.hasAttr pval_attributes with + match List.filter (Jsx_common.hasAttr ~config) pval_attributes with | [] -> [item] | [_] -> let pval_type = Jsx_common.extractUncurried pval_type in @@ -648,7 +648,7 @@ let jsxMapper ~config = let fileName = filenameFromLoc pstr_loc in let emptyLoc = Location.in_file fileName in let mapBinding binding = - if Jsx_common.hasAttrOnBinding binding then + if Jsx_common.hasAttrOnBinding ~config binding then let binding = Jsx_common.removeArity binding in let bindingLoc = binding.pvb_loc in let bindingPatLoc = binding.pvb_pat.ppat_loc in @@ -814,7 +814,9 @@ let jsxMapper ~config = in let bindingWrapper, hasUnit, expression = modifiedBinding binding in let reactComponentAttribute = - try Some (List.find Jsx_common.hasAttr binding.pvb_attributes) + try + Some + (List.find (Jsx_common.hasAttr ~config) binding.pvb_attributes) with Not_found -> None in let _attr_loc, payload = @@ -1037,7 +1039,7 @@ let jsxMapper ~config = ({pval_name = {txt = fnName}; pval_attributes; pval_type} as psig_desc); } as psig -> ( - match List.filter Jsx_common.hasAttr pval_attributes with + match List.filter (Jsx_common.hasAttr ~config) pval_attributes with | [] -> [item] | [_] -> let pval_type = Jsx_common.extractUncurried pval_type in From e2ac5ca8102db590768b744715b0f07feecb9991 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sun, 14 Jan 2024 10:32:41 +0100 Subject: [PATCH 3/8] allow simplified @@jsxConfig --- jscomp/syntax/src/jsx_ppx.ml | 47 ++++++++++++++++++++++++++---------- jscomp/syntax/src/jsx_v4.ml | 2 +- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/jscomp/syntax/src/jsx_ppx.ml b/jscomp/syntax/src/jsx_ppx.ml index e362a9c0a5..4c3ff667a9 100644 --- a/jscomp/syntax/src/jsx_ppx.ml +++ b/jscomp/syntax/src/jsx_ppx.ml @@ -3,7 +3,12 @@ open Asttypes open Parsetree open Longident -let getPayloadFields payload = +type configPayload = + | ModuleName of string + | Fields of (t loc * expression) list + | Invalid + +let getConfigPayload payload = match payload with | PStr ({ @@ -11,8 +16,16 @@ let getPayloadFields payload = Pstr_eval ({pexp_desc = Pexp_record (recordFields, None)}, _); } :: _rest) -> - recordFields - | _ -> [] + Fields recordFields + | PStr + ({ + pstr_desc = + Pstr_eval + ({pexp_desc = Pexp_constant (Pconst_string (moduleName, _))}, _); + } + :: _rest) -> + ModuleName moduleName + | _ -> Invalid type configKey = Int | String @@ -47,16 +60,24 @@ let getInt ~key fields = let getString ~key fields = fields |> getJsxConfigByKey ~key ~type_:String let updateConfig config payload = - let fields = getPayloadFields payload in - (match getInt ~key:"version" fields with - | None -> () - | Some i -> config.Jsx_common.version <- i); - (match getString ~key:"module_" fields with - | None -> () - | Some s -> config.module_ <- s); - match getString ~key:"mode" fields with - | None -> () - | Some s -> config.mode <- s + match getConfigPayload payload with + | Invalid -> () (* TODO(generic-jsx): Report error? *) + | ModuleName moduleName -> + config.Jsx_common.module_ <- moduleName; + if String.lowercase_ascii moduleName <> "react" then ( + (* Force set automatic/version for anything but React *) + config.version <- 4; + config.mode <- "automatic") + | Fields fields -> ( + (match getInt ~key:"version" fields with + | None -> () + | Some i -> config.Jsx_common.version <- i); + (match getString ~key:"module_" fields with + | None -> () + | Some s -> config.module_ <- s); + match getString ~key:"mode" fields with + | None -> () + | Some s -> config.mode <- s) let isJsxConfigAttr ((loc, _) : attribute) = loc.txt = "jsxConfig" diff --git a/jscomp/syntax/src/jsx_v4.ml b/jscomp/syntax/src/jsx_v4.ml index 8d0210c5e6..766178c2bd 100644 --- a/jscomp/syntax/src/jsx_v4.ml +++ b/jscomp/syntax/src/jsx_v4.ml @@ -500,7 +500,7 @@ let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs let domBinding = match moduleAccessName config with | "React" -> Lident "ReactDOM" - | generic -> Ldot (Lident generic, "DOM") + | generic -> Ldot (Lident generic, "Elements") in let children, nonChildrenProps = From b4983e6c7aec668ad68fdfb41f184a68d3d3b743 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Tue, 16 Jan 2024 08:57:14 +0100 Subject: [PATCH 4/8] move to support react.component and generic jsx.component only --- jscomp/syntax/src/jsx_common.ml | 16 +++++------ jscomp/syntax/src/jsx_v4.ml | 41 +++++++++++++---------------- jscomp/syntax/src/reactjs_jsx_v3.ml | 10 +++---- 3 files changed, 31 insertions(+), 36 deletions(-) diff --git a/jscomp/syntax/src/jsx_common.ml b/jscomp/syntax/src/jsx_common.ml index 8f5df68eab..86a9ed330f 100644 --- a/jscomp/syntax/src/jsx_common.ml +++ b/jscomp/syntax/src/jsx_common.ml @@ -11,21 +11,21 @@ type jsxConfig = { let mkModuleAccessName config = String.capitalize_ascii config.module_ -let mkJsxComponentName config = - String.lowercase_ascii config.module_ ^ ".component" - (* Helper method to look up the [@react.component] attribute *) -let hasAttr ~config (loc, _) = loc.txt = mkJsxComponentName config +let hasAttr (loc, _) = + match loc.txt with + | "react.component" | "jsx.component" -> true + | _ -> false (* Iterate over the attributes and try to find the [@react.component] attribute *) -let hasAttrOnBinding ~config {pvb_attributes} = - List.find_opt (hasAttr ~config) pvb_attributes <> None +let hasAttrOnBinding {pvb_attributes} = + List.find_opt hasAttr pvb_attributes <> None -let coreTypeOfAttrs ~config attributes = +let coreTypeOfAttrs attributes = List.find_map (fun ({txt}, payload) -> match (txt, payload) with - | txt, PTyp coreType when txt = mkJsxComponentName config -> Some coreType + | ("react.component" | "jsx.component"), PTyp coreType -> Some coreType | _ -> None) attributes diff --git a/jscomp/syntax/src/jsx_v4.ml b/jscomp/syntax/src/jsx_v4.ml index 766178c2bd..60f3d153d9 100644 --- a/jscomp/syntax/src/jsx_v4.ml +++ b/jscomp/syntax/src/jsx_v4.ml @@ -5,7 +5,6 @@ open Parsetree open Longident let moduleAccessName = Jsx_common.mkModuleAccessName -let jsxComponentName = Jsx_common.mkJsxComponentName let nolabel = Nolabel @@ -119,7 +118,10 @@ let extractChildren ?(removeLastPositionUnit = false) ~loc propsAndChildren = let merlinFocus = ({loc = Location.none; txt = "merlin.focus"}, PStr []) (* Helper method to filter out any attribute that isn't [@react.component] *) -let otherAttrsPure ~config (loc, _) = loc.txt <> jsxComponentName config +let otherAttrsPure (loc, _) = + match loc.txt with + | "react.component" | "jsx.component" -> false + | _ -> true (* Finds the name of the variable the binding is assigned to, otherwise raises Invalid_argument *) let rec getFnName binding = @@ -904,12 +906,10 @@ let vbMatchExpr namedArgList expr = aux (List.rev namedArgList) let mapBinding ~config ~emptyLoc ~pstr_loc ~fileName ~recFlag binding = - if Jsx_common.hasAttrOnBinding ~config binding then ( + if Jsx_common.hasAttrOnBinding binding then ( checkMultipleComponents ~config ~loc:pstr_loc; let binding = Jsx_common.removeArity binding in - let coreTypeOfAttr = - Jsx_common.coreTypeOfAttrs ~config binding.pvb_attributes - in + let coreTypeOfAttr = Jsx_common.coreTypeOfAttrs binding.pvb_attributes in let typVarsOfCoreType = coreTypeOfAttr |> Option.map Jsx_common.typVarsOfCoreType @@ -922,8 +922,7 @@ let mapBinding ~config ~emptyLoc ~pstr_loc ~fileName ~recFlag binding = binding with pvb_pat = {binding.pvb_pat with ppat_loc = emptyLoc}; pvb_loc = emptyLoc; - pvb_attributes = - binding.pvb_attributes |> List.filter (otherAttrsPure ~config); + pvb_attributes = binding.pvb_attributes |> List.filter otherAttrsPure; } in let fnName = getFnName binding.pvb_pat in @@ -1152,7 +1151,7 @@ let transformStructureItem ~config item = pstr_desc = Pstr_primitive ({pval_attributes; pval_type} as value_description); } as pstr -> ( - match List.filter (Jsx_common.hasAttr ~config) pval_attributes with + match List.filter Jsx_common.hasAttr pval_attributes with | [] -> [item] | [_] -> checkMultipleComponents ~config ~loc:pstr_loc; @@ -1161,7 +1160,7 @@ let transformStructureItem ~config item = let pval_type = Jsx_common.extractUncurried pval_type in let coreTypeOfAttr = Jsx_common.coreTypeOfAttrs pval_attributes in let typVarsOfCoreType = - coreTypeOfAttr ~config + coreTypeOfAttr |> Option.map Jsx_common.typVarsOfCoreType |> Option.value ~default:[] in @@ -1183,7 +1182,7 @@ let transformStructureItem ~config item = let retPropsType = Typ.constr ~loc:pstr_loc (Location.mkloc (Lident "props") pstr_loc) - (match coreTypeOfAttr ~config with + (match coreTypeOfAttr with | None -> makePropsTypeParams namedTypeList | Some _ -> ( match typVarsOfCoreType with @@ -1192,8 +1191,8 @@ let transformStructureItem ~config item = in (* type props<'x, 'y> = { x: 'x, y?: 'y, ... } *) let propsRecordType = - makePropsRecordType ~coreTypeOfAttr:(coreTypeOfAttr ~config) - ~typVarsOfCoreType "props" pstr_loc namedTypeList + makePropsRecordType ~coreTypeOfAttr ~typVarsOfCoreType "props" pstr_loc + namedTypeList in (* can't be an arrow because it will defensively uncurry *) let newExternalType = @@ -1212,8 +1211,7 @@ let transformStructureItem ~config item = { value_description with pval_type = {pval_type with ptyp_desc = newExternalType}; - pval_attributes = - List.filter (otherAttrsPure ~config) pval_attributes; + pval_attributes = List.filter otherAttrsPure pval_attributes; }; } in @@ -1259,7 +1257,7 @@ let transformSignatureItem ~config item = psig_loc; psig_desc = Psig_value ({pval_attributes; pval_type} as psig_desc); } as psig -> ( - match List.filter (Jsx_common.hasAttr ~config) pval_attributes with + match List.filter Jsx_common.hasAttr pval_attributes with | [] -> [item] | [_] -> checkMultipleComponents ~config ~loc:psig_loc; @@ -1269,7 +1267,7 @@ let transformSignatureItem ~config item = let hasForwardRef = ref false in let coreTypeOfAttr = Jsx_common.coreTypeOfAttrs pval_attributes in let typVarsOfCoreType = - coreTypeOfAttr ~config + coreTypeOfAttr |> Option.map Jsx_common.typVarsOfCoreType |> Option.value ~default:[] in @@ -1298,7 +1296,7 @@ let transformSignatureItem ~config item = let retPropsType = Typ.constr (Location.mkloc (Lident "props") psig_loc) - (match coreTypeOfAttr ~config with + (match coreTypeOfAttr with | None -> makePropsTypeParams namedTypeList | Some _ -> ( match typVarsOfCoreType with @@ -1306,8 +1304,8 @@ let transformSignatureItem ~config item = | _ -> [Typ.any ()])) in let propsRecordType = - makePropsRecordTypeSig ~coreTypeOfAttr:(coreTypeOfAttr ~config) - ~typVarsOfCoreType "props" psig_loc + makePropsRecordTypeSig ~coreTypeOfAttr ~typVarsOfCoreType "props" + psig_loc ((* If there is Nolabel arg, regard the type as ref in forwardRef *) (if !hasForwardRef then [(true, "ref", [], Location.none, refType Location.none)] @@ -1331,8 +1329,7 @@ let transformSignatureItem ~config item = { psig_desc with pval_type = {pval_type with ptyp_desc = newExternalType}; - pval_attributes = - List.filter (otherAttrsPure ~config) pval_attributes; + pval_attributes = List.filter otherAttrsPure pval_attributes; }; } in diff --git a/jscomp/syntax/src/reactjs_jsx_v3.ml b/jscomp/syntax/src/reactjs_jsx_v3.ml index 355279a812..83316c9d5c 100644 --- a/jscomp/syntax/src/reactjs_jsx_v3.ml +++ b/jscomp/syntax/src/reactjs_jsx_v3.ml @@ -594,7 +594,7 @@ let jsxMapper ~config = ({pval_name = {txt = fnName}; pval_attributes; pval_type} as value_description); } as pstr -> ( - match List.filter (Jsx_common.hasAttr ~config) pval_attributes with + match List.filter Jsx_common.hasAttr pval_attributes with | [] -> [item] | [_] -> let pval_type = Jsx_common.extractUncurried pval_type in @@ -648,7 +648,7 @@ let jsxMapper ~config = let fileName = filenameFromLoc pstr_loc in let emptyLoc = Location.in_file fileName in let mapBinding binding = - if Jsx_common.hasAttrOnBinding ~config binding then + if Jsx_common.hasAttrOnBinding binding then let binding = Jsx_common.removeArity binding in let bindingLoc = binding.pvb_loc in let bindingPatLoc = binding.pvb_pat.ppat_loc in @@ -814,9 +814,7 @@ let jsxMapper ~config = in let bindingWrapper, hasUnit, expression = modifiedBinding binding in let reactComponentAttribute = - try - Some - (List.find (Jsx_common.hasAttr ~config) binding.pvb_attributes) + try Some (List.find Jsx_common.hasAttr binding.pvb_attributes) with Not_found -> None in let _attr_loc, payload = @@ -1039,7 +1037,7 @@ let jsxMapper ~config = ({pval_name = {txt = fnName}; pval_attributes; pval_type} as psig_desc); } as psig -> ( - match List.filter (Jsx_common.hasAttr ~config) pval_attributes with + match List.filter Jsx_common.hasAttr pval_attributes with | [] -> [item] | [_] -> let pval_type = Jsx_common.extractUncurried pval_type in From a09d219f3d4df9f12a176e8d1beb14ca3947b2c1 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Mon, 22 Jan 2024 20:48:19 +0100 Subject: [PATCH 5/8] Revert "allow simplified @@jsxConfig" This reverts commit 7dcd21161dc3c0c562501b981f5f5d84f3bba293. --- jscomp/syntax/src/jsx_ppx.ml | 47 ++++++++++-------------------------- jscomp/syntax/src/jsx_v4.ml | 2 +- 2 files changed, 14 insertions(+), 35 deletions(-) diff --git a/jscomp/syntax/src/jsx_ppx.ml b/jscomp/syntax/src/jsx_ppx.ml index 4c3ff667a9..e362a9c0a5 100644 --- a/jscomp/syntax/src/jsx_ppx.ml +++ b/jscomp/syntax/src/jsx_ppx.ml @@ -3,12 +3,7 @@ open Asttypes open Parsetree open Longident -type configPayload = - | ModuleName of string - | Fields of (t loc * expression) list - | Invalid - -let getConfigPayload payload = +let getPayloadFields payload = match payload with | PStr ({ @@ -16,16 +11,8 @@ let getConfigPayload payload = Pstr_eval ({pexp_desc = Pexp_record (recordFields, None)}, _); } :: _rest) -> - Fields recordFields - | PStr - ({ - pstr_desc = - Pstr_eval - ({pexp_desc = Pexp_constant (Pconst_string (moduleName, _))}, _); - } - :: _rest) -> - ModuleName moduleName - | _ -> Invalid + recordFields + | _ -> [] type configKey = Int | String @@ -60,24 +47,16 @@ let getInt ~key fields = let getString ~key fields = fields |> getJsxConfigByKey ~key ~type_:String let updateConfig config payload = - match getConfigPayload payload with - | Invalid -> () (* TODO(generic-jsx): Report error? *) - | ModuleName moduleName -> - config.Jsx_common.module_ <- moduleName; - if String.lowercase_ascii moduleName <> "react" then ( - (* Force set automatic/version for anything but React *) - config.version <- 4; - config.mode <- "automatic") - | Fields fields -> ( - (match getInt ~key:"version" fields with - | None -> () - | Some i -> config.Jsx_common.version <- i); - (match getString ~key:"module_" fields with - | None -> () - | Some s -> config.module_ <- s); - match getString ~key:"mode" fields with - | None -> () - | Some s -> config.mode <- s) + let fields = getPayloadFields payload in + (match getInt ~key:"version" fields with + | None -> () + | Some i -> config.Jsx_common.version <- i); + (match getString ~key:"module_" fields with + | None -> () + | Some s -> config.module_ <- s); + match getString ~key:"mode" fields with + | None -> () + | Some s -> config.mode <- s let isJsxConfigAttr ((loc, _) : attribute) = loc.txt = "jsxConfig" diff --git a/jscomp/syntax/src/jsx_v4.ml b/jscomp/syntax/src/jsx_v4.ml index 60f3d153d9..d06f3f7542 100644 --- a/jscomp/syntax/src/jsx_v4.ml +++ b/jscomp/syntax/src/jsx_v4.ml @@ -502,7 +502,7 @@ let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs let domBinding = match moduleAccessName config with | "React" -> Lident "ReactDOM" - | generic -> Ldot (Lident generic, "Elements") + | generic -> Ldot (Lident generic, "DOM") in let children, nonChildrenProps = From a1fb8e1d9ac4a1dc79c781df3bfb4c6969ad5e47 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 25 Jan 2024 15:48:05 +0100 Subject: [PATCH 6/8] move fn --- jscomp/syntax/src/jsx_common.ml | 2 -- jscomp/syntax/src/jsx_v4.ml | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/jscomp/syntax/src/jsx_common.ml b/jscomp/syntax/src/jsx_common.ml index 86a9ed330f..4281f0580a 100644 --- a/jscomp/syntax/src/jsx_common.ml +++ b/jscomp/syntax/src/jsx_common.ml @@ -9,8 +9,6 @@ type jsxConfig = { mutable hasComponent: bool; } -let mkModuleAccessName config = String.capitalize_ascii config.module_ - (* Helper method to look up the [@react.component] attribute *) let hasAttr (loc, _) = match loc.txt with diff --git a/jscomp/syntax/src/jsx_v4.ml b/jscomp/syntax/src/jsx_v4.ml index d06f3f7542..8c80ca327f 100644 --- a/jscomp/syntax/src/jsx_v4.ml +++ b/jscomp/syntax/src/jsx_v4.ml @@ -4,7 +4,7 @@ open Asttypes open Parsetree open Longident -let moduleAccessName = Jsx_common.mkModuleAccessName +let moduleAccessName config = String.capitalize_ascii config.Jsx_common.module_ let nolabel = Nolabel From fbcd2c7928349c65f86cf7813908e6b1e5956e05 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 25 Jan 2024 16:01:19 +0100 Subject: [PATCH 7/8] better name --- jscomp/syntax/src/jsx_v4.ml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/jscomp/syntax/src/jsx_v4.ml b/jscomp/syntax/src/jsx_v4.ml index 8c80ca327f..5246bbd31c 100644 --- a/jscomp/syntax/src/jsx_v4.ml +++ b/jscomp/syntax/src/jsx_v4.ml @@ -499,7 +499,7 @@ let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs match config.Jsx_common.mode with (* the new jsx transform *) | "automatic" -> - let domBinding = + let elementBinding = match moduleAccessName config with | "React" -> Lident "ReactDOM" | generic -> Ldot (Lident generic, "DOM") @@ -525,7 +525,10 @@ let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs ( labelled "children", Exp.apply ~attrs:optionalAttrs (Exp.ident - {txt = Ldot (domBinding, "someElement"); loc = Location.none}) + { + txt = Ldot (elementBinding, "someElement"); + loc = Location.none; + }) [(Nolabel, children)] ); ] | ListLiteral {pexp_desc = Pexp_array list} when list = [] -> [] @@ -558,15 +561,18 @@ let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs let jsxExpr, keyAndUnit = match (!childrenArg, keyProp) with | None, key :: _ -> - ( Exp.ident {loc = Location.none; txt = Ldot (domBinding, "jsxKeyed")}, + ( Exp.ident + {loc = Location.none; txt = Ldot (elementBinding, "jsxKeyed")}, [key; (nolabel, unitExpr ~loc:Location.none)] ) | None, [] -> - (Exp.ident {loc = Location.none; txt = Ldot (domBinding, "jsx")}, []) + (Exp.ident {loc = Location.none; txt = Ldot (elementBinding, "jsx")}, []) | Some _, key :: _ -> - ( Exp.ident {loc = Location.none; txt = Ldot (domBinding, "jsxsKeyed")}, + ( Exp.ident + {loc = Location.none; txt = Ldot (elementBinding, "jsxsKeyed")}, [key; (nolabel, unitExpr ~loc:Location.none)] ) | Some _, [] -> - (Exp.ident {loc = Location.none; txt = Ldot (domBinding, "jsxs")}, []) + ( Exp.ident {loc = Location.none; txt = Ldot (elementBinding, "jsxs")}, + [] ) in Exp.apply ~loc:jsxExprLoc ~attrs jsxExpr ([(nolabel, componentNameExpr); (nolabel, props)] @ keyAndUnit) From 8fd987c1e9fa16cfca9e8596a795993fd5bd9ac2 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 25 Jan 2024 16:02:04 +0100 Subject: [PATCH 8/8] changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be4f2516c5..81557b99d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,8 @@ #### :rocket: New Feature -- experimental support of tagged template literals, eg ```sql`select * from ${table}```. https://github.com/rescript-lang/rescript-compiler/pull/6250 +- Experimental support of tagged template literals, eg ```sql`select * from ${table}```. https://github.com/rescript-lang/rescript-compiler/pull/6250 +- Experimental support for generic/custom JSX transforms. https://github.com/rescript-lang/rescript-compiler/pull/6565 #### :bug: Bug Fix