Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
43 changes: 28 additions & 15 deletions lib/Fmt_ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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;_} ->
Expand Down Expand Up @@ -2311,7 +2316,10 @@ and fmt_expression c ?(box = true) ?(pro = noop) ?eol ?parens
| 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)
Expand All @@ -2320,20 +2328,25 @@ 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 ->
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 ())
)
| _ ->
let wrap =
if c.conf.fmt_opts.wrap_fun_args.v then hovbox 2 else hvbox 2
Expand Down
20 changes: 20 additions & 0 deletions test/mlx/mlx.t
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,23 @@ Test for a lexer hack:
[ <element>1</element> ]
$ echo '[<M.element> 1 </M.element>]' | fmt
[ <M.element>1</M.element> ]

JSX elements as props:
$ echo 'let _ = <div element=(<span />) />' | fmt
let _ = <div element=(<span />) />
$ echo 'let _ = <div element=(<Componient />) />' | fmt
let _ = <div element=(<Componient />) />
$ echo 'let _ = <Big element=(<Component />) />' | fmt
let _ = <Big element=(<Component />) />

$ echo 'let _ = <Big>(<Component />)</Big>' | fmt
let _ = <Big><Component /></Big>

$ echo 'let _ = <Big>(React.string children)</Big>' | fmt
let _ = <Big>(React.string children)</Big>

$ echo 'let _ = <Big>(match x with | A -> "33" | B -> "44")</Big>' | fmt
let _ = <Big>(match x with A -> "33" | B -> "44")</Big>

$ echo 'let _ = <Big>(<Lola />)</Big>' | fmt
let _ = <Big><Lola /></Big>
Loading