@react-native-windows/codegen 0.0.0-canary.13 → 0.0.0-canary.131
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1135 -16
- package/README.md +1 -1
- package/bin.js +0 -0
- package/lib-commonjs/Cli.d.ts +7 -0
- package/lib-commonjs/Cli.js +103 -0
- package/lib-commonjs/Cli.js.map +1 -0
- package/lib-commonjs/generators/AliasGen.d.ts +12 -0
- package/lib-commonjs/generators/AliasGen.js +115 -0
- package/lib-commonjs/generators/AliasGen.js.map +1 -0
- package/lib-commonjs/generators/AliasManaging.d.ts +15 -0
- package/lib-commonjs/generators/AliasManaging.js +49 -0
- package/lib-commonjs/generators/AliasManaging.js.map +1 -0
- package/lib-commonjs/generators/GenerateComponentWindows.d.ts +13 -0
- package/lib-commonjs/generators/GenerateComponentWindows.js +468 -0
- package/lib-commonjs/generators/GenerateComponentWindows.js.map +1 -0
- package/lib-commonjs/generators/GenerateNM2.d.ts +15 -0
- package/lib-commonjs/generators/GenerateNM2.js +145 -0
- package/lib-commonjs/generators/GenerateNM2.js.map +1 -0
- package/lib-commonjs/generators/GenerateTypeScript.d.ts +11 -0
- package/lib-commonjs/generators/GenerateTypeScript.js +165 -0
- package/lib-commonjs/generators/GenerateTypeScript.js.map +1 -0
- package/lib-commonjs/generators/ObjectTypes.d.ts +13 -0
- package/lib-commonjs/generators/ObjectTypes.js +81 -0
- package/lib-commonjs/generators/ObjectTypes.js.map +1 -0
- package/lib-commonjs/generators/ParamTypes.d.ts +13 -0
- package/lib-commonjs/generators/ParamTypes.js +183 -0
- package/lib-commonjs/generators/ParamTypes.js.map +1 -0
- package/lib-commonjs/generators/PropObjectTypes.d.ts +18 -0
- package/lib-commonjs/generators/PropObjectTypes.js +208 -0
- package/lib-commonjs/generators/PropObjectTypes.js.map +1 -0
- package/lib-commonjs/generators/ReturnTypes.d.ts +10 -0
- package/lib-commonjs/generators/ReturnTypes.js +29 -0
- package/lib-commonjs/generators/ReturnTypes.js.map +1 -0
- package/lib-commonjs/generators/ValidateConstants.d.ts +8 -0
- package/lib-commonjs/generators/ValidateConstants.js +38 -0
- package/lib-commonjs/generators/ValidateConstants.js.map +1 -0
- package/lib-commonjs/generators/ValidateMethods.d.ts +14 -0
- package/lib-commonjs/generators/ValidateMethods.js +112 -0
- package/lib-commonjs/generators/ValidateMethods.js.map +1 -0
- package/lib-commonjs/index.d.ts +39 -0
- package/lib-commonjs/index.js +227 -0
- package/lib-commonjs/index.js.map +1 -0
- package/package.json +39 -21
- package/src/Cli.ts +69 -232
- package/src/generators/AliasGen.ts +195 -0
- package/src/generators/AliasManaging.ts +75 -0
- package/src/generators/GenerateComponentWindows.ts +616 -0
- package/src/generators/GenerateNM2.ts +128 -131
- package/src/generators/GenerateTypeScript.ts +250 -0
- package/src/generators/ObjectTypes.ts +95 -37
- package/src/generators/ParamTypes.ts +309 -53
- package/src/generators/PropObjectTypes.ts +223 -0
- package/src/generators/ReturnTypes.ts +38 -40
- package/src/generators/ValidateConstants.ts +50 -0
- package/src/generators/ValidateMethods.ts +270 -0
- package/src/index.ts +412 -0
- package/.eslintrc.js +0 -4
- package/.vscode/launch.json +0 -23
- package/CHANGELOG.json +0 -726
- package/jest.config.js +0 -1
- package/tsconfig.json +0 -5
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import type { PropTypeAnnotation, ObjectTypeAnnotation, EventTypeAnnotation, CommandParamTypeAnnotation } from '@react-native/codegen/lib/CodegenSchema';
|
|
2
|
+
import type { CppCodegenOptions } from './ObjectTypes';
|
|
3
|
+
import {
|
|
4
|
+
AliasMap,
|
|
5
|
+
getAnonymousAliasCppName,
|
|
6
|
+
} from './AliasManaging';
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
// eslint-disable-next-line complexity
|
|
10
|
+
export function translateComponentPropsFieldType(type: PropTypeAnnotation,
|
|
11
|
+
aliases: AliasMap<ObjectTypeAnnotation<PropTypeAnnotation>>,
|
|
12
|
+
baseAliasName: string,
|
|
13
|
+
options: CppCodegenOptions): { type: string, initializer: string, alreadySupportsOptionalOrHasDefault?: boolean } {
|
|
14
|
+
switch (type.type) {
|
|
15
|
+
case 'StringTypeAnnotation':
|
|
16
|
+
return { type: options.cppStringType, initializer: type.default ? `{${type.default}}` : '', alreadySupportsOptionalOrHasDefault: !!type.default };
|
|
17
|
+
case 'FloatTypeAnnotation':
|
|
18
|
+
return { type: 'float', initializer: type.default ? `{${type.default}}` : '{}', alreadySupportsOptionalOrHasDefault: !!type.default };
|
|
19
|
+
case 'DoubleTypeAnnotation':
|
|
20
|
+
return { type: 'double', initializer: type.default ? `{${type.default}}` : '{}', alreadySupportsOptionalOrHasDefault: !!type.default };
|
|
21
|
+
case 'Int32TypeAnnotation':
|
|
22
|
+
return { type: 'int32_t', initializer: type.default ? `{${type.default}}` : '{}', alreadySupportsOptionalOrHasDefault: !!type.default };
|
|
23
|
+
case 'BooleanTypeAnnotation':
|
|
24
|
+
return { type: 'bool', initializer: type.default ? `{${type.default}}` : '{}', alreadySupportsOptionalOrHasDefault: !!type.default };
|
|
25
|
+
case 'ArrayTypeAnnotation':
|
|
26
|
+
let arrayTemplateArg = '';
|
|
27
|
+
switch (type.elementType.type) {
|
|
28
|
+
case 'BooleanTypeAnnotation':
|
|
29
|
+
arrayTemplateArg = 'bool';
|
|
30
|
+
break;
|
|
31
|
+
case 'DoubleTypeAnnotation':
|
|
32
|
+
arrayTemplateArg = 'double';
|
|
33
|
+
break;
|
|
34
|
+
case 'FloatTypeAnnotation':
|
|
35
|
+
arrayTemplateArg = 'float';
|
|
36
|
+
break;
|
|
37
|
+
case 'Int32TypeAnnotation':
|
|
38
|
+
arrayTemplateArg = 'int32_t';
|
|
39
|
+
break;
|
|
40
|
+
case 'StringTypeAnnotation':
|
|
41
|
+
arrayTemplateArg = options.cppStringType;
|
|
42
|
+
break;
|
|
43
|
+
case 'ArrayTypeAnnotation':
|
|
44
|
+
const innerType = translateComponentPropsFieldType(type.elementType, aliases, baseAliasName, options);
|
|
45
|
+
arrayTemplateArg = `std::vector<${innerType.type}>`;
|
|
46
|
+
break;
|
|
47
|
+
case 'ObjectTypeAnnotation':
|
|
48
|
+
arrayTemplateArg = translateComponentPropsFieldType(type.elementType, aliases, baseAliasName, options).type;
|
|
49
|
+
break;
|
|
50
|
+
case 'ReservedPropTypeAnnotation':
|
|
51
|
+
switch (type.elementType.name) {
|
|
52
|
+
case 'ColorPrimitive':
|
|
53
|
+
arrayTemplateArg = 'winrt::Microsoft::ReactNative::Color';
|
|
54
|
+
break;
|
|
55
|
+
case 'DimensionPrimitive':
|
|
56
|
+
case 'EdgeInsetsPrimitive':
|
|
57
|
+
case 'ImageRequestPrimitive':
|
|
58
|
+
case 'ImageSourcePrimitive':
|
|
59
|
+
case 'PointPrimitive':
|
|
60
|
+
arrayTemplateArg = 'winrt::Microsoft::ReactNative::JSValue'; // TODO - better handling for these types than JSValue
|
|
61
|
+
break;
|
|
62
|
+
default:
|
|
63
|
+
throw new Error(`Unhandled ReservedPropTypeAnnotation type: ${type.elementType.name}`);
|
|
64
|
+
}
|
|
65
|
+
break;
|
|
66
|
+
case 'StringEnumTypeAnnotation':
|
|
67
|
+
arrayTemplateArg = options.cppStringType; // TODO - better enum type handling than just passing a string
|
|
68
|
+
break;
|
|
69
|
+
default:
|
|
70
|
+
throw new Error(`Unhandled type: ${type.type}`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return { type: `std::vector<${arrayTemplateArg}>`, initializer: '' };
|
|
74
|
+
case 'ReservedPropTypeAnnotation':
|
|
75
|
+
switch (type.name) {
|
|
76
|
+
case 'ColorPrimitive':
|
|
77
|
+
return { type: 'winrt::Microsoft::ReactNative::Color', initializer: '{nullptr}', alreadySupportsOptionalOrHasDefault: true };
|
|
78
|
+
case 'DimensionPrimitive':
|
|
79
|
+
case 'EdgeInsetsPrimitive':
|
|
80
|
+
case 'ImageRequestPrimitive':
|
|
81
|
+
case 'ImageSourcePrimitive':
|
|
82
|
+
case 'PointPrimitive':
|
|
83
|
+
return { type: 'winrt::Microsoft::ReactNative::JSValue', initializer: '{nullptr}', alreadySupportsOptionalOrHasDefault: true }; // TODO - better handling for these types than JSValue
|
|
84
|
+
default:
|
|
85
|
+
throw new Error(`Unhandled ReservedPropTypeAnnotation type: ${type.name}`);
|
|
86
|
+
}
|
|
87
|
+
case 'ObjectTypeAnnotation': {
|
|
88
|
+
return { type: getAnonymousAliasCppName<ObjectTypeAnnotation<PropTypeAnnotation>>(aliases, baseAliasName, type), initializer: '' };
|
|
89
|
+
}
|
|
90
|
+
case 'MixedTypeAnnotation':
|
|
91
|
+
return { type: 'winrt::Microsoft::ReactNative::JSValue', initializer: '{nullptr}', alreadySupportsOptionalOrHasDefault: true };
|
|
92
|
+
case 'Int32EnumTypeAnnotation':
|
|
93
|
+
return { type: 'int32_t', initializer: '' }; // TODO - better enum type handling than just passing a string
|
|
94
|
+
case 'StringEnumTypeAnnotation':
|
|
95
|
+
return { type: options.cppStringType, initializer: '' }; // TODO - better enum type handling than just passing an int
|
|
96
|
+
default:
|
|
97
|
+
throw new Error(`Unhandled type: ${(type as any).type}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function translateComponentEventType(type: EventTypeAnnotation,
|
|
102
|
+
aliases: AliasMap<ObjectTypeAnnotation<EventTypeAnnotation>>,
|
|
103
|
+
baseAliasName: string,
|
|
104
|
+
options: CppCodegenOptions): { type: string, initializer: string, alreadySupportsOptionalOrHasDefault?: boolean } {
|
|
105
|
+
switch (type.type) {
|
|
106
|
+
case 'StringTypeAnnotation':
|
|
107
|
+
return { type: options.cppStringType, initializer: '' };
|
|
108
|
+
case 'FloatTypeAnnotation':
|
|
109
|
+
return { type: 'float', initializer: '{}' };
|
|
110
|
+
case 'DoubleTypeAnnotation':
|
|
111
|
+
return { type: 'double', initializer: '{}' };
|
|
112
|
+
case 'Int32TypeAnnotation':
|
|
113
|
+
return { type: 'int32_t', initializer: '{}' };
|
|
114
|
+
case 'BooleanTypeAnnotation':
|
|
115
|
+
return { type: 'bool', initializer: '{}' };
|
|
116
|
+
case 'ArrayTypeAnnotation':
|
|
117
|
+
{
|
|
118
|
+
let arrayTemplateArg = '';
|
|
119
|
+
switch (type.elementType.type) {
|
|
120
|
+
case 'BooleanTypeAnnotation':
|
|
121
|
+
arrayTemplateArg = 'bool';
|
|
122
|
+
break;
|
|
123
|
+
case 'DoubleTypeAnnotation':
|
|
124
|
+
arrayTemplateArg = 'double';
|
|
125
|
+
break;
|
|
126
|
+
case 'FloatTypeAnnotation':
|
|
127
|
+
arrayTemplateArg = 'float';
|
|
128
|
+
break;
|
|
129
|
+
case 'Int32TypeAnnotation':
|
|
130
|
+
arrayTemplateArg = 'int32_t';
|
|
131
|
+
break;
|
|
132
|
+
case 'StringTypeAnnotation':
|
|
133
|
+
arrayTemplateArg = options.cppStringType;
|
|
134
|
+
break;
|
|
135
|
+
case 'ArrayTypeAnnotation':
|
|
136
|
+
const innerType = translateComponentEventType(type.elementType, aliases, baseAliasName, options);
|
|
137
|
+
arrayTemplateArg = `std::vector<${innerType.type}>`;
|
|
138
|
+
break;
|
|
139
|
+
case 'MixedTypeAnnotation':
|
|
140
|
+
arrayTemplateArg = 'winrt::Microsoft::ReactNative::JSValue';
|
|
141
|
+
break;
|
|
142
|
+
case 'ObjectTypeAnnotation':
|
|
143
|
+
arrayTemplateArg = translateComponentEventType(type.elementType, aliases, baseAliasName, options).type;
|
|
144
|
+
break;
|
|
145
|
+
case 'StringLiteralUnionTypeAnnotation':
|
|
146
|
+
arrayTemplateArg = options.cppStringType; // TODO - better enum type handling than just passing a string
|
|
147
|
+
break;
|
|
148
|
+
default:
|
|
149
|
+
throw new Error(`Unhandled type: ${type.type}`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return { type: `std::vector<${arrayTemplateArg}>`, initializer: '{}' };
|
|
153
|
+
}
|
|
154
|
+
case 'ObjectTypeAnnotation': {
|
|
155
|
+
return { type: getAnonymousAliasCppName<ObjectTypeAnnotation<EventTypeAnnotation>>(aliases, baseAliasName, type), initializer: '' };
|
|
156
|
+
}
|
|
157
|
+
case 'MixedTypeAnnotation': {
|
|
158
|
+
return { type: 'winrt::Microsoft::ReactNative::JSValue', initializer: '{nullptr}', alreadySupportsOptionalOrHasDefault: true };
|
|
159
|
+
}
|
|
160
|
+
case 'StringLiteralUnionTypeAnnotation':
|
|
161
|
+
return { type: options.cppStringType, initializer: '' }; // TODO - better enum type handling than just passing a string
|
|
162
|
+
default:
|
|
163
|
+
throw new Error(`Unhandled type: ${(type as any).type}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
export function translateCommandParamType(type: CommandParamTypeAnnotation,
|
|
169
|
+
aliases: AliasMap<ObjectTypeAnnotation<CommandParamTypeAnnotation>>,
|
|
170
|
+
baseAliasName: string,
|
|
171
|
+
options: CppCodegenOptions): { type: string, initializer: string, alreadySupportsOptionalOrHasDefault?: boolean } {
|
|
172
|
+
switch (type.type) {
|
|
173
|
+
case 'StringTypeAnnotation':
|
|
174
|
+
return { type: options.cppStringType, initializer: '' };
|
|
175
|
+
case 'FloatTypeAnnotation':
|
|
176
|
+
return { type: 'float', initializer: '{}' };
|
|
177
|
+
case 'DoubleTypeAnnotation':
|
|
178
|
+
return { type: 'double', initializer: '{}' };
|
|
179
|
+
case 'Int32TypeAnnotation':
|
|
180
|
+
return { type: 'int32_t', initializer: '{}' };
|
|
181
|
+
case 'BooleanTypeAnnotation':
|
|
182
|
+
return { type: 'bool', initializer: '{}' };
|
|
183
|
+
case 'ArrayTypeAnnotation':
|
|
184
|
+
{
|
|
185
|
+
let arrayTemplateArg = '';
|
|
186
|
+
switch (type.elementType.type) {
|
|
187
|
+
case 'BooleanTypeAnnotation':
|
|
188
|
+
arrayTemplateArg = 'bool';
|
|
189
|
+
break;
|
|
190
|
+
case 'DoubleTypeAnnotation':
|
|
191
|
+
arrayTemplateArg = 'double';
|
|
192
|
+
break;
|
|
193
|
+
case 'FloatTypeAnnotation':
|
|
194
|
+
arrayTemplateArg = 'float';
|
|
195
|
+
break;
|
|
196
|
+
case 'Int32TypeAnnotation':
|
|
197
|
+
arrayTemplateArg = 'int32_t';
|
|
198
|
+
break;
|
|
199
|
+
case 'StringTypeAnnotation':
|
|
200
|
+
arrayTemplateArg = options.cppStringType;
|
|
201
|
+
break;
|
|
202
|
+
case 'MixedTypeAnnotation':
|
|
203
|
+
// TODO - not sure what exact value to be used here
|
|
204
|
+
arrayTemplateArg = 'winrt::Microsoft::ReactNative::JSValue';
|
|
205
|
+
break;
|
|
206
|
+
case 'GenericTypeAnnotation' as any: // TODO verify schema - Getting this type when running codegen on all the built in types
|
|
207
|
+
arrayTemplateArg = 'winrt::Microsoft::ReactNative::JSValue';
|
|
208
|
+
break;
|
|
209
|
+
default:
|
|
210
|
+
throw new Error(`Unhandled type: ${(type.elementType as any).type} - ${JSON.stringify(type.elementType, null, 2)}`);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return { type: `std::vector<${arrayTemplateArg}>`, initializer: '{}' };
|
|
214
|
+
}
|
|
215
|
+
case 'ReservedTypeAnnotation':
|
|
216
|
+
if ((type.name as any) !== 'RootTag') {
|
|
217
|
+
throw new Error(`Unhandled ReservedTypeAnnotation: ${type.name}`)
|
|
218
|
+
}
|
|
219
|
+
return { type: 'bool', initializer: '{-1}' };
|
|
220
|
+
default:
|
|
221
|
+
throw new Error(`Unhandled type: ${(type as any).type}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
@@ -6,67 +6,65 @@
|
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import type {
|
|
10
10
|
NativeModuleReturnTypeAnnotation,
|
|
11
11
|
Nullable,
|
|
12
|
-
} from 'react-native
|
|
13
|
-
import {
|
|
12
|
+
} from '@react-native/codegen/lib/CodegenSchema';
|
|
13
|
+
import {AliasMap} from './AliasManaging';
|
|
14
|
+
import {CppCodegenOptions, translateFieldOrReturnType} from './ObjectTypes';
|
|
14
15
|
|
|
15
16
|
function translateReturnType(
|
|
16
17
|
type: Nullable<NativeModuleReturnTypeAnnotation>,
|
|
18
|
+
aliases: AliasMap,
|
|
19
|
+
baseAliasName: string,
|
|
20
|
+
options: CppCodegenOptions,
|
|
17
21
|
): string {
|
|
18
|
-
// avoid: Property 'type' does not exist on type 'never'
|
|
19
|
-
const returnType = type.type;
|
|
20
22
|
switch (type.type) {
|
|
21
23
|
case 'VoidTypeAnnotation':
|
|
22
24
|
case 'PromiseTypeAnnotation':
|
|
23
25
|
return 'void';
|
|
24
|
-
case 'StringTypeAnnotation':
|
|
25
|
-
return 'std::string';
|
|
26
|
-
case 'NumberTypeAnnotation':
|
|
27
|
-
case 'FloatTypeAnnotation':
|
|
28
|
-
case 'DoubleTypeAnnotation':
|
|
29
|
-
return 'double';
|
|
30
|
-
case 'Int32TypeAnnotation':
|
|
31
|
-
return 'int';
|
|
32
|
-
case 'BooleanTypeAnnotation':
|
|
33
|
-
return 'bool';
|
|
34
|
-
case 'ArrayTypeAnnotation':
|
|
35
|
-
// TODO: type.elementType
|
|
36
|
-
return 'React::JSValueArray';
|
|
37
|
-
case 'GenericObjectTypeAnnotation':
|
|
38
|
-
return 'React::JSValue';
|
|
39
|
-
case 'ObjectTypeAnnotation':
|
|
40
|
-
// TODO: we have more information here, and could create a more specific type
|
|
41
|
-
return 'React::JSValueObject';
|
|
42
|
-
case 'ReservedTypeAnnotation': {
|
|
43
|
-
// avoid: Property 'name' does not exist on type 'never'
|
|
44
|
-
const name = type.name;
|
|
45
|
-
// (#6597)
|
|
46
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
47
|
-
if (name !== 'RootTag')
|
|
48
|
-
throw new Error(
|
|
49
|
-
`Unknown reserved function: ${name} in translateReturnType`,
|
|
50
|
-
);
|
|
51
|
-
return 'double';
|
|
52
|
-
}
|
|
53
|
-
case 'TypeAliasTypeAnnotation':
|
|
54
|
-
return getAliasCppName(type.name);
|
|
55
26
|
case 'NullableTypeAnnotation':
|
|
56
|
-
return `std::optional<${translateReturnType(
|
|
27
|
+
return `std::optional<${translateReturnType(
|
|
28
|
+
type.typeAnnotation,
|
|
29
|
+
aliases,
|
|
30
|
+
baseAliasName,
|
|
31
|
+
options,
|
|
32
|
+
)}>`;
|
|
57
33
|
default:
|
|
58
|
-
|
|
34
|
+
return translateFieldOrReturnType(
|
|
35
|
+
type,
|
|
36
|
+
aliases,
|
|
37
|
+
baseAliasName,
|
|
38
|
+
'translateReturnType',
|
|
39
|
+
options,
|
|
40
|
+
);
|
|
59
41
|
}
|
|
60
42
|
}
|
|
61
43
|
|
|
62
44
|
export function translateSpecReturnType(
|
|
63
45
|
type: Nullable<NativeModuleReturnTypeAnnotation>,
|
|
46
|
+
aliases: AliasMap,
|
|
47
|
+
baseAliasName: string,
|
|
48
|
+
options: CppCodegenOptions,
|
|
64
49
|
) {
|
|
65
|
-
return translateReturnType(
|
|
50
|
+
return translateReturnType(
|
|
51
|
+
type,
|
|
52
|
+
aliases,
|
|
53
|
+
`${baseAliasName}_returnType`,
|
|
54
|
+
options,
|
|
55
|
+
);
|
|
66
56
|
}
|
|
67
57
|
|
|
68
58
|
export function translateImplReturnType(
|
|
69
59
|
type: Nullable<NativeModuleReturnTypeAnnotation>,
|
|
60
|
+
aliases: AliasMap,
|
|
61
|
+
baseAliasName: string,
|
|
62
|
+
options: CppCodegenOptions,
|
|
70
63
|
) {
|
|
71
|
-
return translateReturnType(
|
|
64
|
+
return translateReturnType(
|
|
65
|
+
type,
|
|
66
|
+
aliases,
|
|
67
|
+
`${baseAliasName}_returnType`,
|
|
68
|
+
options,
|
|
69
|
+
);
|
|
72
70
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
* @format
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
import type {NativeModuleSchema} from '@react-native/codegen/lib/CodegenSchema';
|
|
10
|
+
import {AliasMap, getAnonymousAliasCppName} from './AliasManaging';
|
|
11
|
+
|
|
12
|
+
export function generateValidateConstants(
|
|
13
|
+
nativeModule: NativeModuleSchema,
|
|
14
|
+
aliases: AliasMap,
|
|
15
|
+
): [string, string] | undefined {
|
|
16
|
+
const candidates = nativeModule.spec.methods.filter(
|
|
17
|
+
prop => prop.name === 'getConstants',
|
|
18
|
+
);
|
|
19
|
+
if (candidates.length === 0) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const getConstant = candidates[0];
|
|
24
|
+
const funcType =
|
|
25
|
+
getConstant.typeAnnotation.type === 'NullableTypeAnnotation'
|
|
26
|
+
? getConstant.typeAnnotation.typeAnnotation
|
|
27
|
+
: getConstant.typeAnnotation;
|
|
28
|
+
if (
|
|
29
|
+
funcType.params.length > 0 ||
|
|
30
|
+
funcType.returnTypeAnnotation.type !== 'ObjectTypeAnnotation'
|
|
31
|
+
) {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const constantType = funcType.returnTypeAnnotation;
|
|
36
|
+
if (constantType.properties.length === 0) {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const cppName = getAnonymousAliasCppName(aliases, 'Constants', constantType);
|
|
41
|
+
|
|
42
|
+
return [
|
|
43
|
+
` TypedConstant<${cppName}>{0},`,
|
|
44
|
+
` REACT_SHOW_CONSTANT_SPEC_ERRORS(
|
|
45
|
+
0,
|
|
46
|
+
"${cppName}",
|
|
47
|
+
" REACT_GET_CONSTANTS(GetConstants) ${cppName} GetConstants() noexcept {/*implementation*/}\\n"
|
|
48
|
+
" REACT_GET_CONSTANTS(GetConstants) static ${cppName} GetConstants() noexcept {/*implementation*/}\\n");`,
|
|
49
|
+
];
|
|
50
|
+
}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
* @format
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
import type {
|
|
10
|
+
NativeModuleEventEmitterShape,
|
|
11
|
+
NativeModuleFunctionTypeAnnotation,
|
|
12
|
+
NativeModulePropertyShape,
|
|
13
|
+
NativeModuleSchema,
|
|
14
|
+
} from '@react-native/codegen/lib/CodegenSchema';
|
|
15
|
+
import {AliasMap} from './AliasManaging';
|
|
16
|
+
import type {CppCodegenOptions} from './ObjectTypes';
|
|
17
|
+
import {
|
|
18
|
+
translateArgs,
|
|
19
|
+
translateSpecArgs,
|
|
20
|
+
translateEventEmitterArgs,
|
|
21
|
+
} from './ParamTypes';
|
|
22
|
+
import {translateImplReturnType, translateSpecReturnType} from './ReturnTypes';
|
|
23
|
+
|
|
24
|
+
function isMethodSync(funcType: NativeModuleFunctionTypeAnnotation) {
|
|
25
|
+
return (
|
|
26
|
+
funcType.returnTypeAnnotation.type !== 'VoidTypeAnnotation' &&
|
|
27
|
+
funcType.returnTypeAnnotation.type !== 'PromiseTypeAnnotation'
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getPossibleMethodSignatures(
|
|
32
|
+
prop: NativeModulePropertyShape,
|
|
33
|
+
funcType: NativeModuleFunctionTypeAnnotation,
|
|
34
|
+
aliases: AliasMap,
|
|
35
|
+
baseAliasName: string,
|
|
36
|
+
options: CppCodegenOptions,
|
|
37
|
+
): string[] {
|
|
38
|
+
const args = translateArgs(funcType.params, aliases, baseAliasName, options);
|
|
39
|
+
if (funcType.returnTypeAnnotation.type === 'PromiseTypeAnnotation') {
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
41
|
+
if (funcType.returnTypeAnnotation.elementType) {
|
|
42
|
+
args.push(
|
|
43
|
+
`::React::ReactPromise<${translateImplReturnType(
|
|
44
|
+
funcType.returnTypeAnnotation.elementType,
|
|
45
|
+
aliases,
|
|
46
|
+
baseAliasName,
|
|
47
|
+
options,
|
|
48
|
+
)}> &&result`,
|
|
49
|
+
);
|
|
50
|
+
} else {
|
|
51
|
+
args.push('::React::ReactPromise<::React::JSValue> &&result');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// TODO: be much more exhaustive on the possible method signatures that can be used..
|
|
56
|
+
const sig = `REACT_${isMethodSync(funcType) ? 'SYNC_' : ''}METHOD(${
|
|
57
|
+
prop.name
|
|
58
|
+
}) ${translateImplReturnType(
|
|
59
|
+
funcType.returnTypeAnnotation,
|
|
60
|
+
aliases,
|
|
61
|
+
baseAliasName,
|
|
62
|
+
options,
|
|
63
|
+
)} ${prop.name}(${args.join(', ')}) noexcept { /* implementation */ }`;
|
|
64
|
+
|
|
65
|
+
const staticsig = `REACT_${isMethodSync(funcType) ? 'SYNC_' : ''}METHOD(${
|
|
66
|
+
prop.name
|
|
67
|
+
}) static ${translateImplReturnType(
|
|
68
|
+
funcType.returnTypeAnnotation,
|
|
69
|
+
aliases,
|
|
70
|
+
baseAliasName,
|
|
71
|
+
options,
|
|
72
|
+
)} ${prop.name}(${args.join(', ')}) noexcept { /* implementation */ }`;
|
|
73
|
+
|
|
74
|
+
return [sig, staticsig];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function translatePossibleMethodSignatures(
|
|
78
|
+
prop: NativeModulePropertyShape,
|
|
79
|
+
funcType: NativeModuleFunctionTypeAnnotation,
|
|
80
|
+
aliases: AliasMap,
|
|
81
|
+
baseAliasName: string,
|
|
82
|
+
options: CppCodegenOptions,
|
|
83
|
+
): string {
|
|
84
|
+
return getPossibleMethodSignatures(
|
|
85
|
+
prop,
|
|
86
|
+
funcType,
|
|
87
|
+
aliases,
|
|
88
|
+
baseAliasName,
|
|
89
|
+
options,
|
|
90
|
+
)
|
|
91
|
+
.map(sig => `" ${sig}\\n"`)
|
|
92
|
+
.join('\n ');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function renderProperties(
|
|
96
|
+
methods: ReadonlyArray<NativeModulePropertyShape>,
|
|
97
|
+
aliases: AliasMap,
|
|
98
|
+
tuple: boolean,
|
|
99
|
+
options: CppCodegenOptions,
|
|
100
|
+
): {code: string; numberOfProperties: number} {
|
|
101
|
+
// TODO: generate code for constants
|
|
102
|
+
const properties = methods
|
|
103
|
+
.filter(prop => prop.name !== 'getConstants')
|
|
104
|
+
.map((prop, index) => {
|
|
105
|
+
// TODO: prop.optional === true
|
|
106
|
+
// TODO: prop.typeAnnotation.type === 'NullableTypeAnnotation'
|
|
107
|
+
const propAliasName = prop.name;
|
|
108
|
+
const funcType =
|
|
109
|
+
prop.typeAnnotation.type === 'NullableTypeAnnotation'
|
|
110
|
+
? prop.typeAnnotation.typeAnnotation
|
|
111
|
+
: prop.typeAnnotation;
|
|
112
|
+
|
|
113
|
+
const traversedArgs = translateSpecArgs(
|
|
114
|
+
funcType.params,
|
|
115
|
+
aliases,
|
|
116
|
+
propAliasName,
|
|
117
|
+
options,
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
const translatedReturnParam = translateSpecReturnType(
|
|
121
|
+
funcType.returnTypeAnnotation,
|
|
122
|
+
aliases,
|
|
123
|
+
propAliasName,
|
|
124
|
+
options,
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
if (funcType.returnTypeAnnotation.type === 'PromiseTypeAnnotation') {
|
|
128
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
129
|
+
if (funcType.returnTypeAnnotation.elementType) {
|
|
130
|
+
traversedArgs.push(
|
|
131
|
+
`Promise<${translateSpecReturnType(
|
|
132
|
+
funcType.returnTypeAnnotation.elementType,
|
|
133
|
+
aliases,
|
|
134
|
+
propAliasName,
|
|
135
|
+
options,
|
|
136
|
+
)}>`,
|
|
137
|
+
);
|
|
138
|
+
} else {
|
|
139
|
+
traversedArgs.push('Promise<::React::JSValue>');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (tuple) {
|
|
144
|
+
return ` ${
|
|
145
|
+
isMethodSync(funcType) ? 'Sync' : ''
|
|
146
|
+
}Method<${translatedReturnParam}(${traversedArgs.join(
|
|
147
|
+
', ',
|
|
148
|
+
)}) noexcept>{${index}, L"${prop.name}"},`;
|
|
149
|
+
} else {
|
|
150
|
+
return ` REACT_SHOW_METHOD_SPEC_ERRORS(
|
|
151
|
+
${index},
|
|
152
|
+
"${prop.name}",
|
|
153
|
+
${translatePossibleMethodSignatures(
|
|
154
|
+
prop,
|
|
155
|
+
funcType,
|
|
156
|
+
aliases,
|
|
157
|
+
propAliasName,
|
|
158
|
+
options,
|
|
159
|
+
)});`;
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
return {code: properties.join('\n'), numberOfProperties: properties.length};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function getPossibleEventEmitterSignatures(
|
|
167
|
+
eventEmitter: NativeModuleEventEmitterShape,
|
|
168
|
+
aliases: AliasMap,
|
|
169
|
+
options: CppCodegenOptions,
|
|
170
|
+
): string[] {
|
|
171
|
+
const traversedArgs = translateEventEmitterArgs(
|
|
172
|
+
eventEmitter.typeAnnotation.typeAnnotation,
|
|
173
|
+
aliases,
|
|
174
|
+
eventEmitter.name,
|
|
175
|
+
options,
|
|
176
|
+
);
|
|
177
|
+
return [
|
|
178
|
+
`REACT_EVENT(${eventEmitter.name}) std::function<void(${traversedArgs})> ${eventEmitter.name};`,
|
|
179
|
+
];
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function translatePossibleEventSignatures(
|
|
183
|
+
eventEmitter: NativeModuleEventEmitterShape,
|
|
184
|
+
aliases: AliasMap,
|
|
185
|
+
options: CppCodegenOptions,
|
|
186
|
+
): string {
|
|
187
|
+
return getPossibleEventEmitterSignatures(eventEmitter, aliases, options)
|
|
188
|
+
.map(sig => `" ${sig}\\n"`)
|
|
189
|
+
.join('\n ');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function renderEventEmitters(
|
|
193
|
+
eventEmitters: ReadonlyArray<NativeModuleEventEmitterShape>,
|
|
194
|
+
indexOffset: number,
|
|
195
|
+
aliases: AliasMap,
|
|
196
|
+
tuple: boolean,
|
|
197
|
+
options: CppCodegenOptions,
|
|
198
|
+
): string {
|
|
199
|
+
return eventEmitters
|
|
200
|
+
.map((eventEmitter, index) => {
|
|
201
|
+
const traversedArgs = translateEventEmitterArgs(
|
|
202
|
+
eventEmitter.typeAnnotation.typeAnnotation,
|
|
203
|
+
aliases,
|
|
204
|
+
eventEmitter.name,
|
|
205
|
+
options,
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
if (tuple) {
|
|
209
|
+
return ` EventEmitter<void(${traversedArgs})>{${
|
|
210
|
+
index + indexOffset
|
|
211
|
+
}, L"${eventEmitter.name}"},`;
|
|
212
|
+
} else {
|
|
213
|
+
return ` REACT_SHOW_EVENTEMITTER_SPEC_ERRORS(
|
|
214
|
+
${index + indexOffset},
|
|
215
|
+
"${eventEmitter.name}",
|
|
216
|
+
${translatePossibleEventSignatures(
|
|
217
|
+
eventEmitter,
|
|
218
|
+
aliases,
|
|
219
|
+
options,
|
|
220
|
+
)});`;
|
|
221
|
+
}
|
|
222
|
+
})
|
|
223
|
+
.join('\n');
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export function generateValidateMethods(
|
|
227
|
+
nativeModule: NativeModuleSchema,
|
|
228
|
+
aliases: AliasMap,
|
|
229
|
+
options: CppCodegenOptions,
|
|
230
|
+
): {
|
|
231
|
+
traversedProperties: string;
|
|
232
|
+
traversedEventEmitters: string;
|
|
233
|
+
traversedPropertyTuples: string;
|
|
234
|
+
traversedEventEmitterTuples: string;
|
|
235
|
+
} {
|
|
236
|
+
const methods = nativeModule.spec.methods;
|
|
237
|
+
const eventEmitters = nativeModule.spec.eventEmitters;
|
|
238
|
+
const traversedProperties = renderProperties(
|
|
239
|
+
methods,
|
|
240
|
+
aliases,
|
|
241
|
+
false,
|
|
242
|
+
options,
|
|
243
|
+
);
|
|
244
|
+
const traversedEventEmitters = renderEventEmitters(
|
|
245
|
+
eventEmitters,
|
|
246
|
+
traversedProperties.numberOfProperties,
|
|
247
|
+
aliases,
|
|
248
|
+
false,
|
|
249
|
+
options,
|
|
250
|
+
);
|
|
251
|
+
const traversedPropertyTuples = renderProperties(
|
|
252
|
+
methods,
|
|
253
|
+
aliases,
|
|
254
|
+
true,
|
|
255
|
+
options,
|
|
256
|
+
);
|
|
257
|
+
const traversedEventEmitterTuples = renderEventEmitters(
|
|
258
|
+
eventEmitters,
|
|
259
|
+
traversedProperties.numberOfProperties,
|
|
260
|
+
aliases,
|
|
261
|
+
true,
|
|
262
|
+
options,
|
|
263
|
+
);
|
|
264
|
+
return {
|
|
265
|
+
traversedPropertyTuples: traversedPropertyTuples.code,
|
|
266
|
+
traversedEventEmitterTuples,
|
|
267
|
+
traversedProperties: traversedProperties.code,
|
|
268
|
+
traversedEventEmitters,
|
|
269
|
+
};
|
|
270
|
+
}
|