Skip to content

Commit 41580b0

Browse files
committed
Pass existing location to children prop
1 parent a375a47 commit 41580b0

File tree

7 files changed

+146
-7
lines changed

7 files changed

+146
-7
lines changed

compiler/syntax/src/jsx_v4.ml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,7 +1208,7 @@ let append_children_prop (config : Jsx_common.jsx_config) mapper
12081208
| "react" -> Lident "ReactDOM"
12091209
| _generic -> module_access_name config "Elements"
12101210
in
1211-
Exp.apply
1211+
Exp.apply ~loc:child.pexp_loc
12121212
(Exp.ident
12131213
{txt = Ldot (element_binding, "someElement"); loc = Location.none})
12141214
[(Nolabel, mapper.expr mapper child)]
@@ -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

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+
}

0 commit comments

Comments
 (0)