Skip to content

PPX v4: mark props type in externals as @live. #6796

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 3 commits into from
May 31, 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 @@ -28,6 +28,7 @@
#### :bug: Bug Fix

- Fix unhandled cases for exotic idents (allow to use exotic PascalCased identifiers for types). https://github.com/rescript-lang/rescript-compiler/pull/6777
- 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

#### :house: Internal

Expand Down
33 changes: 19 additions & 14 deletions jscomp/syntax/src/jsx_v4.ml
Original file line number Diff line number Diff line change
Expand Up @@ -327,15 +327,15 @@ let make_label_decls named_type_list =
Type.field ~loc ~attrs {txt = label; loc}
(Typ.var @@ safe_type_from_value @@ Labelled label))

let make_type_decls props_name loc named_type_list =
let make_type_decls ~attrs props_name loc named_type_list =
let label_decl_list = make_label_decls named_type_list in
(* 'id, 'className, ... *)
let params =
make_props_type_params_tvar named_type_list
|> List.map (fun core_type -> (core_type, Invariant))
in
[
Type.mk ~loc ~params {txt = props_name; loc}
Type.mk ~attrs ~loc ~params {txt = props_name; loc}
~kind:(Ptype_record label_decl_list);
]

Expand All @@ -346,22 +346,26 @@ let make_type_decls_with_core_type props_name loc core_type typ_vars =
~manifest:core_type;
]

let live_attr = ({txt = "live"; loc = Location.none}, PStr [])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Maybe we can put this in jsx_common.ml like Jsx_common.optionalAttr


(* type props<'x, 'y, ...> = { x: 'x, y?: 'y, ... } *)
let make_props_record_type ~core_type_of_attr ~typ_vars_of_core_type props_name
loc named_type_list =
let make_props_record_type ~core_type_of_attr ~external_ ~typ_vars_of_core_type
props_name loc named_type_list =
let attrs = if external_ then [live_attr] else [] in
Str.type_ Nonrecursive
(match core_type_of_attr with
| None -> make_type_decls props_name loc named_type_list
| None -> make_type_decls ~attrs props_name loc named_type_list
| Some core_type ->
make_type_decls_with_core_type props_name loc core_type
typ_vars_of_core_type)

(* type props<'x, 'y, ...> = { x: 'x, y?: 'y, ... } *)
let make_props_record_type_sig ~core_type_of_attr ~typ_vars_of_core_type
props_name loc named_type_list =
let make_props_record_type_sig ~core_type_of_attr ~external_
~typ_vars_of_core_type props_name loc named_type_list =
let attrs = if external_ then [live_attr] else [] in
Sig.type_ Nonrecursive
(match core_type_of_attr with
| None -> make_type_decls props_name loc named_type_list
| None -> make_type_decls ~attrs props_name loc named_type_list
| Some core_type ->
make_type_decls_with_core_type props_name loc core_type
typ_vars_of_core_type)
Expand Down Expand Up @@ -950,8 +954,8 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding =
let named_type_list = List.fold_left arg_to_type [] named_arg_list in
(* type props = { ... } *)
let props_record_type =
make_props_record_type ~core_type_of_attr ~typ_vars_of_core_type "props"
pstr_loc named_type_list
make_props_record_type ~core_type_of_attr ~external_:false
~typ_vars_of_core_type "props" pstr_loc named_type_list
in
let inner_expression =
Exp.apply
Expand Down Expand Up @@ -1211,8 +1215,8 @@ let transform_structure_item ~config item =
in
(* type props<'x, 'y> = { x: 'x, y?: 'y, ... } *)
let props_record_type =
make_props_record_type ~core_type_of_attr ~typ_vars_of_core_type "props"
pstr_loc named_type_list
make_props_record_type ~core_type_of_attr ~external_:true
~typ_vars_of_core_type "props" pstr_loc named_type_list
in
(* can't be an arrow because it will defensively uncurry *)
let new_external_type =
Expand Down Expand Up @@ -1317,9 +1321,10 @@ let transform_signature_item ~config item =
| [] -> []
| _ -> [Typ.any ()]))
in
let external_ = psig_desc.pval_prim <> [] in
let props_record_type =
make_props_record_type_sig ~core_type_of_attr ~typ_vars_of_core_type
"props" psig_loc named_type_list
make_props_record_type_sig ~core_type_of_attr ~external_
~typ_vars_of_core_type "props" psig_loc named_type_list
in
(* can't be an arrow because it will defensively uncurry *)
let new_external_type =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ let t = React.createElement(Foo.component, Foo.componentProps(~a=1, ~b={"1"}, ()
@@jsxConfig({version: 4, mode: "classic"})

module Foo = {
@live
type props<'a, 'b> = {a: 'a, b: 'b}

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

module Foo = {
@live
type props<'a, 'b> = {a: 'a, b: 'b}

@module("Foo")
Expand Down
13 changes: 13 additions & 0 deletions jscomp/syntax/tests/ppx/react/expected/externalWithRef.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module V3 = {
@@jsxConfig({version: 4, mode: "classic"})

module V4C = {
@live
type props<'x, 'ref> = {
x: 'x,
ref?: 'ref,
Expand All @@ -28,9 +29,21 @@ module V4C = {
"component"
}

module type V4CType = {
@live
type props<'x, 'y> = {
x: 'x,
y: 'y,
}

@module("someModule")
external make: React.componentLike<props<string, string>, React.element> = "component"
}

@@jsxConfig({version: 4, mode: "automatic"})

module V4C = {
@live
type props<'x, 'ref> = {
x: 'x,
ref?: 'ref,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module V3 = {
@@jsxConfig({version: 4, mode: "classic"})

module V4C = {
@live
type props<'x, 'children> = {
x: 'x,
children: 'children,
Expand All @@ -28,6 +29,7 @@ module V4C = {
@@jsxConfig({version: 4, mode: "automatic"})

module V4C = {
@live
type props<'x, 'children> = {
x: 'x,
children: 'children,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ module External = {
type key
type t
}
@live
type props<'model, 'selected, 'onChange, 'items> = {
model: 'model,
selected: 'selected,
Expand Down
2 changes: 2 additions & 0 deletions jscomp/syntax/tests/ppx/react/expected/mangleKeyword.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ module C4C0 = {
}
}
module C4C1 = {
@live
type props<'T_open, 'T_type> = {@as("open") _open: 'T_open, @as("type") _type: 'T_type}

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

external make: @as("open") React.componentLike<props<string, string>, React.element> = "default"
Expand Down
2 changes: 2 additions & 0 deletions jscomp/syntax/tests/ppx/react/expected/noPropsWithKey.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module V4CA = {
}

module V4CB = {
@live
type props = {}

@module("c")
Expand Down Expand Up @@ -51,6 +52,7 @@ module V4CA = {
}

module V4CB = {
@live
type props = {}

@module("c")
Expand Down
2 changes: 2 additions & 0 deletions jscomp/syntax/tests/ppx/react/expected/v4.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ module type TUncurried = {
}

module E = {
@live
type props<'x> = {x: 'x}

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

module EUncurried = {
@live
type props<'x> = {x: 'x}

external make: React.componentLike<props<string>, React.element> = "default"
Expand Down
8 changes: 8 additions & 0 deletions jscomp/syntax/tests/ppx/react/externalWithRef.res
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ module V4C = {
) => React.element = "component"
}

module type V4CType = {
@module("someModule") @react.component
external make: (
~x: string,
~y: string,
) => React.element = "component"
}

@@jsxConfig({version: 4, mode: "automatic"})

module V4C = {
Expand Down
Loading