Skip to content

Fix formatting of external with as attribute and _ placeholder #6970

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
- Fix issue where long layout break added a trailing comma in partial application `...`. https://github.com/rescript-lang/rescript-compiler/pull/6949
- Fix incorrect format of function under unary operator. https://github.com/rescript-lang/rescript-compiler/pull/6953
- Fix incorrect incorrect printing of module binding with signature. https://github.com/rescript-lang/rescript-compiler/pull/6963
- Fix incorrect printing of external with `@as` attribute and `_` placholder (fixed argument). https://github.com/rescript-lang/rescript-compiler/pull/6970

#### :house: Internal

Expand Down
19 changes: 17 additions & 2 deletions jscomp/syntax/src/res_parsetree_viewer.ml
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
open Parsetree

let arrow_type ?(arity = max_int) ct =
let has_as_attr attrs =
Ext_list.exists attrs (fun (x, _) -> x.Asttypes.txt = "as")
in
let rec process attrs_before acc typ arity =
match typ with
| typ when arity <= 0 -> (attrs_before, List.rev acc, typ)
| typ when arity < 0 -> (attrs_before, List.rev acc, typ)
| {
ptyp_desc = Ptyp_arrow ((Nolabel as lbl), typ1, typ2);
ptyp_attributes = [];
Expand All @@ -25,8 +28,20 @@ let arrow_type ?(arity = max_int) ct =
ptyp_desc = Ptyp_arrow (((Labelled _ | Optional _) as lbl), typ1, typ2);
ptyp_attributes = attrs;
} ->
(* Res_core.parse_es6_arrow_type has a workaround that removed an extra arity for the function if the
argument is a Ptyp_any with @as attribute i.e. ~x: @as(`{prop: value}`) _.

When this case is encountered we add that missing arity so the arrow is printed properly.
*)
let arity =
match typ1 with
| {ptyp_desc = Ptyp_any; ptyp_attributes = attrs1}
when has_as_attr attrs1 ->
arity
| _ -> arity - 1
in
let arg = (attrs, lbl, typ1) in
process attrs_before (arg :: acc) typ2 (arity - 1)
process attrs_before (arg :: acc) typ2 arity
| typ -> (attrs_before, List.rev acc, typ)
in
match ct with
Expand Down
27 changes: 27 additions & 0 deletions jscomp/syntax/tests/printer/other/attributes.res
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,30 @@ let x = 1
)
let x = 1

@obj external ff: (~x: int, ~g: int, ~h: int) => _ = ""

@obj external ff: (~x: int, ~g: int, ~h: @as(3) _) => _ = ""

@obj external ff: (~x: int) => (~h: @as(3) _) => _ = ""

@obj
external ff: (
~lo: @as(3) _,
~mid: @as(3) _,
~hi: int,
) => _ = ""


@obj
external ff: (
~hi: int,
~lo: @as(3) _
) => _ = ""

@obj
external ff: (
~hi: int,
~mid: @as(3) _,
~lo: @as(3) _
) => _ = ""

15 changes: 15 additions & 0 deletions jscomp/syntax/tests/printer/other/expected/attributes.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,18 @@ let x = 1

@inlinePrivate(@module("./logo.svg") external logo: string = "default")
let x = 1

@obj external ff: (~x: int, ~g: int, ~h: int) => _ = ""

@obj external ff: (~x: int, ~g: int, ~h: @as(3) _) => _ = ""

@obj external ff: (~x: int) => (~h: @as(3) _) => _ = ""

@obj
external ff: (~lo: @as(3) _, ~mid: @as(3) _, ~hi: int) => _ = ""

@obj
external ff: (~hi: int, ~lo: @as(3) _) => _ = ""

@obj
external ff: (~hi: int, ~mid: @as(3) _, ~lo: @as(3) _) => _ = ""