Skip to content

Commit 3d45c38

Browse files
authored
Pass existing location to children prop (#7540)
* Pass existing location to children prop * No sure about this * Add changelog entry * Update roundtrip tests * Revert loc to React.someElement
1 parent 333b20c commit 3d45c38

File tree

11 files changed

+152
-76
lines changed

11 files changed

+152
-76
lines changed

CHANGELOG.md

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

1717
- Ignore inferred arity in functions inside `%raw` functions, leaving to `%ffi` the responsibility to check the arity since it gives an error in case of mismatch. https://github.com/rescript-lang/rescript/pull/7542
1818
- Pass the rewatch exit code through in wrapper script. https://github.com/rescript-lang/rescript/pull/7565
19+
- Prop punning when types don't match results in I/O error: _none_: No such file or directory. https://github.com/rescript-lang/rescript/pull/7533
20+
- Pass location to children prop in jsx ppx. https://github.com/rescript-lang/rescript/pull/7540
1921

2022
#### :nail_care: Polish
2123

compiler/syntax/src/jsx_v4.ml

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,18 +1220,24 @@ let append_children_prop (config : Jsx_common.jsx_config) mapper
12201220
in
12211221
props
12221222
@ [
1223-
JSXPropValue ({txt = "children"; loc = Location.none}, is_optional, expr);
1223+
JSXPropValue
1224+
({txt = "children"; loc = child.pexp_loc}, is_optional, expr);
12241225
]
1225-
| JSXChildrenItems xs ->
1226+
| JSXChildrenItems (head :: _ as xs) ->
1227+
let loc =
1228+
match List.rev xs with
1229+
| [] -> head.pexp_loc
1230+
| lastChild :: _ ->
1231+
{head.pexp_loc with loc_end = lastChild.pexp_loc.loc_end}
1232+
in
12261233
(* this is a hack to support react components that introspect into their children *)
12271234
props
12281235
@ [
12291236
JSXPropValue
1230-
( {txt = "children"; loc = Location.none},
1237+
( {txt = "children"; loc},
12311238
false,
1232-
Exp.apply
1233-
(Exp.ident
1234-
{txt = module_access_name config "array"; loc = Location.none})
1239+
Exp.apply ~loc
1240+
(Exp.ident {txt = module_access_name config "array"; loc})
12351241
[(Nolabel, Exp.array (List.map (mapper.expr mapper) xs))] );
12361242
]
12371243

tests/analysis_tests/tests-reanalyze/deadcode/expected/deadcode.txt

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,6 @@
2828
addValueReference ComponentAsProp.res:12:24 --> ComponentAsProp.res:12:13
2929
addValueReference ComponentAsProp.res:13:16 --> React.res:3:0
3030
addValueReference ComponentAsProp.res:11:14 --> ComponentAsProp.res:6:34
31-
addValueReference ComponentAsProp.res:9:6 --> ComponentAsProp.res:6:12
32-
addValueReference ComponentAsProp.res:10:6 --> ComponentAsProp.res:6:20
33-
addValueReference ComponentAsProp.res:12:24 --> ComponentAsProp.res:12:13
34-
addValueReference ComponentAsProp.res:13:16 --> React.res:3:0
35-
addValueReference ComponentAsProp.res:11:14 --> ComponentAsProp.res:6:34
36-
addValueReference ComponentAsProp.res:9:6 --> ComponentAsProp.res:6:12
37-
addValueReference ComponentAsProp.res:10:6 --> ComponentAsProp.res:6:20
38-
addValueReference ComponentAsProp.res:12:24 --> ComponentAsProp.res:12:13
39-
addValueReference ComponentAsProp.res:13:16 --> React.res:3:0
40-
addValueReference ComponentAsProp.res:11:14 --> ComponentAsProp.res:6:34
4131
addTypeReference _none_:1:-1 --> ComponentAsProp.res:6:12
4232
addTypeReference _none_:1:-1 --> ComponentAsProp.res:6:20
4333
addTypeReference _none_:1:-1 --> ComponentAsProp.res:6:34
@@ -433,41 +423,11 @@
433423
addValueReference Hooks.res:14:5 --> ImportHooks.res:13:0
434424
addValueReference Hooks.res:15:7 --> React.res:7:0
435425
addValueReference Hooks.res:15:32 --> React.res:7:0
436-
addValueReference Hooks.res:15:7 --> React.res:7:0
437-
addValueReference Hooks.res:15:32 --> React.res:7:0
438-
addValueReference Hooks.res:14:76 --> Hooks.res:14:57
439-
addValueReference Hooks.res:14:63 --> React.res:7:0
440-
addValueReference Hooks.res:17:5 --> ImportHookDefault.res:6:0
441-
addValueReference Hooks.res:19:7 --> React.res:7:0
442-
addValueReference Hooks.res:19:32 --> React.res:7:0
443-
addValueReference Hooks.res:19:7 --> React.res:7:0
444-
addValueReference Hooks.res:19:32 --> React.res:7:0
445-
addValueReference Hooks.res:18:74 --> Hooks.res:18:55
446-
addValueReference Hooks.res:18:61 --> React.res:7:0
447-
addTypeReference Hooks.res:10:29 --> Hooks.res:1:16
448-
addValueReference Hooks.res:10:29 --> Hooks.res:4:12
449-
addValueReference Hooks.res:10:75 --> Hooks.res:5:7
450-
addValueReference Hooks.res:9:7 --> React.res:7:0
451-
addTypeReference Hooks.res:10:29 --> Hooks.res:1:16
452-
addValueReference Hooks.res:10:29 --> Hooks.res:4:12
453-
addValueReference Hooks.res:10:75 --> Hooks.res:5:7
454-
addValueReference Hooks.res:9:7 --> React.res:7:0
455-
addValueReference Hooks.res:13:54 --> React.res:7:0
456-
addValueReference Hooks.res:13:54 --> React.res:7:0
457-
addValueReference Hooks.res:13:40 --> Hooks.res:5:7
458-
addValueReference Hooks.res:13:26 --> Hooks.res:5:14
459-
addValueReference Hooks.res:14:5 --> ImportHooks.res:13:0
460-
addValueReference Hooks.res:15:7 --> React.res:7:0
461-
addValueReference Hooks.res:15:32 --> React.res:7:0
462-
addValueReference Hooks.res:15:7 --> React.res:7:0
463-
addValueReference Hooks.res:15:32 --> React.res:7:0
464426
addValueReference Hooks.res:14:76 --> Hooks.res:14:57
465427
addValueReference Hooks.res:14:63 --> React.res:7:0
466428
addValueReference Hooks.res:17:5 --> ImportHookDefault.res:6:0
467429
addValueReference Hooks.res:19:7 --> React.res:7:0
468430
addValueReference Hooks.res:19:32 --> React.res:7:0
469-
addValueReference Hooks.res:19:7 --> React.res:7:0
470-
addValueReference Hooks.res:19:32 --> React.res:7:0
471431
addValueReference Hooks.res:18:74 --> Hooks.res:18:55
472432
addValueReference Hooks.res:18:61 --> React.res:7:0
473433
addTypeReference _none_:1:-1 --> Hooks.res:4:12
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/missing_required_prop.res:28:7-37
4+
5+
26 ┆ let make = () => {
6+
27 ┆ <Wrapper>
7+
28 ┆ <div> {""->React.string} </div>
8+
29 ┆ </Wrapper>
9+
30 ┆ }
10+
11+
This JSX component does not accept child elements. It has no children prop <Wrapper />
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/missing_required_prop_when_children.res:31:7-32:37
4+
5+
29 ┆ let make = () => {
6+
30 ┆ <Wrapper>
7+
31 ┆ <button> {"yo"->React.string} </button>
8+
32 ┆  <div> {""->React.string} </div>
9+
33 ┆ </Wrapper>
10+
34 ┆ }
11+
12+
The component <Wrapper /> is missing these required props:
13+
value
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/missing_required_prop_when_single_child.res:28:7-37
4+
5+
26 ┆ let make = () => {
6+
27 ┆ <Wrapper>
7+
28 ┆ <div> {""->React.string} </div>
8+
29 ┆ </Wrapper>
9+
30 ┆ }
10+
11+
The component <Wrapper /> is missing these required props:
12+
value
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module React = {
2+
type element = Jsx.element
3+
@val external null: element = "null"
4+
type componentLike<'props, 'return> = Jsx.componentLike<'props, 'return>
5+
type component<'props> = Jsx.component<'props>
6+
external component: componentLike<'props, element> => component<'props> = "%identity"
7+
@module("react/jsx-runtime")
8+
external jsx: (component<'props>, 'props) => element = "jsx"
9+
external string: string => element = "%identity"
10+
}
11+
module ReactDOM = {
12+
external someElement: React.element => option<React.element> = "%identity"
13+
@module("react/jsx-runtime")
14+
external jsx: (string, JsxDOM.domProps) => Jsx.element = "jsx"
15+
}
16+
17+
module Wrapper = {
18+
@react.component
19+
let make = (~value: 'value) => {
20+
<div> {React.null} </div>
21+
}
22+
}
23+
24+
module SomeComponent = {
25+
@react.component
26+
let make = () => {
27+
<Wrapper>
28+
<div> {""->React.string} </div>
29+
</Wrapper>
30+
}
31+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
module React = {
2+
type element = Jsx.element
3+
@val external null: element = "null"
4+
type componentLike<'props, 'return> = Jsx.componentLike<'props, 'return>
5+
type component<'props> = Jsx.component<'props>
6+
external component: componentLike<'props, element> => component<'props> = "%identity"
7+
@module("react/jsx-runtime")
8+
external jsx: (component<'props>, 'props) => element = "jsx"
9+
@module("react/jsx-runtime")
10+
external jsxs: (component<'props>, 'props) => element = "jsxs"
11+
external string: string => element = "%identity"
12+
external array: array<element> => element = "%identity"
13+
}
14+
module ReactDOM = {
15+
external someElement: React.element => option<React.element> = "%identity"
16+
@module("react/jsx-runtime")
17+
external jsx: (string, JsxDOM.domProps) => Jsx.element = "jsx"
18+
}
19+
20+
module Wrapper = {
21+
@react.component
22+
let make = (~value: 'value, ~children: React.element) => {
23+
<div> {children} </div>
24+
}
25+
}
26+
27+
module SomeComponent = {
28+
@react.component
29+
let make = () => {
30+
<Wrapper>
31+
<button> {"yo"->React.string} </button>
32+
<div> {""->React.string} </div>
33+
</Wrapper>
34+
}
35+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module React = {
2+
type element = Jsx.element
3+
@val external null: element = "null"
4+
type componentLike<'props, 'return> = Jsx.componentLike<'props, 'return>
5+
type component<'props> = Jsx.component<'props>
6+
external component: componentLike<'props, element> => component<'props> = "%identity"
7+
@module("react/jsx-runtime")
8+
external jsx: (component<'props>, 'props) => element = "jsx"
9+
external string: string => element = "%identity"
10+
}
11+
module ReactDOM = {
12+
external someElement: React.element => option<React.element> = "%identity"
13+
@module("react/jsx-runtime")
14+
external jsx: (string, JsxDOM.domProps) => Jsx.element = "jsx"
15+
}
16+
17+
module Wrapper = {
18+
@react.component
19+
let make = (~value: 'value, ~children: React.element) => {
20+
<div> {children} </div>
21+
}
22+
}
23+
24+
module SomeComponent = {
25+
@react.component
26+
let make = () => {
27+
<Wrapper>
28+
<div> {""->React.string} </div>
29+
</Wrapper>
30+
}
31+
}
Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
let empty = React.jsx(React.jsxFragment, {})
22

3-
let fragmentWithBracedExpresssion = React.jsx(
4-
React.jsxFragment,
5-
{
6-
children: {React.int(1 + 2)},
7-
},
8-
)
3+
let fragmentWithBracedExpresssion = React.jsx(React.jsxFragment, {children: {React.int(1 + 2)}})
94

105
let fragmentWithJSXElements = React.jsxs(
116
React.jsxFragment,
@@ -23,12 +18,7 @@ let nestedFragments = React.jsxs(
2318
children: React.array([
2419
ReactDOM.jsx("h1", {children: ?ReactDOM.someElement({React.string("Hi")})}),
2520
ReactDOM.jsx("p", {children: ?ReactDOM.someElement({React.string("Hello")})}),
26-
React.jsx(
27-
React.jsxFragment,
28-
{
29-
children: {React.string("Bye")},
30-
},
31-
),
21+
React.jsx(React.jsxFragment, {children: {React.string("Bye")}}),
3222
]),
3323
},
3424
)

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

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,14 @@
11
@@jsxConfig({version: 4})
22

33
let _ = React.jsx(React.jsxFragment, {})
4-
let _ = React.jsx(
5-
React.jsxFragment,
6-
{
7-
children: ReactDOM.jsx("div", {}),
8-
},
9-
)
4+
let _ = React.jsx(React.jsxFragment, {children: ReactDOM.jsx("div", {})})
105
let _ = React.jsxs(
116
React.jsxFragment,
127
{children: React.array([ReactDOM.jsx("div", {}), ReactDOM.jsx("div", {})])},
138
)
14-
let _ = React.jsx(
15-
React.jsxFragment,
16-
{
17-
children: React.jsx(React.jsxFragment, {}),
18-
},
19-
)
9+
let _ = React.jsx(React.jsxFragment, {children: React.jsx(React.jsxFragment, {})})
2010
let _ = React.jsx(Z.make, {})
21-
let _ = React.jsx(
22-
Z.make,
23-
{
24-
children: ReactDOM.jsx("div", {}),
25-
},
26-
)
11+
let _ = React.jsx(Z.make, {children: ReactDOM.jsx("div", {})})
2712
let _ = React.jsx(Z.make, {a: "a", children: ReactDOM.jsx("div", {})})
2813
let _ = React.jsxs(
2914
Z.make,

0 commit comments

Comments
 (0)