Skip to content

Commit

Permalink
Allow empty line between JSX expressions (#7269)
Browse files Browse the repository at this point in the history
* Keep empty line in JSX

* Changes to the tests

* Handle braces expression

* Fix test

* Update CHANGELOG

* WIP

* Fix test

* Handle case with comments

* Fix test

* Fix formatting

* Update CHANGELOG
  • Loading branch information
shulhi authored Feb 2, 2025
1 parent bb0b6a7 commit aea2fed
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 27 deletions.
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>

1 comment on commit aea2fed

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Syntax Benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.05.

Benchmark suite Current: aea2fed Previous: e1b7fb7 Ratio
Parse RedBlackTree.res - time/run 1.3481454533333332 ms 1.2123143266666667 ms 1.11
Parse Napkinscript.res - time/run 42.121334559999994 ms 39.28006235333333 ms 1.07
Parse HeroGraphic.res - time/run 5.695538133333333 ms 5.13472718 ms 1.11

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.