Skip to content

Commit fa21a90

Browse files
author
Antoine Doubovetzky
committed
♻️ (codegen) extract assertGenericTypeAnnotationHasExactlyOneTypeParameter to parsers-commons
1 parent 1fc27c4 commit fa21a90

File tree

5 files changed

+151
-65
lines changed

5 files changed

+151
-65
lines changed

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

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111

1212
'use-strict';
1313

14+
import {IncorrectlyParameterizedGenericParserError} from '../errors';
15+
import {assertGenericTypeAnnotationHasExactlyOneTypeParameter} from '../parsers-commons';
16+
1417
const {wrapNullable, unwrapNullable} = require('../parsers-commons.js');
1518

1619
describe('wrapNullable', () => {
@@ -78,3 +81,94 @@ describe('unwrapNullable', () => {
7881
});
7982
});
8083
});
84+
85+
describe('assertGenericTypeAnnotationHasExactlyOneTypeParameter', () => {
86+
it('throws an IncorrectlyParameterizedGenericParserError if typeParameters is null', () => {
87+
const moduleName = 'testModuleName';
88+
const typeAnnotation = {
89+
typeParameters: null,
90+
id: {
91+
name: 'typeAnnotationName',
92+
},
93+
};
94+
expect(() =>
95+
assertGenericTypeAnnotationHasExactlyOneTypeParameter(
96+
moduleName,
97+
typeAnnotation,
98+
'Flow',
99+
),
100+
).toThrow(IncorrectlyParameterizedGenericParserError);
101+
});
102+
103+
it("throws an error if typeAnnotation.typeParameters.type doesn't have the correct value depending on language", () => {
104+
const moduleName = 'testModuleName';
105+
const flowTypeAnnotation = {
106+
typeParameters: {
107+
type: 'TypeParameterInstantiation',
108+
},
109+
id: {
110+
name: 'typeAnnotationName',
111+
},
112+
};
113+
expect(() =>
114+
assertGenericTypeAnnotationHasExactlyOneTypeParameter(
115+
moduleName,
116+
flowTypeAnnotation,
117+
'Flow',
118+
),
119+
).toThrow(Error);
120+
121+
const typeScriptTypeAnnotation = {
122+
typeParameters: {
123+
type: 'TypeParameterInstantiation',
124+
},
125+
typeName: {
126+
name: 'typeAnnotationName',
127+
},
128+
};
129+
expect(() =>
130+
assertGenericTypeAnnotationHasExactlyOneTypeParameter(
131+
moduleName,
132+
typeScriptTypeAnnotation,
133+
'TypeScript',
134+
),
135+
).toThrow(Error);
136+
});
137+
138+
it("throws an IncorrectlyParameterizedGenericParserError if typeParameters don't have 1 exactly parameter", () => {
139+
const moduleName = 'testModuleName';
140+
const typeAnnotationWithTwoParams = {
141+
typeParameters: {
142+
params: [1, 2],
143+
type: 'TypeParameterInstantiation',
144+
},
145+
id: {
146+
name: 'typeAnnotationName',
147+
},
148+
};
149+
expect(() =>
150+
assertGenericTypeAnnotationHasExactlyOneTypeParameter(
151+
moduleName,
152+
typeAnnotationWithTwoParams,
153+
'Flow',
154+
),
155+
).toThrow(IncorrectlyParameterizedGenericParserError);
156+
157+
const typeAnnotationWithNoParams = {
158+
typeParameters: {
159+
params: [],
160+
type: 'TypeParameterInstantiation',
161+
},
162+
id: {
163+
name: 'typeAnnotationName',
164+
},
165+
};
166+
expect(() =>
167+
assertGenericTypeAnnotationHasExactlyOneTypeParameter(
168+
moduleName,
169+
typeAnnotationWithNoParams,
170+
'Flow',
171+
),
172+
).toThrow(IncorrectlyParameterizedGenericParserError);
173+
});
174+
});

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @flow strict-local
7+
* @flow strict
88
* @format
99
*/
1010

1111
'use strict';
1212

1313
const invariant = require('invariant');
1414

