Skip to content

Commit fc2e2c8

Browse files
committed
PPX v4: mark props type in externals as @live.
Fixes rescript-lang/rescript-vscode#994 Dead code elimination in the editor tooling complains about props never being read in the `props` type record defined by the V4 ppx. This is because externals don't provide the implementation of the component, and it's in the implementation that props could be read. This OR marks the `props` type definition as `@live` for external components, so the dead code analysis does not fire.
1 parent 8403cdb commit fc2e2c8

File tree

9 files changed

+51
-14
lines changed

9 files changed

+51
-14
lines changed

jscomp/syntax/src/jsx_v4.ml

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -327,15 +327,15 @@ let make_label_decls named_type_list =
327327
Type.field ~loc ~attrs {txt = label; loc}
328328
(Typ.var @@ safe_type_from_value @@ Labelled label))
329329

330-
let make_type_decls props_name loc named_type_list =
330+
let make_type_decls ~attrs props_name loc named_type_list =
331331
let label_decl_list = make_label_decls named_type_list in
332332
(* 'id, 'className, ... *)
333333
let params =
334334
make_props_type_params_tvar named_type_list
335335
|> List.map (fun core_type -> (core_type, Invariant))
336336
in
337337
[
338-
Type.mk ~loc ~params {txt = props_name; loc}
338+
Type.mk ~attrs ~loc ~params {txt = props_name; loc}
339339
~kind:(Ptype_record label_decl_list);
340340
]
341341

@@ -346,22 +346,26 @@ let make_type_decls_with_core_type props_name loc core_type typ_vars =
346346
~manifest:core_type;
347347
]
348348

349+
let live_attr = ({txt = "live"; loc = Location.none}, PStr [])
350+
349351
(* type props<'x, 'y, ...> = { x: 'x, y?: 'y, ... } *)
350-
let make_props_record_type ~core_type_of_attr ~typ_vars_of_core_type props_name
351-
loc named_type_list =
352+
let make_props_record_type ~core_type_of_attr ~external_ ~typ_vars_of_core_type
353+
props_name loc named_type_list =
354+
let attrs = if external_ then [live_attr] else [] in
352355
Str.type_ Nonrecursive
353356
(match core_type_of_attr with
354-
| None -> make_type_decls props_name loc named_type_list
357+
| None -> make_type_decls ~attrs props_name loc named_type_list
355358
| Some core_type ->
356359
make_type_decls_with_core_type props_name loc core_type
357360
typ_vars_of_core_type)
358361

