From c2cb9901045b7068f64ebb48fbf885faa0b4182f Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Fri, 8 Aug 2025 03:46:40 -0700 Subject: [PATCH 1/2] Improve codegen to add getDebugProps to components (#53135) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53135 Our Codegenerated components are not generating code for `getDebugProps`. This change modifies Codegen to add those functions for all the codegen components. ## Changelog: [General][Added] - Added getDebugProps to codegen ## Facebook: `getDebugProps` are required by Fantom to write tests. However, we can't generate these function for third party components, because codegen can generate arbitrary structs and we don't have a generic `toString()` method that can be used or automatically generated by C++. By generating this function only for Core Components, we can ensure that we can write Fantom tests without breaking all the users of React Native. Differential Revision: D79805145 Reviewed By: rubennorte --- .../GeneratePropsCpp-test.js.snap | 4 +- .../__snapshots__/GeneratePropsH-test.js.snap | 65 ++++++++- .../GeneratePropsCpp-test.js.snap | 4 +- .../__snapshots__/GeneratePropsH-test.js.snap | 65 ++++++++- .../src/cli/generators/generate-all.js | 12 +- .../src/generators/RNCodegen.js | 4 + .../src/generators/components/CppHelpers.js | 2 +- .../GenerateComponentDescriptorCpp.js | 1 + .../GenerateComponentDescriptorH.js | 1 + .../components/GenerateComponentHObjCpp.js | 1 + .../components/GenerateEventEmitterCpp.js | 1 + .../components/GenerateEventEmitterH.js | 1 + .../generators/components/GeneratePropsCpp.js | 44 +++++- .../generators/components/GeneratePropsH.js | 17 ++- .../components/GeneratePropsJavaDelegate.js | 1 + .../components/GeneratePropsJavaInterface.js | 1 + .../components/GenerateShadowNodeCpp.js | 1 + .../components/GenerateShadowNodeH.js | 1 + .../generators/components/GenerateStateCpp.js | 1 + .../generators/components/GenerateStateH.js | 1 + .../GeneratePropsCpp-test.js.snap | 6 +- .../__snapshots__/GeneratePropsH-test.js.snap | 125 ++++++++++++++++-- .../renderer/debug/DebugStringConvertible.h | 16 +++ .../codegen/generate-specs-cli-executor.js | 3 + 24 files changed, 349 insertions(+), 29 deletions(-) diff --git a/packages/react-native-codegen/e2e/deep_imports/__tests__/components/__snapshots__/GeneratePropsCpp-test.js.snap b/packages/react-native-codegen/e2e/deep_imports/__tests__/components/__snapshots__/GeneratePropsCpp-test.js.snap index 05439a17b690..87cbfe09cb32 100644 --- a/packages/react-native-codegen/e2e/deep_imports/__tests__/components/__snapshots__/GeneratePropsCpp-test.js.snap +++ b/packages/react-native-codegen/e2e/deep_imports/__tests__/components/__snapshots__/GeneratePropsCpp-test.js.snap @@ -717,7 +717,7 @@ InterfaceOnlyNativeComponentViewProps::InterfaceOnlyNativeComponentViewProps( const InterfaceOnlyNativeComponentViewProps &sourceProps, const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), - title(convertRawProp(context, rawProps, \\"title\\", sourceProps.title, {\\"\\"})) {} + title(convertRawProp(context, rawProps, \\"title\\", sourceProps.title, {std::string{\\"\\"}})) {} #ifdef RN_SERIALIZABLE_STATE ComponentName InterfaceOnlyNativeComponentViewProps::getDiffPropsImplementationTarget() const { @@ -1060,7 +1060,7 @@ StringPropNativeComponentViewProps::StringPropNativeComponentViewProps( const StringPropNativeComponentViewProps &sourceProps, const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), - placeholder(convertRawProp(context, rawProps, \\"placeholder\\", sourceProps.placeholder, {\\"\\"})), + placeholder(convertRawProp(context, rawProps, \\"placeholder\\", sourceProps.placeholder, {std::string{\\"\\"}})), defaultValue(convertRawProp(context, rawProps, \\"defaultValue\\", sourceProps.defaultValue, {})) {} #ifdef RN_SERIALIZABLE_STATE diff --git a/packages/react-native-codegen/e2e/deep_imports/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap b/packages/react-native-codegen/e2e/deep_imports/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap index 986c182c759c..31ca4f11bd9f 100644 --- a/packages/react-native-codegen/e2e/deep_imports/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap +++ b/packages/react-native-codegen/e2e/deep_imports/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap @@ -18,6 +18,7 @@ Object { #include #include #include +#include #include #include #include @@ -89,6 +90,7 @@ static inline std::string toString(const ArrayPropsNativeComponentViewSizesMaskW struct ArrayPropsNativeComponentViewObjectStruct { std::string prop{}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ArrayPropsNativeComponentViewObjectStruct&) const = default; @@ -133,6 +135,7 @@ struct ArrayPropsNativeComponentViewArrayOfObjectsStruct { Float prop1{0.0}; int prop2{0}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ArrayPropsNativeComponentViewArrayOfObjectsStruct&) const = default; @@ -203,6 +206,8 @@ class ArrayPropsNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -225,6 +230,7 @@ Object { #include #include +#include namespace facebook::react { @@ -243,6 +249,8 @@ class BooleanPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -265,6 +273,7 @@ Object { #include #include +#include #include namespace facebook::react { @@ -283,6 +292,8 @@ class ColorPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -306,6 +317,7 @@ Object { #include #include #include +#include #include namespace facebook::react { @@ -324,6 +336,8 @@ class DimensionPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -346,6 +360,7 @@ Object { #include #include +#include namespace facebook::react { @@ -363,6 +378,8 @@ class EdgeInsetsPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -385,6 +402,7 @@ Object { #include #include +#include namespace facebook::react { @@ -468,6 +486,8 @@ class EnumPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -490,6 +510,7 @@ Object { #include #include +#include namespace facebook::react { @@ -507,6 +528,8 @@ class EventNestedObjectPropsNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -529,6 +552,7 @@ Object { #include #include +#include namespace facebook::react { @@ -546,6 +570,8 @@ class EventPropsNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -568,6 +594,7 @@ Object { #include #include +#include namespace facebook::react { @@ -591,6 +618,8 @@ class FloatPropsNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -613,6 +642,7 @@ Object { #include #include +#include #include namespace facebook::react { @@ -631,6 +661,8 @@ class ImagePropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -653,6 +685,7 @@ Object { #include #include +#include namespace facebook::react { @@ -672,6 +705,8 @@ class IntegerPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -694,6 +729,7 @@ Object { #include #include +#include namespace facebook::react { @@ -704,13 +740,15 @@ class InterfaceOnlyNativeComponentViewProps final : public ViewProps { #pragma mark - Props - std::string title{\\"\\"}; + std::string title{std::string{\\"\\"}}; #ifdef RN_SERIALIZABLE_STATE ComponentName getDiffPropsImplementationTarget() const override; folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -733,6 +771,7 @@ Object { #include #include +#include namespace facebook::react { @@ -750,6 +789,8 @@ class MixedPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -772,6 +813,7 @@ Object { #include #include +#include #include #include #include @@ -795,6 +837,8 @@ class MultiNativePropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -817,6 +861,7 @@ Object { #include #include +#include namespace facebook::react { @@ -834,6 +879,8 @@ class NoPropsNoEventsNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -858,6 +905,7 @@ Object { #include #include #include +#include #include #include #include @@ -918,13 +966,14 @@ static inline folly::dynamic toDynamic(const ObjectPropsNativeComponentIntEnumPr } #endif struct ObjectPropsNativeComponentObjectPropStruct { - std::string stringProp{\\"\\"}; + std::string stringProp{std::string{\\"\\"}}; bool booleanProp{false}; Float floatProp{0.0}; int intProp{0}; ObjectPropsNativeComponentStringEnumProp stringEnumProp{ObjectPropsNativeComponentStringEnumProp::Small}; ObjectPropsNativeComponentIntEnumProp intEnumProp{ObjectPropsNativeComponentIntEnumProp::IntEnumProp0}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ObjectPropsNativeComponentObjectPropStruct&) const = default; @@ -983,6 +1032,7 @@ static inline folly::dynamic toDynamic(const ObjectPropsNativeComponentObjectPro struct ObjectPropsNativeComponentObjectArrayPropStruct { std::vector array{}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ObjectPropsNativeComponentObjectArrayPropStruct&) const = default; @@ -1018,6 +1068,7 @@ struct ObjectPropsNativeComponentObjectPrimitiveRequiredPropStruct { SharedColor color{}; Point point{}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ObjectPropsNativeComponentObjectPrimitiveRequiredPropStruct&) const = default; @@ -1073,6 +1124,8 @@ class ObjectPropsNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -1095,6 +1148,7 @@ Object { #include #include +#include #include namespace facebook::react { @@ -1113,6 +1167,8 @@ class PointPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -1135,6 +1191,7 @@ Object { #include #include +#include namespace facebook::react { @@ -1145,7 +1202,7 @@ class StringPropNativeComponentViewProps final : public ViewProps { #pragma mark - Props - std::string placeholder{\\"\\"}; + std::string placeholder{std::string{\\"\\"}}; std::string defaultValue{}; #ifdef RN_SERIALIZABLE_STATE @@ -1153,6 +1210,8 @@ class StringPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react diff --git a/packages/react-native-codegen/e2e/namespaced/__tests__/components/__snapshots__/GeneratePropsCpp-test.js.snap b/packages/react-native-codegen/e2e/namespaced/__tests__/components/__snapshots__/GeneratePropsCpp-test.js.snap index 2f1837351470..c8a653467e6a 100644 --- a/packages/react-native-codegen/e2e/namespaced/__tests__/components/__snapshots__/GeneratePropsCpp-test.js.snap +++ b/packages/react-native-codegen/e2e/namespaced/__tests__/components/__snapshots__/GeneratePropsCpp-test.js.snap @@ -717,7 +717,7 @@ InterfaceOnlyNativeComponentViewProps::InterfaceOnlyNativeComponentViewProps( const InterfaceOnlyNativeComponentViewProps &sourceProps, const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), - title(convertRawProp(context, rawProps, \\"title\\", sourceProps.title, {\\"\\"})) {} + title(convertRawProp(context, rawProps, \\"title\\", sourceProps.title, {std::string{\\"\\"}})) {} #ifdef RN_SERIALIZABLE_STATE ComponentName InterfaceOnlyNativeComponentViewProps::getDiffPropsImplementationTarget() const { @@ -1060,7 +1060,7 @@ StringPropNativeComponentViewProps::StringPropNativeComponentViewProps( const StringPropNativeComponentViewProps &sourceProps, const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), - placeholder(convertRawProp(context, rawProps, \\"placeholder\\", sourceProps.placeholder, {\\"\\"})), + placeholder(convertRawProp(context, rawProps, \\"placeholder\\", sourceProps.placeholder, {std::string{\\"\\"}})), defaultValue(convertRawProp(context, rawProps, \\"defaultValue\\", sourceProps.defaultValue, {})) {} #ifdef RN_SERIALIZABLE_STATE diff --git a/packages/react-native-codegen/e2e/namespaced/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap b/packages/react-native-codegen/e2e/namespaced/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap index 5e32179d9cfc..b06cafc695a1 100644 --- a/packages/react-native-codegen/e2e/namespaced/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap +++ b/packages/react-native-codegen/e2e/namespaced/__tests__/components/__snapshots__/GeneratePropsH-test.js.snap @@ -18,6 +18,7 @@ Object { #include #include #include +#include #include #include #include @@ -89,6 +90,7 @@ static inline std::string toString(const ArrayPropsNativeComponentViewSizesMaskW struct ArrayPropsNativeComponentViewObjectStruct { std::string prop{}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ArrayPropsNativeComponentViewObjectStruct&) const = default; @@ -133,6 +135,7 @@ struct ArrayPropsNativeComponentViewArrayOfObjectsStruct { Float prop1{0.0}; int prop2{0}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ArrayPropsNativeComponentViewArrayOfObjectsStruct&) const = default; @@ -203,6 +206,8 @@ class ArrayPropsNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -225,6 +230,7 @@ Object { #include #include +#include namespace facebook::react { @@ -243,6 +249,8 @@ class BooleanPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -265,6 +273,7 @@ Object { #include #include +#include #include namespace facebook::react { @@ -283,6 +292,8 @@ class ColorPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -306,6 +317,7 @@ Object { #include #include #include +#include #include namespace facebook::react { @@ -324,6 +336,8 @@ class DimensionPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -346,6 +360,7 @@ Object { #include #include +#include namespace facebook::react { @@ -363,6 +378,8 @@ class EdgeInsetsPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -385,6 +402,7 @@ Object { #include #include +#include namespace facebook::react { @@ -468,6 +486,8 @@ class EnumPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -490,6 +510,7 @@ Object { #include #include +#include namespace facebook::react { @@ -507,6 +528,8 @@ class EventNestedObjectPropsNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -529,6 +552,7 @@ Object { #include #include +#include namespace facebook::react { @@ -546,6 +570,8 @@ class EventPropsNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -568,6 +594,7 @@ Object { #include #include +#include namespace facebook::react { @@ -591,6 +618,8 @@ class FloatPropsNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -613,6 +642,7 @@ Object { #include #include +#include #include namespace facebook::react { @@ -631,6 +661,8 @@ class ImagePropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -653,6 +685,7 @@ Object { #include #include +#include namespace facebook::react { @@ -672,6 +705,8 @@ class IntegerPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -694,6 +729,7 @@ Object { #include #include +#include namespace facebook::react { @@ -704,13 +740,15 @@ class InterfaceOnlyNativeComponentViewProps final : public ViewProps { #pragma mark - Props - std::string title{\\"\\"}; + std::string title{std::string{\\"\\"}}; #ifdef RN_SERIALIZABLE_STATE ComponentName getDiffPropsImplementationTarget() const override; folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -733,6 +771,7 @@ Object { #include #include +#include namespace facebook::react { @@ -750,6 +789,8 @@ class MixedPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -772,6 +813,7 @@ Object { #include #include +#include #include #include #include @@ -795,6 +837,8 @@ class MultiNativePropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -817,6 +861,7 @@ Object { #include #include +#include namespace facebook::react { @@ -834,6 +879,8 @@ class NoPropsNoEventsNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -858,6 +905,7 @@ Object { #include #include #include +#include #include #include #include @@ -918,13 +966,14 @@ static inline folly::dynamic toDynamic(const ObjectPropsNativeComponentIntEnumPr } #endif struct ObjectPropsNativeComponentObjectPropStruct { - std::string stringProp{\\"\\"}; + std::string stringProp{std::string{\\"\\"}}; bool booleanProp{false}; Float floatProp{0.0}; int intProp{0}; ObjectPropsNativeComponentStringEnumProp stringEnumProp{ObjectPropsNativeComponentStringEnumProp::Small}; ObjectPropsNativeComponentIntEnumProp intEnumProp{ObjectPropsNativeComponentIntEnumProp::IntEnumProp0}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ObjectPropsNativeComponentObjectPropStruct&) const = default; @@ -983,6 +1032,7 @@ static inline folly::dynamic toDynamic(const ObjectPropsNativeComponentObjectPro struct ObjectPropsNativeComponentObjectArrayPropStruct { std::vector array{}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ObjectPropsNativeComponentObjectArrayPropStruct&) const = default; @@ -1018,6 +1068,7 @@ struct ObjectPropsNativeComponentObjectPrimitiveRequiredPropStruct { SharedColor color{}; Point point{}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ObjectPropsNativeComponentObjectPrimitiveRequiredPropStruct&) const = default; @@ -1073,6 +1124,8 @@ class ObjectPropsNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -1095,6 +1148,7 @@ Object { #include #include +#include #include namespace facebook::react { @@ -1113,6 +1167,8 @@ class PointPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -1135,6 +1191,7 @@ Object { #include #include +#include namespace facebook::react { @@ -1145,7 +1202,7 @@ class StringPropNativeComponentViewProps final : public ViewProps { #pragma mark - Props - std::string placeholder{\\"\\"}; + std::string placeholder{std::string{\\"\\"}}; std::string defaultValue{}; #ifdef RN_SERIALIZABLE_STATE @@ -1153,6 +1210,8 @@ class StringPropNativeComponentViewProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react diff --git a/packages/react-native-codegen/src/cli/generators/generate-all.js b/packages/react-native-codegen/src/cli/generators/generate-all.js index 2f4482be45e5..0724e23acd18 100644 --- a/packages/react-native-codegen/src/cli/generators/generate-all.js +++ b/packages/react-native-codegen/src/cli/generators/generate-all.js @@ -46,9 +46,17 @@ try { } catch (err) { throw new Error(`Can't parse schema to JSON. ${schemaPath}`); } - +const includeGetDebugPropsImplementation: boolean = + libraryName.includes('FBReactNativeSpec'); RNCodegen.generate( - {libraryName, schema, outputDirectory, packageName, assumeNonnull}, + { + libraryName, + schema, + outputDirectory, + packageName, + assumeNonnull, + includeGetDebugPropsImplementation, + }, { generators: [ 'descriptors', diff --git a/packages/react-native-codegen/src/generators/RNCodegen.js b/packages/react-native-codegen/src/generators/RNCodegen.js index 807a39214eb8..70322cfb9b3a 100644 --- a/packages/react-native-codegen/src/generators/RNCodegen.js +++ b/packages/react-native-codegen/src/generators/RNCodegen.js @@ -81,6 +81,7 @@ export type GenerateFunction = ( packageName?: string, assumeNonnull: boolean, headerPrefix?: string, + includeGetDebugPropsImplementation?: boolean, ) => FilesOutput; export type LibraryGeneratorsFunctions = $ReadOnly<{ @@ -94,6 +95,7 @@ export type LibraryOptions = $ReadOnly<{ packageName?: string, // Some platforms have a notion of package, which should be configurable. assumeNonnull: boolean, useLocalIncludePaths?: boolean, + includeGetDebugPropsImplementation?: boolean, libraryGenerators?: LibraryGeneratorsFunctions, }>; @@ -255,6 +257,7 @@ module.exports = { packageName, assumeNonnull, useLocalIncludePaths, + includeGetDebugPropsImplementation = false, libraryGenerators = LIBRARY_GENERATORS, }: LibraryOptions, {generators, test}: LibraryConfig, @@ -299,6 +302,7 @@ module.exports = { packageName, assumeNonnull, headerPrefix, + includeGetDebugPropsImplementation, ).forEach((contents: string, fileName: string) => { generatedFiles.push({ name: fileName, diff --git a/packages/react-native-codegen/src/generators/components/CppHelpers.js b/packages/react-native-codegen/src/generators/components/CppHelpers.js index 944304c62051..fa3d56629fec 100644 --- a/packages/react-native-codegen/src/generators/components/CppHelpers.js +++ b/packages/react-native-codegen/src/generators/components/CppHelpers.js @@ -190,7 +190,7 @@ function convertDefaultTypeToString( if (typeAnnotation.default == null) { return ''; } - return `"${typeAnnotation.default}"`; + return `std::string{"${typeAnnotation.default}"}`; case 'Int32TypeAnnotation': return String(typeAnnotation.default); case 'DoubleTypeAnnotation': diff --git a/packages/react-native-codegen/src/generators/components/GenerateComponentDescriptorCpp.js b/packages/react-native-codegen/src/generators/components/GenerateComponentDescriptorCpp.js index 794e04765742..0bf3bfa50f87 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateComponentDescriptorCpp.js +++ b/packages/react-native-codegen/src/generators/components/GenerateComponentDescriptorCpp.js @@ -61,6 +61,7 @@ module.exports = { packageName?: string, assumeNonnull: boolean = false, headerPrefix?: string, + includeGetDebugPropsImplementation?: boolean = false, ): FilesOutput { const fileName = 'ComponentDescriptors.cpp'; diff --git a/packages/react-native-codegen/src/generators/components/GenerateComponentDescriptorH.js b/packages/react-native-codegen/src/generators/components/GenerateComponentDescriptorH.js index 0a68446cd1af..75dba99e559c 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateComponentDescriptorH.js +++ b/packages/react-native-codegen/src/generators/components/GenerateComponentDescriptorH.js @@ -63,6 +63,7 @@ module.exports = { packageName?: string, assumeNonnull: boolean = false, headerPrefix?: string, + includeGetDebugPropsImplementation?: boolean = false, ): FilesOutput { const fileName = 'ComponentDescriptors.h'; diff --git a/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js b/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js index 79724d1810eb..6d0279757adc 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js +++ b/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js @@ -381,6 +381,7 @@ module.exports = { packageName?: string, assumeNonnull: boolean = false, headerPrefix?: string, + includeGetDebugPropsImplementation?: boolean = false, ): FilesOutput { const fileName = 'RCTComponentViewHelpers.h'; diff --git a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js index acec7362f09d..6d9b72cd2909 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js +++ b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js @@ -413,6 +413,7 @@ module.exports = { packageName?: string, assumeNonnull: boolean = false, headerPrefix?: string, + includeGetDebugPropsImplementation?: boolean = false, ): FilesOutput { const moduleComponents: ComponentCollection = Object.keys(schema.modules) .map(moduleName => { diff --git a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js index c7b338ea3666..0c3468dbc61c 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js +++ b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js @@ -320,6 +320,7 @@ module.exports = { packageName?: string, assumeNonnull: boolean = false, headerPrefix?: string, + includeGetDebugPropsImplementation?: boolean = false, ): FilesOutput { const moduleComponents: ComponentCollection = Object.keys(schema.modules) .map(moduleName => { diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsCpp.js b/packages/react-native-codegen/src/generators/components/GeneratePropsCpp.js index ce85cb8497d5..29298d90bf66 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsCpp.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsCpp.js @@ -77,6 +77,8 @@ function generatePropsDiffString( className: string, componentName: string, component: ComponentShape, + debugProps: string = '', + includeGetDebugPropsImplementation?: boolean = false, ) { const diffProps = component.props .map(prop => { @@ -134,6 +136,12 @@ function generatePropsDiffString( }) .join('\n' + ' '); + const getDebugPropsString = `#if RN_DEBUG_STRING_CONVERTIBLE +SharedDebugStringConvertibleList ${className}::getDebugProps() const { + return ViewProps::getDebugProps()${debugProps && debugProps.length > 0 ? ` +\n\t\tSharedDebugStringConvertibleList{${debugProps}\n\t}` : ''}; +} +#endif`; + return ` #ifdef RN_SERIALIZABLE_STATE ComponentName ${className}::getDiffPropsImplementationTarget() const { @@ -153,8 +161,11 @@ folly::dynamic ${className}::getDiffProps( ${diffProps} return result; } -#endif`; +#endif +${includeGetDebugPropsImplementation ? getDebugPropsString : ''} +`; } + function generatePropsString(componentName: string, component: ComponentShape) { return component.props .map(prop => { @@ -170,6 +181,24 @@ function generatePropsString(componentName: string, component: ComponentShape) { .join(',\n' + ' '); } +function generateDebugPropsString( + componentName: string, + component: ComponentShape, +) { + return component.props + .map(prop => { + if (prop.typeAnnotation.type === 'ObjectTypeAnnotation') { + // Skip ObjectTypeAnnotation because there is no generic `toString` + // method for it. We would have to define an interface that the structs implement. + return ''; + } + + const defaultValue = convertDefaultTypeToString(componentName, prop); + return `\n\t\t\tdebugStringConvertibleItem("${prop.name}", ${prop.name}${defaultValue ? `, ${defaultValue}` : ''})`; + }) + .join(','); +} + function getClassExtendString(component: ComponentShape): string { const extendString = ' ' + @@ -202,6 +231,7 @@ module.exports = { packageName?: string, assumeNonnull: boolean = false, headerPrefix?: string, + includeGetDebugPropsImplementation?: boolean = false, ): FilesOutput { const fileName = 'Props.cpp'; const allImports: Set = new Set([ @@ -209,6 +239,13 @@ module.exports = { '#include ', ]); + if (includeGetDebugPropsImplementation) { + allImports.add('#include '); + allImports.add( + '#include ', + ); + } + const componentProps = Object.keys(schema.modules) .map(moduleName => { const module = schema.modules[moduleName]; @@ -229,10 +266,15 @@ module.exports = { const propsString = generatePropsString(componentName, component); const extendString = getClassExtendString(component); + const debugProps = includeGetDebugPropsImplementation + ? generateDebugPropsString(componentName, component) + : ''; const diffPropsString = generatePropsDiffString( newName, componentName, component, + debugProps, + includeGetDebugPropsImplementation, ); const imports = getImports(component.props); diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsH.js b/packages/react-native-codegen/src/generators/components/GeneratePropsH.js index fb0de4343662..a838fd24a85c 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsH.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsH.js @@ -65,14 +65,20 @@ const ClassTemplate = ({ className, props, extendClasses, + includeGetDebugPropsImplementation, }: { enums: string, structs: string, className: string, props: string, extendClasses: string, -}) => - ` + includeGetDebugPropsImplementation: boolean, +}) => { + const getDebugPropsString = `#if RN_DEBUG_STRING_CONVERTIBLE + SharedDebugStringConvertibleList getDebugProps() const override; + #endif`; + + return ` ${enums} ${structs} class ${className} final${extendClasses} { @@ -89,8 +95,11 @@ class ${className} final${extendClasses} { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + ${includeGetDebugPropsImplementation ? getDebugPropsString : ''} }; `.trim(); +}; const EnumTemplate = ({ enumName, @@ -178,6 +187,7 @@ const StructTemplate = ({ `struct ${structName} { ${fields} + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ${structName}&) const = default; @@ -536,6 +546,7 @@ function getExtendsImports( const imports: Set = new Set(); imports.add('#include '); + imports.add('#include '); extendsProps.forEach(extendProps => { switch (extendProps.type) { @@ -783,6 +794,7 @@ module.exports = { packageName?: string, assumeNonnull: boolean = false, headerPrefix?: string, + includeGetDebugPropsImplementation?: boolean = false, ): FilesOutput { const fileName = 'Props.h'; @@ -831,6 +843,7 @@ module.exports = { className: newName, extendClasses: extendString, props: propsString, + includeGetDebugPropsImplementation, }); return replacedTemplate; diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js index cb199581de18..b24a935df35f 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js @@ -299,6 +299,7 @@ module.exports = { packageName?: string, assumeNonnull: boolean = false, headerPrefix?: string, + includeGetDebugPropsImplementation?: boolean = false, ): FilesOutput { // TODO: This doesn't support custom package name yet. const normalizedPackageName = 'com.facebook.react.viewmanagers'; diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js index 66ab2267d84f..7f5833735786 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js @@ -238,6 +238,7 @@ module.exports = { packageName?: string, assumeNonnull: boolean = false, headerPrefix?: string, + includeGetDebugPropsImplementation?: boolean = false, ): FilesOutput { // TODO: This doesn't support custom package name yet. const normalizedPackageName = 'com.facebook.react.viewmanagers'; diff --git a/packages/react-native-codegen/src/generators/components/GenerateShadowNodeCpp.js b/packages/react-native-codegen/src/generators/components/GenerateShadowNodeCpp.js index c6d9f7b738f6..8c3573316f00 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateShadowNodeCpp.js +++ b/packages/react-native-codegen/src/generators/components/GenerateShadowNodeCpp.js @@ -54,6 +54,7 @@ module.exports = { packageName?: string, assumeNonnull: boolean = false, headerPrefix?: string, + includeGetDebugPropsImplementation?: boolean = false, ): FilesOutput { const fileName = 'ShadowNodes.cpp'; diff --git a/packages/react-native-codegen/src/generators/components/GenerateShadowNodeH.js b/packages/react-native-codegen/src/generators/components/GenerateShadowNodeH.js index 8218495e9400..93891001d088 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateShadowNodeH.js +++ b/packages/react-native-codegen/src/generators/components/GenerateShadowNodeH.js @@ -74,6 +74,7 @@ module.exports = { packageName?: string, assumeNonnull: boolean = false, headerPrefix?: string, + includeGetDebugPropsImplementation?: boolean = false, ): FilesOutput { const fileName = 'ShadowNodes.h'; diff --git a/packages/react-native-codegen/src/generators/components/GenerateStateCpp.js b/packages/react-native-codegen/src/generators/components/GenerateStateCpp.js index 87d734a10a7a..8cbb3fb920a1 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateStateCpp.js +++ b/packages/react-native-codegen/src/generators/components/GenerateStateCpp.js @@ -50,6 +50,7 @@ module.exports = { packageName?: string, assumeNonnull: boolean = false, headerPrefix?: string, + includeGetDebugPropsImplementation?: boolean = false, ): FilesOutput { const fileName = 'States.cpp'; diff --git a/packages/react-native-codegen/src/generators/components/GenerateStateH.js b/packages/react-native-codegen/src/generators/components/GenerateStateH.js index 9a4a00b6d257..1a5a03814045 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateStateH.js +++ b/packages/react-native-codegen/src/generators/components/GenerateStateH.js @@ -57,6 +57,7 @@ module.exports = { packageName?: string, assumeNonnull: boolean = false, headerPrefix?: string, + includeGetDebugPropsImplementation?: boolean = false, ): FilesOutput { const fileName = 'States.h'; diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap index dae0dafa6593..6f20264efd38 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap @@ -347,7 +347,7 @@ CommandNativeComponentProps::CommandNativeComponentProps( const CommandNativeComponentProps &sourceProps, const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), - accessibilityHint(convertRawProp(context, rawProps, \\"accessibilityHint\\", sourceProps.accessibilityHint, {\\"\\"})) {} + accessibilityHint(convertRawProp(context, rawProps, \\"accessibilityHint\\", sourceProps.accessibilityHint, {std::string{\\"\\"}})) {} #ifdef RN_SERIALIZABLE_STATE ComponentName CommandNativeComponentProps::getDiffPropsImplementationTarget() const { @@ -1168,7 +1168,7 @@ InterfaceOnlyComponentProps::InterfaceOnlyComponentProps( const InterfaceOnlyComponentProps &sourceProps, const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), - accessibilityHint(convertRawProp(context, rawProps, \\"accessibilityHint\\", sourceProps.accessibilityHint, {\\"\\"})) {} + accessibilityHint(convertRawProp(context, rawProps, \\"accessibilityHint\\", sourceProps.accessibilityHint, {std::string{\\"\\"}})) {} #ifdef RN_SERIALIZABLE_STATE ComponentName InterfaceOnlyComponentProps::getDiffPropsImplementationTarget() const { @@ -1554,7 +1554,7 @@ StringPropComponentProps::StringPropComponentProps( const StringPropComponentProps &sourceProps, const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), - accessibilityHint(convertRawProp(context, rawProps, \\"accessibilityHint\\", sourceProps.accessibilityHint, {\\"\\"})), + accessibilityHint(convertRawProp(context, rawProps, \\"accessibilityHint\\", sourceProps.accessibilityHint, {std::string{\\"\\"}})), accessibilityRole(convertRawProp(context, rawProps, \\"accessibilityRole\\", sourceProps.accessibilityRole, {})) {} #ifdef RN_SERIALIZABLE_STATE diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap index 748e931547d9..933e04fb426c 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap @@ -18,6 +18,7 @@ Map { #include #include #include +#include #include #include #include @@ -86,7 +87,8 @@ static inline std::string toString(const ArrayPropsNativeComponentSizesMaskWrapp return result; } struct ArrayPropsNativeComponentObjectStruct { - std::string stringProp{\\"\\"}; + std::string stringProp{std::string{\\"\\"}}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ArrayPropsNativeComponentObjectStruct&) const = default; @@ -129,7 +131,8 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu struct ArrayPropsNativeComponentArrayObjectStruct { - std::string stringProp{\\"\\"}; + std::string stringProp{std::string{\\"\\"}}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ArrayPropsNativeComponentArrayObjectStruct&) const = default; @@ -174,6 +177,7 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu struct ArrayPropsNativeComponentArrayStruct { std::vector object{}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ArrayPropsNativeComponentArrayStruct&) const = default; @@ -215,7 +219,8 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu struct ArrayPropsNativeComponentArrayOfArrayOfObjectStruct { - std::string stringProp{\\"\\"}; + std::string stringProp{std::string{\\"\\"}}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ArrayPropsNativeComponentArrayOfArrayOfObjectStruct&) const = default; @@ -286,6 +291,8 @@ class ArrayPropsNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -310,6 +317,7 @@ Map { #include #include #include +#include #include #include #include @@ -322,6 +330,7 @@ struct ArrayPropsNativeComponentNativePrimitivesStruct { std::vector srcs{}; std::vector points{}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ArrayPropsNativeComponentNativePrimitivesStruct&) const = default; @@ -385,6 +394,8 @@ class ArrayPropsNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -407,6 +418,7 @@ Map { #include #include +#include namespace facebook::react { @@ -424,6 +436,8 @@ class BooleanPropNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -446,6 +460,7 @@ Map { #include #include +#include #include namespace facebook::react { @@ -464,6 +479,8 @@ class ColorPropNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -486,6 +503,7 @@ Map { #include #include +#include namespace facebook::react { @@ -503,6 +521,8 @@ class CommandNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -525,6 +545,7 @@ Map { #include #include +#include namespace facebook::react { @@ -535,13 +556,15 @@ class CommandNativeComponentProps final : public ViewProps { #pragma mark - Props - std::string accessibilityHint{\\"\\"}; + std::string accessibilityHint{std::string{\\"\\"}}; #ifdef RN_SERIALIZABLE_STATE ComponentName getDiffPropsImplementationTarget() const override; folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -565,6 +588,7 @@ Map { #include #include #include +#include #include namespace facebook::react { @@ -583,6 +607,8 @@ class DimensionPropNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -605,6 +631,7 @@ Map { #include #include +#include namespace facebook::react { @@ -627,6 +654,8 @@ class DoublePropNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -649,6 +678,7 @@ Map { #include #include +#include namespace facebook::react { @@ -666,6 +696,8 @@ class EventsNestedObjectNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -688,6 +720,7 @@ Map { #include #include +#include namespace facebook::react { @@ -705,6 +738,8 @@ class EventsNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -727,6 +762,7 @@ Map { #include #include +#include namespace facebook::react { @@ -744,6 +780,8 @@ class InterfaceOnlyComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -766,6 +804,7 @@ Map { #include #include +#include namespace facebook::react { @@ -783,6 +822,8 @@ class ExcludedAndroidComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -805,6 +846,7 @@ Map { #include #include +#include namespace facebook::react { @@ -822,6 +864,8 @@ class ExcludedAndroidIosComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -844,6 +888,7 @@ Map { #include #include +#include namespace facebook::react { @@ -861,6 +906,8 @@ class ExcludedIosComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; class MultiFileIncludedNativeComponentProps final : public ViewProps { @@ -877,6 +924,8 @@ class MultiFileIncludedNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -899,6 +948,7 @@ Map { #include #include +#include namespace facebook::react { @@ -921,6 +971,8 @@ class FloatPropNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -943,6 +995,7 @@ Map { #include #include +#include #include namespace facebook::react { @@ -961,6 +1014,8 @@ class ImagePropNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -983,6 +1038,7 @@ Map { #include #include +#include #include namespace facebook::react { @@ -1001,6 +1057,8 @@ class InsetsPropNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -1023,6 +1081,7 @@ Map { #include #include +#include namespace facebook::react { @@ -1077,6 +1136,8 @@ class Int32EnumPropsNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -1099,6 +1160,7 @@ Map { #include #include +#include namespace facebook::react { @@ -1118,6 +1180,8 @@ class IntegerPropNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -1140,6 +1204,7 @@ Map { #include #include +#include namespace facebook::react { @@ -1150,13 +1215,15 @@ class InterfaceOnlyComponentProps final : public ViewProps { #pragma mark - Props - std::string accessibilityHint{\\"\\"}; + std::string accessibilityHint{std::string{\\"\\"}}; #ifdef RN_SERIALIZABLE_STATE ComponentName getDiffPropsImplementationTarget() const override; folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -1179,6 +1246,7 @@ Map { #include #include +#include namespace facebook::react { @@ -1196,6 +1264,8 @@ class MixedPropNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -1218,6 +1288,7 @@ Map { #include #include +#include #include #include #include @@ -1241,6 +1312,8 @@ class ImageColorPropNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -1263,6 +1336,7 @@ Map { #include #include +#include namespace facebook::react { @@ -1280,6 +1354,8 @@ class NoPropsNoEventsComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -1304,6 +1380,7 @@ Map { #include #include #include +#include #include #include #include @@ -1359,6 +1436,7 @@ static inline folly::dynamic toDynamic(const ObjectPropsIntEnumProp &value) { struct ObjectPropsObjectPropObjectArrayPropStruct { std::vector array{}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ObjectPropsObjectPropObjectArrayPropStruct&) const = default; @@ -1394,6 +1472,7 @@ struct ObjectPropsObjectPropObjectPrimitiveRequiredPropStruct { SharedColor color{}; Point point{}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ObjectPropsObjectPropObjectPrimitiveRequiredPropStruct&) const = default; @@ -1435,7 +1514,8 @@ static inline folly::dynamic toDynamic(const ObjectPropsObjectPropObjectPrimitiv #endif struct ObjectPropsObjectPropNestedPropANestedPropBStruct { - std::string nestedPropC{\\"\\"}; + std::string nestedPropC{std::string{\\"\\"}}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ObjectPropsObjectPropNestedPropANestedPropBStruct&) const = default; @@ -1470,6 +1550,7 @@ static inline folly::dynamic toDynamic(const ObjectPropsObjectPropNestedPropANes struct ObjectPropsObjectPropNestedPropAStruct { ObjectPropsObjectPropNestedPropANestedPropBStruct nestedPropB{}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ObjectPropsObjectPropNestedPropAStruct&) const = default; @@ -1501,7 +1582,8 @@ static inline folly::dynamic toDynamic(const ObjectPropsObjectPropNestedPropAStr #endif struct ObjectPropsObjectPropNestedArrayAsPropertyArrayPropStruct { - std::string stringProp{\\"\\"}; + std::string stringProp{std::string{\\"\\"}}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ObjectPropsObjectPropNestedArrayAsPropertyArrayPropStruct&) const = default; @@ -1546,6 +1628,7 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu struct ObjectPropsObjectPropNestedArrayAsPropertyStruct { std::vector arrayProp{}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ObjectPropsObjectPropNestedArrayAsPropertyStruct&) const = default; @@ -1577,11 +1660,11 @@ static inline folly::dynamic toDynamic(const ObjectPropsObjectPropNestedArrayAsP #endif struct ObjectPropsObjectPropStruct { - std::string stringProp{\\"\\"}; + std::string stringProp{std::string{\\"\\"}}; bool booleanProp{false}; Float floatProp{0.0}; int intProp{0}; - std::string stringUserDefaultProp{\\"user_default\\"}; + std::string stringUserDefaultProp{std::string{\\"user_default\\"}}; bool booleanUserDefaultProp{true}; Float floatUserDefaultProp{3.14}; int intUserDefaultProp{9999}; @@ -1592,6 +1675,7 @@ struct ObjectPropsObjectPropStruct { ObjectPropsObjectPropNestedPropAStruct nestedPropA{}; ObjectPropsObjectPropNestedArrayAsPropertyStruct nestedArrayAsProperty{}; + #ifdef RN_SERIALIZABLE_STATE bool operator==(const ObjectPropsObjectPropStruct&) const = default; @@ -1700,6 +1784,8 @@ class ObjectPropsProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -1722,6 +1808,7 @@ Map { #include #include +#include #include namespace facebook::react { @@ -1740,6 +1827,8 @@ class PointPropNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -1762,6 +1851,7 @@ Map { #include #include +#include namespace facebook::react { @@ -1803,6 +1893,8 @@ class StringEnumPropsNativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -1825,6 +1917,7 @@ Map { #include #include +#include namespace facebook::react { @@ -1835,7 +1928,7 @@ class StringPropComponentProps final : public ViewProps { #pragma mark - Props - std::string accessibilityHint{\\"\\"}; + std::string accessibilityHint{std::string{\\"\\"}}; std::string accessibilityRole{}; #ifdef RN_SERIALIZABLE_STATE @@ -1843,6 +1936,8 @@ class StringPropComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -1865,6 +1960,7 @@ Map { #include #include +#include namespace facebook::react { @@ -1882,6 +1978,8 @@ class MultiFile1NativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; class MultiFile2NativeComponentProps final : public ViewProps { @@ -1898,6 +1996,8 @@ class MultiFile2NativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react @@ -1920,6 +2020,7 @@ Map { #include #include +#include namespace facebook::react { @@ -1937,6 +2038,8 @@ class MultiComponent1NativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; class MultiComponent2NativeComponentProps final : public ViewProps { @@ -1953,6 +2056,8 @@ class MultiComponent2NativeComponentProps final : public ViewProps { folly::dynamic getDiffProps(const Props* prevProps) const override; #endif + + }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/debug/DebugStringConvertible.h b/packages/react-native/ReactCommon/react/renderer/debug/DebugStringConvertible.h index e94972813fb0..1220027322d8 100644 --- a/packages/react-native/ReactCommon/react/renderer/debug/DebugStringConvertible.h +++ b/packages/react-native/ReactCommon/react/renderer/debug/DebugStringConvertible.h @@ -101,6 +101,9 @@ inline std::string toString(const std::string& value) { inline std::string toString(const int& value) { return std::to_string(value); } +inline std::string toString(const unsigned int& value) { + return std::to_string(value); +} inline std::string toString(const bool& value) { return value ? "true" : "false"; } @@ -116,6 +119,19 @@ std::string toString(const std::optional& value) { return toString(value.value()); } +template +std::string toString(const std::vector& value) { + std::string result = "["; + for (size_t i = 0; i < value.size(); i++) { + result += toString(value[i]); + if (i < value.size() - 1) { + result += ", "; + } + } + result += "]"; + return result; +} + /* * *Informal* `DebugStringConvertible` interface. * diff --git a/packages/react-native/scripts/codegen/generate-specs-cli-executor.js b/packages/react-native/scripts/codegen/generate-specs-cli-executor.js index 78ddd7b0c3e6..119fd2b64cea 100644 --- a/packages/react-native/scripts/codegen/generate-specs-cli-executor.js +++ b/packages/react-native/scripts/codegen/generate-specs-cli-executor.js @@ -79,6 +79,8 @@ function generateSpecFromInMemorySchema( ) { validateLibraryType(libraryType); createOutputDirectoryIfNeeded(outputDirectory, libraryName); + const includeGetDebugPropsImplementation = + libraryName.includes('FBReactNativeSpec'); //only generate getDebugString for React Native Core Components utils.getCodegen().generate( { libraryName, @@ -87,6 +89,7 @@ function generateSpecFromInMemorySchema( packageName, assumeNonnull: platform === 'ios', useLocalIncludePaths, + includeGetDebugPropsImplementation, }, { generators: GENERATORS[libraryType][platform], From b7750764a7f9fb9b1280b5777bab71a619f84627 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Fri, 8 Aug 2025 03:50:55 -0700 Subject: [PATCH 2/2] Add basic test for Modal (#53140) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53140 As per title, this change adds the boilerplate code for a Fantom test on Modal ## Changelog: [Internal] - Reviewed By: andrewdacenko Differential Revision: D79805808 --- .../Libraries/Modal/__tests__/Modal-itest.js | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 packages/react-native/Libraries/Modal/__tests__/Modal-itest.js diff --git a/packages/react-native/Libraries/Modal/__tests__/Modal-itest.js b/packages/react-native/Libraries/Modal/__tests__/Modal-itest.js new file mode 100644 index 000000000000..d59f23482863 --- /dev/null +++ b/packages/react-native/Libraries/Modal/__tests__/Modal-itest.js @@ -0,0 +1,41 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment'; +import type {HostInstance} from 'react-native'; + +import * as Fantom from '@react-native/fantom'; +import * as React from 'react'; +import {createRef} from 'react'; +import {Modal} from 'react-native'; +import ensureInstance from 'react-native/src/private/__tests__/utilities/ensureInstance'; +import ReactNativeElement from 'react-native/src/private/webapis/dom/nodes/ReactNativeElement'; + +describe('', () => { + describe('ref', () => { + describe('exampleMethod()', () => { + // more describe('') or tests with it('') + }); + // ... more methods + describe('instance', () => { + it('uses the "RN:ModalHostView" tag name', () => { + const elementRef = createRef(); + const root = Fantom.createRoot(); + Fantom.runTask(() => { + root.render(); + }); + + expect(elementRef.current).toBeInstanceOf(ReactNativeElement); + const element = ensureInstance(elementRef.current, ReactNativeElement); + expect(element.tagName).toBe('RN:ModalHostView'); + }); + }); + }); +});