diff --git a/CHANGELOG.md b/CHANGELOG.md index b716030a8c..1c357c59ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ #### :bug: Bug Fix - Fix issue with async and newtype in uncurried mode. https://github.com/rescript-lang/rescript-compiler/pull/6601 +- Generic JSX transform: Rename expected module name for lowercase JSX to `Elements` from `DOM`. https://github.com/rescript-lang/rescript-compiler/pull/6606 +- Generic JSX transform: Set default config params for `jsxConfig`. https://github.com/rescript-lang/rescript-compiler/pull/6606 +- Generic JSX transform: Handle namespaced names. https://github.com/rescript-lang/rescript-compiler/pull/6606 #### :house: Internal diff --git a/jscomp/bsc/rescript_compiler_main.ml b/jscomp/bsc/rescript_compiler_main.ml index 0307e1f708..b59f22f661 100644 --- a/jscomp/bsc/rescript_compiler_main.ml +++ b/jscomp/bsc/rescript_compiler_main.ml @@ -251,7 +251,14 @@ let buckle_script_flags : (string * Bsc_args.spec * string) array = "*internal* Set jsx version"; "-bs-jsx-module", string_call (fun i -> - Js_config.jsx_module := Js_config.jsx_module_of_string i), + let isGeneric = match i |> String.lowercase_ascii with + | "react" -> false + | _ -> true in + Js_config.jsx_module := Js_config.jsx_module_of_string i; + if isGeneric then ( + Js_config.jsx_mode := Automatic; + Js_config.jsx_version := Some Jsx_v4 + )), "*internal* Set jsx module"; "-bs-jsx-mode", string_call (fun i -> diff --git a/jscomp/syntax/src/jsx_ppx.ml b/jscomp/syntax/src/jsx_ppx.ml index e362a9c0a5..e0e1cac10e 100644 --- a/jscomp/syntax/src/jsx_ppx.ml +++ b/jscomp/syntax/src/jsx_ppx.ml @@ -48,15 +48,23 @@ 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 + let moduleRaw = getString ~key:"module_" fields in + let isGeneric = + match moduleRaw |> Option.map (fun m -> String.lowercase_ascii m) with + | Some "react" | None -> false + | Some _ -> true + in + (match (isGeneric, getInt ~key:"version" fields) with + | true, _ -> config.Jsx_common.version <- 4 + | false, Some i -> config.Jsx_common.version <- i + | _ -> ()); + (match moduleRaw with | None -> () | Some s -> config.module_ <- s); - match getString ~key:"mode" fields with - | None -> () - | Some s -> config.mode <- s + match (isGeneric, getString ~key:"mode" fields) with + | true, _ -> config.mode <- "automatic" + | false, 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 5246bbd31c..4524ca459c 100644 --- a/jscomp/syntax/src/jsx_v4.ml +++ b/jscomp/syntax/src/jsx_v4.ml @@ -4,7 +4,9 @@ open Asttypes open Parsetree open Longident -let moduleAccessName config = String.capitalize_ascii config.Jsx_common.module_ +let moduleAccessName config value = + String.capitalize_ascii config.Jsx_common.module_ ^ "." ^ value + |> Longident.parse let nolabel = Nolabel @@ -384,10 +386,7 @@ let transformUppercaseCall3 ~config modulePath mapper jsxExprLoc callExprLoc ( labelled "children", Exp.apply (Exp.ident - { - txt = Ldot (Lident (moduleAccessName config), "array"); - loc = Location.none; - }) + {txt = moduleAccessName config "array"; loc = Location.none}) [(Nolabel, expression)] ); ] | _ -> @@ -431,31 +430,17 @@ let transformUppercaseCall3 ~config modulePath mapper jsxExprLoc callExprLoc match (!childrenArg, keyProp) with | None, key :: _ -> ( Exp.ident - { - loc = Location.none; - txt = Ldot (Lident (moduleAccessName config), "jsxKeyed"); - }, + {loc = Location.none; txt = moduleAccessName config "jsxKeyed"}, [key; (nolabel, unitExpr ~loc:Location.none)] ) | None, [] -> - ( Exp.ident - { - loc = Location.none; - txt = Ldot (Lident (moduleAccessName config), "jsx"); - }, + ( Exp.ident {loc = Location.none; txt = moduleAccessName config "jsx"}, [] ) | Some _, key :: _ -> ( Exp.ident - { - loc = Location.none; - txt = Ldot (Lident (moduleAccessName config), "jsxsKeyed"); - }, + {loc = Location.none; txt = moduleAccessName config "jsxsKeyed"}, [key; (nolabel, unitExpr ~loc:Location.none)] ) | Some _, [] -> - ( Exp.ident - { - loc = Location.none; - txt = Ldot (Lident (moduleAccessName config), "jsxs"); - }, + ( Exp.ident {loc = Location.none; txt = moduleAccessName config "jsxs"}, [] ) in Exp.apply ~loc:jsxExprLoc ~attrs jsxExpr @@ -500,9 +485,9 @@ let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs (* the new jsx transform *) | "automatic" -> let elementBinding = - match moduleAccessName config with - | "React" -> Lident "ReactDOM" - | generic -> Ldot (Lident generic, "DOM") + match config.module_ |> String.lowercase_ascii with + | "react" -> Lident "ReactDOM" + | _generic -> moduleAccessName config "Elements" in let children, nonChildrenProps = @@ -539,10 +524,7 @@ let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs ( labelled "children", Exp.apply (Exp.ident - { - txt = Ldot (Lident (moduleAccessName config), "array"); - loc = Location.none; - }) + {txt = moduleAccessName config "array"; loc = Location.none}) [(Nolabel, expression)] ); ] in @@ -1203,10 +1185,7 @@ let transformStructureItem ~config item = (* can't be an arrow because it will defensively uncurry *) let newExternalType = Ptyp_constr - ( { - loc = pstr_loc; - txt = Ldot (Lident (moduleAccessName config), "componentLike"); - }, + ( {loc = pstr_loc; txt = moduleAccessName config "componentLike"}, [retPropsType; innerType] ) in let newStructure = @@ -1321,10 +1300,7 @@ let transformSignatureItem ~config item = (* can't be an arrow because it will defensively uncurry *) let newExternalType = Ptyp_constr - ( { - loc = psig_loc; - txt = Ldot (Lident (moduleAccessName config), "componentLike"); - }, + ( {loc = psig_loc; txt = moduleAccessName config "componentLike"}, [retPropsType; innerType] ) in let newStructure = @@ -1419,8 +1395,7 @@ let expr ~config mapper expression = let fragment = match config.mode with | "automatic" -> - Exp.ident ~loc - {loc; txt = Ldot (Lident (moduleAccessName config), "jsxFragment")} + Exp.ident ~loc {loc; txt = moduleAccessName config "jsxFragment"} | "classic" | _ -> Exp.ident ~loc {loc; txt = Ldot (Lident "React", "fragment")} in @@ -1431,10 +1406,7 @@ let expr ~config mapper expression = let applyJsxArray expr = Exp.apply (Exp.ident - { - txt = Ldot (Lident (moduleAccessName config), "array"); - loc = Location.none; - }) + {txt = moduleAccessName config "array"; loc = Location.none}) [(Nolabel, expr)] in let countOfChildren = function @@ -1472,11 +1444,8 @@ let expr ~config mapper expression = (match config.mode with | "automatic" -> if countOfChildren childrenExpr > 1 then - Exp.ident ~loc - {loc; txt = Ldot (Lident (moduleAccessName config), "jsxs")} - else - Exp.ident ~loc - {loc; txt = Ldot (Lident (moduleAccessName config), "jsx")} + Exp.ident ~loc {loc; txt = moduleAccessName config "jsxs"} + else Exp.ident ~loc {loc; txt = moduleAccessName config "jsx"} | "classic" | _ -> if countOfChildren childrenExpr > 1 then Exp.ident ~loc