From 4da9a31cb35953472420bbe738fa9c386d065a21 Mon Sep 17 00:00:00 2001 From: Shulhi Sapli <913103+shulhi@users.noreply.github.com> Date: Thu, 23 Oct 2025 20:27:10 +0800 Subject: [PATCH 1/7] WIP --- compiler/syntax/src/res_printer.ml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/syntax/src/res_printer.ml b/compiler/syntax/src/res_printer.ml index 7132e16dd9..de5b04fe5c 100644 --- a/compiler/syntax/src/res_printer.ml +++ b/compiler/syntax/src/res_printer.ml @@ -3223,7 +3223,14 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl = * b: 2, * }` -> record is written on multiple lines, break the group *) let force_break = - e.pexp_loc.loc_start.pos_lnum < e.pexp_loc.loc_end.pos_lnum + match (spread_expr, rows) with + | Some expr, _ -> + (* If there's a spread, compare with spread expression's location *) + e.pexp_loc.loc_start.pos_lnum < expr.pexp_loc.loc_start.pos_lnum + | None, first_row :: _ -> + (* Otherwise, compare with the first row's location *) + e.pexp_loc.loc_start.pos_lnum < first_row.lid.loc.loc_start.pos_lnum + | None, [] -> false in let punning_allowed = match (spread_expr, rows) with From d50570d6f8cabec4cb178dd56fba517fe7d6ce92 Mon Sep 17 00:00:00 2001 From: Shulhi Sapli <913103+shulhi@users.noreply.github.com> Date: Thu, 23 Oct 2025 21:33:17 +0800 Subject: [PATCH 2/7] Update tests --- .../data/ast-mapping/expected/JSXElements.res.txt | 14 ++------------ .../data/printer/comments/expected/expr.res.txt | 5 +---- .../data/printer/expr/expected/record.res.txt | 12 ++++++++++++ tests/syntax_tests/data/printer/expr/record.res | 8 ++++++++ 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/tests/syntax_tests/data/ast-mapping/expected/JSXElements.res.txt b/tests/syntax_tests/data/ast-mapping/expected/JSXElements.res.txt index b09e877523..f151681291 100644 --- a/tests/syntax_tests/data/ast-mapping/expected/JSXElements.res.txt +++ b/tests/syntax_tests/data/ast-mapping/expected/JSXElements.res.txt @@ -2,19 +2,9 @@ let emptyUnary = ReactDOM.jsx("input", {}) let emptyNonunary = ReactDOM.jsx("div", {}) -let emptyUnaryWithAttributes = ReactDOM.jsx( - "input", - { - type_: "text", - }, -) +let emptyUnaryWithAttributes = ReactDOM.jsx("input", {type_: "text"}) -let emptyNonunaryWithAttributes = ReactDOM.jsx( - "div", - { - className: "container", - }, -) +let emptyNonunaryWithAttributes = ReactDOM.jsx("div", {className: "container"}) let elementWithChildren = ReactDOM.jsxs( "div", diff --git a/tests/syntax_tests/data/printer/comments/expected/expr.res.txt b/tests/syntax_tests/data/printer/comments/expected/expr.res.txt index 7d4a0b3811..cbe763a3ab 100644 --- a/tests/syntax_tests/data/printer/comments/expected/expr.res.txt +++ b/tests/syntax_tests/data/printer/comments/expected/expr.res.txt @@ -121,10 +121,7 @@ let user = /* before */ { /* c4 */ "age" /* c5 */: /* c6 */ 31 /* c7 */, } // after -let spreadUser = { - /* before */ ...user1 /* after */, - /* c0 */ age /* c1 */: /* c2 */ 32 /* c3 */, -} +let spreadUser = {/* before */ ...user1 /* after */, /* c0 */ age /* c1 */: /* c2 */ 32 /* c3 */} // Pexp_field let x = /* before */ user /* c0 */./* c1 */ name /* c2 */ diff --git a/tests/syntax_tests/data/printer/expr/expected/record.res.txt b/tests/syntax_tests/data/printer/expr/expected/record.res.txt index fb16fe7113..1c81ed5a10 100644 --- a/tests/syntax_tests/data/printer/expr/expected/record.res.txt +++ b/tests/syntax_tests/data/printer/expr/expected/record.res.txt @@ -103,3 +103,15 @@ let optParen = {x: 3, y: ?foo(bar)} let optParen = {x: 3, y: ?(foo->bar)} let optParen = {x: 3, y: ?(() => 3)} let optParen = {x: 3, y: ?-3} + +let x = {a: 2} +let x = { + a: 2, + bbbbbbbbbbbbbbbbbbbbb: 22222222222, + ccccccccccccccccccccc: 22222222222222222, + ddddddddddddddddddddd: 2222222222222, +} +let x = {a: 2} +let x = { + a: 2, +} diff --git a/tests/syntax_tests/data/printer/expr/record.res b/tests/syntax_tests/data/printer/expr/record.res index 82336fc734..3c5c70d48d 100644 --- a/tests/syntax_tests/data/printer/expr/record.res +++ b/tests/syntax_tests/data/printer/expr/record.res @@ -93,3 +93,11 @@ let optParen = { x:3, y: ? (foo(bar)) } let optParen = { x:3, y: ? (foo->bar) } let optParen = { x:3, y: ? (()=>3) } let optParen = { x:3, y: ? (-3) } + +let x = {a: 2} +let x = {a: 2, bbbbbbbbbbbbbbbbbbbbb: 22222222222, ccccccccccccccccccccc: 22222222222222222, ddddddddddddddddddddd: 2222222222222} +let x = {a: 2 +} +let x = { + a: 2 +} From a22a0a92e5ed0d7c84c5bf438d02cbac0fbd57c9 Mon Sep 17 00:00:00 2001 From: Shulhi Sapli <913103+shulhi@users.noreply.github.com> Date: Fri, 24 Oct 2025 15:51:00 +0800 Subject: [PATCH 3/7] Change how force_break is handled in type declaration printing --- compiler/syntax/src/res_printer.ml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/compiler/syntax/src/res_printer.ml b/compiler/syntax/src/res_printer.ml index de5b04fe5c..20fb8869cc 100644 --- a/compiler/syntax/src/res_printer.ml +++ b/compiler/syntax/src/res_printer.ml @@ -1282,7 +1282,7 @@ and print_type_declaration ~state ~name ~equal_sign ~rec_flag i manifest; Doc.concat [Doc.space; Doc.text equal_sign; Doc.space]; print_private_flag td.ptype_private; - print_record_declaration ~state lds cmt_tbl; + print_record_declaration ~record_loc:td.ptype_loc ~state lds cmt_tbl; ] | Ptype_variant cds -> let manifest = @@ -1370,8 +1370,8 @@ and print_type_declaration2 ?inline_record_definitions ~state ~rec_flag manifest; Doc.concat [Doc.space; Doc.text equal_sign; Doc.space]; print_private_flag td.ptype_private; - print_record_declaration ?inline_record_definitions ~state lds - cmt_tbl; + print_record_declaration ?inline_record_definitions + ~record_loc:td.ptype_loc ~state lds cmt_tbl; ] | Ptype_variant cds -> let manifest = @@ -1465,11 +1465,15 @@ and print_type_param ~state (param : Parsetree.core_type * Asttypes.variance) Doc.concat [printed_variance; print_typ_expr ~state typ cmt_tbl] and print_record_declaration ?check_break_from_loc ?inline_record_definitions - ~state (lds : Parsetree.label_declaration list) cmt_tbl = + ?record_loc ~state (lds : Parsetree.label_declaration list) cmt_tbl = let force_break = - match (check_break_from_loc, lds, List.rev lds) with + match (check_break_from_loc, record_loc, lds) with | Some loc, _, _ -> loc.Location.loc_start.pos_lnum < loc.loc_end.pos_lnum - | _, first :: _, last :: _ -> + | None, Some loc, first :: _ -> + (* Check if first field is on a different line than the opening brace *) + loc.loc_start.pos_lnum < first.Parsetree.pld_loc.loc_start.pos_lnum + | None, None, first :: _ -> + let last = List.hd (List.rev lds) in first.pld_loc.loc_start.pos_lnum < last.pld_loc.loc_end.pos_lnum | _, _, _ -> false in From 2b42d0068c28139b6e6123d8171f8d97ff4d5dc7 Mon Sep 17 00:00:00 2001 From: Shulhi Sapli <913103+shulhi@users.noreply.github.com> Date: Fri, 24 Oct 2025 16:16:41 +0800 Subject: [PATCH 4/7] Fix type declaration with spread --- compiler/syntax/src/res_printer.ml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/compiler/syntax/src/res_printer.ml b/compiler/syntax/src/res_printer.ml index 20fb8869cc..45d4e51efa 100644 --- a/compiler/syntax/src/res_printer.ml +++ b/compiler/syntax/src/res_printer.ml @@ -1466,15 +1466,21 @@ and print_type_param ~state (param : Parsetree.core_type * Asttypes.variance) and print_record_declaration ?check_break_from_loc ?inline_record_definitions ?record_loc ~state (lds : Parsetree.label_declaration list) cmt_tbl = + let get_field_start_line (ld : Parsetree.label_declaration) = + (* For spread fields (...), use the type location instead of pld_loc + because pld_loc may incorrectly include preceding whitespace *) + if ld.pld_name.txt = "..." then ld.pld_type.ptyp_loc.loc_start.pos_lnum + else ld.pld_loc.loc_start.pos_lnum + in let force_break = match (check_break_from_loc, record_loc, lds) with | Some loc, _, _ -> loc.Location.loc_start.pos_lnum < loc.loc_end.pos_lnum | None, Some loc, first :: _ -> (* Check if first field is on a different line than the opening brace *) - loc.loc_start.pos_lnum < first.Parsetree.pld_loc.loc_start.pos_lnum + loc.loc_start.pos_lnum < get_field_start_line first | None, None, first :: _ -> let last = List.hd (List.rev lds) in - first.pld_loc.loc_start.pos_lnum < last.pld_loc.loc_end.pos_lnum + get_field_start_line first < last.pld_loc.loc_end.pos_lnum | _, _, _ -> false in Doc.breakable_group ~force_break From ad321b1e69654dd97810d73535781ed89f496dc9 Mon Sep 17 00:00:00 2001 From: Shulhi Sapli <913103+shulhi@users.noreply.github.com> Date: Sat, 25 Oct 2025 19:58:43 +0800 Subject: [PATCH 5/7] Update tests --- .../data/printer/expr/expected/record.res.txt | 17 +++++++++++++++++ tests/syntax_tests/data/printer/expr/record.res | 11 +++++++++++ 2 files changed, 28 insertions(+) diff --git a/tests/syntax_tests/data/printer/expr/expected/record.res.txt b/tests/syntax_tests/data/printer/expr/expected/record.res.txt index 1c81ed5a10..d33ef76db5 100644 --- a/tests/syntax_tests/data/printer/expr/expected/record.res.txt +++ b/tests/syntax_tests/data/printer/expr/expected/record.res.txt @@ -97,6 +97,23 @@ type tt = {x: int, y?: string} type ttt = {x: int, y?: string} +type x = {a: int} + +type x = { + aaaaaaaaaaaa: int, + bbbbbbbbbbbb: int, + cccccccccccc: int, + dddddddddddd: int, + eeeeeeeeeeee: int, + ffffffffffffffff: int, +} + +type y = {a: int} + +type z = { + a: int, +} + let optParen = {x: 3, y: ?(someBool ? Some("") : None)} let optParen = {x: 3, y: ?(3 + 4)} let optParen = {x: 3, y: ?foo(bar)} diff --git a/tests/syntax_tests/data/printer/expr/record.res b/tests/syntax_tests/data/printer/expr/record.res index 3c5c70d48d..6e3e36db02 100644 --- a/tests/syntax_tests/data/printer/expr/record.res +++ b/tests/syntax_tests/data/printer/expr/record.res @@ -87,6 +87,17 @@ type tt = {x:int, y?: string} type ttt = {x:int, y?: string} +type x = {a: int} + +type x = {aaaaaaaaaaaa: int, bbbbbbbbbbbb: int, cccccccccccc: int, dddddddddddd: int, eeeeeeeeeeee: int, ffffffffffffffff: int} + +type y = {a: int +} + +type z = { + a: int, +} + let optParen = { x:3, y: ? (someBool ? Some("") : None) } let optParen = { x:3, y: ? (3+4) } let optParen = { x:3, y: ? (foo(bar)) } From 80ad971c7c5a69bc8790c00617b3ba5c35911563 Mon Sep 17 00:00:00 2001 From: Shulhi Sapli <913103+shulhi@users.noreply.github.com> Date: Sat, 25 Oct 2025 19:59:41 +0800 Subject: [PATCH 6/7] Update more tests (ppx) --- .../ppx/react/expected/aliasProps.res.txt | 35 +++++++++++++++---- .../ppx/react/expected/asyncAwait.res.txt | 8 +++-- .../ppx/react/expected/commentAtTop.res.txt | 4 ++- .../react/expected/defaultValueProp.res.txt | 18 +++++++--- .../expected/externalWithCustomName.res.txt | 5 ++- .../react/expected/fileLevelConfig.res.txt | 4 ++- .../ppx/react/expected/forwardRef.resi.txt | 16 ++++++--- .../data/ppx/react/expected/interface.res.txt | 4 ++- .../ppx/react/expected/interface.resi.txt | 4 ++- .../react/expected/interfaceWithRef.res.txt | 6 +++- .../react/expected/interfaceWithRef.resi.txt | 6 +++- .../ppx/react/expected/mangleKeyword.res.txt | 10 ++++-- .../data/ppx/react/expected/newtype.res.txt | 29 +++++++++++---- .../expected/optimizeAutomaticMode.res.txt | 4 ++- .../data/ppx/react/expected/topLevel.res.txt | 5 ++- .../ppx/react/expected/typeConstraint.res.txt | 5 ++- .../ppx/react/expected/uncurriedProps.res.txt | 8 +++-- .../data/ppx/react/expected/v4.res.txt | 25 +++++++++---- .../printer/comments/expected/typexpr.res.txt | 4 ++- .../printer/typexpr/expected/bsObject.res.txt | 4 ++- 20 files changed, 159 insertions(+), 45 deletions(-) diff --git a/tests/syntax_tests/data/ppx/react/expected/aliasProps.res.txt b/tests/syntax_tests/data/ppx/react/expected/aliasProps.res.txt index efb6c9b53d..f942516aff 100644 --- a/tests/syntax_tests/data/ppx/react/expected/aliasProps.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/aliasProps.res.txt @@ -2,7 +2,10 @@ module C0 = { @res.jsxComponentProps - type props<'priority, 'text> = {priority: 'priority, text?: 'text} + type props<'priority, 'text> = { + priority: 'priority, + text?: 'text, + } let make = ({priority: _, text: ?__text, _}: props<_, _>) => { let text = switch __text { @@ -20,7 +23,10 @@ module C0 = { module C1 = { @res.jsxComponentProps - type props<'priority, 'text> = {priority: 'priority, text?: 'text} + type props<'priority, 'text> = { + priority: 'priority, + text?: 'text, + } let make = ({priority: p, text: ?__text, _}: props<_, _>) => { let text = switch __text { @@ -38,7 +44,9 @@ module C1 = { module C2 = { @res.jsxComponentProps - type props<'foo> = {foo?: 'foo} + type props<'foo> = { + foo?: 'foo, + } let make = ({foo: ?__bar, _}: props<_>) => { let bar = switch __bar { @@ -56,7 +64,11 @@ module C2 = { module C3 = { @res.jsxComponentProps - type props<'foo, 'a, 'b> = {foo?: 'foo, a?: 'a, b: 'b} + type props<'foo, 'a, 'b> = { + foo?: 'foo, + a?: 'a, + b: 'b, + } let make = ({foo: ?__bar, a: ?__a, b, _}: props<_, _, _>) => { let bar = switch __bar { @@ -82,7 +94,10 @@ module C3 = { module C4 = { @res.jsxComponentProps - type props<'a, 'x> = {a: 'a, x?: 'x} + type props<'a, 'x> = { + a: 'a, + x?: 'x, + } let make = ({a: b, x: ?__x, _}: props<_, _>) => { let x = switch __x { @@ -100,7 +115,10 @@ module C4 = { module C5 = { @res.jsxComponentProps - type props<'a, 'z> = {a: 'a, z?: 'z} + type props<'a, 'z> = { + a: 'a, + z?: 'z, + } let make = ({a: (x, y), z: ?__z, _}: props<_, _>) => { let z = switch __z { @@ -124,7 +142,10 @@ module C6 = { let make: React.component } @res.jsxComponentProps - type props<'comp, 'x> = {comp: 'comp, x: 'x} + type props<'comp, 'x> = { + comp: 'comp, + x: 'x, + } let make = ({comp: module(Comp: Comp), x: (a, b), _}: props<_, _>): React.element => React.jsx(Comp.make, {}) diff --git a/tests/syntax_tests/data/ppx/react/expected/asyncAwait.res.txt b/tests/syntax_tests/data/ppx/react/expected/asyncAwait.res.txt index ba012e9dee..d77b11decd 100644 --- a/tests/syntax_tests/data/ppx/react/expected/asyncAwait.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/asyncAwait.res.txt @@ -2,7 +2,9 @@ let f = a => Js.Promise.resolve(a + a) module C0 = { @res.jsxComponentProps - type props<'a> = {a: 'a} + type props<'a> = { + a: 'a, + } let make = async ({a, _}: props<_>) => { let a = await f(a) @@ -17,7 +19,9 @@ module C0 = { module C1 = { @res.jsxComponentProps - type props<'status> = {status: 'status} + type props<'status> = { + status: 'status, + } let make = async ({status, _}: props<_>): React.element => { switch status { diff --git a/tests/syntax_tests/data/ppx/react/expected/commentAtTop.res.txt b/tests/syntax_tests/data/ppx/react/expected/commentAtTop.res.txt index 1ddf0492f9..e8242d70cb 100644 --- a/tests/syntax_tests/data/ppx/react/expected/commentAtTop.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/commentAtTop.res.txt @@ -1,5 +1,7 @@ @res.jsxComponentProps -type props<'msg> = {msg: 'msg} // test React JSX file +type props<'msg> = { + msg: 'msg, // test React JSX file +} let make = ({msg, _}: props<_>): React.element => { ReactDOM.jsx("div", {children: ?ReactDOM.someElement({msg->React.string})}) diff --git a/tests/syntax_tests/data/ppx/react/expected/defaultValueProp.res.txt b/tests/syntax_tests/data/ppx/react/expected/defaultValueProp.res.txt index 29680945ce..22f854f911 100644 --- a/tests/syntax_tests/data/ppx/react/expected/defaultValueProp.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/defaultValueProp.res.txt @@ -1,6 +1,9 @@ module C0 = { @res.jsxComponentProps - type props<'a, 'b> = {a?: 'a, b?: 'b} + type props<'a, 'b> = { + a?: 'a, + b?: 'b, + } let make = ({a: ?__a, b: ?__b, _}: props<_, _>) => { let a = switch __a { | Some(a) => a @@ -20,7 +23,10 @@ module C0 = { module C1 = { @res.jsxComponentProps - type props<'a, 'b> = {a?: 'a, b: 'b} + type props<'a, 'b> = { + a?: 'a, + b: 'b, + } let make = ({a: ?__a, b, _}: props<_, _>) => { let a = switch __a { @@ -39,7 +45,9 @@ module C1 = { module C2 = { let a = "foo" @res.jsxComponentProps - type props<'a> = {a?: 'a} + type props<'a> = { + a?: 'a, + } let make = ({a: ?__a, _}: props<_>) => { let a = switch __a { @@ -57,7 +65,9 @@ module C2 = { module C3 = { @res.jsxComponentProps - type props<'disabled> = {disabled?: 'disabled} + type props<'disabled> = { + disabled?: 'disabled, + } let make = ({disabled: ?__everythingDisabled, _}: props) => { let everythingDisabled = switch __everythingDisabled { diff --git a/tests/syntax_tests/data/ppx/react/expected/externalWithCustomName.res.txt b/tests/syntax_tests/data/ppx/react/expected/externalWithCustomName.res.txt index 9bfbac700a..dd98fc72ff 100644 --- a/tests/syntax_tests/data/ppx/react/expected/externalWithCustomName.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/externalWithCustomName.res.txt @@ -2,7 +2,10 @@ module Foo = { @res.jsxComponentProps @live - type props<'a, 'b> = {a: 'a, b: 'b} + type props<'a, 'b> = { + a: 'a, + b: 'b, + } @module("Foo") external component: React.component> = "component" diff --git a/tests/syntax_tests/data/ppx/react/expected/fileLevelConfig.res.txt b/tests/syntax_tests/data/ppx/react/expected/fileLevelConfig.res.txt index 177190cbe8..77cde0caea 100644 --- a/tests/syntax_tests/data/ppx/react/expected/fileLevelConfig.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/fileLevelConfig.res.txt @@ -2,7 +2,9 @@ module V4A = { @res.jsxComponentProps - type props<'msg> = {msg: 'msg} + type props<'msg> = { + msg: 'msg, + } let make = ({msg, _}: props<_>): React.element => { ReactDOM.jsx("div", {children: ?ReactDOM.someElement({msg->React.string})}) diff --git a/tests/syntax_tests/data/ppx/react/expected/forwardRef.resi.txt b/tests/syntax_tests/data/ppx/react/expected/forwardRef.resi.txt index 82ba473328..47cd6f1010 100644 --- a/tests/syntax_tests/data/ppx/react/expected/forwardRef.resi.txt +++ b/tests/syntax_tests/data/ppx/react/expected/forwardRef.resi.txt @@ -14,7 +14,9 @@ module V4C: { module ForwardRef: { @res.jsxComponentProps - type props<'ref> = {ref?: 'ref} + type props<'ref> = { + ref?: 'ref, + } let make: React.component>>> } @@ -34,7 +36,9 @@ module V4CUncurried: { module ForwardRef: { @res.jsxComponentProps - type props<'ref> = {ref?: 'ref} + type props<'ref> = { + ref?: 'ref, + } let make: React.component>>> } @@ -56,7 +60,9 @@ module V4A: { module ForwardRef: { @res.jsxComponentProps - type props<'ref> = {ref?: 'ref} + type props<'ref> = { + ref?: 'ref, + } let make: React.component>>> } @@ -76,7 +82,9 @@ module V4AUncurried: { module ForwardRef: { @res.jsxComponentProps - type props<'ref> = {ref?: 'ref} + type props<'ref> = { + ref?: 'ref, + } let make: React.component>>> } diff --git a/tests/syntax_tests/data/ppx/react/expected/interface.res.txt b/tests/syntax_tests/data/ppx/react/expected/interface.res.txt index e28bfe5472..df0f7137fb 100644 --- a/tests/syntax_tests/data/ppx/react/expected/interface.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/interface.res.txt @@ -1,6 +1,8 @@ module A = { @res.jsxComponentProps - type props<'x> = {x: 'x} + type props<'x> = { + x: 'x, + } let make = ({x, _}: props<_>): React.element => React.string(x) let make = { let \"Interface$A" = (props: props<_>) => make(props) diff --git a/tests/syntax_tests/data/ppx/react/expected/interface.resi.txt b/tests/syntax_tests/data/ppx/react/expected/interface.resi.txt index 633ffa3c00..d0cc914abf 100644 --- a/tests/syntax_tests/data/ppx/react/expected/interface.resi.txt +++ b/tests/syntax_tests/data/ppx/react/expected/interface.resi.txt @@ -1,6 +1,8 @@ module A: { @res.jsxComponentProps - type props<'x> = {x: 'x} + type props<'x> = { + x: 'x, + } let make: React.component> } diff --git a/tests/syntax_tests/data/ppx/react/expected/interfaceWithRef.res.txt b/tests/syntax_tests/data/ppx/react/expected/interfaceWithRef.res.txt index 7dd865bc9c..e0d0cbb87c 100644 --- a/tests/syntax_tests/data/ppx/react/expected/interfaceWithRef.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/interfaceWithRef.res.txt @@ -1,4 +1,8 @@ -@res.jsxComponentProps type props<'x, 'ref> = {x: 'x, ref?: 'ref} +@res.jsxComponentProps +type props<'x, 'ref> = { + x: 'x, + ref?: 'ref, +} let make = ( {x, _}: props, ref: Js.Nullable.t, diff --git a/tests/syntax_tests/data/ppx/react/expected/interfaceWithRef.resi.txt b/tests/syntax_tests/data/ppx/react/expected/interfaceWithRef.resi.txt index 7f1895b91c..462fa9d640 100644 --- a/tests/syntax_tests/data/ppx/react/expected/interfaceWithRef.resi.txt +++ b/tests/syntax_tests/data/ppx/react/expected/interfaceWithRef.resi.txt @@ -1,2 +1,6 @@ -@res.jsxComponentProps type props<'x, 'ref> = {x: 'x, ref?: 'ref} +@res.jsxComponentProps +type props<'x, 'ref> = { + x: 'x, + ref?: 'ref, +} let make: React.component> diff --git a/tests/syntax_tests/data/ppx/react/expected/mangleKeyword.res.txt b/tests/syntax_tests/data/ppx/react/expected/mangleKeyword.res.txt index faee40442f..f1e40360ec 100644 --- a/tests/syntax_tests/data/ppx/react/expected/mangleKeyword.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/mangleKeyword.res.txt @@ -2,7 +2,10 @@ module C4A0 = { @res.jsxComponentProps - type props<'T_open, 'T_type> = {@as("open") _open: 'T_open, @as("type") _type: 'T_type} + type props<'T_open, 'T_type> = { + @as("open") _open: 'T_open, + @as("type") _type: 'T_type, + } let make = ({@as("open") _open, @as("type") _type, _}: props<_, string>): React.element => React.string(_open) @@ -14,7 +17,10 @@ module C4A0 = { } module C4A1 = { @res.jsxComponentProps @live - type props<'T_open, 'T_type> = {@as("open") _open: 'T_open, @as("type") _type: 'T_type} + type props<'T_open, 'T_type> = { + @as("open") _open: 'T_open, + @as("type") _type: 'T_type, + } external make: React.component> = "default" } diff --git a/tests/syntax_tests/data/ppx/react/expected/newtype.res.txt b/tests/syntax_tests/data/ppx/react/expected/newtype.res.txt index f26904a16b..2fdecb8674 100644 --- a/tests/syntax_tests/data/ppx/react/expected/newtype.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/newtype.res.txt @@ -2,7 +2,11 @@ module V4A = { @res.jsxComponentProps - type props<'a, 'b, 'c> = {a: 'a, b: 'b, c: 'c} + type props<'a, 'b, 'c> = { + a: 'a, + b: 'b, + c: 'c, + } let make = (type a, {a, b, c, _}: props>, 'a>): React.element => ReactDOM.jsx("div", {}) @@ -15,7 +19,11 @@ module V4A = { module V4A1 = { @res.jsxComponentProps - type props<'a, 'b, 'c> = {a: 'a, b: 'b, c: 'c} + type props<'a, 'b, 'c> = { + a: 'a, + b: 'b, + c: 'c, + } let make = (type x y, {a, b, c, _}: props, 'a>): React.element => ReactDOM.jsx("div", {}) @@ -32,7 +40,9 @@ module type T = { module V4A2 = { @res.jsxComponentProps - type props<'foo> = {foo: 'foo} + type props<'foo> = { + foo: 'foo, + } let make = (type a, {foo: (foo: module(T with type t = a)), _}: props<_>): React.element => { module T = unpack(foo) @@ -47,7 +57,9 @@ module V4A2 = { module V4A3 = { @res.jsxComponentProps - type props<'foo> = {foo: 'foo} + type props<'foo> = { + foo: 'foo, + } let make = (type a, {foo, _}: props<_>): React.element => { module T = unpack(foo: T with type t = a) @@ -60,7 +72,10 @@ module V4A3 = { } } @res.jsxComponentProps -type props<'x, 'q> = {x: 'x, q: 'q} +type props<'x, 'q> = { + x: 'x, + q: 'q, +} let make = ({x, q, _}: props<('a, 'b), 'a>): React.element => [fst(x), q] let make = { @@ -73,7 +88,9 @@ let make = { module Uncurried = { @res.jsxComponentProps - type props<'foo> = {foo?: 'foo} + type props<'foo> = { + foo?: 'foo, + } let make = (type a, {?foo, _}: props<_>): React.element => React.null let make = { diff --git a/tests/syntax_tests/data/ppx/react/expected/optimizeAutomaticMode.res.txt b/tests/syntax_tests/data/ppx/react/expected/optimizeAutomaticMode.res.txt index 690eb73eba..dfb3506590 100644 --- a/tests/syntax_tests/data/ppx/react/expected/optimizeAutomaticMode.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/optimizeAutomaticMode.res.txt @@ -5,7 +5,9 @@ module User = { let format = user => "Dr." ++ user.lastName @res.jsxComponentProps - type props<'doctor> = {doctor: 'doctor} + type props<'doctor> = { + doctor: 'doctor, + } let make = ({doctor, _}: props<_>): React.element => { ReactDOM.jsx("h1", {id: "h1", children: ?ReactDOM.someElement({React.string(format(doctor))})}) diff --git a/tests/syntax_tests/data/ppx/react/expected/topLevel.res.txt b/tests/syntax_tests/data/ppx/react/expected/topLevel.res.txt index 2d8fe42ab1..9330346a96 100644 --- a/tests/syntax_tests/data/ppx/react/expected/topLevel.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/topLevel.res.txt @@ -2,7 +2,10 @@ module V4A = { @res.jsxComponentProps - type props<'a, 'b> = {a: 'a, b: 'b} + type props<'a, 'b> = { + a: 'a, + b: 'b, + } let make = ({a, b, _}: props<_, _>) => { Js.log("This function should be named 'TopLevel.react'") diff --git a/tests/syntax_tests/data/ppx/react/expected/typeConstraint.res.txt b/tests/syntax_tests/data/ppx/react/expected/typeConstraint.res.txt index dbec7ea6a0..68a3b0278b 100644 --- a/tests/syntax_tests/data/ppx/react/expected/typeConstraint.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/typeConstraint.res.txt @@ -2,7 +2,10 @@ module V4A = { @res.jsxComponentProps - type props<'a, 'b> = {a: 'a, b: 'b} + type props<'a, 'b> = { + a: 'a, + b: 'b, + } let make = (type a, {a, b, _}: props<_, _>): React.element => ReactDOM.jsx("div", {}) let make = { diff --git a/tests/syntax_tests/data/ppx/react/expected/uncurriedProps.res.txt b/tests/syntax_tests/data/ppx/react/expected/uncurriedProps.res.txt index cbb9dd4494..c029c8c784 100644 --- a/tests/syntax_tests/data/ppx/react/expected/uncurriedProps.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/uncurriedProps.res.txt @@ -1,6 +1,8 @@ @@jsxConfig({version: 4}) @res.jsxComponentProps -type props<'a> = {a?: 'a} +type props<'a> = { + a?: 'a, +} let make = ({a: ?__a, _}: props unit>) => { let a = switch __a { @@ -27,7 +29,9 @@ func(~callback=(str, a, b) => { module Foo = { @res.jsxComponentProps - type props<'callback> = {callback?: 'callback} + type props<'callback> = { + callback?: 'callback, + } let make = ({callback: ?__callback, _}: props<(string, bool, bool) => unit>) => { let callback = switch __callback { diff --git a/tests/syntax_tests/data/ppx/react/expected/v4.res.txt b/tests/syntax_tests/data/ppx/react/expected/v4.res.txt index e5f9b37a7a..a6f05b0e17 100644 --- a/tests/syntax_tests/data/ppx/react/expected/v4.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/v4.res.txt @@ -1,5 +1,8 @@ @res.jsxComponentProps -type props<'x, 'y> = {x: 'x, y: 'y} // Component with type constraint +type props<'x, 'y> = { + x: 'x, // Component with type constraint + y: 'y, +} let make = ({x, y, _}: props): React.element => React.string(x ++ y) let make = { let \"V4" = (props: props<_>) => make(props) @@ -9,7 +12,9 @@ let make = { module AnotherName = { @res.jsxComponentProps type // Component with another name than "make" - props<'x> = {x: 'x} + props<'x> = { + x: 'x, + } let anotherName = ({x, _}: props<_>): React.element => React.string(x) let anotherName = { @@ -21,7 +26,9 @@ module AnotherName = { module Uncurried = { @res.jsxComponentProps - type props<'x> = {x: 'x} + type props<'x> = { + x: 'x, + } let make = ({x, _}: props<_>): React.element => React.string(x) let make = { @@ -33,21 +40,27 @@ module Uncurried = { module type TUncurried = { @res.jsxComponentProps - type props<'x> = {x: 'x} + type props<'x> = { + x: 'x, + } let make: React.component> } module E = { @res.jsxComponentProps @live - type props<'x> = {x: 'x} + type props<'x> = { + x: 'x, + } external make: React.component> = "default" } module EUncurried = { @res.jsxComponentProps @live - type props<'x> = {x: 'x} + type props<'x> = { + x: 'x, + } external make: React.component> = "default" } diff --git a/tests/syntax_tests/data/printer/comments/expected/typexpr.res.txt b/tests/syntax_tests/data/printer/comments/expected/typexpr.res.txt index e3a39acf24..a0e5607359 100644 --- a/tests/syntax_tests/data/printer/comments/expected/typexpr.res.txt +++ b/tests/syntax_tests/data/printer/comments/expected/typexpr.res.txt @@ -26,7 +26,9 @@ type t = /* c0 */ module(/* c1 */ Hashmap /* c2 */ with type t = /* c0 */ string /* c1 */ as 'x // after // Ptyp_poly -type fn = {f: /* c0 */ 'a /* c1 */ 'b /* c2 */. /* c3 */ string /* c4 */} +type fn = { + f: /* c0 */ 'a /* c1 */ 'b /* c2 */. /* c3 */ string /* c4 */, +} type fn = { /* comment1 */ diff --git a/tests/syntax_tests/data/printer/typexpr/expected/bsObject.res.txt b/tests/syntax_tests/data/printer/typexpr/expected/bsObject.res.txt index e7c3c0092f..f854d53857 100644 --- a/tests/syntax_tests/data/printer/typexpr/expected/bsObject.res.txt +++ b/tests/syntax_tests/data/printer/typexpr/expected/bsObject.res.txt @@ -53,4 +53,6 @@ type t = {.} type t = private {.} type t = constr<{.}, {.}, {.}> -type t = {hr: React.component<{.}>} +type t = { + hr: React.component<{.}>, +} From 57aa27b206c892da38bb7c33e1d3cc68eb22efb3 Mon Sep 17 00:00:00 2001 From: Shulhi Sapli <913103+shulhi@users.noreply.github.com> Date: Sun, 26 Oct 2025 19:47:00 +0800 Subject: [PATCH 7/7] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bc54aba4f..5acdb3ed8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ - Rewatch: plain output when not running in tty. https://github.com/rescript-lang/rescript/pull/7970 - Streamline rewatch help texts. https://github.com/rescript-lang/rescript/pull/7973 - Rewatch: Reduced build progress output from 7 steps to 3 for cleaner, less verbose logging. https://github.com/rescript-lang/rescript/pull/7971 +- Formatter: Improve multiline printing of record types and values. https://github.com/rescript-lang/rescript/pull/7993 #### :house: Internal