Skip to content

Commit ead73de

Browse files
Add a BinaryTreeNode example for Cxx TMs (facebook#41767)
Summary: Pull Request resolved: facebook#41767 Changelog: [Internal] Adds a simple example showing a direct recursive node in a Cxx TM. Currently we can't auto-generate [the necessary C++ Types](https://reactnative.dev/docs/next/the-new-architecture/cxx-custom-types#struct-generator) - but we can add it later if this scenarios becomes really common. Direct recursive nodes, can't be value types - it would require infinite memory. Hence they are nullable and managed by a smart pointer. Reviewed By: rshest Differential Revision: D51784136 fbshipit-source-id: f6f0710d03583bdf1e6e72ba42d8df7f8ff8d915
1 parent 5754b4a commit ead73de

File tree

12 files changed

+322
-5
lines changed

12 files changed

+322
-5
lines changed

packages/react-native-codegen/src/parsers/__tests__/parsers-commons-test.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ describe('parseObjectProperty', () => {
322322
);
323323
expect(() =>
324324
parseObjectProperty(
325+
null, // parentObject
325326
property,
326327
moduleName,
327328
types,
@@ -356,6 +357,7 @@ describe('parseObjectProperty', () => {
356357
);
357358
expect(() =>
358359
parseObjectProperty(
360+
null, // parentObject
359361
property,
360362
moduleName,
361363
types,
@@ -1139,7 +1141,7 @@ describe('buildModuleSchema', () => {
11391141
const contents = `
11401142
import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport';
11411143
import * as TurboModuleRegistry from 'react-native/Libraries/TurboModule/TurboModuleRegistry';
1142-
1144+
11431145
export interface Spec extends TurboModule {
11441146
+getBool: (arg: boolean) => boolean; }
11451147
export interface SpecOther extends TurboModule {
@@ -1189,11 +1191,11 @@ describe('buildModuleSchema', () => {
11891191
const contents = `
11901192
import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport';
11911193
import * as TurboModuleRegistry from 'react-native/Libraries/TurboModule/TurboModuleRegistry';
1192-
1194+
11931195
export interface MisnamedSpec extends TurboModule {
11941196
+getArray: (a: Array<any>) => Array<string>;
11951197
}
1196-
1198+
11971199
export default (TurboModuleRegistry.getEnforcing<Spec>(
11981200
'SampleTurboModule',
11991201
): Spec);

packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,10 +731,23 @@ export enum StringOptions {
731731
Three = 'three',
732732
}
733733
734+
export type BinaryTreeNode = {
735+
left?: BinaryTreeNode,
736+
value: number,
737+
right?: BinaryTreeNode,
738+
};
739+
740+
export type GraphNode = {
741+
label: string,
742+
neighbors?: Array<GraphNode>,
743+
};
744+
734745
export interface Spec extends TurboModule {
735746
+getCallback: () => () => void;
736747
+getMixed: (arg: mixed) => mixed;
737748
+getEnums: (quality: Quality, resolution?: Resolution, floppy: Floppy, stringOptions: StringOptions) => string;
749+
+getBinaryTreeNode: (arg: BinaryTreeNode) => BinaryTreeNode;
750+
+getGraphNode: (arg: GraphNode) => GraphNode;
738751
+getMap: (arg: {[a: string]: ?number}) => {[b: string]: ?number};
739752
+getAnotherMap: (arg: {[string]: string}) => {[string]: string};
740753
+getUnion: (chooseInt: ChooseInt, chooseFloat: ChooseFloat, chooseObject: ChooseObject, chooseString: ChooseString) => ChooseObject;

packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,59 @@ exports[`RN Codegen Flow Parser can generate fixture CXX_ONLY_NATIVE_MODULE 1`]
5151
'modules': {
5252
'NativeSampleTurboModule': {
5353
'type': 'NativeModule',
54-
'aliasMap': {},
54+
'aliasMap': {
55+
'BinaryTreeNode': {
56+
'type': 'ObjectTypeAnnotation',
57+
'properties': [
58+
{
59+
'name': 'left',
60+
'optional': true,
61+
'typeAnnotation': {
62+
'type': 'TypeAliasTypeAnnotation',
63+
'name': 'BinaryTreeNode'
64+
}
65+
},
66+
{
67+
'name': 'value',
68+
'optional': false,
69+
'typeAnnotation': {
70+
'type': 'NumberTypeAnnotation'
71+
}
72+
},
73+
{
74+
'name': 'right',
75+
'optional': true,
76+
'typeAnnotation': {
77+
'type': 'TypeAliasTypeAnnotation',
78+
'name': 'BinaryTreeNode'
79+
}
80+
}
81+
]
82+
},
83+
'GraphNode': {
84+
'type': 'ObjectTypeAnnotation',
85+
'properties': [
86+
{
87+
'name': 'label',
88+
'optional': false,
89+
'typeAnnotation': {
90+
'type': 'StringTypeAnnotation'
91+
}
92+
},
93+
{
94+
'name': 'neighbors',
95+
'optional': true,
96+
'typeAnnotation': {
97+
'type': 'ArrayTypeAnnotation',
98+
'elementType': {
99+
'type': 'TypeAliasTypeAnnotation',
100+
'name': 'GraphNode'
101+
}
102+
}
103+
}
104+
]
105+
}
106+
},
55107
'enumMap': {
56108
'Quality': {
57109
'name': 'Quality',
@@ -202,6 +254,48 @@ exports[`RN Codegen Flow Parser can generate fixture CXX_ONLY_NATIVE_MODULE 1`]
202254
]
203255
}
204256
},
257+
{
258+
'name': 'getBinaryTreeNode',
259+
'optional': false,
260+
'typeAnnotation': {
261+
'type': 'FunctionTypeAnnotation',
262+
'returnTypeAnnotation': {
263+
'type': 'TypeAliasTypeAnnotation',
264+
'name': 'BinaryTreeNode'
265+
},
266+
'params': [
267+
{
268+
'name': 'arg',
269+
'optional': false,
270+
'typeAnnotation': {
271+
'type': 'TypeAliasTypeAnnotation',
272+
'name': 'BinaryTreeNode'
273+
}
274+
}
275+
]
276+
}
277+
},
278+
{
279+
'name': 'getGraphNode',
280+
'optional': false,
281+
'typeAnnotation': {
282+
'type': 'FunctionTypeAnnotation',
283+
'returnTypeAnnotation': {
284+
'type': 'TypeAliasTypeAnnotation',
285+
'name': 'GraphNode'
286+
},
287+
'params': [
288+
{
289+
'name': 'arg',
290+
'optional': false,
291+
'typeAnnotation': {
292+
'type': 'TypeAliasTypeAnnotation',
293+
'name': 'GraphNode'
294+
}
295+
}
296+
]
297+
}
298+
},
205299
{
206300
'name': 'getMap',
207301
'optional': false,

packages/react-native-codegen/src/parsers/flow/modules/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ function translateTypeAnnotation(
176176
property => {
177177
return tryParse(() => {
178178
return parseObjectProperty(
179+
flowTypeAnnotation,
179180
property,
180181
hasteModuleName,
181182
types,

packages/react-native-codegen/src/parsers/parsers-commons.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ function isObjectProperty(property: $FlowFixMe, language: ParserType): boolean {
171171
}
172172

173173
function parseObjectProperty(
174+
parentObject?: $FlowFixMe,
174175
property: $FlowFixMe,
175176
hasteModuleName: string,
176177
types: TypeDeclarationMap,
@@ -191,6 +192,34 @@ function parseObjectProperty(
191192
? property.typeAnnotation.typeAnnotation
192193
: property.value;
193194

195+
// Handle recursive types
196+
if (parentObject) {
197+
const propertyType = parser.getResolveTypeAnnotationFN()(
198+
languageTypeAnnotation,
199+
types,
200+
parser,
201+
);
202+
if (
203+
propertyType.typeResolutionStatus.successful === true &&
204+
propertyType.typeResolutionStatus.type === 'alias' &&
205+
(language === 'TypeScript'
206+
? parentObject.typeName &&
207+
parentObject.typeName.name === languageTypeAnnotation.typeName?.name
208+
: parentObject.id &&
209+
parentObject.id.name === languageTypeAnnotation.id?.name)
210+
) {
211+
return {
212+
name,
213+
optional,
214+
typeAnnotation: {
215+
type: 'TypeAliasTypeAnnotation',
216+
name: propertyType.typeResolutionStatus.name,
217+
},
218+
};
219+
}
220+
}
221+
222+
// Handle non-recursive types
194223
const [propertyTypeAnnotation, isPropertyNullable] =
195224
unwrapNullable<$FlowFixMe>(
196225
translateTypeAnnotation(

packages/react-native-codegen/src/parsers/typescript/modules/__test_fixtures__/fixtures.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,10 +825,23 @@ export type ChooseFloat = 1.44 | 2.88 | 5.76;
825825
export type ChooseObject = {} | {low: string};
826826
export type ChooseString = 'One' | 'Two' | 'Three';
827827
828+
export type BinaryTreeNode = {
829+
left?: BinaryTreeNode,
830+
value: number,
831+
right?: BinaryTreeNode,
832+
};
833+
834+
export type GraphNode = {
835+
label: string,
836+
neighbors?: Array<GraphNode>,
837+
};
838+
828839
export interface Spec extends TurboModule {
829840
readonly getCallback: () => () => void;
830841
readonly getMixed: (arg: unknown) => unknown;
831842
readonly getEnums: (quality: Quality, resolution?: Resolution, floppy: Floppy, stringOptions: StringOptions) => string;
843+
readonly getBinaryTreeNode: (arg: BinaryTreeNode) => BinaryTreeNode;
844+
readonly getGraphNode: (arg: GraphNode) => GraphNode;
832845
readonly getMap: (arg: {[a: string]: number | null;}) => {[b: string]: number | null;};
833846
readonly getAnotherMap: (arg: {[key: string]: string}) => {[key: string]: string};
834847
readonly getUnion: (chooseInt: ChooseInt, chooseFloat: ChooseFloat, chooseObject: ChooseObject, chooseString: ChooseString) => ChooseObject;

packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,59 @@ exports[`RN Codegen TypeScript Parser can generate fixture CXX_ONLY_NATIVE_MODUL
4242
'modules': {
4343
'NativeSampleTurboModule': {
4444
'type': 'NativeModule',
45-
'aliasMap': {},
45+
'aliasMap': {
46+
'BinaryTreeNode': {
47+
'type': 'ObjectTypeAnnotation',
48+
'properties': [
49+
{
50+
'name': 'left',
51+
'optional': true,
52+
'typeAnnotation': {
53+
'type': 'TypeAliasTypeAnnotation',
54+
'name': 'BinaryTreeNode'
55+
}
56+
},
57+
{
58+
'name': 'value',
59+
'optional': false,
60+
'typeAnnotation': {
61+
'type': 'NumberTypeAnnotation'
62+
}
63+
},
64+
{
65+
'name': 'right',
66+
'optional': true,
67+
'typeAnnotation': {
68+
'type': 'TypeAliasTypeAnnotation',
69+
'name': 'BinaryTreeNode'
70+
}
71+
}
72+
]
73+
},
74+
'GraphNode': {
75+
'type': 'ObjectTypeAnnotation',
76+
'properties': [
77+
{
78+
'name': 'label',
79+
'optional': false,
80+
'typeAnnotation': {
81+
'type': 'StringTypeAnnotation'
82+
}
83+
},
84+
{
85+
'name': 'neighbors',
86+
'optional': true,
87+
'typeAnnotation': {
88+
'type': 'ArrayTypeAnnotation',
89+
'elementType': {
90+
'type': 'TypeAliasTypeAnnotation',
91+
'name': 'GraphNode'
92+
}
93+
}
94+
}
95+
]
96+
}
97+
},
4698
'enumMap': {
4799
'Quality': {
48100
'name': 'Quality',
@@ -193,6 +245,48 @@ exports[`RN Codegen TypeScript Parser can generate fixture CXX_ONLY_NATIVE_MODUL
193245
]
194246
}
195247
},
248+
{
249+
'name': 'getBinaryTreeNode',
250+
'optional': false,
251+
'typeAnnotation': {
252+
'type': 'FunctionTypeAnnotation',
253+
'returnTypeAnnotation': {
254+
'type': 'TypeAliasTypeAnnotation',
255+
'name': 'BinaryTreeNode'
256+
},
257+
'params': [
258+
{
259+
'name': 'arg',
260+
'optional': false,
261+
'typeAnnotation': {
262+
'type': 'TypeAliasTypeAnnotation',
263+
'name': 'BinaryTreeNode'
264+
}
265+
}
266+
]
267+
}
268+
},
269+
{
270+
'name': 'getGraphNode',
271+
'optional': false,
272+
'typeAnnotation': {
273+
'type': 'FunctionTypeAnnotation',
274+
'returnTypeAnnotation': {
275+
'type': 'TypeAliasTypeAnnotation',
276+
'name': 'GraphNode'
277+
},
278+
'params': [
279+
{
280+
'name': 'arg',
281+
'optional': false,
282+
'typeAnnotation': {
283+
'type': 'TypeAliasTypeAnnotation',
284+
'name': 'GraphNode'
285+
}
286+
}
287+
]
288+
}
289+
},
196290
{
197291
'name': 'getMap',
198292
'optional': false,

packages/react-native-codegen/src/parsers/typescript/modules/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ function translateObjectTypeAnnotation(
5050
/**
5151
* TODO(T108222691): Use flow-types for @babel/parser
5252
*/
53+
typeScriptTypeAnnotation: $FlowFixMe,
5354
nullable: boolean,
5455
objectMembers: $ReadOnlyArray<$FlowFixMe>,
5556
typeResolutionStatus: TypeResolutionStatus,
@@ -66,6 +67,7 @@ function translateObjectTypeAnnotation(
6667
.map<?NamedShape<Nullable<NativeModuleBaseTypeAnnotation>>>(property => {
6768
return tryParse(() => {
6869
return parseObjectProperty(
70+
typeScriptTypeAnnotation,
6971
property,
7072
hasteModuleName,
7173
types,
@@ -266,6 +268,7 @@ function translateTypeAnnotation(
266268

267269
return translateObjectTypeAnnotation(
268270
hasteModuleName,
271+
typeScriptTypeAnnotation,
269272
nullable,
270273
flattenProperties([typeAnnotation], types, parser),
271274
typeResolutionStatus,
@@ -281,6 +284,7 @@ function translateTypeAnnotation(
281284
case 'TSIntersectionType': {
282285
return translateObjectTypeAnnotation(
283286
hasteModuleName,
287+
typeScriptTypeAnnotation,
284288
nullable,
285289
flattenProperties(
286290
flattenIntersectionType(typeAnnotation, types),
@@ -324,6 +328,7 @@ function translateTypeAnnotation(
324328

325329
return translateObjectTypeAnnotation(
326330
hasteModuleName,
331+
typeScriptTypeAnnotation,
327332
nullable,
328333
typeAnnotation.members,
329334
typeResolutionStatus,

0 commit comments

Comments
 (0)