diff --git a/src/res_printer.ml b/src/res_printer.ml index 225230ba..efff971a 100644 --- a/src/res_printer.ml +++ b/src/res_printer.ml @@ -3834,7 +3834,11 @@ and printJsxExpression lident args cmtTbl = let name = printJsxName lident in let (formattedProps, children) = printJsxProps args cmtTbl in (*
*) - let isSelfClosing = match children with | [] -> true | _ -> false in + let isSelfClosing = + match children with + | Some ({Parsetree.pexp_desc = Pexp_construct ({txt = Longident.Lident "[]"}, None)}) -> true + | _ -> false + in Doc.group ( Doc.concat [ Doc.group ( @@ -3851,7 +3855,10 @@ and printJsxExpression lident args cmtTbl = Doc.indent ( Doc.concat [ Doc.line; - printJsxChildren children cmtTbl; + (match children with + | Some childrenExpression -> printJsxChildren childrenExpression cmtTbl + | None -> Doc.nil + ); ] ); Doc.line; @@ -3865,17 +3872,17 @@ and printJsxExpression lident args cmtTbl = and printJsxFragment expr cmtTbl = let opening = Doc.text "<>" in let closing = Doc.text "" in - let (children, _) = ParsetreeViewer.collectListExpressions expr in + (* let (children, _) = ParsetreeViewer.collectListExpressions expr in *) Doc.group ( Doc.concat [ opening; - begin match children with - | [] -> Doc.nil - | children -> + begin match expr.pexp_desc with + | Pexp_construct ({txt = Longident.Lident "[]"}, None) -> Doc.nil + | _ -> Doc.indent ( Doc.concat [ Doc.line; - printJsxChildren children cmtTbl; + printJsxChildren expr cmtTbl; ] ) end; @@ -3884,29 +3891,46 @@ and printJsxFragment expr cmtTbl = ] ) -and printJsxChildren (children: Parsetree.expression list) cmtTbl = - Doc.group ( - Doc.join ~sep:Doc.line ( - List.map (fun (expr : Parsetree.expression) -> - let leadingLineCommentPresent = hasLeadingLineComment cmtTbl expr.pexp_loc in - let exprDoc = printExpressionWithComments expr cmtTbl in - match Parens.jsxChildExpr expr with - | Parenthesized | Braced _ -> - (* {(20: int)} make sure that we also protect the expression inside *) - let innerDoc = if Parens.bracedExpr expr then addParens exprDoc else exprDoc in - if leadingLineCommentPresent then - addBraces innerDoc - else - Doc.concat [Doc.lbrace; innerDoc; Doc.rbrace] - | Nothing -> exprDoc - ) children +and printJsxChildren (childrenExpr : Parsetree.expression) cmtTbl = + match childrenExpr.pexp_desc with + | Pexp_construct ({txt = Longident.Lident "::"}, _) -> + let (children, _) = ParsetreeViewer.collectListExpressions childrenExpr in + Doc.group ( + Doc.join ~sep:Doc.line ( + List.map (fun (expr : Parsetree.expression) -> + let leadingLineCommentPresent = hasLeadingLineComment cmtTbl expr.pexp_loc in + let exprDoc = printExpressionWithComments expr cmtTbl in + match Parens.jsxChildExpr expr with + | Parenthesized | Braced _ -> + (* {(20: int)} make sure that we also protect the expression inside *) + let innerDoc = if Parens.bracedExpr expr then addParens exprDoc else exprDoc in + if leadingLineCommentPresent then + addBraces innerDoc + else + Doc.concat [Doc.lbrace; innerDoc; Doc.rbrace] + | Nothing -> exprDoc + ) children + ) ) - ) + | _ -> + let leadingLineCommentPresent = hasLeadingLineComment cmtTbl childrenExpr.pexp_loc in + let exprDoc = printExpressionWithComments childrenExpr cmtTbl in + Doc.concat [ + Doc.dotdotdot; + match Parens.jsxChildExpr childrenExpr with + | Parenthesized | Braced _ -> + let innerDoc = if Parens.bracedExpr childrenExpr then addParens exprDoc else exprDoc in + if leadingLineCommentPresent then + addBraces innerDoc + else + Doc.concat [Doc.lbrace; innerDoc; Doc.rbrace] + | Nothing -> exprDoc + ] -and printJsxProps args cmtTbl = +and printJsxProps args cmtTbl :(Doc.t * Parsetree.expression option) = let rec loop props args = match args with - | [] -> (Doc.nil, []) + | [] -> (Doc.nil, None) | [ (Asttypes.Labelled "children", children); ( @@ -3925,8 +3949,7 @@ and printJsxProps args cmtTbl = ) ] ) in - let (children, _) = ParsetreeViewer.collectListExpressions children in - (formattedProps, children) + (formattedProps, Some children) | arg::args -> let propDoc = printJsxProp arg cmtTbl in loop (propDoc::props) args diff --git a/tests/conversion/reason/expected/jsxProps.re.txt b/tests/conversion/reason/expected/jsxProps.re.txt index 3d983608..d368bc95 100644 --- a/tests/conversion/reason/expected/jsxProps.re.txt +++ b/tests/conversion/reason/expected/jsxProps.re.txt @@ -7,3 +7,11 @@ let handleClick = (href, event) => @react.component let make = (~href, ~className="", ~children) => handleClick(href, event)}> children + + ...{x =>
} + +
...element
+
...{a => 1}
+
...
+
...[a, b]
+
...{(1, 2)}
diff --git a/tests/conversion/reason/jsxProps.re b/tests/conversion/reason/jsxProps.re index 8eacda05..c34cf48d 100644 --- a/tests/conversion/reason/jsxProps.re +++ b/tests/conversion/reason/jsxProps.re @@ -9,3 +9,11 @@ let make = (~href, ~className="", ~children) => handleClick(href, event)}> children ; + + ...{x =>
} ; + +
...element
; +
...{(a) => 1}
; +
...
; +
...[|a, b|]
; +
...(1, 2)
; diff --git a/tests/parsing/grammar/expressions/expected/jsx.res.txt b/tests/parsing/grammar/expressions/expected/jsx.res.txt index 0e5836ba..0a3c9c66 100644 --- a/tests/parsing/grammar/expressions/expected/jsx.res.txt +++ b/tests/parsing/grammar/expressions/expected/jsx.res.txt @@ -560,4 +560,14 @@ let _ = ~children:[((Js.log (a <= 10)) [@ns.braces ])] ()) [@JSX ])] ()) - [@JSX ])] ())[@JSX ]) \ No newline at end of file + [@JSX ])] ())[@JSX ]) +;;((div ~children:element ())[@JSX ]) +;;((div ~children:((fun a -> 1)[@ns.braces ]) ())[@JSX ]) +;;((div ~children:((span ~children:[] ())[@JSX ]) ())[@JSX ]) +;;((div ~children:[|a|] ())[@JSX ]) +;;((div ~children:(1, 2) ())[@JSX ]) +;;(([element])[@JSX ]) +;;(([(((fun a -> 1))[@ns.braces ])])[@JSX ]) +;;(([((span ~children:[] ())[@JSX ])])[@JSX ]) +;;(([[|a|]])[@JSX ]) +;;(([(1, 2)])[@JSX ]) \ No newline at end of file diff --git a/tests/parsing/grammar/expressions/jsx.res b/tests/parsing/grammar/expressions/jsx.res index 9de13d8b..746a6f75 100644 --- a/tests/parsing/grammar/expressions/jsx.res +++ b/tests/parsing/grammar/expressions/jsx.res @@ -500,3 +500,16 @@ let _ =
{Js.log(a <= 10)}
{Js.log(a <= 10)}
Js.log(a <= 10) }>
{Js.log(a <= 10)}
+ + +
...element
+
...{(a) => 1}
+
...
+
...[a]
+
...(1, 2)
+ +<> ...element +<> ...{(a) => 1} +<> ... +<> ...[a] +<> ...(1, 2) diff --git a/tests/printer/expr/expected/jsx.res.txt b/tests/printer/expr/expected/jsx.res.txt index 20e83bf5..cc54a06a 100644 --- a/tests/printer/expr/expected/jsx.res.txt +++ b/tests/printer/expr/expected/jsx.res.txt @@ -307,3 +307,63 @@ module App = { } }
+ + ...{x =>
} +
...c
+ + + ...{ReactDOMRe.Style.make( + ~width="20px", + ~height="20px", + ~borderRadius="100%", + ~backgroundColor="red", + )} + + + + ...{value => +
} + + + + ...{(value): ReasonReact.element => +
} + + + + ...{value => { + let width = "20px" + let height = "20px" + +
+ }} + + +let v = + + + ...{_ => { + let renderX = x => { + let y = x ++ x +
+ } + renderX("foo") + }} + + diff --git a/tests/printer/expr/jsx.res b/tests/printer/expr/jsx.res index a5bf3dc1..08f2af76 100644 --- a/tests/printer/expr/jsx.res +++ b/tests/printer/expr/jsx.res @@ -316,3 +316,82 @@ module App = { } }
+ + ...{x =>
} +
...c
; + + + ...{ + ReactDOMRe.Style.make( + ~width="20px", + ~height="20px", + ~borderRadius="100%", + ~backgroundColor="red", + ) + } +; + + + ...{ + value => +
+ } + + + + ...{ + (value) :ReasonReact.element => +
+ } +; + + + ...{value => { + let width = "20px" + let height = "20px" + +