Make enum types annotation objects instead of literal strings and numbers (#47349)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47349

This is needed to be able to recurse into the literals and compare them.

I'm primarily unsure if there is a problem representing doubles/floats as numbers instead of strings though.

Changelog: [Internal]

Reviewed By: makovkastar

Differential Revision: D65284058

fbshipit-source-id: b2de9ed5fb7f079a432c94aaea69027863879909
This commit is contained in:
Eli White
2024-12-02 14:32:35 -08:00
committed by Facebook GitHub Bot
parent 96c2be8567
commit fa8a25eb6b
12 changed files with 302 additions and 77 deletions
+1 -1
View File
@@ -327,7 +327,7 @@ export interface NativeModuleBooleanTypeAnnotation {
export type NativeModuleEnumMember = {
readonly name: string;
readonly value: string | number;
readonly value: NativeModuleStringLiteralTypeAnnotation | NativeModuleNumberLiteralTypeAnnotation,
};
export type NativeModuleEnumMemberType =
+1 -1
View File
@@ -311,7 +311,7 @@ export type NativeModuleNumberTypeAnnotation = $ReadOnly<{
export type NativeModuleEnumMember = {
name: string,
value: string | number,
value: StringLiteralTypeAnnotation | NumberLiteralTypeAnnotation,
};
export type NativeModuleEnumMemberType =
@@ -406,6 +406,14 @@ struct Bridging<${enumName}> {
};`;
};
function getMemberValueAppearance(member: NativeModuleEnumMember['value']) {
if (member.type === 'StringLiteralTypeAnnotation') {
return `"${member.value}"`;
} else {
return member.value;
}
}
function generateEnum(
hasteModuleName: string,
origEnumName: string,
@@ -417,9 +425,6 @@ function generateEnum(
const nativeEnumMemberType: NativeEnumMemberValueType =
memberType === 'StringTypeAnnotation' ? 'std::string' : 'int32_t';
const getMemberValueAppearance = (value: string | number) =>
memberType === 'StringTypeAnnotation' ? `"${value}"` : `${value}`;
const fromCases =
members
.map(
@@ -163,11 +163,17 @@ const SIMPLE_NATIVE_MODULES: SchemaType = {
members: [
{
name: 'ONE',
value: '1',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 1,
},
},
{
name: 'TWO',
value: '2',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 2,
},
},
],
},
@@ -178,15 +184,24 @@ const SIMPLE_NATIVE_MODULES: SchemaType = {
members: [
{
name: 'POINT_ZERO',
value: '0.0',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 0.0,
},
},
{
name: 'POINT_ONE',
value: '0.1',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 0.1,
},
},
{
name: 'POINT_TWO',
value: '0.2',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 0.2,
},
},
],
},
@@ -197,11 +212,17 @@ const SIMPLE_NATIVE_MODULES: SchemaType = {
members: [
{
name: 'HELLO',
value: 'hello',
value: {
type: 'StringLiteralTypeAnnotation',
value: 'hello',
},
},
{
name: 'GoodBye',
value: 'goodbye',
value: {
type: 'StringLiteralTypeAnnotation',
value: 'goodbye',
},
},
],
},
@@ -1926,11 +1947,17 @@ const CXX_ONLY_NATIVE_MODULES: SchemaType = {
members: [
{
name: 'IA',
value: '23',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 23,
},
},
{
name: 'IB',
value: '42',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 42,
},
},
],
},
@@ -1941,11 +1968,17 @@ const CXX_ONLY_NATIVE_MODULES: SchemaType = {
members: [
{
name: 'FA',
value: '1.23',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 1.23,
},
},
{
name: 'FB',
value: '4.56',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 4.56,
},
},
],
},
@@ -1956,11 +1989,17 @@ const CXX_ONLY_NATIVE_MODULES: SchemaType = {
members: [
{
name: 'NA',
value: 'NA',
value: {
type: 'StringLiteralTypeAnnotation',
value: 'NA',
},
},
{
name: 'NB',
value: 'NB',
value: {
type: 'StringLiteralTypeAnnotation',
value: 'NB',
},
},
],
},
@@ -1971,11 +2010,17 @@ const CXX_ONLY_NATIVE_MODULES: SchemaType = {
members: [
{
name: 'SA',
value: 's---a',
value: {
type: 'StringLiteralTypeAnnotation',
value: 's---a',
},
},
{
name: 'SB',
value: 's---b',
value: {
type: 'StringLiteralTypeAnnotation',
value: 's---b',
},
},
],
},
@@ -2047,7 +2047,7 @@ template <>
struct Bridging<NativeSampleTurboModuleFloatEnum> {
static NativeSampleTurboModuleFloatEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 0.0) {
if (value == 0) {
return NativeSampleTurboModuleFloatEnum::POINT_ZERO;
} else if (value == 0.1) {
return NativeSampleTurboModuleFloatEnum::POINT_ONE;
@@ -2060,7 +2060,7 @@ struct Bridging<NativeSampleTurboModuleFloatEnum> {
static jsi::Value toJs(jsi::Runtime &rt, NativeSampleTurboModuleFloatEnum value) {
if (value == NativeSampleTurboModuleFloatEnum::POINT_ZERO) {
return bridging::toJs(rt, 0.0);
return bridging::toJs(rt, 0);
} else if (value == NativeSampleTurboModuleFloatEnum::POINT_ONE) {
return bridging::toJs(rt, 0.1);
} else if (value == NativeSampleTurboModuleFloatEnum::POINT_TWO) {
@@ -478,11 +478,17 @@ describe('typeEnumResolution', () => {
members: [
{
name: 'Hello',
value: 'hello',
value: {
type: 'StringLiteralTypeAnnotation',
value: 'hello',
},
},
{
name: 'Goodbye',
value: 'goodbye',
value: {
type: 'StringLiteralTypeAnnotation',
value: 'goodbye',
},
},
],
},
@@ -521,11 +527,17 @@ describe('typeEnumResolution', () => {
members: [
{
name: 'On',
value: '1',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 1,
},
},
{
name: 'Off',
value: '0',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 0,
},
},
],
},
@@ -147,11 +147,17 @@ exports[`RN Codegen Flow Parser can generate fixture CXX_ONLY_NATIVE_MODULE 1`]
'members': [
{
'name': 'SD',
'value': 'SD'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'SD'
}
},
{
'name': 'HD',
'value': 'HD'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'HD'
}
}
]
},
@@ -162,15 +168,24 @@ exports[`RN Codegen Flow Parser can generate fixture CXX_ONLY_NATIVE_MODULE 1`]
'members': [
{
'name': 'Corrupted',
'value': -1
'value': {
'type': 'NumberLiteralTypeAnnotation',
'value': -1
}
},
{
'name': 'Low',
'value': 720
'value': {
'type': 'NumberLiteralTypeAnnotation',
'value': 720
}
},
{
'name': 'High',
'value': 1080
'value': {
'type': 'NumberLiteralTypeAnnotation',
'value': 1080
}
}
]
},
@@ -181,15 +196,24 @@ exports[`RN Codegen Flow Parser can generate fixture CXX_ONLY_NATIVE_MODULE 1`]
'members': [
{
'name': 'One',
'value': 'one'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'one'
}
},
{
'name': 'Two',
'value': 'two'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'two'
}
},
{
'name': 'Three',
'value': 'three'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'three'
}
}
]
}
@@ -471,11 +495,17 @@ exports[`RN Codegen Flow Parser can generate fixture IOS_ONLY_NATIVE_MODULE 1`]
'members': [
{
'name': 'SD',
'value': 'SD'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'SD'
}
},
{
'name': 'HD',
'value': 'HD'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'HD'
}
}
]
},
@@ -486,11 +516,17 @@ exports[`RN Codegen Flow Parser can generate fixture IOS_ONLY_NATIVE_MODULE 1`]
'members': [
{
'name': 'Low',
'value': 720
'value': {
'type': 'NumberLiteralTypeAnnotation',
'value': 720
}
},
{
'name': 'High',
'value': 1080
'value': {
'type': 'NumberLiteralTypeAnnotation',
'value': 1080
}
}
]
},
@@ -501,15 +537,24 @@ exports[`RN Codegen Flow Parser can generate fixture IOS_ONLY_NATIVE_MODULE 1`]
'members': [
{
'name': 'One',
'value': 'one'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'one'
}
},
{
'name': 'Two',
'value': 'two'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'two'
}
},
{
'name': 'Three',
'value': 'three'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'three'
}
}
]
}
+22 -4
View File
@@ -230,10 +230,28 @@ class FlowParser implements Parser {
parseEnumMembers(
typeAnnotation: $FlowFixMe,
): $ReadOnlyArray<NativeModuleEnumMember> {
return typeAnnotation.members.map(member => ({
name: member.id.name,
value: member.init?.value ?? member.id.name,
}));
return typeAnnotation.members.map(member => {
const value =
typeof member.init?.value === 'number'
? {
type: 'NumberLiteralTypeAnnotation',
value: member.init.value,
}
: typeof member.init?.value === 'string'
? {
type: 'StringLiteralTypeAnnotation',
value: member.init.value,
}
: {
type: 'StringLiteralTypeAnnotation',
value: member.id.name,
};
return {
name: member.id.name,
value: value,
};
});
}
isModuleInterface(node: $FlowFixMe): boolean {
+16 -4
View File
@@ -175,21 +175,33 @@ export class MockedParser implements Parser {
? [
{
name: 'Hello',
value: 'hello',
value: {
type: 'StringLiteralTypeAnnotation',
value: 'hello',
},
},
{
name: 'Goodbye',
value: 'goodbye',
value: {
type: 'StringLiteralTypeAnnotation',
value: 'goodbye',
},
},
]
: [
{
name: 'On',
value: '1',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 1,
},
},
{
name: 'Off',
value: '0',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 0,
},
},
];
}
@@ -134,11 +134,17 @@ exports[`RN Codegen TypeScript Parser can generate fixture CXX_ONLY_NATIVE_MODUL
'members': [
{
'name': 'SD',
'value': 'SD'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'SD'
}
},
{
'name': 'HD',
'value': 'HD'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'HD'
}
}
]
},
@@ -149,15 +155,24 @@ exports[`RN Codegen TypeScript Parser can generate fixture CXX_ONLY_NATIVE_MODUL
'members': [
{
'name': 'Corrupted',
'value': -1
'value': {
'type': 'NumberLiteralTypeAnnotation',
'value': -1
}
},
{
'name': 'Low',
'value': 720
'value': {
'type': 'NumberLiteralTypeAnnotation',
'value': 720
}
},
{
'name': 'High',
'value': 1080
'value': {
'type': 'NumberLiteralTypeAnnotation',
'value': 1080
}
}
]
},
@@ -168,15 +183,24 @@ exports[`RN Codegen TypeScript Parser can generate fixture CXX_ONLY_NATIVE_MODUL
'members': [
{
'name': 'One',
'value': 'one'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'one'
}
},
{
'name': 'Two',
'value': 'two'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'two'
}
},
{
'name': 'Three',
'value': 'three'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'three'
}
}
]
}
@@ -458,11 +482,17 @@ exports[`RN Codegen TypeScript Parser can generate fixture IOS_ONLY_NATIVE_MODUL
'members': [
{
'name': 'SD',
'value': 'SD'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'SD'
}
},
{
'name': 'HD',
'value': 'HD'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'HD'
}
}
]
},
@@ -473,11 +503,17 @@ exports[`RN Codegen TypeScript Parser can generate fixture IOS_ONLY_NATIVE_MODUL
'members': [
{
'name': 'Low',
'value': 720
'value': {
'type': 'NumberLiteralTypeAnnotation',
'value': 720
}
},
{
'name': 'High',
'value': 1080
'value': {
'type': 'NumberLiteralTypeAnnotation',
'value': 1080
}
}
]
},
@@ -488,15 +524,24 @@ exports[`RN Codegen TypeScript Parser can generate fixture IOS_ONLY_NATIVE_MODUL
'members': [
{
'name': 'One',
'value': 'one'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'one'
}
},
{
'name': 'Two',
'value': 'two'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'two'
}
},
{
'name': 'Three',
'value': 'three'
'value': {
'type': 'StringLiteralTypeAnnotation',
'value': 'three'
}
}
]
}
@@ -124,9 +124,27 @@ describe('TypeScript Module Parser', () => {
expect(parser).not.toThrow();
expect(parser().enumMap.MyEnum.members).toEqual([
{name: 'ZERO', value: 0},
{name: 'POSITIVE', value: 1},
{name: 'NEGATIVE', value: -1},
{
name: 'ZERO',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 0,
},
},
{
name: 'POSITIVE',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 1,
},
},
{
name: 'NEGATIVE',
value: {
type: 'NumberLiteralTypeAnnotation',
value: -1,
},
},
]);
});
@@ -147,8 +165,20 @@ describe('TypeScript Module Parser', () => {
expect(parser).not.toThrow();
expect(parser().enumMap.MyEnum.members).toEqual([
{name: 'ZERO', value: 0},
{name: 'POSITIVE', value: 1},
{
name: 'ZERO',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 0,
},
},
{
name: 'POSITIVE',
value: {
type: 'NumberLiteralTypeAnnotation',
value: 1,
},
},
]);
});
@@ -250,17 +250,30 @@ class TypeScriptParser implements Parser {
typeAnnotation: $FlowFixMe,
): $ReadOnlyArray<NativeModuleEnumMember> {
return typeAnnotation.members.map(member => {
// Handle negative values
if (member.initializer?.operator === '-') {
return {
name: member.id.name,
value: -member.initializer?.argument?.value ?? member.id.name,
};
}
const value =
member.initializer?.operator === '-'
? {
type: 'NumberLiteralTypeAnnotation',
value: -1 * member.initializer?.argument?.value,
}
: typeof member.initializer?.value === 'number'
? {
type: 'NumberLiteralTypeAnnotation',
value: member.initializer?.value,
}
: typeof member.initializer?.value === 'string'
? {
type: 'StringLiteralTypeAnnotation',
value: member.initializer?.value,
}
: {
type: 'StringLiteralTypeAnnotation',
value: member.id.name,
};
return {
name: member.id.name,
value: member.initializer?.value ?? member.id.name,
value,
};
});
}