diff --git a/compiler/syntax/src/jsx_v4.ml b/compiler/syntax/src/jsx_v4.ml index b7ec8b15e3..049ff9529e 100644 --- a/compiler/syntax/src/jsx_v4.ml +++ b/compiler/syntax/src/jsx_v4.ml @@ -528,8 +528,16 @@ let vb_match_expr named_arg_list expr = in aux (List.rev named_arg_list) +(* https://github.com/rescript-lang/rescript/issues/7722 *) +let add_jsx_element_return_constraint config expression = + Exp.constraint_ expression + (Typ.constr + {txt = module_access_name config "element"; loc = expression.pexp_loc} + []) + let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = if Jsx_common.has_attr_on_binding Jsx_common.has_attr binding then ( + (* @react.component *) check_multiple_components ~config ~loc:pstr_loc; let core_type_of_attr = Jsx_common.core_type_of_attrs binding.pvb_attributes @@ -732,6 +740,7 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = | [] -> Pat.any () | _ -> Pat.record (List.rev patterns_with_label) Open in + let expression = add_jsx_element_return_constraint config expression in let expression = Exp.fun_ ~arity:(Some 1) ~async:is_async Nolabel None (Pat.constraint_ record_pattern @@ -779,6 +788,7 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = (Some props_record_type, binding, new_binding)) else if Jsx_common.has_attr_on_binding Jsx_common.has_attr_with_props binding then + (* @react.componentWithProps *) let modified_binding = { binding with @@ -835,21 +845,24 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = | _ -> Pat.var {txt = "props"; loc} in + let expression = + Jsx_common.async_component ~async:is_async + (Exp.apply + (Exp.ident + { + txt = + Lident + (match rec_flag with + | Recursive -> internal_fn_name + | Nonrecursive -> fn_name); + loc; + }) + [(Nolabel, Exp.ident {txt = Lident "props"; loc})]) + in + let expression = add_jsx_element_return_constraint config expression in let wrapper_expr = Exp.fun_ ~arity:None Nolabel None props_pattern - ~attrs:binding.pvb_expr.pexp_attributes - (Jsx_common.async_component ~async:is_async - (Exp.apply - (Exp.ident - { - txt = - Lident - (match rec_flag with - | Recursive -> internal_fn_name - | Nonrecursive -> fn_name); - loc; - }) - [(Nolabel, Exp.ident {txt = Lident "props"; loc})])) + ~attrs:binding.pvb_expr.pexp_attributes expression in let wrapper_expr = Ast_uncurried.uncurried_fun ~arity:1 wrapper_expr in @@ -1282,7 +1295,7 @@ let mk_react_jsx (config : Jsx_common.jsx_config) mapper loc attrs let args = [(nolabel, elementTag); (nolabel, props_record)] @ key_and_unit in Exp.apply ~loc ~attrs ~transformed_jsx:true jsx_expr args -(* In most situations, the component name is the make function from a module. +(* In most situations, the component name is the make function from a module. However, if the name contains a lowercase letter, it means it probably an external component. In this case, we use the name as is. See tests/syntax_tests/data/ppx/react/externalWithCustomName.res diff --git a/tests/build_tests/super_errors/expected/jsx_invalid_return_type.res.expected b/tests/build_tests/super_errors/expected/jsx_invalid_return_type.res.expected new file mode 100644 index 0000000000..71dfe3023c --- /dev/null +++ b/tests/build_tests/super_errors/expected/jsx_invalid_return_type.res.expected @@ -0,0 +1,15 @@ + + We've found a bug for you! + /.../fixtures/jsx_invalid_return_type.res:14:5-6 + + 12 │ @react.component + 13 │ let make = () => { + 14 │ 42 // This should be an error - returning int instead of React.elem + │ ent + 15 │ } + 16 │ } + + This has type: int + But it's expected to have type: React.element (defined as Jsx.element) + + In JSX, all content must be JSX elements. You can convert int to a JSX element with React.int. \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/jsx_invalid_return_type_component_with_props.res.expected b/tests/build_tests/super_errors/expected/jsx_invalid_return_type_component_with_props.res.expected new file mode 100644 index 0000000000..a03b5a7013 --- /dev/null +++ b/tests/build_tests/super_errors/expected/jsx_invalid_return_type_component_with_props.res.expected @@ -0,0 +1,8 @@ + + We've found a bug for you! + /.../fixtures/jsx_invalid_return_type_component_with_props.res + + This has type: int + But it's expected to have type: React.element (defined as Jsx.element) + + In JSX, all content must be JSX elements. You can convert int to a JSX element with React.int. \ No newline at end of file diff --git a/tests/build_tests/super_errors/fixtures/jsx_invalid_return_type.res b/tests/build_tests/super_errors/fixtures/jsx_invalid_return_type.res new file mode 100644 index 0000000000..26be55438a --- /dev/null +++ b/tests/build_tests/super_errors/fixtures/jsx_invalid_return_type.res @@ -0,0 +1,16 @@ +@@config({ + flags: ["-bs-jsx", "4"], +}) + +module React = { + type element = Jsx.element + type componentLike<'props, 'return> = 'props => 'return + type component<'props> = Jsx.component<'props> +} + +module BadComponent = { + @react.component + let make = () => { + 42 // This should be an error - returning int instead of React.element + } +} diff --git a/tests/build_tests/super_errors/fixtures/jsx_invalid_return_type_component_with_props.res b/tests/build_tests/super_errors/fixtures/jsx_invalid_return_type_component_with_props.res new file mode 100644 index 0000000000..0a3b261059 --- /dev/null +++ b/tests/build_tests/super_errors/fixtures/jsx_invalid_return_type_component_with_props.res @@ -0,0 +1,16 @@ +@@config({ + flags: ["-bs-jsx", "4"], +}) + +module React = { + type element = Jsx.element + type componentLike<'props, 'return> = 'props => 'return + type component<'props> = Jsx.component<'props> +} + +module BadComponent = { + @react.componentWithProps + let make = _props => { + 42 // This should be an error - returning int instead of React.element + } +} diff --git a/tests/syntax_tests/data/ppx/react/expected/aliasProps.res.txt b/tests/syntax_tests/data/ppx/react/expected/aliasProps.res.txt index e9d0ab30a8..f03596d513 100644 --- a/tests/syntax_tests/data/ppx/react/expected/aliasProps.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/aliasProps.res.txt @@ -4,7 +4,7 @@ module C0 = { @res.jsxComponentProps type props<'priority, 'text> = {priority: 'priority, text?: 'text} - let make = ({priority: _, text: ?__text, _}: props<_, _>) => { + let make = ({priority: _, text: ?__text, _}: props<_, _>): React.element => { let text = switch __text { | Some(text) => text | None => "Test" @@ -23,7 +23,7 @@ module C1 = { @res.jsxComponentProps type props<'priority, 'text> = {priority: 'priority, text?: 'text} - let make = ({priority: p, text: ?__text, _}: props<_, _>) => { + let make = ({priority: p, text: ?__text, _}: props<_, _>): React.element => { let text = switch __text { | Some(text) => text | None => "Test" @@ -42,7 +42,7 @@ module C2 = { @res.jsxComponentProps type props<'foo> = {foo?: 'foo} - let make = ({foo: ?__bar, _}: props<_>) => { + let make = ({foo: ?__bar, _}: props<_>): React.element => { let bar = switch __bar { | Some(foo) => foo | None => "" @@ -61,7 +61,7 @@ module C3 = { @res.jsxComponentProps type props<'foo, 'a, 'b> = {foo?: 'foo, a?: 'a, b: 'b} - let make = ({foo: ?__bar, a: ?__a, b, _}: props<_, _, _>) => { + let make = ({foo: ?__bar, a: ?__a, b, _}: props<_, _, _>): React.element => { let bar = switch __bar { | Some(foo) => foo | None => "" @@ -86,7 +86,7 @@ module C4 = { @res.jsxComponentProps type props<'a, 'x> = {a: 'a, x?: 'x} - let make = ({a: b, x: ?__x, _}: props<_, _>) => { + let make = ({a: b, x: ?__x, _}: props<_, _>): React.element => { let x = switch __x { | Some(x) => x | None => true @@ -105,7 +105,7 @@ module C5 = { @res.jsxComponentProps type props<'a, 'z> = {a: 'a, z?: 'z} - let make = ({a: (x, y), z: ?__z, _}: props<_, _>) => { + let make = ({a: (x, y), z: ?__z, _}: props<_, _>): React.element => { let z = switch __z { | Some(z) => z | None => 3 @@ -130,7 +130,8 @@ module C6 = { @res.jsxComponentProps type props<'comp, 'x> = {comp: 'comp, x: 'x} - let make = ({comp: module(Comp: Comp), x: (a, b), _}: props<_, _>) => React.jsx(Comp.make, {}) + let make = ({comp: module(Comp: Comp), x: (a, b), _}: props<_, _>): React.element => + React.jsx(Comp.make, {}) let make = { let \"AliasProps$C6" = (props: props<_>) => make(props) diff --git a/tests/syntax_tests/data/ppx/react/expected/asyncAwait.res.txt b/tests/syntax_tests/data/ppx/react/expected/asyncAwait.res.txt index 66441d1f69..a5c374437d 100644 --- a/tests/syntax_tests/data/ppx/react/expected/asyncAwait.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/asyncAwait.res.txt @@ -4,7 +4,7 @@ module C0 = { @res.jsxComponentProps type props<'a> = {a: 'a} - let make = async ({a, _}: props<_>) => { + let make = async ({a, _}: props<_>): React.element => { let a = await f(a) ReactDOM.jsx("div", {children: ?ReactDOM.someElement({React.int(a)})}) } @@ -19,7 +19,7 @@ module C1 = { @res.jsxComponentProps type props<'status> = {status: 'status} - let make = async ({status, _}: props<_>) => { + let make = async ({status, _}: props<_>): React.element => { switch status { | #on => React.string("on") | #off => React.string("off") diff --git a/tests/syntax_tests/data/ppx/react/expected/commentAtTop.res.txt b/tests/syntax_tests/data/ppx/react/expected/commentAtTop.res.txt index 3f4656ddda..1ddf0492f9 100644 --- a/tests/syntax_tests/data/ppx/react/expected/commentAtTop.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/commentAtTop.res.txt @@ -1,7 +1,7 @@ @res.jsxComponentProps type props<'msg> = {msg: 'msg} // test React JSX file -let make = ({msg, _}: props<_>) => { +let make = ({msg, _}: props<_>): React.element => { ReactDOM.jsx("div", {children: ?ReactDOM.someElement({msg->React.string})}) } let make = { diff --git a/tests/syntax_tests/data/ppx/react/expected/defaultValueProp.res.txt b/tests/syntax_tests/data/ppx/react/expected/defaultValueProp.res.txt index 5cb93d4681..8a7bd26c89 100644 --- a/tests/syntax_tests/data/ppx/react/expected/defaultValueProp.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/defaultValueProp.res.txt @@ -1,7 +1,7 @@ module C0 = { @res.jsxComponentProps type props<'a, 'b> = {a?: 'a, b?: 'b} - let make = ({a: ?__a, b: ?__b, _}: props<_, _>) => { + let make = ({a: ?__a, b: ?__b, _}: props<_, _>): React.element => { let a = switch __a { | Some(a) => a | None => 2 @@ -23,7 +23,7 @@ module C1 = { @res.jsxComponentProps type props<'a, 'b> = {a?: 'a, b: 'b} - let make = ({a: ?__a, b, _}: props<_, _>) => { + let make = ({a: ?__a, b, _}: props<_, _>): React.element => { let a = switch __a { | Some(a) => a | None => 2 @@ -43,7 +43,7 @@ module C2 = { @res.jsxComponentProps type props<'a> = {a?: 'a} - let make = ({a: ?__a, _}: props<_>) => { + let make = ({a: ?__a, _}: props<_>): React.element => { let a = switch __a { | Some(a) => a | None => a @@ -62,7 +62,7 @@ module C3 = { @res.jsxComponentProps type props<'disabled> = {disabled?: 'disabled} - let make = ({disabled: ?__everythingDisabled, _}: props) => { + let make = ({disabled: ?__everythingDisabled, _}: props): React.element => { let everythingDisabled = switch __everythingDisabled { | Some(disabled) => disabled | None => false diff --git a/tests/syntax_tests/data/ppx/react/expected/fileLevelConfig.res.txt b/tests/syntax_tests/data/ppx/react/expected/fileLevelConfig.res.txt index c11e849074..177190cbe8 100644 --- a/tests/syntax_tests/data/ppx/react/expected/fileLevelConfig.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/fileLevelConfig.res.txt @@ -4,7 +4,7 @@ module V4A = { @res.jsxComponentProps type props<'msg> = {msg: 'msg} - let make = ({msg, _}: props<_>) => { + let make = ({msg, _}: props<_>): React.element => { ReactDOM.jsx("div", {children: ?ReactDOM.someElement({msg->React.string})}) } let make = { diff --git a/tests/syntax_tests/data/ppx/react/expected/forwardRef.res.txt b/tests/syntax_tests/data/ppx/react/expected/forwardRef.res.txt index 9b8b541317..b05eb753c0 100644 --- a/tests/syntax_tests/data/ppx/react/expected/forwardRef.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/forwardRef.res.txt @@ -9,23 +9,24 @@ module V4A = { ref?: 'ref, } - let make = ({?className, children, _}: props<_, _, 'ref>, ref: Js.Nullable.t<'ref>) => - ReactDOM.jsxs( - "div", - { - children: React.array([ - ReactDOM.jsx( - "input", - { - type_: "text", - ?className, - ref: ?{Js.Nullable.toOption(ref)->Belt.Option.map(ReactDOM.Ref.domRef)}, - }, - ), - children, - ]), - }, - ) + let make = ({?className, children, _}: props<_, _, 'ref>): React.element => + (ref: Js.Nullable.t<'ref>) => + ReactDOM.jsxs( + "div", + { + children: React.array([ + ReactDOM.jsx( + "input", + { + type_: "text", + ?className, + ref: ?{Js.Nullable.toOption(ref)->Belt.Option.map(ReactDOM.Ref.domRef)}, + }, + ), + children, + ]), + }, + ) let make = React.forwardRef({ let \"ForwardRef$V4A$FancyInput" = (props: props<_>, ref) => make(props, ref) @@ -35,7 +36,7 @@ module V4A = { @res.jsxComponentProps type props = {} - let make = (_: props) => { + let make = (_: props): React.element => { let input = React.useRef(Js.Nullable.null) ReactDOM.jsx( @@ -63,23 +64,24 @@ module V4AUncurried = { ref?: 'ref, } - let make = ({?className, children, _}: props<_, _, 'ref>, ref: Js.Nullable.t<'ref>) => - ReactDOM.jsxs( - "div", - { - children: React.array([ - ReactDOM.jsx( - "input", - { - type_: "text", - ?className, - ref: ?{Js.Nullable.toOption(ref)->Belt.Option.map(ReactDOM.Ref.domRef)}, - }, - ), - children, - ]), - }, - ) + let make = ({?className, children, _}: props<_, _, 'ref>): React.element => + (ref: Js.Nullable.t<'ref>) => + ReactDOM.jsxs( + "div", + { + children: React.array([ + ReactDOM.jsx( + "input", + { + type_: "text", + ?className, + ref: ?{Js.Nullable.toOption(ref)->Belt.Option.map(ReactDOM.Ref.domRef)}, + }, + ), + children, + ]), + }, + ) let make = React.forwardRef({ let \"ForwardRef$V4AUncurried$FancyInput" = (props: props<_>, ref) => make(props, ref) @@ -89,7 +91,7 @@ module V4AUncurried = { @res.jsxComponentProps type props = {} - let make = (_: props) => { + let make = (_: props): React.element => { let input = React.useRef(Js.Nullable.null) ReactDOM.jsx( diff --git a/tests/syntax_tests/data/ppx/react/expected/interface.res.txt b/tests/syntax_tests/data/ppx/react/expected/interface.res.txt index 645636451e..e28bfe5472 100644 --- a/tests/syntax_tests/data/ppx/react/expected/interface.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/interface.res.txt @@ -1,7 +1,7 @@ module A = { @res.jsxComponentProps type props<'x> = {x: 'x} - let make = ({x, _}: props<_>) => React.string(x) + let make = ({x, _}: props<_>): React.element => React.string(x) let make = { let \"Interface$A" = (props: props<_>) => make(props) \"Interface$A" @@ -12,7 +12,7 @@ module NoProps = { @res.jsxComponentProps type props = {} - let make = (_: props) => ReactDOM.jsx("div", {}) + let make = (_: props): React.element => ReactDOM.jsx("div", {}) let make = { let \"Interface$NoProps" = props => make(props) diff --git a/tests/syntax_tests/data/ppx/react/expected/interfaceWithRef.res.txt b/tests/syntax_tests/data/ppx/react/expected/interfaceWithRef.res.txt index eb7616f71f..de8c1284c0 100644 --- a/tests/syntax_tests/data/ppx/react/expected/interfaceWithRef.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/interfaceWithRef.res.txt @@ -1,11 +1,9 @@ @res.jsxComponentProps type props<'x, 'ref> = {x: 'x, ref?: 'ref} -let make = ( - {x, _}: props, - ref: Js.Nullable.t, -) => { - let _ = ref->Js.Nullable.toOption->Belt.Option.map(ReactDOM.Ref.domRef) - React.string(x) -} +let make = ({x, _}: props): React.element => + (ref: Js.Nullable.t) => { + let _ = ref->Js.Nullable.toOption->Belt.Option.map(ReactDOM.Ref.domRef) + React.string(x) + } let make = React.forwardRef({ let \"InterfaceWithRef" = (props: props<_>, ref) => make(props, ref) \"InterfaceWithRef" diff --git a/tests/syntax_tests/data/ppx/react/expected/mangleKeyword.res.txt b/tests/syntax_tests/data/ppx/react/expected/mangleKeyword.res.txt index 4413b38798..173a9dd60f 100644 --- a/tests/syntax_tests/data/ppx/react/expected/mangleKeyword.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/mangleKeyword.res.txt @@ -4,7 +4,8 @@ module C4A0 = { @res.jsxComponentProps type props<'T_open, 'T_type> = {@as("open") _open: 'T_open, @as("type") _type: 'T_type} - let make = ({@as("open") _open, @as("type") _type, _}: props<_, string>) => React.string(_open) + let make = ({@as("open") _open, @as("type") _type, _}: props<_, string>): React.element => + React.string(_open) let make = { let \"MangleKeyword$C4A0" = (props: props<_>) => make(props) diff --git a/tests/syntax_tests/data/ppx/react/expected/nested.res.txt b/tests/syntax_tests/data/ppx/react/expected/nested.res.txt index 0775867aa9..70f8efde0e 100644 --- a/tests/syntax_tests/data/ppx/react/expected/nested.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/nested.res.txt @@ -1,12 +1,12 @@ module Outer = { @res.jsxComponentProps type props = {} - let make = (_: props) => { + let make = (_: props): React.element => { module Inner = { @res.jsxComponentProps type props = {} - let make = (_: props) => ReactDOM.jsx("div", {}) + let make = (_: props): React.element => ReactDOM.jsx("div", {}) let make = { let \"Nested$Outer" = props => make(props) diff --git a/tests/syntax_tests/data/ppx/react/expected/newtype.res.txt b/tests/syntax_tests/data/ppx/react/expected/newtype.res.txt index fb513bf122..f26904a16b 100644 --- a/tests/syntax_tests/data/ppx/react/expected/newtype.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/newtype.res.txt @@ -4,7 +4,7 @@ module V4A = { @res.jsxComponentProps type props<'a, 'b, 'c> = {a: 'a, b: 'b, c: 'c} - let make = (type a, {a, b, c, _}: props>, 'a>) => + let make = (type a, {a, b, c, _}: props>, 'a>): React.element => ReactDOM.jsx("div", {}) let make = { let \"Newtype$V4A" = (props: props<_>) => make(props) @@ -17,7 +17,8 @@ module V4A1 = { @res.jsxComponentProps type props<'a, 'b, 'c> = {a: 'a, b: 'b, c: 'c} - let make = (type x y, {a, b, c, _}: props, 'a>) => ReactDOM.jsx("div", {}) + let make = (type x y, {a, b, c, _}: props, 'a>): React.element => + ReactDOM.jsx("div", {}) let make = { let \"Newtype$V4A1" = (props: props<_>) => make(props) @@ -33,7 +34,7 @@ module V4A2 = { @res.jsxComponentProps type props<'foo> = {foo: 'foo} - let make = (type a, {foo: (foo: module(T with type t = a)), _}: props<_>) => { + let make = (type a, {foo: (foo: module(T with type t = a)), _}: props<_>): React.element => { module T = unpack(foo) ReactDOM.jsx("div", {}) } @@ -48,7 +49,7 @@ module V4A3 = { @res.jsxComponentProps type props<'foo> = {foo: 'foo} - let make = (type a, {foo, _}: props<_>) => { + let make = (type a, {foo, _}: props<_>): React.element => { module T = unpack(foo: T with type t = a) foo } @@ -61,7 +62,7 @@ module V4A3 = { @res.jsxComponentProps type props<'x, 'q> = {x: 'x, q: 'q} -let make = ({x, q, _}: props<('a, 'b), 'a>) => [fst(x), q] +let make = ({x, q, _}: props<('a, 'b), 'a>): React.element => [fst(x), q] let make = { let \"Newtype" = (props: props<_>) => make(props) @@ -74,7 +75,7 @@ module Uncurried = { @res.jsxComponentProps type props<'foo> = {foo?: 'foo} - let make = (type a, {?foo, _}: props<_>) => React.null + let make = (type a, {?foo, _}: props<_>): React.element => React.null let make = { let \"Newtype$Uncurried" = (props: props<_>) => make(props) diff --git a/tests/syntax_tests/data/ppx/react/expected/noPropsWithKey.res.txt b/tests/syntax_tests/data/ppx/react/expected/noPropsWithKey.res.txt index 21d9d0c417..f149c9234e 100644 --- a/tests/syntax_tests/data/ppx/react/expected/noPropsWithKey.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/noPropsWithKey.res.txt @@ -4,7 +4,7 @@ module V4CA = { @res.jsxComponentProps type props = {} - let make = (_: props) => ReactDOM.jsx("div", {}) + let make = (_: props): React.element => ReactDOM.jsx("div", {}) let make = { let \"NoPropsWithKey$V4CA" = props => make(props) @@ -24,7 +24,7 @@ module V4C = { @res.jsxComponentProps type props = {} - let make = (_: props) => + let make = (_: props): React.element => React.jsxs( React.jsxFragment, { diff --git a/tests/syntax_tests/data/ppx/react/expected/optimizeAutomaticMode.res.txt b/tests/syntax_tests/data/ppx/react/expected/optimizeAutomaticMode.res.txt index 19a34b8d05..690eb73eba 100644 --- a/tests/syntax_tests/data/ppx/react/expected/optimizeAutomaticMode.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/optimizeAutomaticMode.res.txt @@ -7,7 +7,7 @@ module User = { @res.jsxComponentProps type props<'doctor> = {doctor: 'doctor} - let make = ({doctor, _}: props<_>) => { + let make = ({doctor, _}: props<_>): React.element => { ReactDOM.jsx("h1", {id: "h1", children: ?ReactDOM.someElement({React.string(format(doctor))})}) } let make = { diff --git a/tests/syntax_tests/data/ppx/react/expected/sharedProps.res.txt b/tests/syntax_tests/data/ppx/react/expected/sharedProps.res.txt index a878b7e544..a24343e61f 100644 --- a/tests/syntax_tests/data/ppx/react/expected/sharedProps.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/sharedProps.res.txt @@ -3,7 +3,7 @@ module V4A1 = { type props = sharedProps - let make = ({x, y, _}: props) => React.string(x ++ y) + let make = ({x, y, _}: props): React.element => React.string(x ++ y) let make = { let \"SharedProps$V4A1" = props => make(props) @@ -14,7 +14,7 @@ module V4A1 = { module V4A2 = { type props<'a> = sharedProps<'a> - let make = ({x, y, _}: props<_>) => React.string(x ++ y) + let make = ({x, y, _}: props<_>): React.element => React.string(x ++ y) let make = { let \"SharedProps$V4A2" = (props: props<_>) => make(props) @@ -25,7 +25,7 @@ module V4A2 = { module V4A3 = { type props<'a> = sharedProps - let make = ({x, y, _}: props<_>) => React.string(x ++ y) + let make = ({x, y, _}: props<_>): React.element => React.string(x ++ y) let make = { let \"SharedProps$V4A3" = (props: props<_>) => make(props) @@ -36,7 +36,7 @@ module V4A3 = { module V4A4 = { type props = sharedProps - let make = ({x, y, _}: props) => React.string(x ++ y) + let make = ({x, y, _}: props): React.element => React.string(x ++ y) let make = { let \"SharedProps$V4A4" = props => make(props) diff --git a/tests/syntax_tests/data/ppx/react/expected/sharedPropsWithProps.res.txt b/tests/syntax_tests/data/ppx/react/expected/sharedPropsWithProps.res.txt index 72072f8985..b7031c6173 100644 --- a/tests/syntax_tests/data/ppx/react/expected/sharedPropsWithProps.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/sharedPropsWithProps.res.txt @@ -6,7 +6,7 @@ module V4A1 = { type props = sharedProps let make = props => React.string(props.x ++ props.y) let make = { - let \"SharedPropsWithProps$V4A1" = props => make(props) + let \"SharedPropsWithProps$V4A1" = (props): React.element => make(props) \"SharedPropsWithProps$V4A1" } } @@ -15,7 +15,7 @@ module V4A2 = { type props = sharedProps let make = (props: props) => React.string(props.x ++ props.y) let make = { - let \"SharedPropsWithProps$V4A2" = (props: props) => make(props) + let \"SharedPropsWithProps$V4A2" = (props: props): React.element => make(props) \"SharedPropsWithProps$V4A2" } } @@ -24,7 +24,7 @@ module V4A3 = { type props<'a> = sharedProps<'a> let make = ({x, y}: props<_>) => React.string(x ++ y) let make = { - let \"SharedPropsWithProps$V4A3" = (props: props<_>) => make(props) + let \"SharedPropsWithProps$V4A3" = (props: props<_>): React.element => make(props) \"SharedPropsWithProps$V4A3" } } @@ -33,7 +33,7 @@ module V4A4 = { type props<'a> = sharedProps let make = ({x, y}: props<_>) => React.string(x ++ y) let make = { - let \"SharedPropsWithProps$V4A4" = (props: props<_>) => make(props) + let \"SharedPropsWithProps$V4A4" = (props: props<_>): React.element => make(props) \"SharedPropsWithProps$V4A4" } } @@ -45,7 +45,7 @@ module V4A5 = { ReactDOM.jsx("div", {children: ?ReactDOM.someElement({React.int(a)})}) } let make = { - let \"SharedPropsWithProps$V4A5" = (props: props<_>) => Jsx.promise(make(props)) + let \"SharedPropsWithProps$V4A5" = (props: props<_>): React.element => Jsx.promise(make(props)) \"SharedPropsWithProps$V4A5" } } @@ -59,7 +59,7 @@ module V4A6 = { } } let make = { - let \"SharedPropsWithProps$V4A6" = (props: props<_>) => Jsx.promise(make(props)) + let \"SharedPropsWithProps$V4A6" = (props: props<_>): React.element => Jsx.promise(make(props)) \"SharedPropsWithProps$V4A6" } } @@ -71,7 +71,8 @@ module V4A7 = { React.int(props.count) } let make = { - let \"SharedPropsWithProps$V4A7" = @directive("'use memo'") props => make(props) + let \"SharedPropsWithProps$V4A7" = + @directive("'use memo'") (props): React.element => make(props) \"SharedPropsWithProps$V4A7" } } diff --git a/tests/syntax_tests/data/ppx/react/expected/topLevel.res.txt b/tests/syntax_tests/data/ppx/react/expected/topLevel.res.txt index cbb6a01b6b..a137954ec0 100644 --- a/tests/syntax_tests/data/ppx/react/expected/topLevel.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/topLevel.res.txt @@ -4,7 +4,7 @@ module V4A = { @res.jsxComponentProps type props<'a, 'b> = {a: 'a, b: 'b} - let make = ({a, b, _}: props<_, _>) => { + let make = ({a, b, _}: props<_, _>): React.element => { Js.log("This function should be named 'TopLevel.react'") ReactDOM.jsx("div", {}) } diff --git a/tests/syntax_tests/data/ppx/react/expected/typeConstraint.res.txt b/tests/syntax_tests/data/ppx/react/expected/typeConstraint.res.txt index c612921f06..dbec7ea6a0 100644 --- a/tests/syntax_tests/data/ppx/react/expected/typeConstraint.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/typeConstraint.res.txt @@ -4,7 +4,7 @@ module V4A = { @res.jsxComponentProps type props<'a, 'b> = {a: 'a, b: 'b} - let make = (type a, {a, b, _}: props<_, _>) => ReactDOM.jsx("div", {}) + let make = (type a, {a, b, _}: props<_, _>): React.element => ReactDOM.jsx("div", {}) let make = { let \"TypeConstraint$V4A" = (props: props<_>) => make(props) diff --git a/tests/syntax_tests/data/ppx/react/expected/uncurriedProps.res.txt b/tests/syntax_tests/data/ppx/react/expected/uncurriedProps.res.txt index 3cd05a73c2..9ffb497a4d 100644 --- a/tests/syntax_tests/data/ppx/react/expected/uncurriedProps.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/uncurriedProps.res.txt @@ -2,7 +2,7 @@ @res.jsxComponentProps type props<'a> = {a?: 'a} -let make = ({a: ?__a, _}: props unit>) => { +let make = ({a: ?__a, _}: props unit>): React.element => { let a = switch __a { | Some(a) => a | None => () => () @@ -30,7 +30,7 @@ module Foo = { @res.jsxComponentProps type props<'callback> = {callback?: 'callback} - let make = ({callback: ?__callback, _}: props<(string, bool, bool) => unit>) => { + let make = ({callback: ?__callback, _}: props<(string, bool, bool) => unit>): React.element => { let callback = switch __callback { | Some(callback) => callback | None => (_, _, _) => () @@ -51,7 +51,7 @@ module Bar = { @res.jsxComponentProps type props = {} - let make = (_: props) => React.jsx(Foo.make, {callback: {(_, _, _) => ()}}) + let make = (_: props): React.element => React.jsx(Foo.make, {callback: {(_, _, _) => ()}}) let make = { let \"UncurriedProps$Bar" = props => make(props) diff --git a/tests/syntax_tests/data/ppx/react/expected/v4.res.txt b/tests/syntax_tests/data/ppx/react/expected/v4.res.txt index 001501391f..0dd67411e7 100644 --- a/tests/syntax_tests/data/ppx/react/expected/v4.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/v4.res.txt @@ -1,6 +1,6 @@ @res.jsxComponentProps type props<'x, 'y> = {x: 'x, y: 'y} // Component with type constraint -let make = ({x, y, _}: props) => React.string(x ++ y) +let make = ({x, y, _}: props): React.element => React.string(x ++ y) let make = { let \"V4" = (props: props<_>) => make(props) \"V4" @@ -11,7 +11,7 @@ module AnotherName = { type // Component with another name than "make" props<'x> = {x: 'x} - let anotherName = ({x, _}: props<_>) => React.string(x) + let anotherName = ({x, _}: props<_>): React.element => React.string(x) let anotherName = { let \"V4$AnotherName$anotherName" = (props: props<_>) => anotherName(props) @@ -23,7 +23,7 @@ module Uncurried = { @res.jsxComponentProps type props<'x> = {x: 'x} - let make = ({x, _}: props<_>) => React.string(x) + let make = ({x, _}: props<_>): React.element => React.string(x) let make = { let \"V4$Uncurried" = (props: props<_>) => make(props) @@ -58,7 +58,7 @@ module Rec = { let rec make = { @merlin.focus - let \"make$Internal" = (_: props) => { + let \"make$Internal" = (_: props): React.element => { make(({}: props)) } let make = { @@ -76,7 +76,7 @@ module Rec1 = { let rec make = { @merlin.focus - let \"make$Internal" = (_: props) => { + let \"make$Internal" = (_: props): React.element => { React.null } let make = { @@ -94,7 +94,7 @@ module Rec2 = { let rec make = { @merlin.focus - let \"make$Internal" = (_: props) => { + let \"make$Internal" = (_: props): React.element => { mm(({}: props)) } let make = { diff --git a/tests/tests/src/alias_default_value_test.res b/tests/tests/src/alias_default_value_test.res index 2ed6dfc4b1..b2419aef38 100644 --- a/tests/tests/src/alias_default_value_test.res +++ b/tests/tests/src/alias_default_value_test.res @@ -41,7 +41,7 @@ module C6 = { } @react.component - let make = (~comp as module(Comp: Comp), ~x as (a, b)) => Comp.xx + let make = (~comp as module(Comp: Comp), ~x as (a, b)) => Comp.xx->React.int } module C7 = { diff --git a/tests/tests/src/jsxv4_newtype.mjs b/tests/tests/src/jsxv4_newtype.mjs index 6e12bf12b9..a6e2b5a2dc 100644 --- a/tests/tests/src/jsxv4_newtype.mjs +++ b/tests/tests/src/jsxv4_newtype.mjs @@ -26,7 +26,7 @@ let V4A2 = { }; function Jsxv4_newtype$V4A3(props) { - return props.foo; + return null; } let V4A3 = { diff --git a/tests/tests/src/jsxv4_newtype.res b/tests/tests/src/jsxv4_newtype.res index 64b48c9823..141d014723 100644 --- a/tests/tests/src/jsxv4_newtype.res +++ b/tests/tests/src/jsxv4_newtype.res @@ -28,6 +28,6 @@ module V4A3 = { @react.component let make = (type a, ~foo) => { module T = unpack(foo: T with type t = a) - foo + React.null } }