Skip to content

Commit

Permalink
Support function return types
Browse files Browse the repository at this point in the history
Summary:
This adds the option for a TurboModule spec to use a "Cxx" suffix to unblock additional capabilities. This extends the pattern where TurboModules can have an "Android" or "IOS" suffix to exclude codegen for the other platform. When in `cxxOnly` mode, the parser will allow function return types (and additional features will be added over time).

Changelog:
[General][Added] C++ TurboModule methods can return functions

Reviewed By: christophpurrer

Differential Revision: D35364346

fbshipit-source-id: 768eb0ec2a1cbe3e458466064247d7e7f01135ff
  • Loading branch information
appden authored and facebook-github-bot committed Apr 5, 2022
1 parent 6f26a92 commit c7380ba
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,30 @@ export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModuleIOS');
`;

const CXX_ONLY_NATIVE_MODULE = `
/**
* 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
*/
'use strict';
import type {TurboModule} from '../RCTExport';
import * as TurboModuleRegistry from '../TurboModuleRegistry';
export interface Spec extends TurboModule {
+getCallback: () => () => void;
}
export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModuleCxx');
`;

module.exports = {
NATIVE_MODULE_WITH_OBJECT_WITH_OBJECT_DEFINED_IN_FILE_AS_PROPERTY,
NATIVE_MODULE_WITH_ARRAY_WITH_UNION_AND_TOUPLE,
Expand All @@ -594,4 +618,5 @@ module.exports = {
EMPTY_NATIVE_MODULE,
ANDROID_ONLY_NATIVE_MODULE,
IOS_ONLY_NATIVE_MODULE,
CXX_ONLY_NATIVE_MODULE,
};
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,43 @@ exports[`RN Codegen Flow Parser can generate fixture ANDROID_ONLY_NATIVE_MODULE
}"
`;

exports[`RN Codegen Flow Parser can generate fixture CXX_ONLY_NATIVE_MODULE 1`] = `
"{
'modules': {
'NativeSampleTurboModule': {
'type': 'NativeModule',
'aliases': {},
'spec': {
'properties': [
{
'name': 'getCallback',
'optional': false,
'typeAnnotation': {
'type': 'FunctionTypeAnnotation',
'returnTypeAnnotation': {
'type': 'FunctionTypeAnnotation',
'returnTypeAnnotation': {
'type': 'VoidTypeAnnotation'
},
'params': []
},
'params': []
}
}
]
},
'moduleNames': [
'SampleTurboModuleCxx'
],
'excludedPlatforms': [
'iOS',
'android'
]
}
}
}"
`;

exports[`RN Codegen Flow Parser can generate fixture EMPTY_NATIVE_MODULE 1`] = `
"{
'modules': {
Expand Down
17 changes: 16 additions & 1 deletion packages/react-native-codegen/src/parsers/flow/modules/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ function translateTypeAnnotation(
types: TypeDeclarationMap,
aliasMap: {...NativeModuleAliasMap},
tryParse: ParserErrorCapturer,
cxxOnly: boolean,
): Nullable<NativeModuleTypeAnnotation> {
const {nullable, typeAnnotation, typeAliasResolutionStatus} =
resolveTypeAnnotation(flowTypeAnnotation, types);
Expand Down Expand Up @@ -121,6 +122,7 @@ function translateTypeAnnotation(
* to be parseable.
*/
nullGuard,
cxxOnly,
),
);

Expand Down Expand Up @@ -177,6 +179,7 @@ function translateTypeAnnotation(
types,
aliasMap,
tryParse,
cxxOnly,
);
}
case 'Stringish': {
Expand Down Expand Up @@ -239,6 +242,7 @@ function translateTypeAnnotation(
types,
aliasMap,
tryParse,
cxxOnly,
),
);

