diff --git a/CHANGELOG.md b/CHANGELOG.md index b11cba95ddb..7d5096f6307 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,8 @@ - Fix "Ill-formed list of warnings" errors for PPXs with rescript-legacy. https://github.com/rescript-lang/rescript/pull/8103 - Fix gentype generating invalid syntax for exotic / escaped record field names and type names. https://github.com/rescript-lang/rescript/pull/8087 +- Formatter: Improve multiline printing of record types and values. https://github.com/rescript-lang/rescript/pull/7993 + #### :house: Internal - Reanalyze: refactor DCE to pure pipeline architecture for order-independence and incremental update support. https://github.com/rescript-lang/rescript/pull/8043 diff --git a/compiler/syntax/src/res_printer.ml b/compiler/syntax/src/res_printer.ml index a2780aaf7e7..6ec27e56ee4 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,12 +1465,22 @@ 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 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, 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 :: _ -> - first.pld_loc.loc_start.pos_lnum < last.pld_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 < get_field_start_line first + | None, None, first :: _ -> + let last = List.hd (List.rev lds) in + get_field_start_line first < last.pld_loc.loc_end.pos_lnum | _, _, _ -> false in Doc.breakable_group ~force_break @@ -3223,7 +3233,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 diff --git a/docs/Formatter.md b/docs/Formatter.md new file mode 100644 index 00000000000..a157b52a422 --- /dev/null +++ b/docs/Formatter.md @@ -0,0 +1,48 @@ +# ReScript Formatter + +## Philosophy + +The ReScript formatter is **opinionated**. Formatting decisions are made by the core team based on our collective judgment and vision for the language. We do not aim to accommodate every stylistic preference or engage in extended debates about formatting choices. + +The formatter currently has **no configuration settings**, and we aspire to keep it that way. This ensures that ReScript code looks consistent across all projects and teams, eliminating style debates and configuration overhead. + +## Decision Making + +- **Core team consensus is final**: When the core team reaches consensus on a formatting decision, that decision stands. There is no requirement for community-wide agreement or extensive discussion. + +- **Community input is welcome but not binding**: We appreciate suggestions and feedback from the community, but these can be closed without extensive justification if the core team is not aligned with the proposal. + +- **No endless style discussions**: We are not interested in protracted debates about formatting preferences. The formatter exists to provide consistent, automated formatting—not to serve as a platform for style negotiations. + +## Prior Decisions + +The following are examples of formatting decisions the core team has made. This list is not exhaustive, and these decisions do not create binding precedents for future discussions. The core team retains full discretion to make different decisions in similar cases. + +- **Smart linebreaks for pipe chains**: The formatter preserves user-introduced linebreaks in pipe chains (`->`), allowing users to control multiline formatting. See [forum announcement](https://forum.rescript-lang.org/t/ann-smart-linebreaks-for-pipe-chains/4734). + +- **Preserve multilineness for records**: The formatter preserves multiline formatting for record types and values when users introduce linebreaks. See [issue #7961](https://github.com/rescript-lang/rescript/issues/7961). + +**Important**: These examples are provided for reference only. They do not establish rules or precedents that constrain future formatting decisions. The core team may choose different approaches in similar situations based on current consensus. + +## Guidelines for Contributors + +### Submitting Formatting Issues + +- You may open issues to report bugs or propose improvements +- Understand that proposals may be closed if they don't align with core team vision +- Avoid reopening closed issues unless there's new technical information +- Respect that "the core team isn't feeling it" is a valid reason for closure + +### What We Consider + +- Technical correctness and consistency +- Alignment with ReScript's design philosophy +- Maintainability and simplicity of the formatter implementation +- Core team consensus + +### What We Generally Avoid + +- Style preferences that don't align with our vision +- Using comparisons to other formatters as the sole justification for changes (while we may align with other formatters on many decisions, we make choices based on our own judgment, not because another formatter does it) +- Requests that would significantly complicate the formatter implementation +- Debates about subjective formatting choices 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 b09e8775235..f151681291e 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/ppx/react/expected/aliasProps.res.txt b/tests/syntax_tests/data/ppx/react/expected/aliasProps.res.txt index efb6c9b53dd..f942516aff7 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 ba012e9deef..d77b11decd3 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 1ddf0492f92..e8242d70cb3 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 29680945ce0..22f854f911f 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 9bfbac700a2..dd98fc72ff3 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 177190cbe87..77cde0caea1 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 82ba4733282..47cd6f10105 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 e28bfe54720..df0f7137fb5 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 633ffa3c007..d0cc914abf7 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 7dd865bc9c7..e0d0cbb87c4 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 7f1895b91c5..462fa9d6404 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 faee40442f8..f1e40360ec5 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 f26904a16b5..2fdecb86740 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 690eb73ebae..dfb3506590e 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 2d8fe42ab14..9330346a961 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 dbec7ea6a01..68a3b0278b3 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 cbb9dd4494a..c029c8c7842 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 e5f9b37a7a4..a6f05b0e17f 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/expr.res.txt b/tests/syntax_tests/data/printer/comments/expected/expr.res.txt index 7d4a0b38115..cbe763a3ab5 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/comments/expected/typexpr.res.txt b/tests/syntax_tests/data/printer/comments/expected/typexpr.res.txt index e3a39acf242..a0e5607359b 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/expr/expected/record.res.txt b/tests/syntax_tests/data/printer/expr/expected/record.res.txt index fb16fe71139..d33ef76db57 100644 --- a/tests/syntax_tests/data/printer/expr/expected/record.res.txt +++ b/tests/syntax_tests/data/printer/expr/expected/record.res.txt @@ -97,9 +97,38 @@ 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)} 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 82336fc7343..6e3e36db028 100644 --- a/tests/syntax_tests/data/printer/expr/record.res +++ b/tests/syntax_tests/data/printer/expr/record.res @@ -87,9 +87,28 @@ 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)) } 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/typexpr/expected/bsObject.res.txt b/tests/syntax_tests/data/printer/typexpr/expected/bsObject.res.txt index e7c3c0092ff..f854d538574 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<{.}>, +}