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

Commit 5fd1d92

Browse files
authored
Fix JSX v4 for first class module (#666)
* add first-class-module test * fix jsx v4 for first-class-module * add test external for first-class-module * add test interface of first-class-module * fix typo comment * update changelog
1 parent 6870d14 commit 5fd1d92

File tree

6 files changed

+264
-3
lines changed

6 files changed

+264
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
- Fix parsing (hence pretty printing) of expressions with underscore `_` and comments.
3434
- Fix printing of comments inside JSX tag https://github.com/rescript-lang/syntax/pull/664
3535
- Fix issue where formatter erases tail comments inside JSX tag https://github.com/rescript-lang/syntax/issues/663
36+
- Fix issue where the JSX prop has type annotation of the first class module https://github.com/rescript-lang/syntax/pull/666
3637

3738
## ReScript 10.0
3839

cli/reactjs_jsx_v4.ml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,9 +1005,13 @@ let transformStructureItem ~config mapper item =
10051005
]
10061006
(Exp.ident ~loc:pstr_loc {loc = emptyLoc; txt = Lident txt})
10071007
in
1008-
let stripConstraint pattern =
1008+
let rec stripConstraintUnpack ~label pattern =
10091009
match pattern with
1010-
| {ppat_desc = Ppat_constraint (pattern, _)} -> pattern
1010+
| {ppat_desc = Ppat_constraint (pattern, _)} ->
1011+
stripConstraintUnpack ~label pattern
1012+
| {ppat_desc = Ppat_unpack _; ppat_loc} ->
1013+
(* remove unpack e.g. model: module(T) *)
1014+
Pat.var ~loc:ppat_loc {txt = label; loc = ppat_loc}
10111015
| _ -> pattern
10121016
in
10131017
let rec returnedExpression patternsWithLabel patternsWithNolabel
@@ -1029,7 +1033,9 @@ let transformStructureItem ~config mapper item =
10291033
| Pexp_fun
10301034
(arg_label, _default, ({ppat_loc; ppat_desc} as pattern), expr)
10311035
-> (
1032-
let patternWithoutConstraint = stripConstraint pattern in
1036+
let patternWithoutConstraint =
1037+
stripConstraintUnpack ~label:(getLabel arg_label) pattern
1038+
in
10331039
if isLabelled arg_label || isOptional arg_label then
10341040
returnedExpression
10351041
(( {loc = ppat_loc; txt = Lident (getLabel arg_label)},
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
@@jsxConfig({version: 3})
2+
3+
module Select = {
4+
module type T = {
5+
type key
6+
type t
7+
}
8+
@obj
9+
external makeProps: (
10+
~model: module(T with type t = '\"type-a" and type key = '\"type-key"),
11+
~selected: option<'\"type-key">,
12+
~onChange: option<'\"type-key"> => unit,
13+
~items: array<'\"type-a">,
14+
~key: string=?,
15+
unit,
16+
) => {
17+
"model": module(T with type t = '\"type-a" and type key = '\"type-key"),
18+
"selected": option<'\"type-key">,
19+
"onChange": option<'\"type-key"> => unit,
20+
"items": array<'\"type-a">,
21+
} = ""
22+
23+
@react.component
24+
let make = (
25+
type a key,
26+
~model as module(T: T with type t = a and type key = key),
27+
~selected: option<key>,
28+
~onChange: option<key> => unit,
29+
~items: array<a>,
30+
) => {
31+
let _ = (model, selected, onChange, items)
32+
ReactDOMRe.createDOMElementVariadic("div", [])
33+
}
34+
let make = {
35+
let \"FirstClassModules$Select" = (
36+
\"Props": {
37+
"model": module(T with type t = '\"type-a" and type key = '\"type-key"),
38+
"selected": option<'\"type-key">,
39+
"onChange": option<'\"type-key"> => unit,
40+
"items": array<'\"type-a">,
41+
},
42+
) =>
43+
make(
44+
~items=\"Props"["items"],
45+
~onChange=\"Props"["onChange"],
46+
~selected=\"Props"["selected"],
47+
~model=\"Props"["model"],
48+
)
49+
\"FirstClassModules$Select"
50+
}
51+
}
52+
53+
@@jsxConfig({version: 4, mode: "classic"})
54+
55+
module Select = {
56+
module type T = {
57+
type key
58+
type t
59+
}
60+
type props<'model, 'selected, 'onChange, 'items> = {
61+
model: 'model,
62+
selected: 'selected,
63+
onChange: 'onChange,
64+
items: 'items,
65+
}
66+
67+
@react.component
68+
let make = (
69+
{model, selected, onChange, items, _}: props<
70+
module(T with type t = '\"type-a" and type key = '\"type-key"),
71+
option<'\"type-key">,
72+
option<'\"type-key"> => unit,
73+
array<'\"type-a">,
74+
>,
75+
) => {
76+
let _ = (model, selected, onChange, items)
77+
ReactDOM.createDOMElementVariadic("div", [])
78+
}
79+
let make = {
80+
let \"FirstClassModules$Select" = (props: props<_>) => make(props)
81+
82+
\"FirstClassModules$Select"
83+
}
84+
}
85+
86+
module External = {
87+
module type T = {
88+
type key
89+
type t
90+
}
91+
type props<'model, 'selected, 'onChange, 'items> = {
92+
model: 'model,
93+
selected: 'selected,
94+
onChange: 'onChange,
95+
items: 'items,
96+
}
97+
98+
@module("c")
99+
external make: React.componentLike<
100+
props<
101+
module(T with type t = 'a and type key = 'key),
102+
option<'key>,
103+
(option<'key> => unit),
104+
array<'a>,
105+
>,
106+
React.element,
107+
> = "default"
108+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
@@jsxConfig({version: 3})
2+
3+
module Select: {
4+
module type T = {
5+
type key
6+
type t
7+
}
8+
9+
@obj
10+
external makeProps: (
11+
~model: module(T with type t = 'a and type key = 'key),
12+
~selected: option<'key>,
13+
~onChange: option<'key> => unit,
14+
~items: array<'a>,
15+
~key: string=?,
16+
unit,
17+
) => {
18+
"model": module(T with type t = 'a and type key = 'key),
19+
"selected": option<'key>,
20+
"onChange": (option<'key> => unit),
21+
"items": array<'a>,
22+
} = ""
23+
let make: React.componentLike<
24+
{
25+
"model": module(T with type t = 'a and type key = 'key),
26+
"selected": option<'key>,
27+
"onChange": (option<'key> => unit),
28+
"items": array<'a>,
29+
},
30+
React.element,
31+
>
32+
}
33+
34+
@@jsxConfig({version: 4, mode: "classic"})
35+
36+
module Select: {
37+
module type T = {
38+
type key
39+
type t
40+
}
41+
type props<'model, 'selected, 'onChange, 'items> = {
42+
model: 'model,
43+
selected: 'selected,
44+
onChange: 'onChange,
45+
items: 'items,
46+
}
47+
48+
let make: React.componentLike<
49+
props<
50+
module(T with type t = 'a and type key = 'key),
51+
option<'key>,
52+
(option<'key> => unit),
53+
array<'a>,
54+
>,
55+
React.element,
56+
>
57+
}

tests/ppx/react/firstClassModules.res

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
@@jsxConfig({version: 3})
2+
3+
module Select = {
4+
module type T = {
5+
type key
6+
type t
7+
}
8+
9+
@react.component
10+
let make = (
11+
type a key,
12+
~model as module(T: T with type t = a and type key = key),
13+
~selected: option<key>,
14+
~onChange: option<key> => unit,
15+
~items: array<a>,
16+
) => {
17+
let _ = (model, selected, onChange, items)
18+
<div />
19+
}
20+
}
21+
22+
@@jsxConfig({version: 4, mode: "classic"})
23+
24+
module Select = {
25+
module type T = {
26+
type key
27+
type t
28+
}
29+
30+
@react.component
31+
let make = (
32+
type a key,
33+
~model as module(T: T with type t = a and type key = key),
34+
~selected: option<key>,
35+
~onChange: option<key> => unit,
36+
~items: array<a>,
37+
) => {
38+
let _ = (model, selected, onChange, items)
39+
<div />
40+
}
41+
}
42+
43+
module External = {
44+
module type T = {
45+
type key
46+
type t
47+
}
48+
49+
@react.component @module("c")
50+
external make: (
51+
~model: module(T with type t = 'a and type key = 'key),
52+
~selected: option<'key>,
53+
~onChange: option<'key> => unit,
54+
~items: array<'a>,
55+
) => React.element = "default"
56+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
@@jsxConfig({version: 3})
2+
3+
module Select: {
4+
module type T = {
5+
type key
6+
type t
7+
}
8+
9+
@react.component
10+
let make: (
11+
~model: module(T with type t = 'a and type key = 'key),
12+
~selected: option<'key>,
13+
~onChange: option<'key> => unit,
14+
~items: array<'a>,
15+
) => React.element
16+
}
17+
18+
@@jsxConfig({version: 4, mode: "classic"})
19+
20+
module Select: {
21+
module type T = {
22+
type key
23+
type t
24+
}
25+
26+
@react.component
27+
let make: (
28+
~model: module(T with type t = 'a and type key = 'key),
29+
~selected: option<'key>,
30+
~onChange: option<'key> => unit,
31+
~items: array<'a>,
32+
) => React.element
33+
}

0 commit comments

Comments
 (0)