Skip to content

Commit

Permalink
Generate enum types that would be allowed to be used as well as strin…
Browse files Browse the repository at this point in the history
…g/number in c++ turbo modules generators (#36030)

Summary:
Pull Request resolved: #36030

Generate enum types in c++ turbo modules.

For enums in the ts schema file such as:
```
export enum NumEnum {
  ONE = 1,
  TWO = 2,
}
```
This would export enums and the relevant Bridging to js and from js code to the spec H files such as:
```
#pragma mark - SampleTurboModuleCxxNumEnum

enum SampleTurboModuleCxxNumEnum { ONE, TWO };

template <>
struct Bridging<SampleTurboModuleCxxNumEnum> {
  static SampleTurboModuleCxxNumEnum fromJs(jsi::Runtime &rt, int32_t value) {

    if (value == 1) {
      return SampleTurboModuleCxxNumEnum::ONE;
    } else if (value == 2) {
      return SampleTurboModuleCxxNumEnum::TWO;
    } else {
      throw jsi::JSError(rt, "No appropriate enum member found for value");
    }
  }

  static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleCxxNumEnum value) {
    if (value == SampleTurboModuleCxxNumEnum::ONE) {
      return bridging::toJs(rt, 1);
    } else if (value == SampleTurboModuleCxxNumEnum::TWO) {
      return bridging::toJs(rt, 2);
    } else {
      throw jsi::JSError(rt, "No appropriate enum member found for enum value");
    }
  }
};

```
That code would allow us to use these enums in the cxx files like this:
```
  NativeCxxModuleExampleCxxEnumInt getNumEnum(
      jsi::Runtime &rt,
      NativeCxxModuleExampleCxxEnumInt arg);
```

Changelog: [General] [Added] Generate enum types that would be allowed to be used as well as string/number in c++ turbo modules generators

Reviewed By: christophpurrer

Differential Revision: D42884147

fbshipit-source-id: d34d1fc7ba268b570821dc108444196f69a431b2
  • Loading branch information
vzaidman authored and facebook-github-bot committed Feb 13, 2023
1 parent bf3656b commit ceb1d0d
Show file tree
Hide file tree
Showing 21 changed files with 973 additions and 106 deletions.

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions packages/react-native-codegen/src/generators/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,27 @@ function indent(nice: string, spaces: number): string {
.join('\n');
}

function toPascalCase(inString: string): string {
if (inString.length === 0) {
return inString;
}

return inString[0].toUpperCase() + inString.slice(1);
}

function toSafeCppString(input: string): string {
return input.split('-').map(toPascalCase).join('');
}

function getEnumName(moduleName: string, origEnumName: string): string {
const uppercasedPropName = toSafeCppString(origEnumName);
return `${moduleName}${uppercasedPropName}`;
}

module.exports = {
capitalize,
indent,
toPascalCase,
toSafeCppString,
getEnumName,
};
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ import type {
const {
getCppTypeForAnnotation,
getEnumMaskName,
getEnumName,
generateStructName,
getImports,
} = require('./CppHelpers.js');

const {getEnumName} = require('../Utils');

function getNativeTypeFromAnnotation(
componentName: string,
prop:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,7 @@
'use strict';
import type {NamedShape, PropTypeAnnotation} from '../../CodegenSchema';

function upperCaseFirst(inString: string): string {
if (inString.length === 0) {
return inString;
}

return inString[0].toUpperCase() + inString.slice(1);
}

function toSafeCppString(input: string): string {
return input.split('-').map(upperCaseFirst).join('');
}
const {getEnumName, toSafeCppString} = require('../Utils');

function toIntEnumValueName(propName: string, value: number): string {
return `${toSafeCppString(propName)}${value}`;
Expand Down Expand Up @@ -124,11 +114,6 @@ function generateStructName(
return `${componentName}${additional}Struct`;
}

function getEnumName(componentName: string, propName: string): string {
const uppercasedPropName = toSafeCppString(propName);
return `${componentName}${uppercasedPropName}`;
}

function getEnumMaskName(enumName: string): string {
return `${enumName}Mask`;
}
Expand Down Expand Up @@ -224,10 +209,8 @@ function convertDefaultTypeToString(
module.exports = {
convertDefaultTypeToString,
getCppTypeForAnnotation,
getEnumName,
getEnumMaskName,
getImports,
toSafeCppString,
toIntEnumValueName,
generateStructName,
generateEventStructName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ const nullthrows = require('nullthrows');

const {
getCppTypeForAnnotation,
toSafeCppString,
generateEventStructName,
} = require('./CppHelpers');
const {indent} = require('../Utils');
const {indent, toSafeCppString} = require('../Utils');

import type {
ComponentShape,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ const {
const {
convertDefaultTypeToString,
getEnumMaskName,
getEnumName,
toSafeCppString,
generateStructName,
toIntEnumValueName,
} = require('./CppHelpers.js');

const {getEnumName, toSafeCppString} = require('../Utils');

import type {
ExtendsPropsShape,
NamedShape,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
import type {ComponentShape, PropTypeAnnotation} from '../../CodegenSchema';
import type {SchemaType} from '../../CodegenSchema';

const {getImports, toSafeCppString} = require('./CppHelpers');
const {getImports} = require('./CppHelpers');

const {toSafeCppString} = require('../Utils');

type FilesOutput = Map<string, string>;
type PropValueType = string | number | boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type {
NativeModuleFunctionTypeAnnotation,
NativeModuleParamTypeAnnotation,
NativeModuleTypeAnnotation,
NativeModuleEnumMap,
} from '../../CodegenSchema';

import type {AliasResolver} from './Utils';
Expand Down Expand Up @@ -114,9 +115,11 @@ ${modules}
type Param = NamedShape<Nullable<NativeModuleParamTypeAnnotation>>;

function serializeArg(
moduleName: string,
arg: Param,
index: number,
resolveAlias: AliasResolver,
enumMap: NativeModuleEnumMap,
): string {
const {typeAnnotation: nullableTypeAnnotation, optional} = arg;
const [typeAnnotation, nullable] =
Expand Down Expand Up @@ -208,9 +211,11 @@ function serializeArg(
}

function serializePropertyIntoHostFunction(
moduleName: string,
hasteModuleName: string,
property: NativeModulePropertyShape,
resolveAlias: AliasResolver,
enumMap: NativeModuleEnumMap,
): string {
const [propertyTypeAnnotation] =
unwrapNullable<NativeModuleFunctionTypeAnnotation>(property.typeAnnotation);
Expand All @@ -220,7 +225,7 @@ function serializePropertyIntoHostFunction(
methodName: property.name,
returnTypeAnnotation: propertyTypeAnnotation.returnTypeAnnotation,
args: propertyTypeAnnotation.params.map((p, i) =>
serializeArg(p, i, resolveAlias),
serializeArg(moduleName, p, i, resolveAlias, enumMap),
),
});
}
Expand All @@ -239,15 +244,18 @@ module.exports = {
const nativeModule = nativeModules[hasteModuleName];
const {
aliasMap,
enumMap,
spec: {properties},
moduleName,
} = nativeModule;
const resolveAlias = createAliasResolver(aliasMap);
const hostFunctions = properties.map(property =>
serializePropertyIntoHostFunction(
moduleName,
hasteModuleName,
property,
resolveAlias,
enumMap,
),
);

Expand Down
Loading

0 comments on commit ceb1d0d

Please sign in to comment.