Skip to content

Allow empty line between JSX expressions #7269

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 11 commits into from
Feb 2, 2025
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

# 12.0.0-alpha.9 (Unreleased)

#### :nail_care: Polish

- Allow single newline in JSX. https://github.com/rescript-lang/rescript/pull/7269

# 12.0.0-alpha.8

#### :bug: Bug fix
Expand Down
72 changes: 45 additions & 27 deletions compiler/syntax/src/res_printer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4429,33 +4429,51 @@ and print_jsx_children ~state (children_expr : Parsetree.expression) ~sep
match children_expr.pexp_desc with
| Pexp_construct ({txt = Longident.Lident "::"}, _) ->
let children, _ = ParsetreeViewer.collect_list_expressions children_expr in
Doc.group
(Doc.join ~sep
(List.map
(fun (expr : Parsetree.expression) ->
let leading_line_comment_present =
has_leading_line_comment cmt_tbl expr.pexp_loc
in
let expr_doc =
print_expression_with_comments ~state expr cmt_tbl
in
let add_parens_or_braces expr_doc =
(* {(20: int)} make sure that we also protect the expression inside *)
let inner_doc =
if Parens.braced_expr expr then add_parens expr_doc
else expr_doc
in
if leading_line_comment_present then add_braces inner_doc
else Doc.concat [Doc.lbrace; inner_doc; Doc.rbrace]
in
match Parens.jsx_child_expr expr with
| Nothing -> expr_doc
| Parenthesized -> add_parens_or_braces expr_doc
| Braced braces_loc ->
print_comments
(add_parens_or_braces expr_doc)
cmt_tbl braces_loc)
children))
let print_expr (expr : Parsetree.expression) =
let leading_line_comment_present =
has_leading_line_comment cmt_tbl expr.pexp_loc
in
let expr_doc = print_expression_with_comments ~state expr cmt_tbl in
let add_parens_or_braces expr_doc =
(* {(20: int)} make sure that we also protect the expression inside *)
let inner_doc =
if Parens.braced_expr expr then add_parens expr_doc else expr_doc
in
if leading_line_comment_present then add_braces inner_doc
else Doc.concat [Doc.lbrace; inner_doc; Doc.rbrace]
in
match Parens.jsx_child_expr expr with
| Nothing -> expr_doc
| Parenthesized -> add_parens_or_braces expr_doc
| Braced braces_loc ->
print_comments (add_parens_or_braces expr_doc) cmt_tbl braces_loc
in
let get_first_leading_comment loc =
match get_first_leading_comment cmt_tbl loc with
| None -> loc
| Some comment -> Comment.loc comment
in
let get_loc expr =
match ParsetreeViewer.process_braces_attr expr with
| None, _ -> get_first_leading_comment expr.pexp_loc
| Some ({loc}, _), _ -> get_first_leading_comment loc
in
let rec loop prev acc exprs =
match exprs with
| [] -> List.rev acc
| expr :: tails ->
let start_loc = (get_loc expr).loc_start.pos_lnum in
let end_loc = (get_loc prev).loc_end.pos_lnum in
let expr_doc = print_expr expr in
let docs =
if start_loc - end_loc > 1 then
Doc.concat [Doc.hard_line; expr_doc] :: acc
else expr_doc :: acc
in
loop expr docs tails
in
let docs = loop children_expr [] children in
Doc.group (Doc.join ~sep docs)
| _ ->
let leading_line_comment_present =
has_leading_line_comment cmt_tbl children_expr.pexp_loc
Expand Down
65 changes: 65 additions & 0 deletions tests/syntax_tests/data/printer/expr/expected/jsx.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ module App = {
// comment
content
}

{
// comment
if condition() {
Expand Down Expand Up @@ -460,3 +461,67 @@ let x = {
let _ = <C> {children} </C>
msg->React.string
}

let x =
<div>
{
hello()
hello()
}
{
world()
world()
}

{
hello()
hello()
}
{
world()
world()
}
// another test
<span
id="1"
className="sdf sdfdsf sdfs sdf asdf dsf"
onClick={() => {
()
}}
/>

// Comment 2

<span
id="2"
className="sdf sdfdsf sdfs sdf asdf dsf"
onClick={() => {
()
}}>
<span
id="2-1"
className="sdf sdfdsf sdfs sdf asdf dsf"
onClick={() => {
()
}}
/>

// Comment
<span
id="2-2"
className="sdf sdfdsf sdfs sdf asdf dsf"
onClick={() => {
()
}}
/>

<span id="2-3" />
</span>
<span
id="3"
className="sdf sdfdsf sdfs sdf asdf dsf"
onClick={() => {
()
}}
/>
</div>
66 changes: 66 additions & 0 deletions tests/syntax_tests/data/printer/expr/jsx.res
Original file line number Diff line number Diff line change
Expand Up @@ -443,3 +443,69 @@ let x = {
let _ = <C> {children} </C>
msg->React.string
}

let x =
<div>
{
hello()
hello()
}
{
world()
world()
}

{
hello()
hello()
} {
world()
world()
}
// another test
<span
id="1"
className="sdf sdfdsf sdfs sdf asdf dsf"
onClick={() => {
()
}}
/>

// Comment 2

<span
id="2"
className="sdf sdfdsf sdfs sdf asdf dsf"
onClick={() => {
()
}}
>
<span
id="2-1"
className="sdf sdfdsf sdfs sdf asdf dsf"
onClick={() => {
()
}}
/>


// Comment
<span
id="2-2"
className="sdf sdfdsf sdfs sdf asdf dsf"
onClick={() => {
()
}}
/>

<span id="2-3"
/>
</span>
<span
id="3"
className="sdf sdfdsf sdfs sdf asdf dsf"
onClick={() => {
()
}}
/>
</div>