Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Commit fab78d4

Browse files
authored
jsx: allow locally abstract types and type constraints on @react.component definitions (#487)
* jsx: allow locally abstract types in @react.component definitions * jsx: allow type constraints on @react.componenet definitions
1 parent 63fff7b commit fab78d4

File tree

5 files changed

+26
-3
lines changed

5 files changed

+26
-3
lines changed

src/reactjs_jsx_ppx_v3.ml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,10 @@ let otherAttrsPure (loc, _) = loc.txt <> "react.component"
9393
let hasAttrOnBinding { pvb_attributes } = find_opt hasAttr pvb_attributes <> None
9494

9595
(* Finds the name of the variable the binding is assigned to, otherwise raises Invalid_argument *)
96-
let getFnName binding =
96+
let rec getFnName binding =
9797
match binding with
98-
| { pvb_pat = { ppat_desc = Ppat_var { txt } } } -> txt
98+
| { ppat_desc = Ppat_var { txt } } -> txt
99+
| { ppat_desc = Ppat_constraint (pat, _) } -> getFnName pat
99100
| _ -> raise (Invalid_argument "react.component calls cannot be destructured.")
100101
[@@raises Invalid_argument]
101102

@@ -487,7 +488,7 @@ let jsxMapper () =
487488
let bindingLoc = binding.pvb_loc in
488489
let bindingPatLoc = binding.pvb_pat.ppat_loc in
489490
let binding = { binding with pvb_pat = { binding.pvb_pat with ppat_loc = emptyLoc }; pvb_loc = emptyLoc } in
490-
let fnName = getFnName binding in
491+
let fnName = getFnName binding.pvb_pat in
491492
let internalFnName = fnName ^ "$Internal" in
492493
let fullModuleName = makeModuleName fileName !nestedModules fnName in
493494
let modifiedBindingOld binding =
@@ -506,6 +507,10 @@ let jsxMapper () =
506507
spelunkForFunExpression innerFunctionExpression
507508
| { pexp_desc = Pexp_sequence (_wrapperExpression, innerFunctionExpression) } ->
508509
spelunkForFunExpression innerFunctionExpression
510+
| { pexp_desc = Pexp_newtype (_label, innerFunctionExpression) } ->
511+
spelunkForFunExpression innerFunctionExpression
512+
| { pexp_desc = Pexp_constraint (innerFunctionExpression, _typ) } ->
513+
spelunkForFunExpression innerFunctionExpression
509514
| _ ->
510515
raise
511516
(Invalid_argument
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@obj external makeProps: (~a: a, ~b: 'b, ~key: string=?, unit) => {"a": a, "b": 'b} = ""
2+
let make = (type a, ~a: a, ~b, _) => ReactDOMRe.createDOMElementVariadic("div", [])
3+
let make = {
4+
let \"Newtype" = (\"Props": {"a": a, "b": 'b}) => make(~b=\"Props"["b"], ~a=\"Props"["a"])
5+
\"Newtype"
6+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@obj external makeProps: (~a: 'a, ~b: 'b, ~key: string=?, unit) => {"a": 'a, "b": 'b} = ""
2+
let make:
3+
type a. (~a: a, ~b: a, a) => React.element =
4+
(~a, ~b, _) => ReactDOMRe.createDOMElementVariadic("div", [])
5+
let make = {
6+
let \"TypeConstraint" = (\"Props": {"a": 'a, "b": 'b}) => make(~b=\"Props"["b"], ~a=\"Props"["a"])
7+
\"TypeConstraint"
8+
}

tests/ppx/react/newtype.res

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@react.component
2+
let make = (type a, ~a: a, ~b, _) => <div />

tests/ppx/react/typeConstraint.res

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@react.component
2+
let make: type a. (~a: a, ~b: a, a) => React.element = (~a, ~b, _) => <div />

0 commit comments

Comments
 (0)