From 43322bb01e82385f9469e64d504d40b62e37fc2f Mon Sep 17 00:00:00 2001 From: David Sancho Moreno Date: Sat, 22 Nov 2025 12:23:21 +0100 Subject: [PATCH 1/2] Add parents when it's a jsx child --- lib/Fmt_ast.ml | 39 ++++++++++++++++++++++++--------------- test/mlx/mlx.t | 8 ++++++++ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/lib/Fmt_ast.ml b/lib/Fmt_ast.ml index 5b22ccfcfd..9fb87432c7 100644 --- a/lib/Fmt_ast.ml +++ b/lib/Fmt_ast.ml @@ -2305,13 +2305,21 @@ and fmt_expression c ?(box = true) ?(pro = noop) ?eol ?parens match props with | [] -> str "" | props -> + let is_jsx_element e = + match e.pexp_attributes with + | [{attr_name={txt="JSX";_}; attr_payload=PStr []; _}] -> true + | _ -> false + in let fmt_labelled ?(prefix="") label e = let flabel = str (Printf.sprintf "%s%s" prefix label.txt) in match e.pexp_desc with | Pexp_ident {txt=Lident id; loc=_} when String.equal id label.txt -> flabel | _ -> - flabel $ str "=" $ fmt_expression c (sub_exp ~ctx e) + if is_jsx_element e then + flabel $ str "=" $ fmt_expression c ~parens:true (sub_exp ~ctx e) + else + flabel $ str "=" $ fmt_expression c (sub_exp ~ctx e) in let fmt_prop = function | Nolabel, e -> fmt_expression c (sub_exp ~ctx e) @@ -2320,20 +2328,21 @@ and fmt_expression c ?(box = true) ?(pro = noop) ?eol ?parens in space_break $ hvbox 0 (list props (break 1 0) fmt_prop) in - begin match !children with - | None -> hvbox 2 (start_tag () $ props) $ space_break $ str "/>" - | Some (children_loc, []) when not (Cmts.has_after c.cmts children_loc) -> - hvbox 2 (start_tag () $ props) $ space_break $ str "/>" - | Some (children_loc, children) -> - let head = hvbox 2 (start_tag () $ props $ str ">") in - let children = - hvbox 0 ( - list children (break 1 0) - (fun e -> fmt_expression c (sub_exp ~ctx e)) - $ Cmts.fmt_after c children_loc) - in - hvbox 2 (head $ break 0 0 $ children $ break 0 (-2) $ end_tag ()) - end + Params.parens_if parens c.conf ( + match !children with + | None -> hvbox 2 (start_tag () $ props) $ space_break $ str "/>" + | Some (children_loc, []) when not (Cmts.has_after c.cmts children_loc) -> + hvbox 2 (start_tag () $ props) $ space_break $ str "/>" + | Some (children_loc, children) -> + let head = hvbox 2 (start_tag () $ props $ str ">") in + let children = + hvbox 0 ( + list children (break 1 0) + (fun e -> fmt_expression c ~parens:false (sub_exp ~ctx e)) + $ Cmts.fmt_after c children_loc) + in + hvbox 2 (head $ break 0 0 $ children $ break 0 (-2) $ end_tag ()) + ) | _ -> let wrap = if c.conf.fmt_opts.wrap_fun_args.v then hovbox 2 else hvbox 2 diff --git a/test/mlx/mlx.t b/test/mlx/mlx.t index 2ac6ef2169..0a290c6a6d 100644 --- a/test/mlx/mlx.t +++ b/test/mlx/mlx.t @@ -172,3 +172,11 @@ Test for a lexer hack: [ 1 ] $ echo '[ 1 ]' | fmt [ 1 ] + +JSX elements as props: + $ echo 'let _ =
) />' | fmt + let _ =
) /> + $ echo 'let _ =
) />' | fmt + let _ =
) /> + $ echo 'let _ = ) />' | fmt + let _ = ) /> From 55a8e5fdf4d9098f465c4bd238056670e9289b01 Mon Sep 17 00:00:00 2001 From: David Sancho Moreno Date: Sat, 22 Nov 2025 15:01:59 +0100 Subject: [PATCH 2/2] Make sure sub expressions don't have par --- lib/Fmt_ast.ml | 16 ++++++++++------ test/mlx/mlx.t | 12 ++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/lib/Fmt_ast.ml b/lib/Fmt_ast.ml index 9fb87432c7..2a760019ec 100644 --- a/lib/Fmt_ast.ml +++ b/lib/Fmt_ast.ml @@ -2273,6 +2273,11 @@ and fmt_expression c ?(box = true) ?(pro = noop) ?eol ?parens | Pexp_apply (e0, e1N1) -> ( match pexp_attributes with | [{attr_name={txt="JSX";loc=_}; attr_payload=PStr []; _}] -> + let is_jsx_element e = + match e.pexp_attributes with + | [{attr_name={txt="JSX";_}; attr_payload=PStr []; _}] -> true + | _ -> false + in let children = ref None in let props = List.filter_map e1N1 ~f:(function | Labelled {txt="children";_}, {pexp_desc=Pexp_list es;pexp_loc;_} -> @@ -2305,11 +2310,6 @@ and fmt_expression c ?(box = true) ?(pro = noop) ?eol ?parens match props with | [] -> str "" | props -> - let is_jsx_element e = - match e.pexp_attributes with - | [{attr_name={txt="JSX";_}; attr_payload=PStr []; _}] -> true - | _ -> false - in let fmt_labelled ?(prefix="") label e = let flabel = str (Printf.sprintf "%s%s" prefix label.txt) in match e.pexp_desc with @@ -2338,7 +2338,11 @@ and fmt_expression c ?(box = true) ?(pro = noop) ?eol ?parens let children = hvbox 0 ( list children (break 1 0) - (fun e -> fmt_expression c ~parens:false (sub_exp ~ctx e)) + (fun e -> + if is_jsx_element e then + fmt_expression c ~parens:false (sub_exp ~ctx e) + else + fmt_expression c (sub_exp ~ctx e)) $ Cmts.fmt_after c children_loc) in hvbox 2 (head $ break 0 0 $ children $ break 0 (-2) $ end_tag ()) diff --git a/test/mlx/mlx.t b/test/mlx/mlx.t index 0a290c6a6d..00687c7fb0 100644 --- a/test/mlx/mlx.t +++ b/test/mlx/mlx.t @@ -180,3 +180,15 @@ JSX elements as props: let _ =
) /> $ echo 'let _ = ) />' | fmt let _ = ) /> + + $ echo 'let _ = ()' | fmt + let _ = + + $ echo 'let _ = (React.string children)' | fmt + let _ = (React.string children) + + $ echo 'let _ = (match x with | A -> "33" | B -> "44")' | fmt + let _ = (match x with A -> "33" | B -> "44") + + $ echo 'let _ = ()' | fmt + let _ =