From a91a2772fa625af440f76bb96e194871d68f4143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9di-R=C3=A9mi=20Hashim?= Date: Thu, 21 Aug 2025 10:54:17 +0200 Subject: [PATCH 1/4] Preserve @as decorator on record fields when creating interface --- analysis/src/CreateInterface.ml | 23 +++++++++++++++---- .../tests/src/CreateInterface.res | 7 ++++++ .../src/expected/CreateInterface.res.txt | 5 ++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/analysis/src/CreateInterface.ml b/analysis/src/CreateInterface.ml index 1bbb3632fe..d91eb928dd 100644 --- a/analysis/src/CreateInterface.ml +++ b/analysis/src/CreateInterface.ml @@ -38,6 +38,8 @@ module AttributesUtils : sig val contains : string -> t -> bool + val isEmpty : t -> bool + val toString : t -> string end = struct type attribute = {line: int; offset: int; name: string} @@ -76,6 +78,8 @@ end = struct let contains attributeForSearch t = t |> List.exists (fun {name} -> name = attributeForSearch) + let isEmpty t = t = [] + let toString t = match t with | [] -> "" @@ -250,11 +254,22 @@ let printSignature ~extractor ~signature = Buffer.add_string buf (indent ^ newItemStr ^ "\n"); processSignature ~indent items | Sig_type (id, typeDecl, resStatus) :: items -> - let newItemStr = - sigItemToString - (Printtyp.tree_of_type_declaration id typeDecl resStatus) + let lines = + let posStart, posEnd = Loc.range typeDecl.type_loc in + extractor |> SourceFileExtractor.extract ~posStart ~posEnd in - Buffer.add_string buf (indent ^ newItemStr ^ "\n"); + let attributes = AttributesUtils.make lines in + + (if not (AttributesUtils.isEmpty attributes) then + (* Copy the type declaration verbatim to preserve attributes *) + Buffer.add_string buf ((lines |> String.concat "\n") ^ "\n") + else + let newItemStr = + sigItemToString + (Printtyp.tree_of_type_declaration id typeDecl resStatus) + in + Buffer.add_string buf (indent ^ newItemStr ^ "\n")); + processSignature ~indent items | Sig_typext (id, extConstr, extStatus) :: items -> let newItemStr = diff --git a/tests/analysis_tests/tests/src/CreateInterface.res b/tests/analysis_tests/tests/src/CreateInterface.res index 7bc514cc27..3f7ab03d48 100644 --- a/tests/analysis_tests/tests/src/CreateInterface.res +++ b/tests/analysis_tests/tests/src/CreateInterface.res @@ -143,3 +143,10 @@ module Memo = { let make = React.memo(make) } + +external x: (@as("bar") ~foo: int) => unit = "myexternal" + +type record = { + @as("foo_bar") + fooBar: int +} diff --git a/tests/analysis_tests/tests/src/expected/CreateInterface.res.txt b/tests/analysis_tests/tests/src/expected/CreateInterface.res.txt index 4e12129485..700f3a599d 100644 --- a/tests/analysis_tests/tests/src/expected/CreateInterface.res.txt +++ b/tests/analysis_tests/tests/src/expected/CreateInterface.res.txt @@ -109,4 +109,9 @@ module Memo: { @react.component let make: (~name: string) => React.element } +external x: (@as("bar") ~foo: int) => unit = "myexternal" +type record = { + @as("foo_bar") + fooBar: int +} From 219c308c034db372c88687a6fc0fd5384737e810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9di-R=C3=A9mi=20Hashim?= Date: Thu, 21 Aug 2025 10:57:59 +0200 Subject: [PATCH 2/4] Add CHANGELOG entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c1dac27e0..bf61f0caab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ #### :bug: Bug fix +- Preserve `@as(...)` decorator on record fields when creating interface. https://github.com/rescript-lang/rescript/pull/7779 + #### :memo: Documentation #### :nail_care: Polish From f093c9cf327af001e1bcf3a9fa16c9878b788a33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9di-R=C3=A9mi=20Hashim?= Date: Thu, 21 Aug 2025 14:53:23 +0200 Subject: [PATCH 3/4] Always copy type declarations verbatim --- analysis/src/CreateInterface.ml | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/analysis/src/CreateInterface.ml b/analysis/src/CreateInterface.ml index d91eb928dd..d9bfe665ec 100644 --- a/analysis/src/CreateInterface.ml +++ b/analysis/src/CreateInterface.ml @@ -253,23 +253,13 @@ let printSignature ~extractor ~signature = in Buffer.add_string buf (indent ^ newItemStr ^ "\n"); processSignature ~indent items - | Sig_type (id, typeDecl, resStatus) :: items -> + | Sig_type (_id, typeDecl, _recStatus) :: items -> let lines = let posStart, posEnd = Loc.range typeDecl.type_loc in extractor |> SourceFileExtractor.extract ~posStart ~posEnd in - let attributes = AttributesUtils.make lines in - - (if not (AttributesUtils.isEmpty attributes) then - (* Copy the type declaration verbatim to preserve attributes *) - Buffer.add_string buf ((lines |> String.concat "\n") ^ "\n") - else - let newItemStr = - sigItemToString - (Printtyp.tree_of_type_declaration id typeDecl resStatus) - in - Buffer.add_string buf (indent ^ newItemStr ^ "\n")); - + (* Copy the type declaration verbatim to preserve attributes *) + Buffer.add_string buf ((lines |> String.concat "\n") ^ "\n"); processSignature ~indent items | Sig_typext (id, extConstr, extStatus) :: items -> let newItemStr = From 7a4127f1be7a4c0302d8c014bc6eaa1c3b3d261b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9di-R=C3=A9mi=20Hashim?= Date: Thu, 21 Aug 2025 15:12:18 +0200 Subject: [PATCH 4/4] Remove unused helpers --- analysis/src/CreateInterface.ml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/analysis/src/CreateInterface.ml b/analysis/src/CreateInterface.ml index d9bfe665ec..107fa5973d 100644 --- a/analysis/src/CreateInterface.ml +++ b/analysis/src/CreateInterface.ml @@ -38,8 +38,6 @@ module AttributesUtils : sig val contains : string -> t -> bool - val isEmpty : t -> bool - val toString : t -> string end = struct type attribute = {line: int; offset: int; name: string} @@ -78,8 +76,6 @@ end = struct let contains attributeForSearch t = t |> List.exists (fun {name} -> name = attributeForSearch) - let isEmpty t = t = [] - let toString t = match t with | [] -> ""