359362
(* type props<'x, 'y, ...> = { x: 'x, y?: 'y, ... } *)
360-
let make_props_record_type_sig ~core_type_of_attr ~typ_vars_of_core_type
361-
props_name loc named_type_list =
363+
let make_props_record_type_sig ~core_type_of_attr ~external_
364+
~typ_vars_of_core_type props_name loc named_type_list =
365+
let attrs = if external_ then [live_attr] else [] in
362366
Sig.type_ Nonrecursive
363367
(match core_type_of_attr with
364-
| None -> make_type_decls props_name loc named_type_list
368+
| None -> make_type_decls ~attrs props_name loc named_type_list
365369
| Some core_type ->
366370
make_type_decls_with_core_type props_name loc core_type
367371
typ_vars_of_core_type)
@@ -950,8 +954,8 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding =
950954
let named_type_list = List.fold_left arg_to_type [] named_arg_list in
951955
(* type props = { ... } *)
952956
let props_record_type =
953-
make_props_record_type ~core_type_of_attr ~typ_vars_of_core_type "props"
954-
pstr_loc named_type_list
957+
make_props_record_type ~core_type_of_attr ~external_:false
958+
~typ_vars_of_core_type "props" pstr_loc named_type_list
955959
in
956960
let inner_expression =
957961
Exp.apply
@@ -1211,8 +1215,8 @@ let transform_structure_item ~config item =
12111215
in
12121216
(* type props<'x, 'y> = { x: 'x, y?: 'y, ... } *)
12131217
let props_record_type =
1214-
make_props_record_type ~core_type_of_attr ~typ_vars_of_core_type "props"
1215-
pstr_loc named_type_list
1218+
make_props_record_type ~core_type_of_attr ~external_:true
1219+
~typ_vars_of_core_type "props" pstr_loc named_type_list
12161220
in
12171221
(* can't be an arrow because it will defensively uncurry *)
12181222
let new_external_type =
@@ -1317,9 +1321,10 @@ let transform_signature_item ~config item =
13171321
| [] -> []
13181322
| _ -> [Typ.any ()]))
13191323
in
1324+
let external_ = psig_desc.pval_prim <> [] in
13201325
let props_record_type =
1321-
make_props_record_type_sig ~core_type_of_attr ~typ_vars_of_core_type
1322-
"props" psig_loc named_type_list
1326+
make_props_record_type_sig ~core_type_of_attr ~external_
1327+
~typ_vars_of_core_type "props" psig_loc named_type_list
13231328
in
13241329
(* can't be an arrow because it will defensively uncurry *)
13251330
let new_external_type =

jscomp/syntax/tests/ppx/react/expected/externalWithCustomName.res.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ let t = React.createElement(Foo.component, Foo.componentProps(~a=1, ~b={"1"}, ()
1313
@@jsxConfig({version: 4, mode: "classic"})
1414

1515
module Foo = {
16+
@live
1617
type props<'a, 'b> = {a: 'a, b: 'b}
1718

1819
@module("Foo")
@@ -24,6 +25,7 @@ let t = React.createElement(Foo.component, {a: 1, b: "1"})
2425
@@jsxConfig({version: 4, mode: "automatic"})
2526

2627
module Foo = {
28+
@live
2729
type props<'a, 'b> = {a: 'a, b: 'b}
2830

2931
@module("Foo")

jscomp/syntax/tests/ppx/react/expected/externalWithRef.res.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ module V3 = {
1818
@@jsxConfig({version: 4, mode: "classic"})
1919

2020
module V4C = {
21+
@live
2122
type props<'x, 'ref> = {
2223
x: 'x,
2324
ref?: 'ref,
@@ -28,9 +29,21 @@ module V4C = {
2829
"component"
2930
}
3031

32+
module type V4CType = {
33+
@live
34+
type props<'x, 'y> = {
35+
x: 'x,
36+
y: 'y,
37+
}
38+
39+
@module("someModule")
40+
external make: React.componentLike<props<string, string>, React.element> = "component"
41+
}
42+
3143
@@jsxConfig({version: 4, mode: "automatic"})
3244

3345
module V4C = {
46+
@live
3447
type props<'x, 'ref> = {
3548
x: 'x,
3649
ref?: 'ref,

jscomp/syntax/tests/ppx/react/expected/externalWithTypeVariables.res.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ module V3 = {
1616
@@jsxConfig({version: 4, mode: "classic"})
1717

1818
module V4C = {
19+
@live
1920
type props<'x, 'children> = {
2021
x: 'x,
2122
children: 'children,
@@ -28,6 +29,7 @@ module V4C = {
2829
@@jsxConfig({version: 4, mode: "automatic"})
2930

3031
module V4C = {
32+
@live
3133
type props<'x, 'children> = {
3234
x: 'x,
3335
children: 'children,

jscomp/syntax/tests/ppx/react/expected/firstClassModules.res.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ module External = {
8888
type key
8989
type t
9090
}
91+
@live
9192
type props<'model, 'selected, 'onChange, 'items> = {
9293
model: 'model,
9394
selected: 'selected,

jscomp/syntax/tests/ppx/react/expected/mangleKeyword.res.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ module C4C0 = {
4747
}
4848
}
4949
module C4C1 = {
50+
@live
5051
type props<'T_open, 'T_type> = {@as("open") _open: 'T_open, @as("type") _type: 'T_type}
5152

5253
external make: @as("open") React.componentLike<props<string, string>, React.element> = "default"
@@ -68,6 +69,7 @@ module C4A0 = {
6869
}
6970
}
7071
module C4A1 = {
72+
@live
7173
type props<'T_open, 'T_type> = {@as("open") _open: 'T_open, @as("type") _type: 'T_type}
7274

7375
external make: @as("open") React.componentLike<props<string, string>, React.element> = "default"

jscomp/syntax/tests/ppx/react/expected/noPropsWithKey.res.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module V4CA = {
1212
}
1313

1414
module V4CB = {
15+
@live
1516
type props = {}
1617

1718
@module("c")
@@ -51,6 +52,7 @@ module V4CA = {
5152
}
5253

5354
module V4CB = {
55+
@live
5456
type props = {}
5557

5658
@module("c")

jscomp/syntax/tests/ppx/react/expected/v4.res.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@ module type TUncurried = {
3535
}
3636

3737
module E = {
38+
@live
3839
type props<'x> = {x: 'x}
3940

4041
external make: React.componentLike<props<string>, React.element> = "default"
4142
}
4243

4344
module EUncurried = {
45+
@live
4446
type props<'x> = {x: 'x}
4547

4648
external make: React.componentLike<props<string>, React.element> = "default"

jscomp/syntax/tests/ppx/react/externalWithRef.res

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ module V4C = {
1818
) => React.element = "component"
1919
}
2020

21+
module type V4CType = {
22+
@module("someModule") @react.component
23+
external make: (
24+
~x: string,
25+
~y: string,
26+
) => React.element = "component"
27+
}
28+
2129
@@jsxConfig({version: 4, mode: "automatic"})
2230

2331
module V4C = {

0 commit comments

Comments
 (0)