mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add support for enum event arguments
Summary:
This diff adds codegen support for event arguments such as:
```
type Event = $ReadOnly<{|
orientation: ('portrait' | 'landscape'),
|}>;
```
Facebook
#noautofix
Reviewed By: shergin
Differential Revision: D15769046
fbshipit-source-id: b2ad8d044b06c2394a9aa75a198ea504672cde68
This commit is contained in:
committed by
Facebook Github Bot
parent
23df1b09a8
commit
2deb39b8f6
@@ -31,6 +31,14 @@ export type ObjectPropertyType =
|
||||
name: string,
|
||||
optional: boolean,
|
||||
|}>
|
||||
| $ReadOnly<{|
|
||||
type: 'StringEnumTypeAnnotation',
|
||||
name: string,
|
||||
optional: boolean,
|
||||
options: $ReadOnlyArray<{|
|
||||
name: string,
|
||||
|}>,
|
||||
|}>
|
||||
| $ReadOnly<{|
|
||||
type: 'ObjectTypeAnnotation',
|
||||
name: string,
|
||||
|
||||
@@ -70,6 +70,15 @@ function generateSetter(variableName, propertyName, propertyParts) {
|
||||
return `${variableName}.setProperty(runtime, "${propertyName}", ${eventChain}`;
|
||||
}
|
||||
|
||||
function generateEnumSetter(variableName, propertyName, propertyParts) {
|
||||
const trailingPeriod = propertyParts.length === 0 ? '' : '.';
|
||||
const eventChain = `event.${propertyParts.join(
|
||||
'.',
|
||||
)}${trailingPeriod}${propertyName})`;
|
||||
|
||||
return `${variableName}.setProperty(runtime, "${propertyName}", toString(${eventChain});`;
|
||||
}
|
||||
|
||||
function generateSetters(
|
||||
parentPropertyName: string,
|
||||
properties: $ReadOnlyArray<ObjectPropertyType>,
|
||||
@@ -87,6 +96,12 @@ function generateSetters(
|
||||
eventProperty.name,
|
||||
propertyParts,
|
||||
);
|
||||
case 'StringEnumTypeAnnotation':
|
||||
return generateEnumSetter(
|
||||
parentPropertyName,
|
||||
eventProperty.name,
|
||||
propertyParts,
|
||||
);
|
||||
case 'ObjectTypeAnnotation':
|
||||
const propertyName = eventProperty.name;
|
||||
return `
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
const nullthrows = require('nullthrows');
|
||||
|
||||
const {getCppTypeForAnnotation} = require('./CppHelpers.js');
|
||||
const {getCppTypeForAnnotation, toSafeCppString} = require('./CppHelpers.js');
|
||||
const {generateStructName} = require('./EventEmitterHelpers.js');
|
||||
|
||||
import type {
|
||||
@@ -67,6 +67,16 @@ struct ::_STRUCT_NAME_:: {
|
||||
};
|
||||
`.trim();
|
||||
|
||||
const enumTemplate = `enum class ::_ENUM_NAME_:: {
|
||||
::_VALUES_::
|
||||
};
|
||||
|
||||
inline char const *toString(const ::_ENUM_NAME_:: value) {
|
||||
switch (value) {
|
||||
::_TO_CASES_::
|
||||
}
|
||||
}`.trim();
|
||||
|
||||
function getNativeTypeFromAnnotation(
|
||||
componentName: string,
|
||||
eventProperty: ObjectPropertyType,
|
||||
@@ -80,6 +90,11 @@ function getNativeTypeFromAnnotation(
|
||||
case 'Int32TypeAnnotation':
|
||||
case 'FloatTypeAnnotation':
|
||||
return getCppTypeForAnnotation(type);
|
||||
case 'StringEnumTypeAnnotation':
|
||||
return generateStructName(
|
||||
componentName,
|
||||
nameParts.concat([eventProperty.name]),
|
||||
);
|
||||
case 'ObjectTypeAnnotation':
|
||||
return generateStructName(
|
||||
componentName,
|
||||
@@ -90,6 +105,29 @@ function getNativeTypeFromAnnotation(
|
||||
throw new Error(`Receieved invalid event property type ${type}`);
|
||||
}
|
||||
}
|
||||
function generateEnum(structs, componentName, options, nameParts) {
|
||||
const structName = generateStructName(componentName, nameParts);
|
||||
const fields = options
|
||||
.map((option, index) => `${toSafeCppString(option.name)}`)
|
||||
.join(',\n ');
|
||||
|
||||
const toCases = options
|
||||
.map(
|
||||
option =>
|
||||
`case ${structName}::${toSafeCppString(option.name)}: return "${
|
||||
option.name
|
||||
}";`,
|
||||
)
|
||||
.join('\n' + ' ');
|
||||
|
||||
structs.set(
|
||||
structName,
|
||||
enumTemplate
|
||||
.replace(/::_ENUM_NAME_::/g, structName)
|
||||
.replace('::_VALUES_::', fields)
|
||||
.replace('::_TO_CASES_::', toCases),
|
||||
);
|
||||
}
|
||||
|
||||
function generateStruct(
|
||||
structs: StructsMap,
|
||||
@@ -126,6 +164,14 @@ function generateStruct(
|
||||
nullthrows(property.properties),
|
||||
);
|
||||
return;
|
||||
case 'StringEnumTypeAnnotation':
|
||||
generateEnum(
|
||||
structs,
|
||||
componentName,
|
||||
property.options,
|
||||
nameParts.concat([name]),
|
||||
);
|
||||
return;
|
||||
default:
|
||||
(property: empty);
|
||||
throw new Error(
|
||||
|
||||
@@ -587,6 +587,32 @@ const EVENT_PROPS: SchemaType = {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'onOrientationChange',
|
||||
optional: true,
|
||||
bubblingType: 'direct',
|
||||
typeAnnotation: {
|
||||
type: 'EventTypeAnnotation',
|
||||
argument: {
|
||||
type: 'ObjectTypeAnnotation',
|
||||
properties: [
|
||||
{
|
||||
type: 'StringEnumTypeAnnotation',
|
||||
name: 'orientation',
|
||||
optional: false,
|
||||
options: [
|
||||
{
|
||||
name: 'landscape',
|
||||
},
|
||||
{
|
||||
name: 'portrait',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'onEnd',
|
||||
optional: true,
|
||||
|
||||
+7
@@ -165,6 +165,13 @@ void EventsNativeComponentEventEmitter::onEventDirect(EventsNativeComponentOnEve
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
void EventsNativeComponentEventEmitter::onOrientationChange(EventsNativeComponentOnOrientationChangeStruct event) const {
|
||||
dispatchEvent(\\"orientationChange\\", [event=std::move(event)](jsi::Runtime &runtime) {
|
||||
auto payload = jsi::Object(runtime);
|
||||
payload.setProperty(runtime, \\"orientation\\", toString(event.orientation));
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
void EventsNativeComponentEventEmitter::onEnd() const {
|
||||
dispatchEvent(\\"end\\");
|
||||
}
|
||||
|
||||
+18
@@ -166,6 +166,22 @@ struct EventsNativeComponentOnEventDirectStruct {
|
||||
bool value;
|
||||
};
|
||||
|
||||
enum class EventsNativeComponentOnOrientationChangeOrientationStruct {
|
||||
Landscape,
|
||||
Portrait
|
||||
};
|
||||
|
||||
inline char const *toString(const EventsNativeComponentOnOrientationChangeOrientationStruct value) {
|
||||
switch (value) {
|
||||
case EventsNativeComponentOnOrientationChangeOrientationStruct::Landscape: return \\"landscape\\";
|
||||
case EventsNativeComponentOnOrientationChangeOrientationStruct::Portrait: return \\"portrait\\";
|
||||
}
|
||||
}
|
||||
|
||||
struct EventsNativeComponentOnOrientationChangeStruct {
|
||||
EventsNativeComponentOnOrientationChangeOrientationStruct orientation;
|
||||
};
|
||||
|
||||
class EventsNativeComponentEventEmitter : public ViewEventEmitter {
|
||||
public:
|
||||
using ViewEventEmitter::ViewEventEmitter;
|
||||
@@ -174,6 +190,8 @@ class EventsNativeComponentEventEmitter : public ViewEventEmitter {
|
||||
|
||||
void onEventDirect(EventsNativeComponentOnEventDirectStruct value) const;
|
||||
|
||||
void onOrientationChange(EventsNativeComponentOnOrientationChangeStruct value) const;
|
||||
|
||||
void onEnd() const;
|
||||
};
|
||||
|
||||
|
||||
+5
@@ -221,12 +221,17 @@ const EventsNativeComponentViewConfig = {
|
||||
topEventDirect: {
|
||||
registrationName: 'onEventDirect',
|
||||
},
|
||||
|
||||
topOrientationChange: {
|
||||
registrationName: 'onOrientationChange',
|
||||
},
|
||||
},
|
||||
|
||||
validAttributes: {
|
||||
disabled: true,
|
||||
onChange: true,
|
||||
onEventDirect: true,
|
||||
onOrientationChange: true,
|
||||
onEnd: true,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -30,6 +30,11 @@ const EVENT_DEFINITION = `
|
||||
int32_optional_value: ?Int32,
|
||||
int32_optional_both?: ?Int32,
|
||||
|
||||
enum_required: ('small' | 'large'),
|
||||
enum_optional_key?: ('small' | 'large'),
|
||||
enum_optional_value: ?('small' | 'large'),
|
||||
enum_optional_both?: ?('small' | 'large'),
|
||||
|
||||
object_required: {
|
||||
boolean_required: boolean,
|
||||
}
|
||||
|
||||
+936
File diff suppressed because it is too large
Load Diff
@@ -50,8 +50,16 @@ function getPropertyType(name, optional, typeAnnotation) {
|
||||
optional,
|
||||
properties: typeAnnotation.properties.map(buildPropertiesForEvent),
|
||||
};
|
||||
case 'UnionTypeAnnotation':
|
||||
return {
|
||||
type: 'StringEnumTypeAnnotation',
|
||||
name,
|
||||
optional,
|
||||
options: typeAnnotation.types.map(option => ({name: option.value})),
|
||||
};
|
||||
default:
|
||||
throw new Error(`Unable to determine type for "${name}"`);
|
||||
(type: empty);
|
||||
throw new Error(`Unable to determine event type for "${name}"`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ function getTypeAnnotationForArray(name, typeAnnotation, defaultValue) {
|
||||
options: typeAnnotation.types.map(option => ({name: option.value})),
|
||||
};
|
||||
default:
|
||||
(type: empty);
|
||||
throw new Error(`Unknown prop type for "${name}"`);
|
||||
}
|
||||
}
|
||||
@@ -177,6 +178,7 @@ function getTypeAnnotation(name, typeAnnotation, defaultValue) {
|
||||
}
|
||||
throw new Error(`A default enum value is required for "${name}"`);
|
||||
default:
|
||||
(type: empty);
|
||||
throw new Error(`Unknown prop type for "${name}"`);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user