Skip to content

Commit e1681e7

Browse files
authored
Fix: use configured Jsx module for constraining component return type (#7945)
* Fix: use configured Jsx module for constraining component return type * CHANGELOG
1 parent c3c1c17 commit e1681e7

37 files changed

+160
-154
lines changed

CHANGELOG.md

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

2121
#### :bug: Bug fix
2222

23+
- Fix: use configured Jsx module for constraining component return type. https://github.com/rescript-lang/rescript/pull/7945
24+
2325
#### :memo: Documentation
2426

2527
#### :nail_care: Polish

compiler/syntax/src/jsx_v4.ml

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -46,33 +46,8 @@ let ref_type loc =
4646
{loc; txt = Ldot (Ldot (Lident "Js", "Nullable"), "t")}
4747
[ref_type_var loc]
4848

49-
let jsx_element_type ~loc =
50-
Typ.constr ~loc {loc; txt = Ldot (Lident "Jsx", "element")} []
51-
52-
let jsx_element_constraint expr =
53-
Exp.constraint_ expr (jsx_element_type ~loc:expr.pexp_loc)
54-
55-
(* Traverse the component body and force every reachable return expression to
56-
be annotated as `Jsx.element`. This walks through the wrapper constructs the
57-
PPX introduces (fun/newtype/let/sequence) so that the constraint ends up on
58-
the real return position even after we rewrite the function. *)
59-
let rec constrain_jsx_return expr =
60-
match expr.pexp_desc with
61-
| Pexp_fun ({rhs} as desc) ->
62-
{expr with pexp_desc = Pexp_fun {desc with rhs = constrain_jsx_return rhs}}
63-
| Pexp_newtype (param, inner) ->
64-
{expr with pexp_desc = Pexp_newtype (param, constrain_jsx_return inner)}
65-
| Pexp_constraint (inner, _) ->
66-
let constrained_inner = constrain_jsx_return inner in
67-
jsx_element_constraint constrained_inner
68-
| Pexp_let (rec_flag, bindings, body) ->
69-
{
70-
expr with
71-
pexp_desc = Pexp_let (rec_flag, bindings, constrain_jsx_return body);
72-
}
73-
| Pexp_sequence (first, second) ->
74-
{expr with pexp_desc = Pexp_sequence (first, constrain_jsx_return second)}
75-
| _ -> jsx_element_constraint expr
49+
let jsx_element_type config ~loc =
50+
Typ.constr ~loc {loc; txt = module_access_name config "element"} []
7651

7752
(* Helper method to filter out any attribute that isn't [@react.component] *)
7853
let other_attrs_pure (loc, _) =
@@ -555,6 +530,34 @@ let vb_match_expr named_arg_list expr =
555530
aux (List.rev named_arg_list)
556531

557532
let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding =
533+
(* Traverse the component body and force every reachable return expression to
534+
be annotated as `Jsx.element`. This walks through the wrapper constructs the
535+
PPX introduces (fun/newtype/let/sequence) so that the constraint ends up on
536+
the real return position even after we rewrite the function. *)
537+
let rec constrain_jsx_return expr =
538+
let jsx_element_constraint expr =
539+
Exp.constraint_ expr (jsx_element_type config ~loc:expr.pexp_loc)
540+
in
541+
match expr.pexp_desc with
542+
| Pexp_fun ({rhs} as desc) ->
543+
{
544+
expr with
545+
pexp_desc = Pexp_fun {desc with rhs = constrain_jsx_return rhs};
546+
}
547+
| Pexp_newtype (param, inner) ->
548+
{expr with pexp_desc = Pexp_newtype (param, constrain_jsx_return inner)}
549+
| Pexp_constraint (inner, _) ->
550+
let constrained_inner = constrain_jsx_return inner in
551+
jsx_element_constraint constrained_inner
552+
| Pexp_let (rec_flag, bindings, body) ->
553+
{
554+
expr with
555+
pexp_desc = Pexp_let (rec_flag, bindings, constrain_jsx_return body);
556+
}
557+
| Pexp_sequence (first, second) ->
558+
{expr with pexp_desc = Pexp_sequence (first, constrain_jsx_return second)}
559+
| _ -> jsx_element_constraint expr
560+
in
558561
if Jsx_common.has_attr_on_binding Jsx_common.has_attr binding then (
559562
check_multiple_components ~config ~loc:pstr_loc;
560563
let core_type_of_attr =
@@ -988,7 +991,7 @@ let transform_structure_item ~config item =
988991
let new_external_type =
989992
Ptyp_constr
990993
( {loc = pstr_loc; txt = module_access_name config "componentLike"},
991-
[ret_props_type; jsx_element_type ~loc:pstr_loc] )
994+
[ret_props_type; jsx_element_type config ~loc:pstr_loc] )
992995
in
993996
let new_structure =
994997
{
@@ -1077,7 +1080,7 @@ let transform_signature_item ~config item =
10771080
let new_external_type =
10781081
Ptyp_constr
10791082
( {loc = psig_loc; txt = module_access_name config "componentLike"},
1080-
[ret_props_type; jsx_element_type ~loc:psig_loc] )
1083+
[ret_props_type; jsx_element_type config ~loc:psig_loc] )
10811084
in
10821085
let new_structure =
10831086
{

tests/analysis_tests/tests/src/expected/CreateInterface.res.txt

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@ Create Interface src/CreateInterface.res
22
type r = {name: string, age: int}
33
let add: (~x: int, ~y: int) => int
44
@react.component
5-
let make: (~name: string) => Jsx.element
5+
let make: (~name: string) => React.element
66
module Other: {
77
@react.component
8-
let otherComponentName: (~name: string) => Jsx.element
8+
let otherComponentName: (~name: string) => React.element
99
}
1010
module Mod: {
1111
@react.component
12-
let make: (~name: string) => Jsx.element
12+
let make: (~name: string) => React.element
1313
}
1414
module type ModTyp = {
1515
@react.component
16-
let make: (~name: string) => Jsx.element
16+
let make: (~name: string) => React.element
1717
}
1818
@module("path") external dirname: string => string = "dirname"
1919
@module("path") @variadic
@@ -49,21 +49,21 @@ module RFS: {
4949
module Functor: () =>
5050
{
5151
@react.component
52-
let make: unit => Jsx.element
52+
let make: unit => React.element
5353
}
5454
module type FT = {
5555
module Functor: (
5656
X: {
5757
let a: int
5858
@react.component
59-
let make: (~name: string) => Jsx.element
59+
let make: (~name: string) => React.element
6060
let b: int
6161
},
6262
Y: ModTyp,
6363
) =>
6464
{
6565
@react.component
66-
let make: (~name: string) => Jsx.element
66+
let make: (~name: string) => React.element
6767
}
6868
}
6969
module NormaList = List
@@ -73,34 +73,34 @@ module rec RM: ModTyp
7373
and D: ModTyp
7474
module type OptT = {
7575
@react.component
76-
let withOpt1: (~x: int=?, ~y: int) => Jsx.element
76+
let withOpt1: (~x: int=?, ~y: int) => React.element
7777
module type Opt2 = {
7878
@react.component
79-
let withOpt2: (~x: int=?, ~y: int) => Jsx.element
79+
let withOpt2: (~x: int=?, ~y: int) => React.element
8080
}
8181
module type Opt3 = {
8282
@react.component
83-
let withOpt3: (~x: option<int>, ~y: int) => Jsx.element
83+
let withOpt3: (~x: option<int>, ~y: int) => React.element
8484
}
8585
}
8686
module Opt: {
8787
@react.component
88-
let withOpt1: (~x: int=?, ~y: int) => Jsx.element
88+
let withOpt1: (~x: int=?, ~y: int) => React.element
8989
module Opt2: {
9090
@react.component
91-
let withOpt2: (~x: int=?, ~y: int) => Jsx.element
91+
let withOpt2: (~x: int=?, ~y: int) => React.element
9292
}
9393
module type Opt2 = {
9494
@react.component
95-
let withOpt2: (~x: int=?, ~y: int) => Jsx.element
95+
let withOpt2: (~x: int=?, ~y: int) => React.element
9696
}
9797
module Opt3: {
9898
@react.component
99-
let withOpt3: (~x: option<int>, ~y: int) => Jsx.element
99+
let withOpt3: (~x: option<int>, ~y: int) => React.element
100100
}
101101
module type Opt3 = {
102102
@react.component
103-
let withOpt3: (~x: option<int>, ~y: int) => Jsx.element
103+
let withOpt3: (~x: option<int>, ~y: int) => React.element
104104
}
105105
}
106106
module Opt2: OptT
@@ -122,7 +122,7 @@ external upperBound: ([< #d | #e | #f]) => unit = "myexternal"
122122
external lowerBound: ([> #d | #e | #f]) => unit = "myexternal"
123123
module ComponentWithPolyProp: {
124124
@react.component
125-
let make: (~size: [< #large | #small]=?) => Jsx.element
125+
let make: (~size: [< #large | #small]=?) => React.element
126126
}
127127
module OrderedSet: {
128128
type t<'a, 'identity> = {

tests/analysis_tests/tests/src/expected/Jsx2.resi.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Hover src/Jsx2.resi 1:4
2-
{"contents": {"kind": "markdown", "value": "```rescript\nJsx.element\n```\n\n---\n\n```\n \n```\n```rescript\ntype Jsx.element\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22Jsx.res%22%2C25%2C0%5D)\n"}}
2+
{"contents": {"kind": "markdown", "value": "```rescript\nReact.element\n```\n\n---\n\n```\n \n```\n```rescript\ntype React.element = Jsx.element\n```\nGo to: [Type definition](command:rescript-vscode.go_to_location?%5B%22React.res%22%2C0%2C0%5D)\n"}}
33

44
Hover src/Jsx2.resi 4:4
55
{"contents": {"kind": "markdown", "value": "```rescript\nint\n```"}}

tests/analysis_tests/tests/src/expected/JsxV4.res.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ Hover src/JsxV4.res 14:9
2222
Create Interface src/JsxV4.res
2323
module M4: {
2424
@react.component
25-
let make: (~first: string, ~fun: string=?, ~second: string=?) => Jsx.element
25+
let make: (~first: string, ~fun: string=?, ~second: string=?) => React.element
2626
}
2727
module MM: {
2828
@react.component
29-
let make: unit => Jsx.element
29+
let make: unit => React.element
3030
}
3131
module Other: {
3232
@react.component
33-
let make: (~name: string) => Jsx.element
33+
let make: (~name: string) => React.element
3434
}
3535

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@@jsxConfig({version: 4})
1+
@@jsxConfig({version: 4, module_: "Jsx"})
22

33
@react.component
44
let make = async () => 1

tests/build_tests/super_errors/fixtures/react_componentWithProps_missing_jsx_element.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@@jsxConfig({version: 4})
1+
@@jsxConfig({version: 4, module_: "Jsx"})
22

33
type props<'a> = {value: 'a}
44

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@@jsxConfig({version: 4})
1+
@@jsxConfig({version: 4, module_: "Jsx"})
22

33
@react.component
44
let make = () => 1
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@@jsxConfig({version: 4})
1+
@@jsxConfig({version: 4, module_: "Jsx"})
22

33
@react.component
44
let make = React.forwardRef((_, _ref) => 1)

tests/syntax_tests/data/ppx/react/expected/aliasProps.res.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ module C0 = {
99
| Some(text) => text
1010
| None => "Test"
1111
}
12-
(React.string(text): Jsx.element)
12+
(React.string(text): React.element)
1313
}
1414
let make = {
1515
let \"AliasProps$C0" = (props: props<_>) => make(props)
@@ -27,7 +27,7 @@ module C1 = {
2727
| Some(text) => text
2828
| None => "Test"
2929
}
30-
(React.string(p ++ text): Jsx.element)
30+
(React.string(p ++ text): React.element)
3131
}
3232
let make = {
3333
let \"AliasProps$C1" = (props: props<_>) => make(props)
@@ -45,7 +45,7 @@ module C2 = {
4545
| Some(foo) => foo
4646
| None => ""
4747
}
48-
(React.string(bar): Jsx.element)
48+
(React.string(bar): React.element)
4949
}
5050
let make = {
5151
let \"AliasProps$C2" = (props: props<_>) => make(props)
@@ -70,7 +70,7 @@ module C3 = {
7070
(
7171
{
7272
React.string(bar ++ a ++ b)
73-
}: Jsx.element
73+
}: React.element
7474
)
7575
}
7676
let make = {
@@ -89,7 +89,7 @@ module C4 = {
8989
| Some(x) => x
9090
| None => true
9191
}
92-
(ReactDOM.jsx("div", {children: ?ReactDOM.someElement(b)}): Jsx.element)
92+
(ReactDOM.jsx("div", {children: ?ReactDOM.someElement(b)}): React.element)
9393
}
9494
let make = {
9595
let \"AliasProps$C4" = (props: props<_>) => make(props)
@@ -107,7 +107,7 @@ module C5 = {
107107
| Some(z) => z
108108
| None => 3
109109
}
110-
(x + y + z: Jsx.element)
110+
(x + y + z: React.element)
111111
}
112112
let make = {
113113
let \"AliasProps$C5" = (props: props<_>) => make(props)
@@ -121,12 +121,12 @@ module C6 = {
121121
@res.jsxComponentProps
122122
type props = {}
123123

124-
let make: React.componentLike<props, Jsx.element>
124+
let make: React.componentLike<props, React.element>
125125
}
126126
@res.jsxComponentProps
127127
type props<'comp, 'x> = {comp: 'comp, x: 'x}
128128

129-
let make = ({comp: module(Comp: Comp), x: (a, b), _}: props<_, _>): Jsx.element =>
129+
let make = ({comp: module(Comp: Comp), x: (a, b), _}: props<_, _>): React.element =>
130130
React.jsx(Comp.make, {})
131131
let make = {
132132
let \"AliasProps$C6" = (props: props<_>) => make(props)

0 commit comments

Comments
 (0)