Skip to content

Commit 6ec02b1

Browse files
cristianoccknitt
andauthored
Refactor used attributes (#6795)
* Refactor used attributes * Mark "as" attribute as used when processed in untagged variants. * Mark @as used early in constructor declarations, and turn on unused check. A couple of test files were mis-using `@as`. * Fix format * CHANGELOG --------- Co-authored-by: Christoph Knittel <[email protected]>
1 parent f24afbd commit 6ec02b1

11 files changed

+45
-36
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
- Fix unhandled cases for exotic idents (allow to use exotic PascalCased identifiers for types). https://github.com/rescript-lang/rescript-compiler/pull/6777
3131
- PPX v4: mark props type in externals as `@live` to avoid dead code warnings for prop fields in the editor tooling. https://github.com/rescript-lang/rescript-compiler/pull/6796
32+
- Fix unused attribute check for `@as`. https://github.com/rescript-lang/rescript-compiler/pull/6795
3233

3334
#### :house: Internal
3435

jscomp/frontend/ast_attributes.ml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ let iter_process_bs_string_int_unwrap_uncurry (attrs : t) =
212212
let st = ref `Nothing in
213213
let assign v (({loc; _}, _) as attr : attr) =
214214
if !st = `Nothing then (
215-
Bs_ast_invariant.mark_used_bs_attribute attr;
215+
Used_attributes.mark_used_attribute attr;
216216
st := v)
217217
else Bs_syntaxerr.err loc Conflict_attributes
218218
in
@@ -235,7 +235,7 @@ let iter_process_bs_string_as (attrs : t) : string option =
235235
match Ast_payload.is_single_string payload with
236236
| None -> Bs_syntaxerr.err loc Expect_string_literal
237237
| Some (v, _dec) ->
238-
Bs_ast_invariant.mark_used_bs_attribute attr;
238+
Used_attributes.mark_used_attribute attr;
239239
st := Some v)
240240
else raise (Ast_untagged_variants.Error (loc, Duplicated_bs_as))
241241
| _ -> ());
@@ -244,7 +244,7 @@ let has_bs_optional (attrs : t) : bool =
244244
Ext_list.exists attrs (fun (({txt}, _) as attr) ->
245245
match txt with
246246
| "optional" ->
247-
Bs_ast_invariant.mark_used_bs_attribute attr;
247+
Used_attributes.mark_used_attribute attr;
248248
true
249249
| _ -> false)
250250

