diff --git a/CHANGELOG.md b/CHANGELOG.md index a26e9d35..4c5bbe5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,10 @@ - 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 +#### :eyeglasses: Spec Compliance + +- Functions with consecutive dots now print as multiple arrow functions like in JavaScript. + ## ReScript 10.0 - Fix printing for inline nullary functor types [#477](https://github.com/rescript-lang/syntax/pull/477) diff --git a/src/res_parsetree_viewer.ml b/src/res_parsetree_viewer.ml index c22dfb23..94679489 100644 --- a/src/res_parsetree_viewer.ml +++ b/src/res_parsetree_viewer.ml @@ -10,11 +10,12 @@ let arrowType ct = let arg = ([], lbl, typ1) in process attrsBefore (arg :: acc) typ2 | { - ptyp_desc = Ptyp_arrow ((Nolabel as lbl), typ1, typ2); - ptyp_attributes = [({txt = "bs" | "res.async"}, _)] as attrs; + ptyp_desc = Ptyp_arrow (Nolabel, _typ1, _typ2); + ptyp_attributes = [({txt = "bs"}, _)]; } -> - let arg = (attrs, lbl, typ1) in - process attrsBefore (arg :: acc) typ2 + (* stop here, the uncurried attribute always indicates the beginning of an arrow function + * e.g. `(. int) => (. int)` instead of `(. int, . int)` *) + (attrsBefore, List.rev acc, typ) | {ptyp_desc = Ptyp_arrow (Nolabel, _typ1, _typ2); ptyp_attributes = _attrs} as returnType -> let args = List.rev acc in @@ -156,12 +157,10 @@ let funExpr expr = let stringLocs, returnExpr = collectNewTypes [stringLoc] rest in let param = NewTypes {attrs; locs = stringLocs} in collect attrsBefore (param :: acc) returnExpr - | { - pexp_desc = Pexp_fun (lbl, defaultExpr, pattern, returnExpr); - pexp_attributes = [({txt = "bs"}, _)] as attrs; - } -> - let parameter = Parameter {attrs; lbl; defaultExpr; pat = pattern} in - collect attrsBefore (parameter :: acc) returnExpr + | {pexp_desc = Pexp_fun _; pexp_attributes = [({txt = "bs"}, _)]} -> + (* stop here, the uncurried attribute always indicates the beginning of an arrow function + * e.g. `(. a) => (. b)` instead of `(. a, . b)` *) + (attrsBefore, List.rev acc, expr) | { pexp_desc = Pexp_fun diff --git a/tests/conversion/reason/expected/uncurrried.res.txt b/tests/conversion/reason/expected/uncurrried.res.txt index b273f54a..48283a41 100644 --- a/tests/conversion/reason/expected/uncurrried.res.txt +++ b/tests/conversion/reason/expected/uncurrried.res.txt @@ -44,7 +44,7 @@ let () = switch something(. x, y) { let () = { // ok - let dontDoThisAhome = (. a, b, . c, d, . e, f) => a + b + c + d + e + f + let dontDoThisAhome = (. a, b) => (. c, d) => (. e, f) => a + b + c + d + e + f // ok dontDoThisAhome(. a, b)(. c, d)(. e, f) } diff --git a/tests/printer/expr/expected/fun.res.txt b/tests/printer/expr/expected/fun.res.txt index 9d91f069..8c2d973d 100644 --- a/tests/printer/expr/expected/fun.res.txt +++ b/tests/printer/expr/expected/fun.res.txt @@ -352,3 +352,7 @@ let query = (~url, ()): ((unit, unit) => unit) => { let query = (~url, ()): ((unit, unit, unit) => unit) => { ((), (), ()) => Js.log("Queried " ++ url) } + +let f = (. a) => (. b) => a + b +let f = (. a, b) => (. b, c) => a + b + c + d +let f = (. a, b) => (. b, c) => (. e, f, g) => a + b + c + d + e + f + g diff --git a/tests/printer/expr/fun.res b/tests/printer/expr/fun.res index 2bc59a6e..2c5c5009 100644 --- a/tests/printer/expr/fun.res +++ b/tests/printer/expr/fun.res @@ -293,3 +293,7 @@ let query = (~url, ()): (unit => unit => unit) => { let query = (~url, ()): (unit => unit => unit => unit) => { () => () => () => Js.log("Queried " ++ url) } + +let f = (. a) => (. b) => a + b +let f = (. a, b) => (. b, c) => a + b + c + d +let f = (. a, b) => (. b , c) => (. e , f, g) => a + b + c + d + e + f + g diff --git a/tests/printer/typexpr/expected/arrow.res.txt b/tests/printer/typexpr/expected/arrow.res.txt index 621f70d0..4253ff51 100644 --- a/tests/printer/typexpr/expected/arrow.res.txt +++ b/tests/printer/typexpr/expected/arrow.res.txt @@ -205,12 +205,12 @@ float // uncurried type t = (. int) => int type t = (. int, int) => int -type t = (. int, . int) => int -type t = (. int, int, . int, int) => int +type t = (. int) => (. int) => int +type t = (. int, int) => (. int, int) => int type t = (. @attr int) => unit -type t = (. @attr int, . @attr2 int) => unit -type t = (. @attrOnInt int, @attrOnInt int, . @attrOnInt int, @attrOnInt int) => int +type t = (. @attr int) => (. @attr2 int) => unit +type t = (. @attrOnInt int, @attrOnInt int) => (. @attrOnInt int, @attrOnInt int) => int type t = (. @attr ~x: int, ~y: int, . @attr ~z: int, @attr ~omega: int) => unit @val external requestAnimationFrame: (float => unit) => unit = "requestAnimationFrame"