15-
type ParserType = 'Flow' | 'TypeScript';
15+
export type ParserType = 'Flow' | 'TypeScript';
1616

1717
class ParserError extends Error {
1818
nodes: $ReadOnlyArray<$FlowFixMe>;

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

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ const {
3232
visit,
3333
isModuleRegistryCall,
3434
} = require('../utils.js');
35-
const {unwrapNullable, wrapNullable} = require('../../parsers-commons');
35+
const {
36+
unwrapNullable,
37+
wrapNullable,
38+
assertGenericTypeAnnotationHasExactlyOneTypeParameter,
39+
} = require('../../parsers-commons');
3640
const {
3741
emitBoolean,
3842
emitDouble,
@@ -42,7 +46,6 @@ const {
4246
typeAliasResolution,
4347
} = require('../../parsers-primitives');
4448
const {
45-
IncorrectlyParameterizedGenericParserError,
4649
MisnamedModuleInterfaceParserError,
4750
ModuleInterfaceNotFoundParserError,
4851
MoreThanOneModuleInterfaceParserError,
@@ -96,6 +99,7 @@ function translateTypeAnnotation(
9699
assertGenericTypeAnnotationHasExactlyOneTypeParameter(
97100
hasteModuleName,
98101
typeAnnotation,
102+
language,
99103
);
100104

101105
return wrapNullable(nullable, {
@@ -107,6 +111,7 @@ function translateTypeAnnotation(
107111
assertGenericTypeAnnotationHasExactlyOneTypeParameter(
108112
hasteModuleName,
109113
typeAnnotation,
114+
language,
110115
);
111116

112117
try {
@@ -182,6 +187,7 @@ function translateTypeAnnotation(
182187
assertGenericTypeAnnotationHasExactlyOneTypeParameter(
183188
hasteModuleName,
184189
typeAnnotation,
190+
language,
185191
);
186192

187193
const [paramType, isParamNullable] = unwrapNullable(
@@ -411,35 +417,6 @@ function translateTypeAnnotation(
411417
}
412418
}
413419

414-
function assertGenericTypeAnnotationHasExactlyOneTypeParameter(
415-
moduleName: string,
416-
/**
417-
* TODO(T71778680): This is a GenericTypeAnnotation. Flow type this node
418-
*/
419-
typeAnnotation: $FlowFixMe,
420-
) {
421-
if (typeAnnotation.typeParameters == null) {
422-
throw new IncorrectlyParameterizedGenericParserError(
423-
moduleName,
424-
typeAnnotation,
425-
language,
426-
);
427-
}
428-
429-
invariant(
430-
typeAnnotation.typeParameters.type === 'TypeParameterInstantiation',
431-
"assertGenericTypeAnnotationHasExactlyOneTypeParameter: Type parameters must be an AST node of type 'TypeParameterInstantiation'",
432-
);
433-
434-
if (typeAnnotation.typeParameters.params.length !== 1) {
435-
throw new IncorrectlyParameterizedGenericParserError(
436-
moduleName,
437-
typeAnnotation,
438-
language,
439-
);
440-
}
441-
}
442-
443420
function translateFunctionTypeAnnotation(
444421
hasteModuleName: string,
445422
// TODO(T71778680): This is a FunctionTypeAnnotation. Type this.

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ import type {
1616
NativeModuleTypeAnnotation,
1717
Nullable,
1818
} from '../CodegenSchema.js';
19+
import {IncorrectlyParameterizedGenericParserError} from './errors';
20+
import type {ParserType} from './errors';
21+
22+
const invariant = require('invariant');
1923

2024
function wrapModuleSchema(
2125
nativeModuleSchema: NativeModuleSchema,
@@ -52,8 +56,44 @@ function wrapNullable<+T: NativeModuleTypeAnnotation>(
5256
};
5357
}
5458

59+
function assertGenericTypeAnnotationHasExactlyOneTypeParameter(
60+
moduleName: string,
61+
/**
62+
* TODO(T108222691): Use flow-types for @babel/parser
63+
*/
64+
typeAnnotation: $FlowFixMe,
65+
language: ParserType,
66+
) {
67+
if (typeAnnotation.typeParameters == null) {
68+
throw new IncorrectlyParameterizedGenericParserError(
69+
moduleName,
70+
typeAnnotation,
71+
language,
72+
);
73+
}
74+
75+
const typeAnnotationType =
76+
language === 'TypeScript'
77+
? 'TSTypeParameterInstantiation'
78+
: 'TypeParameterInstantiation';
79+
80+
invariant(
81+
typeAnnotation.typeParameters.type === typeAnnotationType,
82+
`assertGenericTypeAnnotationHasExactlyOneTypeParameter: Type parameters must be an AST node of type '${typeAnnotationType}'`,
83+
);
84+
85+
if (typeAnnotation.typeParameters.params.length !== 1) {
86+
throw new IncorrectlyParameterizedGenericParserError(
87+
moduleName,
88+
typeAnnotation,
89+
language,
90+
);
91+
}
92+
}
93+
5594
module.exports = {
5695
wrapModuleSchema,
5796
unwrapNullable,
5897
wrapNullable,
98+
assertGenericTypeAnnotationHasExactlyOneTypeParameter,
5999
};

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

Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ const {
3232
visit,
3333
isModuleRegistryCall,
3434
} = require('../utils.js');
35-
const {unwrapNullable, wrapNullable} = require('../../parsers-commons');
35+
const {
36+
unwrapNullable,
37+
wrapNullable,
38+
assertGenericTypeAnnotationHasExactlyOneTypeParameter,
39+
} = require('../../parsers-commons');
3640
const {
3741
emitBoolean,
3842
emitDouble,
@@ -42,7 +46,6 @@ const {
4246
typeAliasResolution,
4347
} = require('../../parsers-primitives');
4448
const {
45-
IncorrectlyParameterizedGenericParserError,
4649
MisnamedModuleInterfaceParserError,
4750
ModuleInterfaceNotFoundParserError,
4851
MoreThanOneModuleInterfaceParserError,
@@ -65,7 +68,6 @@ const {
6568
IncorrectModuleRegistryCallArgumentTypeParserError,
6669
} = require('../../errors.js');
6770

68-
const invariant = require('invariant');
6971
const language = 'TypeScript';
7072

7173
function nullGuard<T>(fn: () => T): ?T {
@@ -208,6 +210,7 @@ function translateTypeAnnotation(
208210
assertGenericTypeAnnotationHasExactlyOneTypeParameter(
209211
hasteModuleName,
210212
typeAnnotation,
213+
language,
211214
);
212215

213216
return wrapNullable(nullable, {
@@ -219,6 +222,7 @@ function translateTypeAnnotation(
219222
assertGenericTypeAnnotationHasExactlyOneTypeParameter(
220223
hasteModuleName,
221224
typeAnnotation,
225+
language,
222226
);
223227

224228
return translateArrayTypeAnnotation(
@@ -447,35 +451,6 @@ function translateTypeAnnotation(
447451
}
448452
}
449453

450-
function assertGenericTypeAnnotationHasExactlyOneTypeParameter(
451-
moduleName: string,
452-
/**
453-
* TODO(T108222691): Use flow-types for @babel/parser
454-
*/
455-
typeAnnotation: $FlowFixMe,
456-
) {
457-
if (typeAnnotation.typeParameters == null) {
458-
throw new IncorrectlyParameterizedGenericParserError(
459-
moduleName,
460-
typeAnnotation,
461-
language,
462-
);
463-
}
464-
465-
invariant(
466-
typeAnnotation.typeParameters.type === 'TSTypeParameterInstantiation',
467-
"assertGenericTypeAnnotationHasExactlyOneTypeParameter: Type parameters must be an AST node of type 'TSTypeParameterInstantiation'",
468-
);
469-
470-
if (typeAnnotation.typeParameters.params.length !== 1) {
471-
throw new IncorrectlyParameterizedGenericParserError(
472-
moduleName,
473-
typeAnnotation,
474-
language,
475-
);
476-
}
477-
}
478-
479454
function translateFunctionTypeAnnotation(
480455
hasteModuleName: string,
481456
// TODO(T108222691): Use flow-types for @babel/parser

0 commit comments

Comments
 (0)