diff --git a/src/reactjs_jsx_ppx_v3.ml b/src/reactjs_jsx_ppx_v3.ml index 628855db..10a7f28d 100644 --- a/src/reactjs_jsx_ppx_v3.ml +++ b/src/reactjs_jsx_ppx_v3.ml @@ -93,9 +93,10 @@ let otherAttrsPure (loc, _) = loc.txt <> "react.component" 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 = +let rec getFnName binding = match binding with - | { pvb_pat = { ppat_desc = Ppat_var { txt } } } -> txt + | { ppat_desc = Ppat_var { txt } } -> txt + | { ppat_desc = Ppat_constraint (pat, _) } -> getFnName pat | _ -> raise (Invalid_argument "react.component calls cannot be destructured.") [@@raises Invalid_argument] @@ -487,7 +488,7 @@ let jsxMapper () = 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 fnName = getFnName binding.pvb_pat in let internalFnName = fnName ^ "$Internal" in let fullModuleName = makeModuleName fileName !nestedModules fnName in let modifiedBindingOld binding = @@ -506,6 +507,10 @@ let jsxMapper () = spelunkForFunExpression innerFunctionExpression | { pexp_desc = Pexp_sequence (_wrapperExpression, innerFunctionExpression) } -> spelunkForFunExpression innerFunctionExpression + | { pexp_desc = Pexp_newtype (_label, innerFunctionExpression) } -> + spelunkForFunExpression innerFunctionExpression + | { pexp_desc = Pexp_constraint (innerFunctionExpression, _typ) } -> + spelunkForFunExpression innerFunctionExpression | _ -> raise (Invalid_argument diff --git a/tests/ppx/react/expected/newtype.res.txt b/tests/ppx/react/expected/newtype.res.txt new file mode 100644 index 00000000..ffb21c13 --- /dev/null +++ b/tests/ppx/react/expected/newtype.res.txt @@ -0,0 +1,6 @@ +@obj external makeProps: (~a: a, ~b: 'b, ~key: string=?, unit) => {"a": a, "b": 'b} = "" +let make = (type a, ~a: a, ~b, _) => ReactDOMRe.createDOMElementVariadic("div", []) +let make = { + let \"Newtype" = (\"Props": {"a": a, "b": 'b}) => make(~b=\"Props"["b"], ~a=\"Props"["a"]) + \"Newtype" +} diff --git a/tests/ppx/react/expected/typeConstraint.res.txt b/tests/ppx/react/expected/typeConstraint.res.txt new file mode 100644 index 00000000..8940b164 --- /dev/null +++ b/tests/ppx/react/expected/typeConstraint.res.txt @@ -0,0 +1,8 @@ +@obj external makeProps: (~a: 'a, ~b: 'b, ~key: string=?, unit) => {"a": 'a, "b": 'b} = "" +let make: + type a. (~a: a, ~b: a, a) => React.element = + (~a, ~b, _) => ReactDOMRe.createDOMElementVariadic("div", []) +let make = { + let \"TypeConstraint" = (\"Props": {"a": 'a, "b": 'b}) => make(~b=\"Props"["b"], ~a=\"Props"["a"]) + \"TypeConstraint" +} diff --git a/tests/ppx/react/newtype.res b/tests/ppx/react/newtype.res new file mode 100644 index 00000000..23e4d4a1 --- /dev/null +++ b/tests/ppx/react/newtype.res @@ -0,0 +1,2 @@ +@react.component +let make = (type a, ~a: a, ~b, _) =>
diff --git a/tests/ppx/react/typeConstraint.res b/tests/ppx/react/typeConstraint.res new file mode 100644 index 00000000..cbe88490 --- /dev/null +++ b/tests/ppx/react/typeConstraint.res @@ -0,0 +1,2 @@ +@react.component +let make: type a. (~a: a, ~b: a, a) => React.element = (~a, ~b, _) =>