Skip to content

Commit beebcff

Browse files
authored
Fix support for recursive components in JSX V4. (#5986)
1 parent 21bba83 commit beebcff

File tree

6 files changed

+114
-9
lines changed

6 files changed

+114
-9
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ These are only breaking changes for unformatted code.
5757
- Fix issue with error messages for uncurried functions where expected and given type were swapped https://github.com/rescript-lang/rescript-compiler/pull/5973
5858
- Fix issue with nested async functions, where the inner function would be emitted without `async` https://github.com/rescript-lang/rescript-compiler/pull/5983
5959
- Fix issue with async context check, and printer, for async functions with locally abstract type https://github.com/rescript-lang/rescript-compiler/pull/5982
60+
- Fix support for recursive components in JSX V4 https://github.com/rescript-lang/rescript-compiler/pull/5986
6061

6162
#### :nail_care: Polish
6263

jscomp/build_tests/react_ppx/src/recursive_component_test.bs.js

+13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jscomp/build_tests/react_ppx/src/recursive_component_test.res

+10
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,13 @@
77
*/
88
@react.component
99
let rec make = (~foo, ()) => React.createElement(make, makeProps(~foo, ()))
10+
11+
@@jsxConfig({version:4})
12+
13+
module Rec = {
14+
@react.component
15+
let rec make = () => {
16+
mm(({}: props))
17+
}
18+
and mm = (x) => make(x)
19+
}

res_syntax/src/reactjs_jsx_v4.ml

+15-9
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,12 @@ let transformStructureItem ~config mapper item =
10641064
in
10651065
let innerExpression =
10661066
Exp.apply
1067-
(Exp.ident (Location.mknoloc @@ Lident fnName))
1067+
(Exp.ident
1068+
(Location.mknoloc
1069+
@@ Lident
1070+
(match recFlag with
1071+
| Recursive -> internalFnName
1072+
| Nonrecursive -> fnName)))
10681073
([(Nolabel, Exp.ident (Location.mknoloc @@ Lident "props"))]
10691074
@
10701075
match hasForwardRef with
@@ -1206,14 +1211,15 @@ let transformStructureItem ~config mapper item =
12061211
| Recursive ->
12071212
( [
12081213
bindingWrapper
1209-
(Exp.let_ ~loc:emptyLoc Recursive
1210-
[
1211-
makeNewBinding binding expression internalFnName;
1212-
Vb.mk
1213-
(Pat.var {loc = emptyLoc; txt = fnName})
1214-
fullExpression;
1215-
]
1216-
(Exp.ident {loc = emptyLoc; txt = Lident fnName}));
1214+
(Exp.let_ ~loc:emptyLoc Nonrecursive
1215+
[makeNewBinding binding expression internalFnName]
1216+
(Exp.let_ ~loc:emptyLoc Nonrecursive
1217+
[
1218+
Vb.mk
1219+
(Pat.var {loc = emptyLoc; txt = fnName})
1220+
fullExpression;
1221+
]
1222+
(Exp.ident {loc = emptyLoc; txt = Lident fnName})));
12171223
],
12181224
None )
12191225
| Nonrecursive ->

res_syntax/tests/ppx/react/expected/v4.res.txt

+52
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,55 @@ module EUncurried = {
4545

4646
external make: React.componentLike<props<string>, React.element> = "default"
4747
}
48+
49+
module Rec = {
50+
type props = {}
51+
52+
let rec make = {
53+
@merlin.focus
54+
let \"make$Internal" = (_: props) => {
55+
make(({}: props))
56+
}
57+
let make = {
58+
let \"V4$Rec" = props => \"make$Internal"(props)
59+
60+
\"V4$Rec"
61+
}
62+
make
63+
}
64+
}
65+
66+
module Rec1 = {
67+
type props = {}
68+
69+
let rec make = {
70+
@merlin.focus
71+
let \"make$Internal" = (_: props) => {
72+
React.null
73+
}
74+
let make = {
75+
let \"V4$Rec1" = props => \"make$Internal"(props)
76+
77+
\"V4$Rec1"
78+
}
79+
make
80+
}
81+
}
82+
83+
module Rec2 = {
84+
type props = {}
85+
86+
let rec make = {
87+
@merlin.focus
88+
let \"make$Internal" = (_: props) => {
89+
mm(({}: props))
90+
}
91+
let make = {
92+
let \"V4$Rec2" = props => \"make$Internal"(props)
93+
94+
\"V4$Rec2"
95+
}
96+
make
97+
}
98+
and mm = x => make(x)
99+
}

res_syntax/tests/ppx/react/v4.res

+23
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,26 @@ module EUncurried = {
2727
@react.component
2828
external make: (. ~x: string) => React.element = "default"
2929
}
30+
31+
module Rec = {
32+
@react.component
33+
let rec make = () => {
34+
make({}:props)
35+
}
36+
}
37+
38+
module Rec1 = {
39+
@react.component
40+
let rec make = () => {
41+
React.null
42+
}
43+
}
44+
45+
module Rec2 = {
46+
@react.component
47+
let rec make = () => {
48+
mm(({}: props))
49+
}
50+
and mm = (x) => make(x)
51+
}
52+

0 commit comments

Comments
 (0)