@@ -257,7 +257,7 @@ let iter_process_bs_int_as (attrs : t) =
257257
match Ast_payload.is_single_int payload with
258258
| None -> Bs_syntaxerr.err loc Expect_int_literal
259259
| Some _ as v ->
260-
Bs_ast_invariant.mark_used_bs_attribute attr;
260+
Used_attributes.mark_used_attribute attr;
261261
st := v)
262262
else raise (Ast_untagged_variants.Error (loc, Duplicated_bs_as))
263263
| _ -> ());
@@ -271,7 +271,7 @@ let iter_process_bs_string_or_int_as (attrs : Parsetree.attributes) =
271271
match txt with
272272
| "as" ->
273273
if !st = None then (
274-
Bs_ast_invariant.mark_used_bs_attribute attr;
274+
Used_attributes.mark_used_attribute attr;
275275
match Ast_payload.is_single_int payload with
276276
| None -> (
277277
match payload with

jscomp/frontend/ast_config.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ let rec iter_on_bs_config_str (x : Parsetree.structure) =
5959
| [] -> ()
6060
| {pstr_desc = Pstr_attribute (({txt = "config"; loc}, payload) as attr)} :: _
6161
->
62-
Bs_ast_invariant.mark_used_bs_attribute attr;
62+
Used_attributes.mark_used_attribute attr;
6363
Ext_list.iter
6464
(Ast_payload.ident_or_record_as_config loc payload)
6565
(Ast_payload.table_dispatch !structural_config_table)
@@ -75,7 +75,7 @@ let rec iter_on_bs_config_sig (x : Parsetree.signature) =
7575
| [] -> ()
7676
| {psig_desc = Psig_attribute (({txt = "config"; loc}, payload) as attr)} :: _
7777
->
78-
Bs_ast_invariant.mark_used_bs_attribute attr;
78+
Used_attributes.mark_used_attribute attr;
7979
Ext_list.iter
8080
(Ast_payload.ident_or_record_as_config loc payload)
8181
(Ast_payload.table_dispatch !signature_config_table)

jscomp/frontend/bs_ast_invariant.ml

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,33 +28,16 @@
2828
*)
2929
let is_bs_attribute txt =
3030
match txt with
31-
(* TODO #6636: | "as "| "int" *)
32-
| "bs" | "config" | "ignore" | "optional" | "string" | "uncurry" | "unwrap" ->
31+
(* TODO #6636: "int" *)
32+
| "as" | "bs" | "config" | "ignore" | "optional" | "string" | "uncurry"
33+
| "unwrap" ->
3334
true
3435
| _ -> false
3536

36-
let used_attributes : string Asttypes.loc Hash_set_poly.t =
37-
Hash_set_poly.create 16
38-
39-
(*
40-
let dump_attribute fmt = (fun ( (sloc : string Asttypes.loc),payload) ->
41-
Format.fprintf fmt "@[%s %a@]" sloc.txt (Printast.payload 0 ) payload
42-
)
43-
44-
let dump_used_attributes fmt =
45-
Format.fprintf fmt "Used attributes Listing Start:@.";
46-
Hash_set_poly.iter used_attributes (fun attr -> dump_attribute fmt attr) ;
47-
Format.fprintf fmt "Used attributes Listing End:@."
48-
*)
49-
50-
(* only mark non-ghost used bs attribute *)
51-
let mark_used_bs_attribute ((x, _) : Parsetree.attribute) =
52-
if not x.loc.loc_ghost then Hash_set_poly.add used_attributes x
53-
5437
let warn_unused_attribute ((({txt; loc} as sloc), _) : Parsetree.attribute) =
5538
if
5639
is_bs_attribute txt && (not loc.loc_ghost)
57-
&& not (Hash_set_poly.mem used_attributes sloc)
40+
&& not (Used_attributes.is_used_attribute sloc)
5841
then
5942
(*
6043
dump_used_attributes Format.err_formatter;
@@ -126,11 +109,15 @@ let emit_external_warnings : iterator =
126109
(fun self lbl ->
127110
Ext_list.iter lbl.pld_attributes (fun attr ->
128111
match attr with
129-
| {txt = "as"}, _ -> mark_used_bs_attribute attr
112+
| {txt = "as"}, _ -> Used_attributes.mark_used_attribute attr
130113
| _ -> ());
131114
super.label_declaration self lbl);
132115
constructor_declaration =
133116
(fun self ({pcd_name = {txt; loc}} as ctr) ->
117+
let _ =
118+
Ast_untagged_variants.process_tag_type
119+
ctr.pcd_attributes (* mark @as used in variant cases *)
120+
in
134121
(match txt with
135122
| "false" | "true" | "()" ->
136123
Location.raise_errorf ~loc "%s can not be redefined " txt

jscomp/frontend/bs_ast_invariant.mli

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424

2525
type iterator = Ast_iterator.iterator
2626

27-
val mark_used_bs_attribute : Parsetree.attribute -> unit
28-
2927
(** [warn_discarded_unused_attributes discarded]
3028
warn if [discarded] has unused bs attribute
3129
*)

jscomp/frontend/bs_builtin_ppx.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ let succeed attr attrs =
5555
match attrs with
5656
| [_] -> ()
5757
| _ ->
58-
Bs_ast_invariant.mark_used_bs_attribute attr;
58+
Used_attributes.mark_used_attribute attr;
5959
Bs_ast_invariant.warn_discarded_unused_attributes attrs
6060

6161
type mapper = Bs_ast_mapper.mapper

jscomp/ml/ast_untagged_variants.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ let expand_head: (Env.t -> Types.type_expr -> Types.type_expr) ref = ref (Obj.ma
111111

112112
let process_tag_type (attrs : Parsetree.attributes) =
113113
let st : tag_type option ref = ref None in
114-
Ext_list.iter attrs (fun ({txt; loc}, payload) ->
114+
Ext_list.iter attrs (fun (({txt; loc}, payload) as attr) ->
115115
match txt with
116116
| "as" ->
117117
if !st = None then (
@@ -135,7 +135,8 @@ let process_tag_type (attrs : Parsetree.attributes) =
135135
| Some (Lident "null") -> st := Some Null
136136
| Some (Lident "undefined") -> st := Some Undefined
137137
| Some _ -> raise (Error (loc, InvalidVariantAsAnnotation)));
138-
if !st = None then raise (Error (loc, InvalidVariantAsAnnotation)))
138+
if !st = None then raise (Error (loc, InvalidVariantAsAnnotation))
139+
else Used_attributes.mark_used_attribute attr)
139140
else raise (Error (loc, Duplicated_bs_as))
140141
| _ -> ());
141142
!st

jscomp/ml/used_attributes.ml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
let used_attributes : string Asttypes.loc Hash_set_poly.t =
2+
Hash_set_poly.create 16
3+
4+
5+
(* let dump_attribute fmt = (fun ( (sloc : string Asttypes.loc)) ->
6+
Format.fprintf fmt "@[%s@]" sloc.txt
7+
)
8+
9+
let dump_used_attributes fmt =
10+
Format.fprintf fmt "Used attributes Listing Start:@.";
11+
Hash_set_poly.iter used_attributes (fun attr -> dump_attribute fmt attr) ;
12+
Format.fprintf fmt "Used attributes Listing End:@." *)
13+
14+
15+
(* only mark non-ghost used bs attribute *)
16+
let mark_used_attribute ((x, _) : Parsetree.attribute) =
17+
if not x.loc.loc_ghost then Hash_set_poly.add used_attributes x
18+
19+
let is_used_attribute (sloc : string Asttypes.loc) = Hash_set_poly.mem used_attributes sloc

jscomp/ml/used_attributes.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
val mark_used_attribute : Parsetree.attribute -> unit
2+
3+
val is_used_attribute : string Asttypes.loc -> bool

jscomp/test/AsInUncurriedExternals.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ let mo = makeOptions
1212

1313
let options = mo(~name="foo", ())
1414

15-
let shouldNotFail: (~objectMode: @as(json`false`) _, ~name: string) => int = (~objectMode, ~name) =>
15+
let shouldNotFail: (~objectMode: _, ~name: string) => int = (~objectMode, ~name) =>
1616
3

jscomp/test/polyvar_convert.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
type t = [
2-
| @as("x") #a
2+
| #a
33
| #b
44
]
55

0 commit comments

Comments
 (0)