diff --git a/src/res_printer.ml b/src/res_printer.ml index e68b25f7..5506039d 100644 --- a/src/res_printer.ml +++ b/src/res_printer.ml @@ -2807,6 +2807,10 @@ and printExpression (e : Parsetree.expression) cmtTbl = let forceBreak = e.pexp_loc.loc_start.pos_lnum < e.pexp_loc.loc_end.pos_lnum in + let punningAllowed = match spreadExpr, rows with + | (None, [_]) -> false (* disallow punning for single-element records *) + | _ -> true + in Doc.breakableGroup ~forceBreak ( Doc.concat([ Doc.lbrace; @@ -2815,7 +2819,7 @@ and printExpression (e : Parsetree.expression) cmtTbl = Doc.softLine; spread; Doc.join ~sep:(Doc.concat [Doc.text ","; Doc.line]) - (List.map (fun row -> printRecordRow row cmtTbl) rows) + (List.map (fun row -> printRecordRow row cmtTbl punningAllowed) rows) ] ); Doc.trailingComma; @@ -4818,17 +4822,28 @@ and printDirectionFlag flag = match flag with | Asttypes.Downto -> Doc.text " downto " | Asttypes.Upto -> Doc.text " to " -and printRecordRow (lbl, expr) cmtTbl = +and printRecordRow (lbl, expr) cmtTbl punningAllowed = let cmtLoc = {lbl.loc with loc_end = expr.pexp_loc.loc_end} in - let doc = Doc.group (Doc.concat [ - printLidentPath lbl cmtTbl; - Doc.text ": "; - (let doc = printExpressionWithComments expr cmtTbl in - match Parens.expr expr with - | Parens.Parenthesized -> addParens doc - | Braced braces -> printBraces doc expr braces - | Nothing -> doc); - ]) in + let doc = Doc.group ( + match expr.pexp_desc with + | Pexp_ident({txt = Lident key; loc = keyLoc}) when ( + punningAllowed && + Longident.last lbl.txt = key && + lbl.loc.loc_start.pos_cnum == keyLoc.loc_start.pos_cnum + ) -> + (* print punned field *) + printLidentPath lbl cmtTbl; + | _ -> + Doc.concat [ + printLidentPath lbl cmtTbl; + Doc.text ": "; + (let doc = printExpressionWithComments expr cmtTbl in + match Parens.expr expr with + | Parens.Parenthesized -> addParens doc + | Braced braces -> printBraces doc expr braces + | Nothing -> doc); + ] + ) in printComments doc cmtTbl cmtLoc and printBsObjectRow (lbl, expr) cmtTbl = diff --git a/tests/conversion/reason/expected/bracedJsx.re.txt b/tests/conversion/reason/expected/bracedJsx.re.txt index 27f93d34..b49e82fe 100644 --- a/tests/conversion/reason/expected/bracedJsx.re.txt +++ b/tests/conversion/reason/expected/bracedJsx.re.txt @@ -91,7 +91,7 @@ let make = () => { ], ), } - | SetValue(input) => {...state, input: input} + | SetValue(input) => {...state, input} } , {history: [], input: ""}) diff --git a/tests/conversion/reason/expected/braces.re.txt b/tests/conversion/reason/expected/braces.re.txt index cf164c93..0a3e335d 100644 --- a/tests/conversion/reason/expected/braces.re.txt +++ b/tests/conversion/reason/expected/braces.re.txt @@ -20,5 +20,5 @@ let getDailyNewCases = x => | Pair({prevRecord, record}) => let confirmed = record.confirmed - prevRecord.confirmed let deaths = record.deaths - prevRecord.deaths - {confirmed: confirmed, deaths: deaths} + {confirmed, deaths} } diff --git a/tests/printer/expr/expected/block.res.txt b/tests/printer/expr/expected/block.res.txt index 8333405a..d7d8068b 100644 --- a/tests/printer/expr/expected/block.res.txt +++ b/tests/printer/expr/expected/block.res.txt @@ -60,7 +60,7 @@ React.useEffect0(() => { switch videoContainerRect { | Some(videoContainerRect) => let newChapter = ({startTime: percent *. duration}: Video.chapter) - {a: a, b: b}->onChange + {a, b}->onChange | _ => () } }} diff --git a/tests/printer/expr/expected/record.res.txt b/tests/printer/expr/expected/record.res.txt index 9226003d..576cd48c 100644 --- a/tests/printer/expr/expected/record.res.txt +++ b/tests/printer/expr/expected/record.res.txt @@ -39,3 +39,35 @@ let user = { } // braced + constrained expr let user = {name: {(ceo.name: string)}} + +// Punning +let r = {a} // actually not a record, just an expression in braces +let r = {a, b} +let r = {a, b, c: 42} +let r = {A.a, b} +let r = {A.a: a, b} +let r = {a: a, b} +let r = {a, b: b} + +// Punning + comments +let r = { + // a + a, + // b + b, +} +let r = { + a, // a + b, // b +} +let r = { + /* a */ + a, + /* b */ + b, +} +let r = { + a /* a */, + b /* b */, +} +let r = {a /* a */, b /* b */} diff --git a/tests/printer/expr/record.res b/tests/printer/expr/record.res index 55e655e8..4cb993c9 100644 --- a/tests/printer/expr/record.res +++ b/tests/printer/expr/record.res @@ -28,3 +28,36 @@ let user = {name: { }} // braced + constrained expr let user = {name: {(ceo.name: string)}} + + +// Punning +let r = {a} // actually not a record, just an expression in braces +let r = {a, b} +let r = {a, b, c: 42} +let r = {A.a, b} +let r = {A.a: a, b} +let r = {a: a, b} +let r = {a, b: b} + +// Punning + comments +let r = { + // a + a, + // b + b, +} +let r = { + a, // a + b, // b +} +let r = { + /* a */ + a, + /* b */ + b, +} +let r = { + a /* a */, + b /* b */, +} +let r = {a /* a */, b /* b */}