From 2fc6d8f8e30c694673b51a187772242d11f3427c Mon Sep 17 00:00:00 2001 From: mununki Date: Tue, 12 Sep 2023 10:20:42 +0900 Subject: [PATCH 01/10] add tests --- jscomp/syntax/tests/ppx/react/asyncAwait.res | 7 +++++++ .../tests/ppx/react/expected/asyncAwait.res.txt | 12 ++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 jscomp/syntax/tests/ppx/react/asyncAwait.res create mode 100644 jscomp/syntax/tests/ppx/react/expected/asyncAwait.res.txt diff --git a/jscomp/syntax/tests/ppx/react/asyncAwait.res b/jscomp/syntax/tests/ppx/react/asyncAwait.res new file mode 100644 index 0000000000..a785b9e088 --- /dev/null +++ b/jscomp/syntax/tests/ppx/react/asyncAwait.res @@ -0,0 +1,7 @@ +let f = a => Js.Promise.resolve(a + a) + +@react.component +let make = async (~a) => { + let a = await f(a) +
{React.int(a)}
+} diff --git a/jscomp/syntax/tests/ppx/react/expected/asyncAwait.res.txt b/jscomp/syntax/tests/ppx/react/expected/asyncAwait.res.txt new file mode 100644 index 0000000000..99854c8474 --- /dev/null +++ b/jscomp/syntax/tests/ppx/react/expected/asyncAwait.res.txt @@ -0,0 +1,12 @@ +let f = a => Js.Promise.resolve(a + a) +type props<'a> = {a: 'a} + +let make = ({a, _}: props<_>) => { + let a = await f(a) + ReactDOM.jsx("div", {children: ?ReactDOM.someElement({React.int(a)})}) +} +let make = { + let \"AsyncAwait" = (props: props<_>) => make(props) + + \"AsyncAwait" +} From 38239bc0b8aec85a82202e34d99a19911cb7aeef Mon Sep 17 00:00:00 2001 From: mununki Date: Tue, 12 Sep 2023 19:16:09 +0900 Subject: [PATCH 02/10] support async in JSX ppx --- CHANGELOG.md | 1 + jscomp/syntax/src/react_jsx_common.ml | 13 +++++++++++++ jscomp/syntax/src/reactjs_jsx_v4.ml | 8 ++++++++ .../tests/ppx/react/expected/asyncAwait.res.txt | 2 +- 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61e2f61a6b..a657d6846f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - Add builtin abstract types for File and Blob APIs. https://github.com/rescript-lang/rescript-compiler/pull/6383 - Untagged variants: Support `promise`, RegExes, Dates, File and Blob. https://github.com/rescript-lang/rescript-compiler/pull/6383 - Support aliased types as payloads to untagged variants. https://github.com/rescript-lang/rescript-compiler/pull/6394 +- Support the async component for React Server Component in JSX ppx #### :nail_care: Polish diff --git a/jscomp/syntax/src/react_jsx_common.ml b/jscomp/syntax/src/react_jsx_common.ml index 0cfe798a78..c951bebd46 100644 --- a/jscomp/syntax/src/react_jsx_common.ml +++ b/jscomp/syntax/src/react_jsx_common.ml @@ -63,3 +63,16 @@ let removeArity binding = | _ -> expr in {binding with pvb_expr = removeArityRecord binding.pvb_expr} + +let add_async_attribute ~async (body : Parsetree.expression) = + if async then + { + body with + pexp_attributes = + ({txt = "res.async"; loc = Location.none}, PStr []) + :: body.pexp_attributes; + } + else body + +let is_async : Parsetree.attribute -> bool = + fun ({txt}, _) -> txt = "async" || txt = "res.async" diff --git a/jscomp/syntax/src/reactjs_jsx_v4.ml b/jscomp/syntax/src/reactjs_jsx_v4.ml index a80da10366..6c73da0949 100644 --- a/jscomp/syntax/src/reactjs_jsx_v4.ml +++ b/jscomp/syntax/src/reactjs_jsx_v4.ml @@ -909,6 +909,11 @@ let mapBinding ~config ~emptyLoc ~pstr_loc ~fileName ~recFlag binding = let bindingWrapper, hasForwardRef, expression = modifiedBinding ~bindingLoc ~bindingPatLoc ~fnName binding in + let isAsync = + Ext_list.find_first binding.pvb_expr.pexp_attributes + React_jsx_common.is_async + |> Option.is_some + in (* do stuff here! *) let namedArgList, newtypes, _typeConstraints = recursivelyTransformNamedArgsForMake @@ -1083,6 +1088,9 @@ let mapBinding ~config ~emptyLoc ~pstr_loc ~fileName ~recFlag binding = | _ -> [Typ.any ()])))) expression in + let expression = + React_jsx_common.add_async_attribute ~async:isAsync expression + in let expression = (* Add new tupes (type a,b,c) to make's definition *) newtypes diff --git a/jscomp/syntax/tests/ppx/react/expected/asyncAwait.res.txt b/jscomp/syntax/tests/ppx/react/expected/asyncAwait.res.txt index 99854c8474..640dc5a2e0 100644 --- a/jscomp/syntax/tests/ppx/react/expected/asyncAwait.res.txt +++ b/jscomp/syntax/tests/ppx/react/expected/asyncAwait.res.txt @@ -1,7 +1,7 @@ let f = a => Js.Promise.resolve(a + a) type props<'a> = {a: 'a} -let make = ({a, _}: props<_>) => { +let make = async ({a, _}: props<_>) => { let a = await f(a) ReactDOM.jsx("div", {children: ?ReactDOM.someElement({React.int(a)})}) } From 2c90fb4074452483e0ba51ae309695d8db50bd46 Mon Sep 17 00:00:00 2001 From: mununki Date: Tue, 12 Sep 2023 19:20:24 +0900 Subject: [PATCH 03/10] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a657d6846f..43e2023ef6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,7 @@ - Add builtin abstract types for File and Blob APIs. https://github.com/rescript-lang/rescript-compiler/pull/6383 - Untagged variants: Support `promise`, RegExes, Dates, File and Blob. https://github.com/rescript-lang/rescript-compiler/pull/6383 - Support aliased types as payloads to untagged variants. https://github.com/rescript-lang/rescript-compiler/pull/6394 -- Support the async component for React Server Component in JSX ppx +- Support the async component for React Server Component in JSX V4. https://github.com/rescript-lang/rescript-compiler/pull/6399 #### :nail_care: Polish From efed71f5c1faf6ab7ecc722957c2f7bcb1439d00 Mon Sep 17 00:00:00 2001 From: mununki Date: Tue, 12 Sep 2023 21:53:35 +0900 Subject: [PATCH 04/10] convert async component type --- jscomp/others/jsxPPXReactSupportC.res | 4 ++++ jscomp/others/jsxPPXReactSupportU.res | 4 ++++ jscomp/syntax/src/react_jsx_common.ml | 10 ++++++++++ jscomp/syntax/src/reactjs_jsx_v4.ml | 11 +++++++++++ .../tests/ppx/react/expected/asyncAwait.res.txt | 2 +- 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/jscomp/others/jsxPPXReactSupportC.res b/jscomp/others/jsxPPXReactSupportC.res index 4930472ed4..6f79a15481 100644 --- a/jscomp/others/jsxPPXReactSupportC.res +++ b/jscomp/others/jsxPPXReactSupportC.res @@ -48,3 +48,7 @@ let createElementWithKey = (~key=?, component, props) => let createElementVariadicWithKey = (~key=?, component, props, elements) => createElementVariadic(component, addKeyProp(~key?, props), elements) + +external asyncComponent: ('props => promise) => Jsx.component< + 'props, +> = "%identity" \ No newline at end of file diff --git a/jscomp/others/jsxPPXReactSupportU.res b/jscomp/others/jsxPPXReactSupportU.res index 8987f68e4d..1bec7ea6e6 100644 --- a/jscomp/others/jsxPPXReactSupportU.res +++ b/jscomp/others/jsxPPXReactSupportU.res @@ -50,3 +50,7 @@ let createElementWithKey = (~key=?, component, props) => let createElementVariadicWithKey = (~key=?, component, props, elements) => createElementVariadic(component, addKeyProp(~key?, props), elements) + +external asyncComponent: ('props => promise) => Jsx.component< + 'props, +> = "%identity" \ No newline at end of file diff --git a/jscomp/syntax/src/react_jsx_common.ml b/jscomp/syntax/src/react_jsx_common.ml index c951bebd46..d751b21f05 100644 --- a/jscomp/syntax/src/react_jsx_common.ml +++ b/jscomp/syntax/src/react_jsx_common.ml @@ -76,3 +76,13 @@ let add_async_attribute ~async (body : Parsetree.expression) = let is_async : Parsetree.attribute -> bool = fun ({txt}, _) -> txt = "async" || txt = "res.async" + +let async_component expr = + let open Ast_helper in + Exp.apply + (Exp.ident + { + loc = Location.none; + txt = Ldot (Lident "JsxPPXReactSupport", "asyncComponent"); + }) + [(Nolabel, expr)] diff --git a/jscomp/syntax/src/reactjs_jsx_v4.ml b/jscomp/syntax/src/reactjs_jsx_v4.ml index 6c73da0949..a1d0c1cc54 100644 --- a/jscomp/syntax/src/reactjs_jsx_v4.ml +++ b/jscomp/syntax/src/reactjs_jsx_v4.ml @@ -969,6 +969,17 @@ let mapBinding ~config ~emptyLoc ~pstr_loc ~fileName ~recFlag binding = |> Ast_uncurried.uncurriedFun ~loc:fullExpression.pexp_loc ~arity:1 else fullExpression in + let fullExpression = + if isAsync then + Exp.apply + (Exp.ident + { + loc = Location.none; + txt = Ldot (Lident "JsxPPXReactSupport", "asyncComponent"); + }) + [(Nolabel, fullExpression)] + else fullExpression + in let fullExpression = match fullModuleName with | "" -> fullExpression diff --git a/jscomp/syntax/tests/ppx/react/expected/asyncAwait.res.txt b/jscomp/syntax/tests/ppx/react/expected/asyncAwait.res.txt index 640dc5a2e0..6b18e4f91f 100644 --- a/jscomp/syntax/tests/ppx/react/expected/asyncAwait.res.txt +++ b/jscomp/syntax/tests/ppx/react/expected/asyncAwait.res.txt @@ -6,7 +6,7 @@ let make = async ({a, _}: props<_>) => { ReactDOM.jsx("div", {children: ?ReactDOM.someElement({React.int(a)})}) } let make = { - let \"AsyncAwait" = (props: props<_>) => make(props) + let \"AsyncAwait" = JsxPPXReactSupport.asyncComponent((props: props<_>) => make(props)) \"AsyncAwait" } From 8fbaee44a7b645aa51c9b83dd8146ec49d1cc890 Mon Sep 17 00:00:00 2001 From: mununki Date: Tue, 12 Sep 2023 21:55:11 +0900 Subject: [PATCH 05/10] eof --- jscomp/others/jsxPPXReactSupportC.res | 2 +- jscomp/others/jsxPPXReactSupportU.res | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jscomp/others/jsxPPXReactSupportC.res b/jscomp/others/jsxPPXReactSupportC.res index 6f79a15481..85cf3ae8d4 100644 --- a/jscomp/others/jsxPPXReactSupportC.res +++ b/jscomp/others/jsxPPXReactSupportC.res @@ -51,4 +51,4 @@ let createElementVariadicWithKey = (~key=?, component, props, elements) => external asyncComponent: ('props => promise) => Jsx.component< 'props, -> = "%identity" \ No newline at end of file +> = "%identity" diff --git a/jscomp/others/jsxPPXReactSupportU.res b/jscomp/others/jsxPPXReactSupportU.res index 1bec7ea6e6..a7d417d71b 100644 --- a/jscomp/others/jsxPPXReactSupportU.res +++ b/jscomp/others/jsxPPXReactSupportU.res @@ -53,4 +53,4 @@ let createElementVariadicWithKey = (~key=?, component, props, elements) => external asyncComponent: ('props => promise) => Jsx.component< 'props, -> = "%identity" \ No newline at end of file +> = "%identity" From a0402ae0b20cff57e115f00a3ffe316b11b313c3 Mon Sep 17 00:00:00 2001 From: mununki Date: Wed, 13 Sep 2023 04:23:30 +0900 Subject: [PATCH 06/10] use asyncComponent func --- jscomp/syntax/src/react_jsx_common.ml | 20 +++++++++++--------- jscomp/syntax/src/reactjs_jsx_v4.ml | 10 +--------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/jscomp/syntax/src/react_jsx_common.ml b/jscomp/syntax/src/react_jsx_common.ml index d751b21f05..1e199d1d15 100644 --- a/jscomp/syntax/src/react_jsx_common.ml +++ b/jscomp/syntax/src/react_jsx_common.ml @@ -77,12 +77,14 @@ let add_async_attribute ~async (body : Parsetree.expression) = let is_async : Parsetree.attribute -> bool = fun ({txt}, _) -> txt = "async" || txt = "res.async" -let async_component expr = - let open Ast_helper in - Exp.apply - (Exp.ident - { - loc = Location.none; - txt = Ldot (Lident "JsxPPXReactSupport", "asyncComponent"); - }) - [(Nolabel, expr)] +let async_component ~async expr = + if async then + let open Ast_helper in + Exp.apply + (Exp.ident + { + loc = Location.none; + txt = Ldot (Lident "JsxPPXReactSupport", "asyncComponent"); + }) + [(Nolabel, expr)] + else expr diff --git a/jscomp/syntax/src/reactjs_jsx_v4.ml b/jscomp/syntax/src/reactjs_jsx_v4.ml index a1d0c1cc54..5837aef54a 100644 --- a/jscomp/syntax/src/reactjs_jsx_v4.ml +++ b/jscomp/syntax/src/reactjs_jsx_v4.ml @@ -970,15 +970,7 @@ let mapBinding ~config ~emptyLoc ~pstr_loc ~fileName ~recFlag binding = else fullExpression in let fullExpression = - if isAsync then - Exp.apply - (Exp.ident - { - loc = Location.none; - txt = Ldot (Lident "JsxPPXReactSupport", "asyncComponent"); - }) - [(Nolabel, fullExpression)] - else fullExpression + React_jsx_common.async_component ~async:isAsync fullExpression in let fullExpression = match fullModuleName with From e8964919ed1fc6bac2faa74e2f2702521aea53fc Mon Sep 17 00:00:00 2001 From: mununki Date: Mon, 2 Oct 2023 02:00:49 +0900 Subject: [PATCH 07/10] fix polymorphic type inference --- jscomp/others/jsxPPXReactSupportC.res | 4 +-- jscomp/others/jsxPPXReactSupportU.res | 4 +-- jscomp/syntax/src/reactjs_jsx_v4.ml | 6 ++-- jscomp/syntax/tests/ppx/react/asyncAwait.res | 20 ++++++++--- .../ppx/react/expected/asyncAwait.res.txt | 33 +++++++++++++++---- 5 files changed, 47 insertions(+), 20 deletions(-) diff --git a/jscomp/others/jsxPPXReactSupportC.res b/jscomp/others/jsxPPXReactSupportC.res index 85cf3ae8d4..a024d44718 100644 --- a/jscomp/others/jsxPPXReactSupportC.res +++ b/jscomp/others/jsxPPXReactSupportC.res @@ -49,6 +49,4 @@ let createElementWithKey = (~key=?, component, props) => let createElementVariadicWithKey = (~key=?, component, props, elements) => createElementVariadic(component, addKeyProp(~key?, props), elements) -external asyncComponent: ('props => promise) => Jsx.component< - 'props, -> = "%identity" +external asyncComponent: promise => Jsx.element = "%identity" diff --git a/jscomp/others/jsxPPXReactSupportU.res b/jscomp/others/jsxPPXReactSupportU.res index a7d417d71b..a850efc120 100644 --- a/jscomp/others/jsxPPXReactSupportU.res +++ b/jscomp/others/jsxPPXReactSupportU.res @@ -51,6 +51,4 @@ let createElementWithKey = (~key=?, component, props) => let createElementVariadicWithKey = (~key=?, component, props, elements) => createElementVariadic(component, addKeyProp(~key?, props), elements) -external asyncComponent: ('props => promise) => Jsx.component< - 'props, -> = "%identity" +external asyncComponent: promise => Jsx.element = "%identity" diff --git a/jscomp/syntax/src/reactjs_jsx_v4.ml b/jscomp/syntax/src/reactjs_jsx_v4.ml index 5837aef54a..dbc8a85209 100644 --- a/jscomp/syntax/src/reactjs_jsx_v4.ml +++ b/jscomp/syntax/src/reactjs_jsx_v4.ml @@ -947,6 +947,9 @@ let mapBinding ~config ~emptyLoc ~pstr_loc ~fileName ~recFlag binding = (Pat.var @@ Location.mknoloc "props") (Typ.constr (Location.mknoloc @@ Lident "props") [Typ.any ()]) in + let innerExpression = + React_jsx_common.async_component ~async:isAsync innerExpression + in let fullExpression = (* React component name should start with uppercase letter *) (* let make = { let \"App" = props => make(props); \"App" } *) @@ -969,9 +972,6 @@ let mapBinding ~config ~emptyLoc ~pstr_loc ~fileName ~recFlag binding = |> Ast_uncurried.uncurriedFun ~loc:fullExpression.pexp_loc ~arity:1 else fullExpression in - let fullExpression = - React_jsx_common.async_component ~async:isAsync fullExpression - in let fullExpression = match fullModuleName with | "" -> fullExpression diff --git a/jscomp/syntax/tests/ppx/react/asyncAwait.res b/jscomp/syntax/tests/ppx/react/asyncAwait.res index a785b9e088..9a253a04a2 100644 --- a/jscomp/syntax/tests/ppx/react/asyncAwait.res +++ b/jscomp/syntax/tests/ppx/react/asyncAwait.res @@ -1,7 +1,19 @@ let f = a => Js.Promise.resolve(a + a) -@react.component -let make = async (~a) => { - let a = await f(a) -
{React.int(a)}
+module C0 = { + @react.component + let make = async (~a) => { + let a = await f(a) +
{React.int(a)}
+ } } + +module C1 = { + @react.component + let make = async (~status) => { + switch status { + | #on => React.string("on") + | #off => React.string("off") + } + } +} \ No newline at end of file diff --git a/jscomp/syntax/tests/ppx/react/expected/asyncAwait.res.txt b/jscomp/syntax/tests/ppx/react/expected/asyncAwait.res.txt index 6b18e4f91f..d8d86dccca 100644 --- a/jscomp/syntax/tests/ppx/react/expected/asyncAwait.res.txt +++ b/jscomp/syntax/tests/ppx/react/expected/asyncAwait.res.txt @@ -1,12 +1,31 @@ let f = a => Js.Promise.resolve(a + a) -type props<'a> = {a: 'a} -let make = async ({a, _}: props<_>) => { - let a = await f(a) - ReactDOM.jsx("div", {children: ?ReactDOM.someElement({React.int(a)})}) +module C0 = { + type props<'a> = {a: 'a} + + let make = async ({a, _}: props<_>) => { + let a = await f(a) + ReactDOM.jsx("div", {children: ?ReactDOM.someElement({React.int(a)})}) + } + let make = { + let \"AsyncAwait$C0" = (props: props<_>) => JsxPPXReactSupport.asyncComponent(make(props)) + + \"AsyncAwait$C0" + } } -let make = { - let \"AsyncAwait" = JsxPPXReactSupport.asyncComponent((props: props<_>) => make(props)) - \"AsyncAwait" +module C1 = { + type props<'status> = {status: 'status} + + let make = async ({status, _}: props<_>) => { + switch status { + | #on => React.string("on") + | #off => React.string("off") + } + } + let make = { + let \"AsyncAwait$C1" = (props: props<_>) => JsxPPXReactSupport.asyncComponent(make(props)) + + \"AsyncAwait$C1" + } } From 8126a139ccb0e2458423aa298fda34aea2ee4460 Mon Sep 17 00:00:00 2001 From: mununki Date: Tue, 3 Oct 2023 21:17:26 +0900 Subject: [PATCH 08/10] remove duplicated function --- jscomp/{frontend => ml}/ast_async.ml | 0 jscomp/syntax/src/react_jsx_common.ml | 10 ---------- jscomp/syntax/src/reactjs_jsx_v4.ml | 4 +--- 3 files changed, 1 insertion(+), 13 deletions(-) rename jscomp/{frontend => ml}/ast_async.ml (100%) diff --git a/jscomp/frontend/ast_async.ml b/jscomp/ml/ast_async.ml similarity index 100% rename from jscomp/frontend/ast_async.ml rename to jscomp/ml/ast_async.ml diff --git a/jscomp/syntax/src/react_jsx_common.ml b/jscomp/syntax/src/react_jsx_common.ml index 1e199d1d15..08bd1c1017 100644 --- a/jscomp/syntax/src/react_jsx_common.ml +++ b/jscomp/syntax/src/react_jsx_common.ml @@ -64,16 +64,6 @@ let removeArity binding = in {binding with pvb_expr = removeArityRecord binding.pvb_expr} -let add_async_attribute ~async (body : Parsetree.expression) = - if async then - { - body with - pexp_attributes = - ({txt = "res.async"; loc = Location.none}, PStr []) - :: body.pexp_attributes; - } - else body - let is_async : Parsetree.attribute -> bool = fun ({txt}, _) -> txt = "async" || txt = "res.async" diff --git a/jscomp/syntax/src/reactjs_jsx_v4.ml b/jscomp/syntax/src/reactjs_jsx_v4.ml index dbc8a85209..fa867e2c9d 100644 --- a/jscomp/syntax/src/reactjs_jsx_v4.ml +++ b/jscomp/syntax/src/reactjs_jsx_v4.ml @@ -1091,9 +1091,7 @@ let mapBinding ~config ~emptyLoc ~pstr_loc ~fileName ~recFlag binding = | _ -> [Typ.any ()])))) expression in - let expression = - React_jsx_common.add_async_attribute ~async:isAsync expression - in + let expression = Ast_async.add_async_attribute ~async:isAsync expression in let expression = (* Add new tupes (type a,b,c) to make's definition *) newtypes From 4d1e792d561a90e423157e95d18b3f053b003265 Mon Sep 17 00:00:00 2001 From: mununki Date: Tue, 3 Oct 2023 21:19:59 +0900 Subject: [PATCH 09/10] relocate ast_await into ml --- jscomp/{frontend => ml}/ast_await.ml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename jscomp/{frontend => ml}/ast_await.ml (100%) diff --git a/jscomp/frontend/ast_await.ml b/jscomp/ml/ast_await.ml similarity index 100% rename from jscomp/frontend/ast_await.ml rename to jscomp/ml/ast_await.ml From 9d283ba0feaacfd9d3e6a6e4e2f78c31913d0875 Mon Sep 17 00:00:00 2001 From: mununki Date: Tue, 3 Oct 2023 23:05:05 +0900 Subject: [PATCH 10/10] remove duplicated is_async function --- jscomp/frontend/ast_attributes.ml | 10 ++-------- jscomp/ml/ast_async.ml | 3 +++ jscomp/ml/ast_await.ml | 3 +++ jscomp/syntax/src/react_jsx_common.ml | 3 --- jscomp/syntax/src/reactjs_jsx_v4.ml | 3 +-- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/jscomp/frontend/ast_attributes.ml b/jscomp/frontend/ast_attributes.ml index 3345bcf65e..ebcf5ac05d 100644 --- a/jscomp/frontend/ast_attributes.ml +++ b/jscomp/frontend/ast_attributes.ml @@ -166,14 +166,8 @@ let is_inline : attr -> bool = let has_inline_payload (attrs : t) = Ext_list.find_first attrs is_inline -let is_await : attr -> bool = - fun ({txt}, _) -> txt = "await" || txt = "res.await" - -let is_async : attr -> bool = - fun ({txt}, _) -> txt = "async" || txt = "res.async" - -let has_await_payload (attrs : t) = Ext_list.find_first attrs is_await -let has_async_payload (attrs : t) = Ext_list.find_first attrs is_async +let has_await_payload (attrs : t) = Ext_list.find_first attrs Ast_await.is_await +let has_async_payload (attrs : t) = Ext_list.find_first attrs Ast_async.is_async type derive_attr = {bs_deriving: Ast_payload.action list option} [@@unboxed] diff --git a/jscomp/ml/ast_async.ml b/jscomp/ml/ast_async.ml index 34a59d62a5..d16b193a4c 100644 --- a/jscomp/ml/ast_async.ml +++ b/jscomp/ml/ast_async.ml @@ -1,3 +1,6 @@ +let is_async : Parsetree.attribute -> bool = + fun ({txt}, _) -> txt = "async" || txt = "res.async" + let add_promise_type ?(loc = Location.none) ~async (result : Parsetree.expression) = if async then diff --git a/jscomp/ml/ast_await.ml b/jscomp/ml/ast_await.ml index 2906ea4690..410f3b9c70 100644 --- a/jscomp/ml/ast_await.ml +++ b/jscomp/ml/ast_await.ml @@ -1,3 +1,6 @@ +let is_await : Parsetree.attribute -> bool = + fun ({txt}, _) -> txt = "await" || txt = "res.await" + let create_await_expression (e : Parsetree.expression) = let loc = e.pexp_loc in let unsafe_await = diff --git a/jscomp/syntax/src/react_jsx_common.ml b/jscomp/syntax/src/react_jsx_common.ml index 08bd1c1017..51c4711032 100644 --- a/jscomp/syntax/src/react_jsx_common.ml +++ b/jscomp/syntax/src/react_jsx_common.ml @@ -64,9 +64,6 @@ let removeArity binding = in {binding with pvb_expr = removeArityRecord binding.pvb_expr} -let is_async : Parsetree.attribute -> bool = - fun ({txt}, _) -> txt = "async" || txt = "res.async" - let async_component ~async expr = if async then let open Ast_helper in diff --git a/jscomp/syntax/src/reactjs_jsx_v4.ml b/jscomp/syntax/src/reactjs_jsx_v4.ml index fa867e2c9d..1801edd011 100644 --- a/jscomp/syntax/src/reactjs_jsx_v4.ml +++ b/jscomp/syntax/src/reactjs_jsx_v4.ml @@ -910,8 +910,7 @@ let mapBinding ~config ~emptyLoc ~pstr_loc ~fileName ~recFlag binding = modifiedBinding ~bindingLoc ~bindingPatLoc ~fnName binding in let isAsync = - Ext_list.find_first binding.pvb_expr.pexp_attributes - React_jsx_common.is_async + Ext_list.find_first binding.pvb_expr.pexp_attributes Ast_async.is_async |> Option.is_some in (* do stuff here! *)