diff --git a/formatTest/unit_tests/expected_output/whitespace.re b/formatTest/unit_tests/expected_output/whitespace.re index 4bebd4149..1b0973c70 100644 --- a/formatTest/unit_tests/expected_output/whitespace.re +++ b/formatTest/unit_tests/expected_output/whitespace.re @@ -182,6 +182,152 @@ module EdgeCase = { let x = 1; }; +/** Record-like expressions */ +let r = { + a: 1, + + b: 2, + c: 3, +}; + +/* with punning */ +let r = { + a, + + b, + c, +}; + +/* with spread */ +let r = { + ...x, + + a: 1, + + b: 2, + c: 3, +}; + +/* comments */ +let r = { + ...x, + + /* a */ + a: 1, + + /* b */ + /* c */ + + /* d */ + b: 2, + /* e */ + + c: 3, + + /* f */ + d, + + e, +}; + +/* string keys */ +let x = { + "a": 1, + + "b": 2, + "c": 3, +}; + +/* string keys punning */ +let x = { + "a": a, + + "b": b, + "c": c, +}; + +/* string keys with spread */ +let x = { + ...x, + + "a": 1, + + "b": 2, + "c": 3, +}; + +/* string keys with comments */ +let x = { + ...x, + + /* a */ + "a": 1, + + /* b */ + /* c */ + + /* d */ + "b": 2, + /* e */ + + "c": 3, + + /* f */ + "d": d, + + "e": e, +}; + +let make = _children => { + ...component, + + initialState: () => { + posts: [], + activeRoute: + urlToRoute( + ReasonReact.Router.dangerouslyGetInitialUrl(), + ), + }, + + didMount: self => { + let watcherID = + ReasonReact.Router.watchUrl(url => + self.send( + ChangeRoute(urlToRoute(url)), + ) + ); + self.onUnmount(() => + ReasonReact.Router.unwatchUrl(watcherID) + ); + }, + + reducer: (action, state) => + switch (action) { + | ChangeRoute(activeRoute) => + ReasonReact.Update({ + ...state, + activeRoute, + }) + | FetchCats => ReasonReact.NoUpdate + }, + + render: ({state: {posts, activeRoute}}) => +
+

+ + {ReasonReact.string("Instagram")} + +

+ { + switch (activeRoute) { + | Default => + | Detail(postId) => + + } + } +
, +}; + let f = (a, b) => a + b; /* this comment sticks at the end */ diff --git a/formatTest/unit_tests/input/whitespace.re b/formatTest/unit_tests/input/whitespace.re index 7311f9ffa..cc02640a7 100644 --- a/formatTest/unit_tests/input/whitespace.re +++ b/formatTest/unit_tests/input/whitespace.re @@ -31,7 +31,7 @@ module Comments = { /* wow another one below too */ let add = Test.x; - + /* this is @@ -187,6 +187,137 @@ module EdgeCase = { let x = 1; }; +/** Record-like expressions */ +let r = { + a: 1, + + b: 2, + c: 3, +}; + +/* with punning */ +let r = { + a, + + b, + c, +}; + +/* with spread */ +let r = { + ...x, + + a: 1, + + b: 2, + c: 3, +}; + +/* comments */ +let r = { + ...x, + + /* a */ + a: 1, + + /* b */ + /* c */ + + /* d */ + b: 2, + /* e */ + + c: 3, + + /* f */ + d, + + e, +}; + +/* string keys */ +let x = { + "a": 1, + + "b": 2, + "c": 3, +}; + +/* string keys punning */ +let x = { + "a", + + "b", + "c" +}; + +/* string keys with spread */ +let x = { + ...x, + + "a": 1, + + "b": 2, + "c": 3, +}; + +/* string keys with comments */ +let x = { + ...x, + + /* a */ + "a": 1, + + /* b */ + /* c */ + + /* d */ + "b": 2, + /* e */ + + "c": 3, + + /* f */ + "d", + + "e", +}; + +let make = _children => { + ...component, + + initialState: () => { + posts: [], + activeRoute: urlToRoute(ReasonReact.Router.dangerouslyGetInitialUrl()), + }, + + didMount: self => { + let watcherID = + ReasonReact.Router.watchUrl(url => + self.send(ChangeRoute(urlToRoute(url))) + ); + self.onUnmount(() => ReasonReact.Router.unwatchUrl(watcherID)); + }, + + reducer: (action, state) => + switch (action) { + | ChangeRoute(activeRoute) => + ReasonReact.Update({...state, activeRoute}) + | FetchCats => ReasonReact.NoUpdate + }, + + render: ({state: {posts, activeRoute}}) => +
+

{ReasonReact.string("Instagram")}

+ { + switch (activeRoute) { + | Default => + | Detail(postId) => + } + } +
, +}; + let f = (a, b) => a + b; /* this comment sticks at the end */ diff --git a/src/reason-parser/reason_parser.mly b/src/reason-parser/reason_parser.mly index 705d927ba..14d42b488 100644 --- a/src/reason-parser/reason_parser.mly +++ b/src/reason-parser/reason_parser.mly @@ -3582,7 +3582,7 @@ string_literal_expr_maybe_punned_with_comma: { let loc = mklocation $startpos $endpos in let (s, _, _) = $1 in let lident_lident_loc = mkloc (Lident s) loc in - let exp = mkexp (Pexp_ident lident_lident_loc) in + let exp = mkexp ~loc (Pexp_ident lident_lident_loc) in (lident_lident_loc, exp) } | STRING COLON expr COMMA @@ -3600,7 +3600,7 @@ string_literal_expr_maybe_punned: let lident_lident_loc = mkloc (Lident s) loc in let exp = match $2 with | Some x -> x - | None -> mkexp (Pexp_ident lident_lident_loc) + | None -> mkexp ~loc (Pexp_ident lident_lident_loc) in (lident_lident_loc, exp) } diff --git a/src/reason-parser/reason_pprint_ast.ml b/src/reason-parser/reason_pprint_ast.ml index 81ce1d082..5fc16d9bb 100644 --- a/src/reason-parser/reason_pprint_ast.ml +++ b/src/reason-parser/reason_pprint_ast.ml @@ -5734,7 +5734,7 @@ let printer = object(self:'self) self#wrapCurriedFunctionBinding ~sweet:true ~attachTo:upToColon funToken ~arrow:"=>" firstArg tl returnedAppTerms - in source_map ~loc:totalRowLoc theRow + in (source_map ~loc:totalRowLoc theRow, totalRowLoc) in let rec getRows l = match l with @@ -5751,20 +5751,27 @@ let printer = object(self:'self) | [hd] -> [makeRow hd false] | _ -> getRows l ) + (* This case represents a "spread" being present -> {...x, a: 1, b: 2} *) | Some withRecord -> - let firstRow = ( - (* Unclear why "sugar_expr" was special cased hre. *) - let appTerms = self#unparseExprApplicationItems withRecord in - formatAttachmentApplication applicationFinalWrapping (Some (false, (atom "..."))) appTerms - ) in - source_map ~loc:withRecord.pexp_loc firstRow :: getRows l + let firstRow = + let row = ( + (* Unclear why "sugar_expr" was special cased hre. *) + let appTerms = self#unparseExprApplicationItems withRecord in + formatAttachmentApplication applicationFinalWrapping (Some (false, (atom "..."))) appTerms + ) + in ( + source_map ~loc:withRecord.pexp_loc row, + withRecord.pexp_loc + ) + in + firstRow::(getRows l) in makeList ~wrap:(lwrap ^ "{" ,"}" ^ rwrap) ~break:(if !forceBreak then Layout.Always else Layout.IfNeed) ~sep:commaTrail ~postSpace:true - allRows + (groupAndPrint ~xf:fst ~getLoc:snd ~comments:self#comments allRows) method isSeriesOfOpensFollowedByNonSequencyExpression expr = match (expr.pexp_attributes, expr.pexp_desc) with