From 7c0af6e57f641a296cf786e9771475135d8f0f08 Mon Sep 17 00:00:00 2001 From: nojaf Date: Mon, 17 Feb 2025 09:20:55 +0100 Subject: [PATCH 1/5] Exploring problem space --- compiler/syntax/src/jsx_v4.ml | 6 ++++-- .../react/expected/sharedPropsWithProps.res.txt | 14 ++++++++++++++ .../data/ppx/react/sharedPropsWithProps.res | 10 ++++++++++ tests/tests/src/alias_default_value_test.mjs | 12 ++++++++++++ tests/tests/src/alias_default_value_test.res | 11 +++++++++++ 5 files changed, 51 insertions(+), 2 deletions(-) diff --git a/compiler/syntax/src/jsx_v4.ml b/compiler/syntax/src/jsx_v4.ml index fcf2272153..64dc90bc5b 100644 --- a/compiler/syntax/src/jsx_v4.ml +++ b/compiler/syntax/src/jsx_v4.ml @@ -1185,7 +1185,7 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = in (Some props_record_type, binding, new_binding)) else if Jsx_common.has_attr_on_binding Jsx_common.has_attr_with_props binding - then + then ( let modified_binding = { binding with @@ -1198,6 +1198,8 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = make_module_name file_name config.nested_modules fn_name in + Format.printf "Yow %s\n" full_module_name; + let is_async = Ast_async.dig_async_payload_from_function modified_binding.pvb_expr in @@ -1283,7 +1285,7 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = binding with pvb_attributes = binding.pvb_attributes |> List.filter other_attrs_pure; }, - new_binding ) + new_binding )) else (None, binding, None) let transform_structure_item ~config item = 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 03dfa09891..623a8b2b33 100644 --- a/tests/syntax_tests/data/ppx/react/expected/sharedPropsWithProps.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/sharedPropsWithProps.res.txt @@ -131,3 +131,17 @@ module V4A6 = { \"SharedPropsWithProps$V4A6" } } + +module V4A7 = { + type props = {count: int} + + let make = + @directive("'use memo'") + props => { + React.int(props.count) + } + let make = { + let \"SharedPropsWithProps$V4A7" = props => make(props) + \"SharedPropsWithProps$V4A7" + } +} diff --git a/tests/syntax_tests/data/ppx/react/sharedPropsWithProps.res b/tests/syntax_tests/data/ppx/react/sharedPropsWithProps.res index 00d382bc92..95acd39625 100644 --- a/tests/syntax_tests/data/ppx/react/sharedPropsWithProps.res +++ b/tests/syntax_tests/data/ppx/react/sharedPropsWithProps.res @@ -91,3 +91,13 @@ module V4A6 = { } } } + +module V4A7 = { + type props = {count: int} + + @react.componentWithProps + let make = @directive("'use memo'") + props => { + React.int(props.count) + } +} diff --git a/tests/tests/src/alias_default_value_test.mjs b/tests/tests/src/alias_default_value_test.mjs index 434e2b9763..46e6f0758c 100644 --- a/tests/tests/src/alias_default_value_test.mjs +++ b/tests/tests/src/alias_default_value_test.mjs @@ -82,6 +82,17 @@ let C7 = { make: Alias_default_value_test$C7 }; +function make(props) { + 'use memo'; + return props.count; +} + +let Alias_default_value_test$C8 = make; + +let C8 = { + make: Alias_default_value_test$C8 +}; + export { C0, C1, @@ -90,5 +101,6 @@ export { C4, C6, C7, + C8, } /* No side effect */ diff --git a/tests/tests/src/alias_default_value_test.res b/tests/tests/src/alias_default_value_test.res index 1ebe9f00fa..2ed6dfc4b1 100644 --- a/tests/tests/src/alias_default_value_test.res +++ b/tests/tests/src/alias_default_value_test.res @@ -64,3 +64,14 @@ module C7 = { React.string(`Hello ${name}, you clicked me ` ++ times) } } + +module C8 = { + type props = {count: int} + + @react.componentWithProps + let make = + @directive("'use memo'") + props => { + React.int(props.count) + } +} From 65c2bf2c5fc0606bd0632e065d44948db0f9e1ec Mon Sep 17 00:00:00 2001 From: nojaf Date: Mon, 17 Feb 2025 10:12:26 +0100 Subject: [PATCH 2/5] Copy attributes from function --- compiler/syntax/src/jsx_v4.ml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/syntax/src/jsx_v4.ml b/compiler/syntax/src/jsx_v4.ml index 64dc90bc5b..0d70756660 100644 --- a/compiler/syntax/src/jsx_v4.ml +++ b/compiler/syntax/src/jsx_v4.ml @@ -1185,7 +1185,7 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = in (Some props_record_type, binding, new_binding)) else if Jsx_common.has_attr_on_binding Jsx_common.has_attr_with_props binding - then ( + then let modified_binding = { binding with @@ -1198,8 +1198,6 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = make_module_name file_name config.nested_modules fn_name in - Format.printf "Yow %s\n" full_module_name; - let is_async = Ast_async.dig_async_payload_from_function modified_binding.pvb_expr in @@ -1246,6 +1244,7 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = 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 @@ -1285,7 +1284,7 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = binding with pvb_attributes = binding.pvb_attributes |> List.filter other_attrs_pure; }, - new_binding )) + new_binding ) else (None, binding, None) let transform_structure_item ~config item = From 91d23dce8736baae1b566008fc62a0c813b09cb2 Mon Sep 17 00:00:00 2001 From: nojaf Date: Thu, 20 Feb 2025 22:55:18 +0100 Subject: [PATCH 3/5] Remove moved attributes from expr --- compiler/syntax/src/jsx_v4.ml | 6 ++++++ tests/tests/src/alias_default_value_test.mjs | 4 +--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/compiler/syntax/src/jsx_v4.ml b/compiler/syntax/src/jsx_v4.ml index 0d70756660..b1eb169b84 100644 --- a/compiler/syntax/src/jsx_v4.ml +++ b/compiler/syntax/src/jsx_v4.ml @@ -1283,6 +1283,12 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = { binding with pvb_attributes = binding.pvb_attributes |> List.filter other_attrs_pure; + pvb_expr = + { + binding.pvb_expr with + (* moved to wrapper_expr *) + pexp_attributes = []; + }; }, new_binding ) else (None, binding, None) diff --git a/tests/tests/src/alias_default_value_test.mjs b/tests/tests/src/alias_default_value_test.mjs index 46e6f0758c..f525661bb8 100644 --- a/tests/tests/src/alias_default_value_test.mjs +++ b/tests/tests/src/alias_default_value_test.mjs @@ -82,13 +82,11 @@ let C7 = { make: Alias_default_value_test$C7 }; -function make(props) { +function Alias_default_value_test$C8(props) { 'use memo'; return props.count; } -let Alias_default_value_test$C8 = make; - let C8 = { make: Alias_default_value_test$C8 }; From c416538f8215f3c8b0f243e1c364d4f049bb5ad5 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 21 Feb 2025 09:44:36 +0100 Subject: [PATCH 4/5] Update test --- .../ppx/react/expected/sharedPropsWithProps.res.txt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) 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 623a8b2b33..f0e4dd013d 100644 --- a/tests/syntax_tests/data/ppx/react/expected/sharedPropsWithProps.res.txt +++ b/tests/syntax_tests/data/ppx/react/expected/sharedPropsWithProps.res.txt @@ -135,13 +135,11 @@ module V4A6 = { module V4A7 = { type props = {count: int} - let make = - @directive("'use memo'") - props => { - React.int(props.count) - } + let make = props => { + React.int(props.count) + } let make = { - let \"SharedPropsWithProps$V4A7" = props => make(props) + let \"SharedPropsWithProps$V4A7" = @directive("'use memo'") props => make(props) \"SharedPropsWithProps$V4A7" } } From 1f9c8f1717199601003b6f9157edb435ebe3d87b Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 21 Feb 2025 09:56:37 +0100 Subject: [PATCH 5/5] Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6600d69249..01697d7cae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ - Fix error message for arity in the presence of optional arguments. https://github.com/rescript-lang/rescript/pull/7284 - Fix issue in functors with more than one argument (which are curried): emit nested function always. https://github.com/rescript-lang/rescript/pull/7273 - Fix dot completion issue with React primitives. https://github.com/rescript-lang/rescript/pull/7292 +- Fix @react.componentWithProps no longer works with @directive("'use memo'"). https://github.com/rescript-lang/rescript/pull/7300 #### :house: Internal