Skip to content

Commit 773124f

Browse files
committed
Deal with prop spreading
1 parent e30cab3 commit 773124f

File tree

3 files changed

+64
-11
lines changed

3 files changed

+64
-11
lines changed

compiler/core/js_dump.ml

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,7 +1075,30 @@ and print_jsx cxt ~(level : int) f (fnName : string) (tag : J.expression)
10751075

10761076
(* TODO: clean up the code , a lot of code is duplicated *)
10771077
and print_jsx_prop_spreading cxt ~level f fnName tag props =
1078-
(* TODO: the children as somewhere present in the props Seq *)
1078+
(* The spreading expression is going to look something like:
1079+
(newrecord.type = "text", newrecord.tabIndex = 0, newrecord.children = 5, newrecord)
1080+
Where there are some assignments to the props object and then the props object is returned.
1081+
We want to extract the assignments and turn them into props.
1082+
And so capture the object we need to spread.
1083+
*)
1084+
let fields, spread =
1085+
let rec visit acc e =
1086+
match e.J.expression_desc with
1087+
| J.Seq
1088+
( {
1089+
J.expression_desc =
1090+
J.Bin
1091+
( Js_op.Eq,
1092+
{J.expression_desc = J.Static_index (_, name, _)},
1093+
value );
1094+
},
1095+
rest ) ->
1096+
visit ((name, value) :: acc) rest
1097+
| _ -> (List.rev acc, e)
1098+
in
1099+
visit [] props
1100+
in
1101+
10791102
let print_tag () =
10801103
match tag.expression_desc with
10811104
| J.Str {txt} -> P.string f txt
@@ -1085,7 +1108,7 @@ and print_jsx_prop_spreading cxt ~level f fnName tag props =
10851108
let _ = expression ~level cxt f tag in
10861109
()
10871110
in
1088-
(* let children_opt =
1111+
let children_opt =
10891112
List.find_map
10901113
(fun (n, e) ->
10911114
if n = "children" then
@@ -1097,17 +1120,32 @@ and print_jsx_prop_spreading cxt ~level f fnName tag props =
10971120
else Some [e]
10981121
else None)
10991122
fields
1100-
in *)
1101-
let print_props () =
1102-
P.string f " {...(";
1103-
let _ = expression ~level:0 cxt f props in
1104-
P.string f ")}"
11051123
in
1106-
(match None with
1124+
let print_props fields =
1125+
let props = List.filter (fun (n, _) -> n <> "children") fields in
1126+
if List.length props > 0 then
1127+
(List.iter (fun (n, x) ->
1128+
P.space f;
1129+
P.string f n;
1130+
P.string f "=";
1131+
P.string f "{";
1132+
let _ = expression ~level:0 cxt f x in
1133+
P.string f "}"))
1134+
props
1135+
in
1136+
let print_spreaded_props () =
1137+
(* Spread the object first, as that is what happens in ReScript *)
1138+
P.string f " {...";
1139+
let _ = expression ~level:0 cxt f spread in
1140+
P.string f "} ";
1141+
(* Then print the rest of the props *)
1142+
print_props fields
1143+
in
1144+
(match children_opt with
11071145
| None ->
11081146
P.string f "<";
11091147
print_tag ();
1110-
print_props ();
1148+
print_spreaded_props ();
11111149
P.string f "/>"
11121150
| Some children ->
11131151
let child_is_jsx child =
@@ -1118,7 +1156,7 @@ and print_jsx_prop_spreading cxt ~level f fnName tag props =
11181156

11191157
P.string f "<";
11201158
print_tag ();
1121-
print_props ();
1159+
print_spreaded_props ();
11221160
P.string f ">";
11231161

11241162
let _ =
@@ -1128,6 +1166,8 @@ and print_jsx_prop_spreading cxt ~level f fnName tag props =
11281166
if not (child_is_jsx e) then P.string f "{";
11291167
let next = expression ~level acc f e in
11301168
if not (child_is_jsx e) then P.string f "}";
1169+
(* Can we some indent this? *)
1170+
P.newline f;
11311171
next)
11321172
cxt
11331173
in

tests/tests/src/nojaf.mjs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,13 @@ let baseProps = {
3434

3535
let newrecord = {...baseProps};
3636

37-
let _unary_element_with_spread_props = <input {...(newrecord.type = "text", newrecord)}/>;
37+
let _unary_element_with_spread_props = <input {...newrecord} type={"text"}/>;
38+
39+
let newrecord$1 = {...baseProps};
40+
41+
let _container_with_spread_props = <div {...newrecord$1} title={"barry"} className={"barry"}>{"Hello, world!"}
42+
<input type={"text"}/>
43+
</div>;
3844

3945
export {
4046
React,
@@ -48,5 +54,6 @@ export {
4854
_container_element_with_props_and_children,
4955
baseProps,
5056
_unary_element_with_spread_props,
57+
_container_with_spread_props,
5158
}
5259
/* _single_element_child Not a pure module */

tests/tests/src/nojaf.res

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,9 @@ let baseProps: JsxDOM.domProps = {
106106
}
107107

108108
let _unary_element_with_spread_props = <input {...baseProps} type_="text" />
109+
110+
let _container_with_spread_props =
111+
<div {...baseProps} title="barry" className="barry">
112+
{React.string("Hello, world!")}
113+
<input type_="text" />
114+
</div>

0 commit comments

Comments
 (0)