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

Fix JSX v4 for first class module #666

Merged
merged 6 commits into from
Oct 2, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions cli/reactjs_jsx_v4.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1005,9 +1005,13 @@ let transformStructureItem ~config mapper item =
]
(Exp.ident ~loc:pstr_loc {loc = emptyLoc; txt = Lident txt})
in
let stripConstraint pattern =
let rec stripConstraintUnpack ~label pattern =
match pattern with
| {ppat_desc = Ppat_constraint (pattern, _)} -> pattern
| {ppat_desc = Ppat_constraint (pattern, _)} ->
stripConstraintUnpack ~label pattern
| {ppat_desc = Ppat_unpack _; ppat_loc} ->
(* remove unpack e.g. model: module(T) *)
Pat.var ~loc:ppat_loc {txt = label; loc = ppat_loc}
| _ -> pattern
in
let rec returnedExpression patternsWithLabel patternsWithNolabel
Expand All @@ -1029,7 +1033,9 @@ let transformStructureItem ~config mapper item =
| Pexp_fun
(arg_label, _default, ({ppat_loc; ppat_desc} as pattern), expr)
-> (
let patternWithoutConstraint = stripConstraint pattern in
let patternWithoutConstraint =
stripConstraintUnpack ~label:(getLabel arg_label) pattern
in
if isLabelled arg_label || isOptional arg_label then
returnedExpression
(( {loc = ppat_loc; txt = Lident (getLabel arg_label)},
Expand Down
108 changes: 108 additions & 0 deletions tests/ppx/react/expected/firstClassModules.res.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
@@jsxConfig({version: 3})

module Select = {
module type T = {
type key
type t
}
@obj
external makeProps: (
~model: module(T with type t = '\"type-a" and type key = '\"type-key"),
~selected: option<'\"type-key">,
~onChange: option<'\"type-key"> => unit,
~items: array<'\"type-a">,
~key: string=?,
unit,
) => {
"model": module(T with type t = '\"type-a" and type key = '\"type-key"),
"selected": option<'\"type-key">,
"onChange": option<'\"type-key"> => unit,
"items": array<'\"type-a">,
} = ""

@react.component
let make = (
type a key,
~model as module(T: T with type t = a and type key = key),
~selected: option<key>,
~onChange: option<key> => unit,
~items: array<a>,
) => {
let _ = (model, selected, onChange, items)
ReactDOMRe.createDOMElementVariadic("div", [])
}
let make = {
let \"FirstClassModules$Select" = (
\"Props": {
"model": module(T with type t = '\"type-a" and type key = '\"type-key"),
"selected": option<'\"type-key">,
"onChange": option<'\"type-key"> => unit,
"items": array<'\"type-a">,
},
) =>
make(
~items=\"Props"["items"],
~onChange=\"Props"["onChange"],
~selected=\"Props"["selected"],
~model=\"Props"["model"],
)
\"FirstClassModules$Select"
}
}

@@jsxConfig({version: 4, mode: "classic"})

module Select = {
module type T = {
type key
type t
}
type props<'model, 'selected, 'onChange, 'items> = {
model: 'model,
selected: 'selected,
onChange: 'onChange,
items: 'items,
}

@react.component
let make = (
{model, selected, onChange, items, _}: props<
module(T with type t = '\"type-a" and type key = '\"type-key"),
option<'\"type-key">,
option<'\"type-key"> => unit,
array<'\"type-a">,
>,
) => {
let _ = (model, selected, onChange, items)
ReactDOM.createDOMElementVariadic("div", [])
}
let make = {
let \"FirstClassModules$Select" = (props: props<_>) => make(props)

\"FirstClassModules$Select"
}
}

module External = {
module type T = {
type key
type t
}
type props<'model, 'selected, 'onChange, 'items> = {
model: 'model,
selected: 'selected,
onChange: 'onChange,
items: 'items,
}

@module("c")
external make: React.componentLike<
props<
module(T with type t = 'a and type key = 'key),
option<'key>,
(option<'key> => unit),
array<'a>,
>,
React.element,
> = "default"
}
57 changes: 57 additions & 0 deletions tests/ppx/react/expected/firstClassModules.resi.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
@@jsxConfig({version: 3})

module Select: {
module type T = {
type key
type t
}

@obj
external makeProps: (
~model: module(T with type t = 'a and type key = 'key),
~selected: option<'key>,
~onChange: option<'key> => unit,
~items: array<'a>,
~key: string=?,
unit,
) => {
"model": module(T with type t = 'a and type key = 'key),
"selected": option<'key>,
"onChange": (option<'key> => unit),
"items": array<'a>,
} = ""
let make: React.componentLike<
{
"model": module(T with type t = 'a and type key = 'key),
"selected": option<'key>,
"onChange": (option<'key> => unit),
"items": array<'a>,
},
React.element,
>
}

@@jsxConfig({version: 4, mode: "classic"})

module Select: {
module type T = {
type key
type t
}
type props<'model, 'selected, 'onChange, 'items> = {
model: 'model,
selected: 'selected,
onChange: 'onChange,
items: 'items,
}

let make: React.componentLike<
props<
module(T with type t = 'a and type key = 'key),
option<'key>,
(option<'key> => unit),
array<'a>,
>,
React.element,
>
}
56 changes: 56 additions & 0 deletions tests/ppx/react/firstClassModules.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
@@jsxConfig({version: 3})

module Select = {
module type T = {
type key
type t
}

@react.component
let make = (
type a key,
~model as module(T: T with type t = a and type key = key),
~selected: option<key>,
~onChange: option<key> => unit,
~items: array<a>,
) => {
let _ = (model, selected, onChange, items)
<div />
}
}

@@jsxConfig({version: 4, mode: "classic"})

module Select = {
module type T = {
type key
type t
}

@react.component
let make = (
type a key,
~model as module(T: T with type t = a and type key = key),
~selected: option<key>,
~onChange: option<key> => unit,
~items: array<a>,
) => {
let _ = (model, selected, onChange, items)
<div />
}
}

module External = {
module type T = {
type key
type t
}

@react.component @module("c")
external make: (
~model: module(T with type t = 'a and type key = 'key),
~selected: option<'key>,
~onChange: option<'key> => unit,
~items: array<'a>,
) => React.element = "default"
}
33 changes: 33 additions & 0 deletions tests/ppx/react/firstClassModules.resi
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@@jsxConfig({version: 3})

module Select: {
module type T = {
type key
type t
}

@react.component
let make: (
~model: module(T with type t = 'a and type key = 'key),
~selected: option<'key>,
~onChange: option<'key> => unit,
~items: array<'a>,
) => React.element
}

@@jsxConfig({version: 4, mode: "classic"})

module Select: {
module type T = {
type key
type t
}

@react.component
let make: (
~model: module(T with type t = 'a and type key = 'key),
~selected: option<'key>,
~onChange: option<'key> => unit,
~items: array<'a>,
) => React.element
}