Expand Down Expand Up @@ -355,6 +359,7 @@ function translateTypeAnnotation(
types,
aliasMap,
tryParse,
cxxOnly,
),
);
}
Expand Down Expand Up @@ -401,6 +406,7 @@ function translateFunctionTypeAnnotation(
types: TypeDeclarationMap,
aliasMap: {...NativeModuleAliasMap},
tryParse: ParserErrorCapturer,
cxxOnly: boolean,
): NativeModuleFunctionTypeAnnotation {
type Param = NamedShape<Nullable<NativeModuleParamTypeAnnotation>>;
const params: Array<Param> = [];
Expand All @@ -420,6 +426,7 @@ function translateFunctionTypeAnnotation(
types,
aliasMap,
tryParse,
cxxOnly,
),
);

Expand Down Expand Up @@ -463,10 +470,11 @@ function translateFunctionTypeAnnotation(
types,
aliasMap,
tryParse,
cxxOnly,
),
);

if (returnTypeAnnotation.type === 'FunctionTypeAnnotation') {
if (!cxxOnly && returnTypeAnnotation.type === 'FunctionTypeAnnotation') {
throw new UnsupportedFunctionReturnTypeAnnotationParserError(
hasteModuleName,
flowFunctionTypeAnnotation.returnType,
Expand Down Expand Up @@ -494,6 +502,7 @@ function buildPropertySchema(
types: TypeDeclarationMap,
aliasMap: {...NativeModuleAliasMap},
tryParse: ParserErrorCapturer,
cxxOnly: boolean,
): NativeModulePropertyShape {
let nullable = false;
let {key, value} = property;
Expand Down Expand Up @@ -522,6 +531,7 @@ function buildPropertySchema(
types,
aliasMap,
tryParse,
cxxOnly,
),
),
};
Expand Down Expand Up @@ -653,13 +663,17 @@ function buildModuleSchema(
// Eventually this should be made explicit in the Flow type itself.
// Also check the hasteModuleName for platform suffix.
// Note: this shape is consistent with ComponentSchema.
let cxxOnly = false;
const excludedPlatforms = [];
const namesToValidate = [...moduleNames, hasteModuleName];
namesToValidate.forEach(name => {
if (name.endsWith('Android')) {
excludedPlatforms.push('iOS');
} else if (name.endsWith('IOS')) {
excludedPlatforms.push('android');
} else if (name.endsWith('Cxx')) {
cxxOnly = true;
excludedPlatforms.push('iOS', 'android');
}
});

Expand All @@ -680,6 +694,7 @@ function buildModuleSchema(
types,
aliasMap,
tryParse,
cxxOnly,
),
}));
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,28 @@ export default TurboModuleRegistry.getEnforcing<Spec>(
);
`;

const CXX_ONLY_NATIVE_MODULE = `
/**
* 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
*/
import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport';
import * as TurboModuleRegistry from 'react-native/Libraries/TurboModule/TurboModuleRegistry';
export interface Spec extends TurboModule {
readonly getCallback: () => () => void;
}
export default TurboModuleRegistry.getEnforcing<Spec>(
'SampleTurboModuleCxx',
);
`;

module.exports = {
NATIVE_MODULE_WITH_OBJECT_WITH_OBJECT_DEFINED_IN_FILE_AS_PROPERTY,
NATIVE_MODULE_WITH_ARRAY_WITH_UNION_AND_TOUPLE,
Expand All @@ -525,4 +547,5 @@ module.exports = {
EMPTY_NATIVE_MODULE,
ANDROID_ONLY_NATIVE_MODULE,
IOS_ONLY_NATIVE_MODULE,
CXX_ONLY_NATIVE_MODULE,
};
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,43 @@ exports[`RN Codegen TypeScript Parser can generate fixture ANDROID_ONLY_NATIVE_M
}"
`;

exports[`RN Codegen TypeScript Parser can generate fixture CXX_ONLY_NATIVE_MODULE 1`] = `
"{
'modules': {
'NativeSampleTurboModule': {
'type': 'NativeModule',
'aliases': {},
'spec': {
'properties': [
{
'name': 'getCallback',
'optional': false,
'typeAnnotation': {
'type': 'FunctionTypeAnnotation',
'returnTypeAnnotation': {
'type': 'FunctionTypeAnnotation',
'returnTypeAnnotation': {
'type': 'VoidTypeAnnotation'
},
'params': []
},
'params': []
}
}
]
},
'moduleNames': [
'SampleTurboModuleCxx'
],
'excludedPlatforms': [
'iOS',
'android'
]
}
}
}"
`;

exports[`RN Codegen TypeScript Parser can generate fixture EMPTY_NATIVE_MODULE 1`] = `
"{
'modules': {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ function translateTypeAnnotation(
types: TypeDeclarationMap,
aliasMap: {...NativeModuleAliasMap},
tryParse: ParserErrorCapturer,
cxxOnly: boolean,
): Nullable<NativeModuleTypeAnnotation> {
const {nullable, typeAnnotation, typeAliasResolutionStatus} =
resolveTypeAnnotation(typeScriptTypeAnnotation, types);
Expand Down Expand Up @@ -121,6 +122,7 @@ function translateTypeAnnotation(
* to be parseable.
*/
nullGuard,
cxxOnly,
),
);

Expand Down Expand Up @@ -177,6 +179,7 @@ function translateTypeAnnotation(
types,
aliasMap,
tryParse,
cxxOnly,
);
}
case 'Stringish': {
Expand Down Expand Up @@ -239,6 +242,7 @@ function translateTypeAnnotation(
types,
aliasMap,
tryParse,
cxxOnly,
),
);

