Skip to content

Commit e30cab3

Browse files
committed
WIP, deal with prop spreading
1 parent aa94f6f commit e30cab3

File tree

3 files changed

+128
-3
lines changed

3 files changed

+128
-3
lines changed

compiler/core/js_dump.ml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,7 @@ and expression_desc cxt ~(level : int) f x : cxt =
543543
| _ -> Some (f, x))
544544
in
545545
print_jsx cxt ~level f fnName tag fields
546+
(* jsxKeyed call *)
546547
| [
547548
tag;
548549
{
@@ -559,6 +560,9 @@ and expression_desc cxt ~(level : int) f x : cxt =
559560
in
560561
let fields = ("key", key) :: fields in
561562
print_jsx cxt ~level f fnName tag fields
563+
(* In the case of prop spreading *)
564+
| [tag; ({expression_desc = J.Seq _} as props)] ->
565+
print_jsx_prop_spreading cxt ~level f fnName tag props
562566
| _ ->
563567
expression_desc cxt ~level f
564568
(Call
@@ -1069,6 +1073,71 @@ and print_jsx cxt ~(level : int) f (fnName : string) (tag : J.expression)
10691073

10701074
cxt
10711075

1076+
(* TODO: clean up the code , a lot of code is duplicated *)
1077+
and print_jsx_prop_spreading cxt ~level f fnName tag props =
1078+
(* TODO: the children as somewhere present in the props Seq *)
1079+
let print_tag () =
1080+
match tag.expression_desc with
1081+
| J.Str {txt} -> P.string f txt
1082+
(* fragment *)
1083+
| J.Var (J.Qualified ({id = {name = "JsxRuntime"}}, Some "Fragment")) -> ()
1084+
| _ ->
1085+
let _ = expression ~level cxt f tag in
1086+
()
1087+
in
1088+
(* let children_opt =
1089+
List.find_map
1090+
(fun (n, e) ->
1091+
if n = "children" then
1092+
if fnName = "jsxs" then
1093+
match e.J.expression_desc with
1094+
| J.Optional_block ({expression_desc = J.Array (xs, _)}, _) ->
1095+
Some xs
1096+
| _ -> Some [e]
1097+
else Some [e]
1098+
else None)
1099+
fields
1100+
in *)
1101+
let print_props () =
1102+
P.string f " {...(";
1103+
let _ = expression ~level:0 cxt f props in
1104+
P.string f ")}"
1105+
in
1106+
(match None with
1107+
| None ->
1108+
P.string f "<";
1109+
print_tag ();
1110+
print_props ();
1111+
P.string f "/>"
1112+
| Some children ->
1113+
let child_is_jsx child =
1114+
match child.J.expression_desc with
1115+
| J.Call (_, _, {call_transformed_jsx = is_jsx}) -> is_jsx
1116+
| _ -> false
1117+
in
1118+
1119+
P.string f "<";
1120+
print_tag ();
1121+
print_props ();
1122+
P.string f ">";
1123+
1124+
let _ =
1125+
children
1126+
|> List.fold_left
1127+
(fun acc e ->
1128+
if not (child_is_jsx e) then P.string f "{";
1129+
let next = expression ~level acc f e in
1130+
if not (child_is_jsx e) then P.string f "}";
1131+
next)
1132+
cxt
1133+
in
1134+
1135+
P.string f "</";
1136+
print_tag ();
1137+
P.string f ">");
1138+
1139+
cxt
1140+
10721141
and property_name_and_value_list cxt f (l : J.property_map) =
10731142
iter_lst cxt f l
10741143
(fun cxt f (pn, e) ->

tests/tests/src/nojaf.mjs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Generated by ReScript, PLEASE EDIT WITH CARE
22

3+
import * as Primitive_option from "rescript/lib/es6/Primitive_option.js";
34
import * as JsxRuntime from "react/jsx-runtime";
45

56
let React = {};
@@ -14,11 +15,38 @@ let Icon = {
1415
make: Nojaf$Icon
1516
};
1617

17-
<div><h1>{"Hello, world!"}</h1><Nojaf$Icon/></div>;
18+
let _single_element_child = <div><h1>{"Hello, world!"}</h1></div>;
19+
20+
let _multiple_element_children = <div><h1>{"Hello, world!"}</h1><Nojaf$Icon/></div>;
21+
22+
let _single_element_fragment = <>{Primitive_option.some(<input/>)}</>;
23+
24+
let _multiple_element_fragment = <><input type={"text"}/><input type={"number"}/></>;
25+
26+
let _unary_element_with_props = <input className={"foo"} type={"text"}/>;
27+
28+
let _container_element_with_props_and_children = <div className={"foo"} title={"foo"}>{"Hello, world!"}</div>;
29+
30+
let baseProps = {
31+
className: "foo",
32+
title: "foo"
33+
};
34+
35+
let newrecord = {...baseProps};
36+
37+
let _unary_element_with_spread_props = <input {...(newrecord.type = "text", newrecord)}/>;
1838

1939
export {
2040
React,
2141
ReactDOM,
2242
Icon,
43+
_single_element_child,
44+
_multiple_element_children,
45+
_single_element_fragment,
46+
_multiple_element_fragment,
47+
_unary_element_with_props,
48+
_container_element_with_props_and_children,
49+
baseProps,
50+
_unary_element_with_spread_props,
2351
}
24-
/* Not a pure module */
52+
/* _single_element_child Not a pure module */

tests/tests/src/nojaf.res

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,36 @@ module Icon = {
7373
}
7474
}
7575

76-
let _ =
76+
let _single_element_child =
77+
<div>
78+
<h1> {React.string("Hello, world!")} </h1>
79+
</div>
80+
81+
let _multiple_element_children =
7782
<div>
7883
<h1> {React.string("Hello, world!")} </h1>
7984
<Icon />
8085
</div>
86+
87+
let _single_element_fragment =
88+
<>
89+
<input />
90+
</>
91+
92+
let _multiple_element_fragment =
93+
<>
94+
<input type_="text" />
95+
<input type_="number" />
96+
</>
97+
98+
let _unary_element_with_props = <input type_="text" className="foo" />
99+
100+
let _container_element_with_props_and_children =
101+
<div title="foo" className="foo"> {React.string("Hello, world!")} </div>
102+
103+
let baseProps: JsxDOM.domProps = {
104+
title: "foo",
105+
className: "foo",
106+
}
107+
108+
let _unary_element_with_spread_props = <input {...baseProps} type_="text" />

0 commit comments

Comments
 (0)