diff --git a/CHANGELOG.md b/CHANGELOG.md index 94e96972..a26e9d35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,8 @@ - Fix location issue in error messages with JSX V4 where the multiple props types are defined https://github.com/rescript-lang/syntax/pull/655 - Fix location issue in make function in JSX V4 that breaks dead code elimination https://github.com/rescript-lang/syntax/pull/660 - Fix parsing (hence pretty printing) of expressions with underscore `_` and comments. +- Fix printing of comments inside JSX tag https://github.com/rescript-lang/syntax/pull/664 +- Fix issue where formatter erases tail comments inside JSX tag https://github.com/rescript-lang/syntax/issues/663 ## ReScript 10.0 diff --git a/src/res_comments_table.ml b/src/res_comments_table.ml index 1e310fb7..3078505b 100644 --- a/src/res_comments_table.ml +++ b/src/res_comments_table.ml @@ -1,5 +1,6 @@ module Comment = Res_comment module Doc = Res_doc +module ParsetreeViewer = Res_parsetree_viewer type t = { leading: (Location.t, Comment.t list) Hashtbl.t; @@ -1310,9 +1311,43 @@ and walkExpression expr t comments = walkExpression callExpr t inside; after) in - let afterExpr, rest = partitionAdjacentTrailing callExpr.pexp_loc after in - attach t.trailing callExpr.pexp_loc afterExpr; - walkList (arguments |> List.map (fun (_, e) -> ExprArgument e)) t rest + if ParsetreeViewer.isJsxExpression expr then ( + let props = + arguments + |> List.filter (fun (label, _) -> + match label with + | Asttypes.Labelled "children" -> false + | Asttypes.Nolabel -> false + | _ -> true) + in + let maybeChildren = + arguments + |> List.find_opt (fun (label, _) -> + label = Asttypes.Labelled "children") + in + match maybeChildren with + (* There is no need to deal with this situation as the children cannot be NONE *) + | None -> () + | Some (_, children) -> + let leading, inside, _ = partitionByLoc after children.pexp_loc in + if props = [] then + (* All comments inside a tag are trailing comments of the tag if there are no props + + *) + let afterExpr, _ = + partitionAdjacentTrailing callExpr.pexp_loc after + in + attach t.trailing callExpr.pexp_loc afterExpr + else + walkList (props |> List.map (fun (_, e) -> ExprArgument e)) t leading; + walkExpression children t inside) + else + let afterExpr, rest = partitionAdjacentTrailing callExpr.pexp_loc after in + attach t.trailing callExpr.pexp_loc afterExpr; + walkList (arguments |> List.map (fun (_, e) -> ExprArgument e)) t rest | Pexp_fun (_, _, _, _) | Pexp_newtype _ -> ( let _, parameters, returnExpr = funExpr expr in let comments = diff --git a/src/res_printer.ml b/src/res_printer.ml index ebd5bc76..60066d09 100644 --- a/src/res_printer.ml +++ b/src/res_printer.ml @@ -4039,20 +4039,15 @@ and printJsxExpression ~customLayout lident args cmtTbl = { Parsetree.pexp_desc = Pexp_construct ({txt = Longident.Lident "[]"}, None); - pexp_loc = loc; - } -> - if isSelfClosing then - Doc.concat - [Doc.line; printComments (Doc.text "/>") cmtTbl loc] - else - Doc.concat [Doc.softLine; printComments Doc.nil cmtTbl loc] - | _ -> Doc.nil); + } + when isSelfClosing -> + Doc.concat [Doc.line; Doc.text "/>"] + | _ -> Doc.concat [Doc.softLine; Doc.greaterThan]); ]); (if isSelfClosing then Doc.nil else Doc.concat [ - Doc.greaterThan; (if hasChildren then printChildren children else match children with diff --git a/tests/conversion/reason/expected/bracedJsx.res.txt b/tests/conversion/reason/expected/bracedJsx.res.txt index b49e82fe..17d75e3d 100644 --- a/tests/conversion/reason/expected/bracedJsx.res.txt +++ b/tests/conversion/reason/expected/bracedJsx.res.txt @@ -111,7 +111,8 @@ let make = () => {
(event->ReactEvent.Mouse.target)["querySelector"]("input")["focus"]()} - ref={containerRef->ReactDOMRe.Ref.domRef}> + ref={containerRef->ReactDOMRe.Ref.domRef} + > {state.history ->Array.mapWithIndex((index, item) =>
diff --git a/tests/printer/comments/expected/jsx.res.txt b/tests/printer/comments/expected/jsx.res.txt index bfca6703..6bd7d439 100644 --- a/tests/printer/comments/expected/jsx.res.txt +++ b/tests/printer/comments/expected/jsx.res.txt @@ -9,7 +9,7 @@ module Cite = { @@ -18,6 +18,19 @@ module Cite = { // Comment + + + + + +
// Must not jump inside braces {React.string("Hello, World!")} diff --git a/tests/printer/comments/jsx.res b/tests/printer/comments/jsx.res index 86a438b6..c7f70082 100644 --- a/tests/printer/comments/jsx.res +++ b/tests/printer/comments/jsx.res @@ -20,6 +20,19 @@ module Cite = { // Comment + + + + + +
// Must not jump inside braces {React.string("Hello, World!")} diff --git a/tests/printer/expr/expected/jsx.res.txt b/tests/printer/expr/expected/jsx.res.txt index bdc104ff..326cbe3c 100644 --- a/tests/printer/expr/expected/jsx.res.txt +++ b/tests/printer/expr/expected/jsx.res.txt @@ -104,7 +104,8 @@ let avatarSection = onMouseLeave={_ => setHoveringAdmin(false)} onClick={_e => { stopImpersonating(csrfToken) - }}> + }} + >
: React.nullElement} diff --git a/tests/printer/other/expected/signaturePicker.res.txt b/tests/printer/other/expected/signaturePicker.res.txt index f73d98b8..fe32b18e 100644 --- a/tests/printer/other/expected/signaturePicker.res.txt +++ b/tests/printer/other/expected/signaturePicker.res.txt @@ -28,7 +28,8 @@ let make = () => {
{"Signature"->string}