Expand Down Expand Up @@ -355,6 +359,7 @@ function translateTypeAnnotation(
types,
aliasMap,
tryParse,
cxxOnly,
),
);
}
Expand Down Expand Up @@ -401,6 +406,7 @@ function translateFunctionTypeAnnotation(
types: TypeDeclarationMap,
aliasMap: {...NativeModuleAliasMap},
tryParse: ParserErrorCapturer,
cxxOnly: boolean,
): NativeModuleFunctionTypeAnnotation {
type Param = NamedShape<Nullable<NativeModuleParamTypeAnnotation>>;
const params: Array<Param> = [];
Expand All @@ -423,6 +429,7 @@ function translateFunctionTypeAnnotation(
types,
aliasMap,
tryParse,
cxxOnly,
),
);

Expand Down Expand Up @@ -466,10 +473,11 @@ function translateFunctionTypeAnnotation(
types,
aliasMap,
tryParse,
cxxOnly,
),
);

if (returnTypeAnnotation.type === 'FunctionTypeAnnotation') {
if (!cxxOnly && returnTypeAnnotation.type === 'FunctionTypeAnnotation') {
throw new UnsupportedFunctionReturnTypeAnnotationParserError(
hasteModuleName,
typescriptFunctionTypeAnnotation.returnType,
Expand All @@ -494,6 +502,7 @@ function buildPropertySchema(
types: TypeDeclarationMap,
aliasMap: {...NativeModuleAliasMap},
tryParse: ParserErrorCapturer,
cxxOnly: boolean,
): NativeModulePropertyShape {
let nullable = false;
let {key} = property;
Expand Down Expand Up @@ -524,6 +533,7 @@ function buildPropertySchema(
types,
aliasMap,
tryParse,
cxxOnly,
),
),
};
Expand Down Expand Up @@ -658,13 +668,17 @@ function buildModuleSchema(
// Eventually this should be made explicit in the Flow type itself.
// Also check the hasteModuleName for platform suffix.
// Note: this shape is consistent with ComponentSchema.
let cxxOnly = false;
const excludedPlatforms = [];
const namesToValidate = [...moduleNames, hasteModuleName];
namesToValidate.forEach(name => {
if (name.endsWith('Android')) {
excludedPlatforms.push('iOS');
} else if (name.endsWith('IOS')) {
excludedPlatforms.push('android');
} else if (name.endsWith('Cxx')) {
cxxOnly = true;
excludedPlatforms.push('iOS', 'android');
}
});

Expand All @@ -689,6 +703,7 @@ function buildModuleSchema(
types,
aliasMap,
tryParse,
cxxOnly,
),
}));
})
Expand Down

0 comments on commit c7380ba

Please sign in to comment.