Support mixed props for components

Summary:
Changelog:
[Changed][General] - Support mixed props for components in codegen

Reviewed By: rickhanlonii

Differential Revision: D43894460

fbshipit-source-id: e5faf2f83e6829170cdce550e923c3c09ddff0b0
This commit is contained in:
Genki Kondo
2023-03-19 16:47:22 -07:00
committed by Facebook GitHub Bot
parent e5b97f0f13
commit 0ae5e50e37
47 changed files with 949 additions and 4 deletions
@@ -0,0 +1,25 @@
/**
* 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.
*
* @format
* @flow strict-local
*/
import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTypes';
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
import type {HostComponent} from 'react-native/Libraries/Renderer/shims/ReactNativeTypes';
import type {UnsafeMixed} from 'react-native/Libraries/Types/CodegenTypes';
type NativeProps = $ReadOnly<{|
...ViewProps,
// Props
mixedProp?: UnsafeMixed,
|}>;
export default (codegenNativeComponent<NativeProps>(
'MixedPropNativeComponentView',
): HostComponent<NativeProps>);
@@ -330,6 +330,34 @@ namespace react {
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateComponentDescriptorH can generate for 'MixedPropNativeComponent.js' 1`] = `
Object {
"ComponentDescriptors.h": "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateComponentDescriptorH.js
*/
#pragma once
#include <react/renderer/components/RNCodegenModuleFixtures/ShadowNodes.h>
#include <react/renderer/core/ConcreteComponentDescriptor.h>
namespace facebook {
namespace react {
using MixedPropNativeComponentViewComponentDescriptor = ConcreteComponentDescriptor<MixedPropNativeComponentViewShadowNode>;
} // namespace react
} // namespace facebook
",
@@ -300,6 +300,31 @@ NS_ASSUME_NONNULL_END",
}
`;
exports[`GenerateComponentHObjCpp can generate for 'MixedPropNativeComponent.js' 1`] = `
Object {
"RCTComponentViewHelpers.h": "/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateComponentHObjCpp.js
*/
#import <Foundation/Foundation.h>
#import <React/RCTDefines.h>
#import <React/RCTLog.h>
NS_ASSUME_NONNULL_BEGIN
@protocol RCTMixedPropNativeComponentViewViewProtocol <NSObject>
@end
NS_ASSUME_NONNULL_END",
}
`;
exports[`GenerateComponentHObjCpp can generate for 'MultiNativePropNativeComponent.js' 1`] = `
Object {
"RCTComponentViewHelpers.h": "/**
@@ -362,6 +362,31 @@ void InterfaceOnlyNativeComponentViewEventEmitter::onChange(OnChange event) cons
});
}
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateEventEmitterCpp can generate for 'MixedPropNativeComponent.js' 1`] = `
Object {
"EventEmitters.cpp": "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateEventEmitterCpp.js
*/
#include <react/renderer/components/RNCodegenModuleFixtures/EventEmitters.h>
namespace facebook {
namespace react {
} // namespace react
} // namespace facebook
",
@@ -461,6 +461,40 @@ class JSI_EXPORT InterfaceOnlyNativeComponentViewEventEmitter : public ViewEvent
};
void onChange(OnChange value) const;
};
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateEventEmitterH can generate for 'MixedPropNativeComponent.js' 1`] = `
Object {
"EventEmitters.h": "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateEventEmitterH.js
*/
#pragma once
#include <react/renderer/components/view/ViewEventEmitter.h>
#include <jsi/jsi.h>
namespace facebook {
namespace react {
class JSI_EXPORT MixedPropNativeComponentViewEventEmitter : public ViewEventEmitter {
public:
using ViewEventEmitter::ViewEventEmitter;
};
} // namespace react
@@ -421,6 +421,39 @@ InterfaceOnlyNativeComponentViewProps::InterfaceOnlyNativeComponentViewProps(
}
`;
exports[`GeneratePropsCpp can generate for 'MixedPropNativeComponent.js' 1`] = `
Object {
"Props.cpp": "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsCpp.js
*/
#include <react/renderer/components/RNCodegenModuleFixtures/Props.h>
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/core/propsConversions.h>
namespace facebook {
namespace react {
MixedPropNativeComponentViewProps::MixedPropNativeComponentViewProps(
const PropsParserContext &context,
const MixedPropNativeComponentViewProps &sourceProps,
const RawProps &rawProps): ViewProps(context, sourceProps, rawProps),
mixedProp(convertRawProp(context, rawProps, \\"mixedProp\\", sourceProps.mixedProp, {}))
{}
} // namespace react
} // namespace facebook
",
}
`;
exports[`GeneratePropsCpp can generate for 'MultiNativePropNativeComponent.js' 1`] = `
Object {
"Props.cpp": "
@@ -625,6 +625,42 @@ class JSI_EXPORT InterfaceOnlyNativeComponentViewProps final : public ViewProps
}
`;
exports[`GeneratePropsH can generate for 'MixedPropNativeComponent.js' 1`] = `
Object {
"Props.h": "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsH.js
*/
#pragma once
#include <jsi/jsi.h>
#include <react/renderer/components/view/ViewProps.h>
#include <react/renderer/core/PropsParserContext.h>
namespace facebook {
namespace react {
class JSI_EXPORT MixedPropNativeComponentViewProps final : public ViewProps {
public:
MixedPropNativeComponentViewProps() = default;
MixedPropNativeComponentViewProps(const PropsParserContext& context, const MixedPropNativeComponentViewProps &sourceProps, const RawProps &rawProps);
#pragma mark - Props
folly::dynamic mixedProp{};
};
} // namespace react
} // namespace facebook
",
}
`;
exports[`GeneratePropsH can generate for 'MultiNativePropNativeComponent.js' 1`] = `
Object {
"Props.h": "
@@ -505,6 +505,44 @@ public class InterfaceOnlyNativeComponentViewManagerDelegate<T extends View, U e
}
`;
exports[`GeneratePropsJavaDelegate can generate for 'MixedPropNativeComponent.js' 1`] = `
Object {
"java/com/facebook/react/viewmanagers/MixedPropNativeComponentViewManagerDelegate.java": "/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsJavaDelegate.js
*/
package com.facebook.react.viewmanagers;
import android.view.View;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.DynamicFromObject;
import com.facebook.react.uimanager.BaseViewManagerDelegate;
import com.facebook.react.uimanager.BaseViewManagerInterface;
public class MixedPropNativeComponentViewManagerDelegate<T extends View, U extends BaseViewManagerInterface<T> & MixedPropNativeComponentViewManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
public MixedPropNativeComponentViewManagerDelegate(U viewManager) {
super(viewManager);
}
@Override
public void setProperty(T view, String propName, @Nullable Object value) {
switch (propName) {
case \\"mixedProp\\":
mViewManager.setMixedProp(view, new DynamicFromObject(value));
break;
default:
super.setProperty(view, propName, value);
}
}
}
",
}
`;
exports[`GeneratePropsJavaDelegate can generate for 'MultiNativePropNativeComponent.js' 1`] = `
Object {
"java/com/facebook/react/viewmanagers/MultiNativePropNativeComponentViewManagerDelegate.java": "/**
@@ -296,6 +296,29 @@ public interface InterfaceOnlyNativeComponentViewManagerInterface<T extends View
}
`;
exports[`GeneratePropsJavaInterface can generate for 'MixedPropNativeComponent.js' 1`] = `
Object {
"java/com/facebook/react/viewmanagers/MixedPropNativeComponentViewManagerInterface.java": "/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsJavaInterface.js
*/
package com.facebook.react.viewmanagers;
import android.view.View;
import com.facebook.react.bridge.Dynamic;
public interface MixedPropNativeComponentViewManagerInterface<T extends View> {
void setMixedProp(T view, Dynamic value);
}
",
}
`;
exports[`GeneratePropsJavaInterface can generate for 'MultiNativePropNativeComponent.js' 1`] = `
Object {
"java/com/facebook/react/viewmanagers/MultiNativePropNativeComponentViewManagerInterface.java": "/**
@@ -294,6 +294,31 @@ namespace react {
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateShadowNodeCpp can generate for 'MixedPropNativeComponent.js' 1`] = `
Object {
"ShadowNodes.cpp": "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateShadowNodeCpp.js
*/
#include <react/renderer/components/RNCodegenModuleFixtures/ShadowNodes.h>
namespace facebook {
namespace react {
extern const char MixedPropNativeComponentViewComponentName[] = \\"MixedPropNativeComponentView\\";
} // namespace react
} // namespace facebook
",
@@ -465,6 +465,46 @@ namespace react {
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateShadowNodeH can generate for 'MixedPropNativeComponent.js' 1`] = `
Object {
"ShadowNodes.h": "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateShadowNodeH.js
*/
#pragma once
#include <react/renderer/components/RNCodegenModuleFixtures/EventEmitters.h>
#include <react/renderer/components/RNCodegenModuleFixtures/Props.h>
#include <react/renderer/components/RNCodegenModuleFixtures/States.h>
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
#include <jsi/jsi.h>
namespace facebook {
namespace react {
JSI_EXPORT extern const char MixedPropNativeComponentViewComponentName[];
/*
* \`ShadowNode\` for <MixedPropNativeComponentView> component.
*/
using MixedPropNativeComponentViewShadowNode = ConcreteViewShadowNode<
MixedPropNativeComponentViewComponentName,
MixedPropNativeComponentViewProps,
MixedPropNativeComponentViewEventEmitter,
MixedPropNativeComponentViewState>;
} // namespace react
} // namespace facebook
",
@@ -509,6 +509,40 @@ export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL
}
`;
exports[`GenerateViewConfigJs can generate for 'MixedPropNativeComponent.js' 1`] = `
Map {
"RNCodegenModuleFixturesNativeViewConfig.js" => "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @flow
*
* @generated by codegen project: GenerateViewConfigJs.js
*/
'use strict';
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
let nativeComponentName = 'MixedPropNativeComponentView';
export const __INTERNAL_VIEW_CONFIG = {
uiViewClassName: 'MixedPropNativeComponentView',
validAttributes: {
mixedProp: true,
},
};
export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL_VIEW_CONFIG);
",
}
`;
exports[`GenerateViewConfigJs can generate for 'MultiNativePropNativeComponent.js' 1`] = `
Map {
"RNCodegenModuleFixturesNativeViewConfig.js" => "
+6 -1
View File
@@ -58,6 +58,10 @@ export type ObjectTypeAnnotation<+T> = $ReadOnly<{
baseTypes?: $ReadOnlyArray<string>,
}>;
export type MixedTypeAnnotation = $ReadOnly<{
type: 'MixedTypeAnnotation',
}>;
type FunctionTypeAnnotation<+P, +R> = $ReadOnly<{
type: 'FunctionTypeAnnotation',
params: $ReadOnlyArray<NamedShape<P>>,
@@ -177,7 +181,8 @@ export type PropTypeAnnotation =
type: 'ArrayTypeAnnotation',
elementType: ObjectTypeAnnotation<PropTypeAnnotation>,
}>,
}>;
}>
| MixedTypeAnnotation;
export type ReservedPropTypeAnnotation = $ReadOnly<{
type: 'ReservedPropTypeAnnotation',
@@ -122,6 +122,8 @@ function getNativeTypeFromAnnotation(
return getEnumName(componentName, prop.name);
case 'Int32EnumTypeAnnotation':
return getEnumName(componentName, prop.name);
case 'MixedTypeAnnotation':
return 'folly::dynamic';
default:
(typeAnnotation: empty);
throw new Error(
@@ -200,6 +200,8 @@ function convertDefaultTypeToString(
prop.name,
typeAnnotation.default,
)}`;
case 'MixedTypeAnnotation':
return '';
default:
(typeAnnotation: empty);
throw new Error(`Unsupported type annotation: ${typeAnnotation.type}`);
@@ -676,6 +676,8 @@ function generateStruct(
}
generateStruct(structs, componentName, nameParts.concat([name]), props);
return;
case 'MixedTypeAnnotation':
return;
default:
(property.typeAnnotation.type: empty);
throw new Error(
@@ -144,6 +144,8 @@ function getJavaValueForProp(
return '(String) value';
case 'Int32EnumTypeAnnotation':
return `value == null ? ${typeAnnotation.default} : ((Double) value).intValue()`;
case 'MixedTypeAnnotation':
return 'new DynamicFromObject(value)';
default:
(typeAnnotation: empty);
throw new Error('Received invalid typeAnnotation');
@@ -127,6 +127,8 @@ function getJavaValueForProp(
case 'Int32EnumTypeAnnotation':
addNullable(imports);
return '@Nullable Integer value';
case 'MixedTypeAnnotation':
return 'Dynamic value';
default:
(typeAnnotation: empty);
throw new Error('Received invalid typeAnnotation');
@@ -20,6 +20,7 @@ import type {
FloatTypeAnnotation,
Int32TypeAnnotation,
PropTypeAnnotation,
MixedTypeAnnotation,
} from '../../../CodegenSchema';
const {capitalize} = require('../../Utils');
@@ -89,7 +90,8 @@ export type PojoTypeAnnotation =
type: 'ArrayTypeAnnotation',
elementType: PojoTypeAliasAnnotation,
}>,
}>;
}>
| MixedTypeAnnotation;
class PojoCollector {
_pojos: Map<string, Pojo> = new Map();
@@ -24,6 +24,7 @@ function toJavaType(
addImport('com.facebook.react.bridge.ReadableMap');
const importArrayList = () => addImport('java.util.ArrayList');
const importYogaValue = () => addImport('com.facebook.yoga.YogaValue');
const importDynamic = () => addImport('com.facebook.react.bridge.Dynamic');
switch (typeAnnotation.type) {
/**
* Primitives
@@ -222,6 +223,11 @@ function toJavaType(
return `ArrayList<${elementTypeString}>`;
}
case 'MixedTypeAnnotation': {
importDynamic();
return 'Dynamic';
}
default: {
(typeAnnotation.type: empty);
throw new Error(
@@ -60,6 +60,7 @@ function getReactDiffProcessValue(typeAnnotation: PropTypeAnnotation) {
case 'ObjectTypeAnnotation':
case 'StringEnumTypeAnnotation':
case 'Int32EnumTypeAnnotation':
case 'MixedTypeAnnotation':
return j.literal(true);
case 'ReservedPropTypeAnnotation':
switch (typeAnnotation.name) {
@@ -117,6 +117,14 @@ function getImports(
if (typeAnnotation.type === 'ObjectTypeAnnotation') {
imports.add('import com.facebook.react.bridge.ReadableMap;');
}
if (typeAnnotation.type === 'MixedTypeAnnotation') {
if (type === 'delegate') {
imports.add('import com.facebook.react.bridge.DynamicFromObject;');
} else {
imports.add('import com.facebook.react.bridge.Dynamic;');
}
}
});
return imports;
@@ -1123,6 +1123,35 @@ const INT32_ENUM_PROP: SchemaType = {
},
};
const MIXED_PROP: SchemaType = {
modules: {
CustomView: {
type: 'Component',
components: {
MixedPropNativeComponent: {
extendsProps: [
{
type: 'ReactNativeBuiltInType',
knownTypeName: 'ReactNativeCoreViewProps',
},
],
events: [],
props: [
{
name: 'mixedProp',
optional: false,
typeAnnotation: {
type: 'MixedTypeAnnotation',
},
},
],
commands: [],
},
},
},
},
};
const EVENT_PROPS: SchemaType = {
modules: {
Switch: {
@@ -1701,6 +1730,7 @@ module.exports = {
MULTI_NATIVE_PROP,
STRING_ENUM_PROP,
INT32_ENUM_PROP,
MIXED_PROP,
EVENT_PROPS,
EVENTS_WITH_PAPER_NAME,
EVENT_NESTED_OBJECT_PROPS,
@@ -555,6 +555,34 @@ namespace react {
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateComponentDescriptorH can generate fixture MIXED_PROP 1`] = `
Map {
"ComponentDescriptors.h" => "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateComponentDescriptorH.js
*/
#pragma once
#include <react/renderer/components/MIXED_PROP/ShadowNodes.h>
#include <react/renderer/core/ConcreteComponentDescriptor.h>
namespace facebook {
namespace react {
using MixedPropNativeComponentComponentDescriptor = ConcreteComponentDescriptor<MixedPropNativeComponentShadowNode>;
} // namespace react
} // namespace facebook
",
@@ -634,6 +634,31 @@ NS_ASSUME_NONNULL_END",
}
`;
exports[`GenerateComponentHObjCpp can generate fixture MIXED_PROP 1`] = `
Map {
"RCTComponentViewHelpers.h" => "/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateComponentHObjCpp.js
*/
#import <Foundation/Foundation.h>
#import <React/RCTDefines.h>
#import <React/RCTLog.h>
NS_ASSUME_NONNULL_BEGIN
@protocol RCTMixedPropNativeComponentViewProtocol <NSObject>
@end
NS_ASSUME_NONNULL_END",
}
`;
exports[`GenerateComponentHObjCpp can generate fixture MULTI_NATIVE_PROP 1`] = `
Map {
"RCTComponentViewHelpers.h" => "/**
@@ -558,6 +558,31 @@ void InterfaceOnlyComponentEventEmitter::onChange(OnChange event) const {
});
}
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateEventEmitterCpp can generate fixture MIXED_PROP 1`] = `
Map {
"EventEmitters.cpp" => "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateEventEmitterCpp.js
*/
#include <react/renderer/components/MIXED_PROP/EventEmitters.h>
namespace facebook {
namespace react {
} // namespace react
} // namespace facebook
",
@@ -733,6 +733,40 @@ class JSI_EXPORT InterfaceOnlyComponentEventEmitter : public ViewEventEmitter {
};
void onChange(OnChange value) const;
};
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateEventEmitterH can generate fixture MIXED_PROP 1`] = `
Map {
"EventEmitters.h" => "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateEventEmitterH.js
*/
#pragma once
#include <react/renderer/components/view/ViewEventEmitter.h>
#include <jsi/jsi.h>
namespace facebook {
namespace react {
class JSI_EXPORT MixedPropNativeComponentEventEmitter : public ViewEventEmitter {
public:
using ViewEventEmitter::ViewEventEmitter;
};
} // namespace react
@@ -694,6 +694,39 @@ InterfaceOnlyComponentProps::InterfaceOnlyComponentProps(
}
`;
exports[`GeneratePropsCpp can generate fixture MIXED_PROP 1`] = `
Map {
"Props.cpp" => "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsCpp.js
*/
#include <react/renderer/components/MIXED_PROP/Props.h>
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/core/propsConversions.h>
namespace facebook {
namespace react {
MixedPropNativeComponentProps::MixedPropNativeComponentProps(
const PropsParserContext &context,
const MixedPropNativeComponentProps &sourceProps,
const RawProps &rawProps): ViewProps(context, sourceProps, rawProps),
mixedProp(convertRawProp(context, rawProps, \\"mixedProp\\", sourceProps.mixedProp, {}))
{}
} // namespace react
} // namespace facebook
",
}
`;
exports[`GeneratePropsCpp can generate fixture MULTI_NATIVE_PROP 1`] = `
Map {
"Props.cpp" => "
@@ -999,6 +999,42 @@ class JSI_EXPORT InterfaceOnlyComponentProps final : public ViewProps {
}
`;
exports[`GeneratePropsH can generate fixture MIXED_PROP 1`] = `
Map {
"Props.h" => "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsH.js
*/
#pragma once
#include <jsi/jsi.h>
#include <react/renderer/components/view/ViewProps.h>
#include <react/renderer/core/PropsParserContext.h>
namespace facebook {
namespace react {
class JSI_EXPORT MixedPropNativeComponentProps final : public ViewProps {
public:
MixedPropNativeComponentProps() = default;
MixedPropNativeComponentProps(const PropsParserContext& context, const MixedPropNativeComponentProps &sourceProps, const RawProps &rawProps);
#pragma mark - Props
folly::dynamic mixedProp{};
};
} // namespace react
} // namespace facebook
",
}
`;
exports[`GeneratePropsH can generate fixture MULTI_NATIVE_PROP 1`] = `
Map {
"Props.h" => "
@@ -785,6 +785,44 @@ public class InterfaceOnlyComponentManagerDelegate<T extends View, U extends Bas
}
`;
exports[`GeneratePropsJavaDelegate can generate fixture MIXED_PROP 1`] = `
Map {
"java/com/facebook/react/viewmanagers/MixedPropNativeComponentManagerDelegate.java" => "/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsJavaDelegate.js
*/
package com.facebook.react.viewmanagers;
import android.view.View;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.DynamicFromObject;
import com.facebook.react.uimanager.BaseViewManagerDelegate;
import com.facebook.react.uimanager.BaseViewManagerInterface;
public class MixedPropNativeComponentManagerDelegate<T extends View, U extends BaseViewManagerInterface<T> & MixedPropNativeComponentManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
public MixedPropNativeComponentManagerDelegate(U viewManager) {
super(viewManager);
}
@Override
public void setProperty(T view, String propName, @Nullable Object value) {
switch (propName) {
case \\"mixedProp\\":
mViewManager.setMixedProp(view, new DynamicFromObject(value));
break;
default:
super.setProperty(view, propName, value);
}
}
}
",
}
`;
exports[`GeneratePropsJavaDelegate can generate fixture MULTI_NATIVE_PROP 1`] = `
Map {
"java/com/facebook/react/viewmanagers/ImageColorPropNativeComponentManagerDelegate.java" => "/**
@@ -458,6 +458,29 @@ public interface InterfaceOnlyComponentManagerInterface<T extends View> {
}
`;
exports[`GeneratePropsJavaInterface can generate fixture MIXED_PROP 1`] = `
Map {
"java/com/facebook/react/viewmanagers/MixedPropNativeComponentManagerInterface.java" => "/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsJavaInterface.js
*/
package com.facebook.react.viewmanagers;
import android.view.View;
import com.facebook.react.bridge.Dynamic;
public interface MixedPropNativeComponentManagerInterface<T extends View> {
void setMixedProp(T view, Dynamic value);
}
",
}
`;
exports[`GeneratePropsJavaInterface can generate fixture MULTI_NATIVE_PROP 1`] = `
Map {
"java/com/facebook/react/viewmanagers/ImageColorPropNativeComponentManagerInterface.java" => "/**
@@ -758,6 +758,34 @@ public class InterfaceOnlyComponentProps {
}
`;
exports[`GeneratePropsJavaPojo can generate fixture MIXED_PROP 1`] = `
Map {
"java/com/facebook/react/viewmanagers/CustomView/MixedPropNativeComponentProps.java" => "/**
* 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.
*
* @generated by codegen project: GeneratePropsJavaPojo.js
*/
package com.facebook.react.viewmanagers.CustomView;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.Dynamic;
@DoNotStrip
public class MixedPropNativeComponentProps {
private Dynamic mMixedProp;
@DoNotStrip
public Dynamic getMixedProp() {
return mMixedProp;
}
}
",
}
`;
exports[`GeneratePropsJavaPojo can generate fixture MULTI_NATIVE_PROP 1`] = `
Map {
"java/com/facebook/react/viewmanagers/Slider/ImageColorPropNativeComponentProps.java" => "/**
@@ -495,6 +495,31 @@ namespace react {
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateShadowNodeCpp can generate fixture MIXED_PROP 1`] = `
Map {
"ShadowNodes.cpp" => "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateShadowNodeCpp.js
*/
#include <react/renderer/components/MIXED_PROP/ShadowNodes.h>
namespace facebook {
namespace react {
extern const char MixedPropNativeComponentComponentName[] = \\"MixedPropNativeComponent\\";
} // namespace react
} // namespace facebook
",
@@ -787,6 +787,46 @@ namespace react {
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateShadowNodeH can generate fixture MIXED_PROP 1`] = `
Map {
"ShadowNodes.h" => "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateShadowNodeH.js
*/
#pragma once
#include <react/renderer/components/MIXED_PROP/EventEmitters.h>
#include <react/renderer/components/MIXED_PROP/Props.h>
#include <react/renderer/components/MIXED_PROP/States.h>
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
#include <jsi/jsi.h>
namespace facebook {
namespace react {
JSI_EXPORT extern const char MixedPropNativeComponentComponentName[];
/*
* \`ShadowNode\` for <MixedPropNativeComponent> component.
*/
using MixedPropNativeComponentShadowNode = ConcreteViewShadowNode<
MixedPropNativeComponentComponentName,
MixedPropNativeComponentProps,
MixedPropNativeComponentEventEmitter,
MixedPropNativeComponentState>;
} // namespace react
} // namespace facebook
",
@@ -474,6 +474,30 @@ namespace react {
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateStateCpp can generate fixture MIXED_PROP 1`] = `
Map {
"States.cpp" => "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateStateCpp.js
*/
#include <react/renderer/components/MIXED_PROP/States.h>
namespace facebook {
namespace react {
} // namespace react
} // namespace facebook
",
@@ -804,6 +804,47 @@ namespace react {
} // namespace react
} // namespace facebook",
}
`;
exports[`GenerateStateH can generate fixture MIXED_PROP 1`] = `
Map {
"States.h" => "/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateStateH.js
*/
#pragma once
#ifdef ANDROID
#include <folly/dynamic.h>
#include <react/renderer/mapbuffer/MapBuffer.h>
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
#endif
namespace facebook {
namespace react {
class MixedPropNativeComponentState {
public:
MixedPropNativeComponentState() = default;
#ifdef ANDROID
MixedPropNativeComponentState(MixedPropNativeComponentState const &previousState, folly::dynamic data){};
folly::dynamic getDynamic() const {
return {};
};
MapBuffer getMapBuffer() const {
return MapBufferBuilder::EMPTY();
};
#endif
};
} // namespace react
} // namespace facebook",
}
@@ -899,6 +899,41 @@ TEST(InterfaceOnlyComponentProps_accessibilityHint, etc) {
}
`;
exports[`GenerateTests can generate fixture MIXED_PROP 1`] = `
Map {
"Tests.cpp" => "/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateTests.js
* */
#include <gtest/gtest.h>
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/components/MIXED_PROP/Props.h>
#include <react/renderer/core/RawProps.h>
#include <react/renderer/core/RawPropsParser.h>
#include <react/renderer/core/propsConversions.h>
using namespace facebook::react;
TEST(MixedPropNativeComponentProps_DoesNotDie, etc) {
auto propParser = RawPropsParser();
propParser.prepare<MixedPropNativeComponentProps>();
auto const &sourceProps = MixedPropNativeComponentProps();
auto const &rawProps = RawProps(folly::dynamic::object(\\"xx_invalid_xx\\", \\"xx_invalid_xx\\"));
ContextContainer contextContainer{};
PropsParserContext parserContext{-1, contextContainer};
rawProps.parse(propParser, parserContext);
MixedPropNativeComponentProps(parserContext, sourceProps, rawProps);
}",
}
`;
exports[`GenerateTests can generate fixture MULTI_NATIVE_PROP 1`] = `
Map {
"Tests.cpp" => "/**
@@ -41,6 +41,7 @@ Class<RCTComponentViewProtocol> ObjectPropsCls(void) __attribute__((used)); // O
Class<RCTComponentViewProtocol> ImageColorPropNativeComponentCls(void) __attribute__((used)); // MULTI_NATIVE_PROP
Class<RCTComponentViewProtocol> StringEnumPropsNativeComponentCls(void) __attribute__((used)); // STRING_ENUM_PROP
Class<RCTComponentViewProtocol> Int32EnumPropsNativeComponentCls(void) __attribute__((used)); // INT32_ENUM_PROP
Class<RCTComponentViewProtocol> MixedPropNativeComponentCls(void) __attribute__((used)); // MIXED_PROP
Class<RCTComponentViewProtocol> EventsNativeComponentCls(void) __attribute__((used)); // EVENT_PROPS
Class<RCTComponentViewProtocol> InterfaceOnlyComponentCls(void) __attribute__((used)); // EVENTS_WITH_PAPER_NAME
Class<RCTComponentViewProtocol> EventsNestedObjectNativeComponentCls(void) __attribute__((used)); // EVENT_NESTED_OBJECT_PROPS
@@ -58,6 +58,8 @@ Class<RCTComponentViewProtocol> RCTThirdPartyFabricComponentsProvider(const char
{\\"Int32EnumPropsNativeComponent\\", Int32EnumPropsNativeComponentCls}, // INT32_ENUM_PROP
{\\"MixedPropNativeComponent\\", MixedPropNativeComponentCls}, // MIXED_PROP
{\\"EventsNativeComponent\\", EventsNativeComponentCls}, // EVENT_PROPS
{\\"InterfaceOnlyComponent\\", InterfaceOnlyComponentCls}, // EVENTS_WITH_PAPER_NAME
@@ -817,6 +817,40 @@ export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL
}
`;
exports[`GenerateViewConfigJs can generate fixture MIXED_PROP 1`] = `
Map {
"MIXED_PROPNativeViewConfig.js" => "
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @flow
*
* @generated by codegen project: GenerateViewConfigJs.js
*/
'use strict';
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
let nativeComponentName = 'MixedPropNativeComponent';
export const __INTERNAL_VIEW_CONFIG = {
uiViewClassName: 'MixedPropNativeComponent',
validAttributes: {
mixedProp: true,
},
};
export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL_VIEW_CONFIG);
",
}
`;
exports[`GenerateViewConfigJs can generate fixture MULTI_NATIVE_PROP 1`] = `
Map {
"MULTI_NATIVE_PROPNativeViewConfig.js" => "
@@ -209,7 +209,7 @@ const ALL_PROP_TYPES_NO_EVENTS = `
const codegenNativeComponent = require('codegenNativeComponent');
import type {Int32, Double, Float, WithDefault} from 'CodegenTypes';
import type {Int32, Double, Float, WithDefault, UnsafeMixed} from 'CodegenTypes';
import type {ImageSource} from 'ImageSource';
import type {ColorValue, ColorArrayValue, PointValue, EdgeInsetsValue, DimensionValue} from 'StyleSheetTypes';
import type {ViewProps} from 'ViewPropTypes';
@@ -317,6 +317,10 @@ type ModuleProps = $ReadOnly<{|
dimension_optional_key?: DimensionValue,
dimension_optional_value: ?DimensionValue,
dimension_optional_both?: ?DimensionValue,
// Mixed props
mixed_required: UnsafeMixed,
mixed_optional_key?: UnsafeMixed,
|}>;
export default (codegenNativeComponent<ModuleProps, Options>(
@@ -571,6 +571,20 @@ exports[`RN Codegen Flow Parser can generate fixture ALL_PROP_TYPES_NO_EVENTS 1`
'type': 'ReservedPropTypeAnnotation',
'name': 'DimensionPrimitive'
}
},
{
'name': 'mixed_required',
'optional': false,
'typeAnnotation': {
'type': 'MixedTypeAnnotation'
}
},
{
'name': 'mixed_optional_key',
'optional': true,
'typeAnnotation': {
'type': 'MixedTypeAnnotation'
}
}
],
'commands': []
@@ -391,6 +391,10 @@ function getTypeAnnotation<+T>(
throw new Error(
`Cannot use "${type}" type annotation for "${name}": must use a specific numeric type like Int32, Double, or Float`,
);
case 'UnsafeMixed':
return {
type: 'MixedTypeAnnotation',
};
default:
(type: empty);
throw new Error(
@@ -197,7 +197,7 @@ const ALL_PROP_TYPES_NO_EVENTS = `
const codegenNativeComponent = require('codegenNativeComponent');
import type {Int32, Double, Float, WithDefault} from 'CodegenTypes';
import type {Int32, Double, Float, WithDefault, UnsafeMixed} from 'CodegenTypes';
import type {ImageSource} from 'ImageSource';
import type {
ColorValue,
@@ -310,6 +310,10 @@ export interface ModuleProps extends ViewProps {
dimension_optional_key?: DimensionValue;
dimension_optional_value: DimensionValue | null | undefined;
dimension_optional_both?: DimensionValue | null | undefined;
// Mixed props
mixed_required: UnsafeMixed,
mixed_optional_key?: UnsafeMixed,
}
export default codegenNativeComponent<ModuleProps>(
@@ -569,6 +569,20 @@ exports[`RN Codegen TypeScript Parser can generate fixture ALL_PROP_TYPES_NO_EVE
'type': 'ReservedPropTypeAnnotation',
'name': 'DimensionPrimitive'
}
},
{
'name': 'mixed_required',
'optional': false,
'typeAnnotation': {
'type': 'MixedTypeAnnotation'
}
},
{
'name': 'mixed_optional_key',
'optional': true,
'typeAnnotation': {
'type': 'MixedTypeAnnotation'
}
}
],
'commands': []
@@ -262,6 +262,10 @@ function getCommonTypeAnnotation<T>(
return {
type: 'StringTypeAnnotation',
};
case 'UnsafeMixed':
return {
type: 'MixedTypeAnnotation',
};
default:
return undefined;
}
+1
View File
@@ -29,6 +29,7 @@ export type Double = number;
export type Float = number;
export type Int32 = number;
export type UnsafeObject = $FlowFixMe; // Object is forbidden in strict mode
export type UnsafeMixed = mixed;
type DefaultTypes = number | boolean | string | $ReadOnlyArray<string>;
// Default handling, ignore the unused value