Skip to content

Preserve JSX #7387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 31 commits into from
May 5, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ffc7666
Add additional node to Pexp_apply
nojaf Apr 10, 2025
92e38cb
Try and pass jsx_element from typed_tree to js_call
nojaf Apr 10, 2025
dd56e61
Follow Lprim
nojaf Apr 11, 2025
a0c170f
Transform initial simple element
nojaf Apr 23, 2025
a98e3b8
Initial fragment support
nojaf Apr 24, 2025
1801da1
WIP extract, good stuff
nojaf Apr 24, 2025
ab32462
Print props, catch with key functions
nojaf Apr 25, 2025
6b075c0
Don't pass untyped ast, simple flag is sufficient.
nojaf Apr 25, 2025
d0bfedc
Support fragments
nojaf Apr 25, 2025
3d2930e
Unwrap children
nojaf May 3, 2025
547dfca
Poor man feature flag
nojaf May 3, 2025
09950f1
Remove duplicated in
nojaf May 3, 2025
0ab6987
Older camls
nojaf May 3, 2025
8e4811b
Revert "Poor man feature flag"
nojaf May 3, 2025
aa94f6f
Add new -bs-jsx-preserve flag
nojaf May 3, 2025
e30cab3
WIP, deal with prop spreading
nojaf May 4, 2025
773124f
Deal with prop spreading
nojaf May 4, 2025
46d3d50
Clean up Lprim and move the information to the call primitive.
cristianoc May 4, 2025
1a20f38
Add test for spreading children
nojaf May 4, 2025
8929f37
Refactor duplicate code
nojaf May 4, 2025
cecf67d
Support keyed and prop spreading
nojaf May 4, 2025
3fcf1df
Rename test file
nojaf May 4, 2025
8b7eb45
Keep key prop before spreading props. Also ensure test can run.
nojaf May 4, 2025
90b28f0
Add only spread props case
nojaf May 4, 2025
faa5618
Give record a name
nojaf May 5, 2025
400b550
Use config flag in Js_dump instead
nojaf May 5, 2025
3e1867e
Remove helper code
nojaf May 5, 2025
32bffd8
Extra call info
nojaf May 5, 2025
f104529
Detect direct Array as well
nojaf May 5, 2025
848b3ab
Don't run with mocha
nojaf May 5, 2025
aceb0e2
Feedback code review
nojaf May 5, 2025
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
Prev Previous commit
Next Next commit
Deal with prop spreading
  • Loading branch information
nojaf committed May 4, 2025
commit 773124f8ae01704dd8849b64e360b5cc1ffc485b
60 changes: 50 additions & 10 deletions compiler/core/js_dump.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,30 @@ and print_jsx cxt ~(level : int) f (fnName : string) (tag : J.expression)

(* TODO: clean up the code , a lot of code is duplicated *)
and print_jsx_prop_spreading cxt ~level f fnName tag props =
(* TODO: the children as somewhere present in the props Seq *)
(* The spreading expression is going to look something like:
(newrecord.type = "text", newrecord.tabIndex = 0, newrecord.children = 5, newrecord)
Where there are some assignments to the props object and then the props object is returned.
We want to extract the assignments and turn them into props.
And so capture the object we need to spread.
*)
let fields, spread =
let rec visit acc e =
match e.J.expression_desc with
| J.Seq
( {
J.expression_desc =
J.Bin
( Js_op.Eq,
{J.expression_desc = J.Static_index (_, name, _)},
value );
},
rest ) ->
visit ((name, value) :: acc) rest
| _ -> (List.rev acc, e)
in
visit [] props
in

let print_tag () =
match tag.expression_desc with
| J.Str {txt} -> P.string f txt
Expand All @@ -1085,7 +1108,7 @@ and print_jsx_prop_spreading cxt ~level f fnName tag props =
let _ = expression ~level cxt f tag in
()
in
(* let children_opt =
let children_opt =
List.find_map
(fun (n, e) ->
if n = "children" then
Expand All @@ -1097,17 +1120,32 @@ and print_jsx_prop_spreading cxt ~level f fnName tag props =
else Some [e]
else None)
fields
in *)
let print_props () =
P.string f " {...(";
let _ = expression ~level:0 cxt f props in
P.string f ")}"
in
(match None with
let print_props fields =
let props = List.filter (fun (n, _) -> n <> "children") fields in
if List.length props > 0 then
(List.iter (fun (n, x) ->
P.space f;
P.string f n;
P.string f "=";
P.string f "{";
let _ = expression ~level:0 cxt f x in
P.string f "}"))
props
in
let print_spreaded_props () =
(* Spread the object first, as that is what happens in ReScript *)
P.string f " {...";
let _ = expression ~level:0 cxt f spread in
P.string f "} ";
(* Then print the rest of the props *)
print_props fields
in
(match children_opt with
| None ->
P.string f "<";
print_tag ();
print_props ();
print_spreaded_props ();
P.string f "/>"
| Some children ->
let child_is_jsx child =
Expand All @@ -1118,7 +1156,7 @@ and print_jsx_prop_spreading cxt ~level f fnName tag props =

P.string f "<";
print_tag ();
print_props ();
print_spreaded_props ();
P.string f ">";

let _ =
Expand All @@ -1128,6 +1166,8 @@ and print_jsx_prop_spreading cxt ~level f fnName tag props =
if not (child_is_jsx e) then P.string f "{";
let next = expression ~level acc f e in
if not (child_is_jsx e) then P.string f "}";
(* Can we some indent this? *)
P.newline f;
next)
cxt
in
Expand Down
9 changes: 8 additions & 1 deletion tests/tests/src/nojaf.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@ let baseProps = {

let newrecord = {...baseProps};

let _unary_element_with_spread_props = <input {...(newrecord.type = "text", newrecord)}/>;
let _unary_element_with_spread_props = <input {...newrecord} type={"text"}/>;

let newrecord$1 = {...baseProps};

let _container_with_spread_props = <div {...newrecord$1} title={"barry"} className={"barry"}>{"Hello, world!"}
<input type={"text"}/>
</div>;

export {
React,
Expand All @@ -48,5 +54,6 @@ export {
_container_element_with_props_and_children,
baseProps,
_unary_element_with_spread_props,
_container_with_spread_props,
}
/* _single_element_child Not a pure module */
6 changes: 6 additions & 0 deletions tests/tests/src/nojaf.res
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,9 @@ let baseProps: JsxDOM.domProps = {
}

let _unary_element_with_spread_props = <input {...baseProps} type_="text" />

let _container_with_spread_props =
<div {...baseProps} title="barry" className="barry">
{React.string("Hello, world!")}
<input type_="text" />
</div>