chore: Add getKeyName function to codegen Parser class (#35202)
Summary: This PR adds a `getKeyName` function to the codegen Parser class and implements it in the Flow and TypeScript parsers as requested on https://github.com/facebook/react-native/issues/34872. ## Changelog [Internal] [Added] - Add `getKeyName` function to codegen Parser class Pull Request resolved: https://github.com/facebook/react-native/pull/35202 Test Plan: Run `yarn jest react-native-codegen` and ensure CI is green ![image](https://user-images.githubusercontent.com/11707729/200028600-87e9c1d7-d56d-4cf7-bdbc-18bdf1b03fc5.png) Reviewed By: cipolleschi Differential Revision: D41081711 Pulled By: jacdebug fbshipit-source-id: 7ad2953a0e2f90f04d03270bda40d669d4d0d50a
This commit is contained in:
Родитель
90b6735c3b
Коммит
f849f49525
|
@ -28,8 +28,10 @@ const {
|
|||
} = require('../errors');
|
||||
|
||||
import {MockedParser} from '../parserMock';
|
||||
import {TypeScriptParser} from '../typescript/parser';
|
||||
|
||||
const parser = new MockedParser();
|
||||
const typeScriptParser = new TypeScriptParser();
|
||||
|
||||
const flowTranslateTypeAnnotation = require('../flow/modules/index');
|
||||
const typeScriptTranslateTypeAnnotation = require('../typescript/modules/index');
|
||||
|
@ -316,9 +318,9 @@ describe('parseObjectProperty', () => {
|
|||
aliasMap,
|
||||
tryParse,
|
||||
cxxOnly,
|
||||
language,
|
||||
nullable,
|
||||
flowTranslateTypeAnnotation,
|
||||
parser,
|
||||
),
|
||||
).toThrow(expected);
|
||||
});
|
||||
|
@ -349,9 +351,9 @@ describe('parseObjectProperty', () => {
|
|||
aliasMap,
|
||||
tryParse,
|
||||
cxxOnly,
|
||||
language,
|
||||
nullable,
|
||||
typeScriptTranslateTypeAnnotation,
|
||||
parser,
|
||||
),
|
||||
).toThrow(expected);
|
||||
});
|
||||
|
@ -377,9 +379,9 @@ describe('parseObjectProperty', () => {
|
|||
aliasMap,
|
||||
tryParse,
|
||||
cxxOnly,
|
||||
language,
|
||||
nullable,
|
||||
typeScriptTranslateTypeAnnotation,
|
||||
typeScriptParser,
|
||||
);
|
||||
const expected = {
|
||||
name: 'testName',
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
/**
|
||||
* 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
|
||||
* @oncall react_native
|
||||
*/
|
||||
|
||||
'use-strict';
|
||||
|
||||
const {
|
||||
UnsupportedObjectPropertyTypeAnnotationParserError,
|
||||
} = require('../errors');
|
||||
|
||||
import {TypeScriptParser} from '../typescript/parser';
|
||||
import {FlowParser} from '../flow/parser';
|
||||
|
||||
const hasteModuleName = 'moduleName';
|
||||
describe('TypeScriptParser', () => {
|
||||
const parser = new FlowParser();
|
||||
describe('getKeyName', () => {
|
||||
describe('when propertyOrIndex is ObjectTypeProperty', () => {
|
||||
it('returns property name', () => {
|
||||
const property = {
|
||||
type: 'ObjectTypeProperty',
|
||||
key: {
|
||||
name: 'propertyName',
|
||||
},
|
||||
};
|
||||
|
||||
const expected = 'propertyName';
|
||||
|
||||
expect(parser.getKeyName(property, hasteModuleName)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when propertyOrIndex is ObjectTypeIndexer', () => {
|
||||
it('returns indexer name', () => {
|
||||
const indexer = {
|
||||
type: 'ObjectTypeIndexer',
|
||||
id: {
|
||||
name: 'indexerName',
|
||||
},
|
||||
};
|
||||
|
||||
const expected = 'indexerName';
|
||||
|
||||
expect(parser.getKeyName(indexer, hasteModuleName)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('returns `key` if indexer has no name', () => {
|
||||
const indexer = {
|
||||
type: 'ObjectTypeIndexer',
|
||||
id: {},
|
||||
};
|
||||
|
||||
const expected = 'key';
|
||||
|
||||
expect(parser.getKeyName(indexer, hasteModuleName)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when propertyOrIndex is not ObjectTypeProperty or ObjectTypeIndexer', () => {
|
||||
it('throw UnsupportedObjectPropertyTypeAnnotationParserError', () => {
|
||||
const indexer = {
|
||||
type: 'EnumDeclaration',
|
||||
memberType: 'NumberTypeAnnotation',
|
||||
};
|
||||
|
||||
expect(() => parser.getKeyName(indexer, hasteModuleName)).toThrowError(
|
||||
UnsupportedObjectPropertyTypeAnnotationParserError,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('FlowParser', () => {
|
||||
const parser = new TypeScriptParser();
|
||||
describe('getKeyName', () => {
|
||||
describe('when propertyOrIndex is TSPropertySignature', () => {
|
||||
it('returns property name', () => {
|
||||
const property = {
|
||||
type: 'TSPropertySignature',
|
||||
key: {
|
||||
name: 'propertyName',
|
||||
},
|
||||
};
|
||||
|
||||
const expected = 'propertyName';
|
||||
|
||||
expect(parser.getKeyName(property, hasteModuleName)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when propertyOrIndex is TSIndexSignature', () => {
|
||||
it('returns indexer name', () => {
|
||||
const indexer = {
|
||||
type: 'TSIndexSignature',
|
||||
parameters: [
|
||||
{
|
||||
name: 'indexerName',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const expected = 'indexerName';
|
||||
|
||||
expect(parser.getKeyName(indexer, hasteModuleName)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when propertyOrIndex is not TSPropertySignature or TSIndexSignature', () => {
|
||||
it('throw UnsupportedObjectPropertyTypeAnnotationParserError', () => {
|
||||
const indexer = {
|
||||
type: 'TSEnumDeclaration',
|
||||
memberType: 'NumberTypeAnnotation',
|
||||
};
|
||||
|
||||
expect(() => parser.getKeyName(indexer, hasteModuleName)).toThrowError(
|
||||
UnsupportedObjectPropertyTypeAnnotationParserError,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -266,9 +266,9 @@ function translateTypeAnnotation(
|
|||
aliasMap,
|
||||
tryParse,
|
||||
cxxOnly,
|
||||
language,
|
||||
nullable,
|
||||
translateTypeAnnotation,
|
||||
parser,
|
||||
);
|
||||
});
|
||||
},
|
||||
|
|
|
@ -13,9 +13,30 @@
|
|||
import type {ParserType} from '../errors';
|
||||
import type {Parser} from '../parser';
|
||||
|
||||
const {
|
||||
UnsupportedObjectPropertyTypeAnnotationParserError,
|
||||
} = require('../errors');
|
||||
|
||||
class FlowParser implements Parser {
|
||||
typeParameterInstantiation: string = 'TypeParameterInstantiation';
|
||||
|
||||
getKeyName(propertyOrIndex: $FlowFixMe, hasteModuleName: string): string {
|
||||
switch (propertyOrIndex.type) {
|
||||
case 'ObjectTypeProperty':
|
||||
return propertyOrIndex.key.name;
|
||||
case 'ObjectTypeIndexer':
|
||||
// flow index name is optional
|
||||
return propertyOrIndex.id?.name ?? 'key';
|
||||
default:
|
||||
throw new UnsupportedObjectPropertyTypeAnnotationParserError(
|
||||
hasteModuleName,
|
||||
propertyOrIndex,
|
||||
propertyOrIndex.type,
|
||||
this.language(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
getMaybeEnumMemberType(maybeEnumDeclaration: $FlowFixMe): string {
|
||||
return maybeEnumDeclaration.body.type
|
||||
.replace('EnumNumberBody', 'NumberTypeAnnotation')
|
||||
|
|
|
@ -22,6 +22,14 @@ export interface Parser {
|
|||
*/
|
||||
typeParameterInstantiation: string;
|
||||
|
||||
/**
|
||||
* Given a property or an index declaration, it returns the key name.
|
||||
* @parameter propertyOrIndex: an object containing a property or an index declaration.
|
||||
* @parameter hasteModuleName: a string with the native module name.
|
||||
* @returns: the key name.
|
||||
* @throws if propertyOrIndex does not contain a property or an index declaration.
|
||||
*/
|
||||
getKeyName(propertyOrIndex: $FlowFixMe, hasteModuleName: string): string;
|
||||
/**
|
||||
* Given a type declaration, it possibly returns the name of the Enum type.
|
||||
* @parameter maybeEnumDeclaration: an object possibly containing an Enum declaration.
|
||||
|
|
|
@ -13,9 +13,30 @@
|
|||
import type {Parser} from './parser';
|
||||
import type {ParserType} from './errors';
|
||||
|
||||
const {
|
||||
UnsupportedObjectPropertyTypeAnnotationParserError,
|
||||
} = require('./errors');
|
||||
|
||||
export class MockedParser implements Parser {
|
||||
typeParameterInstantiation: string = 'TypeParameterInstantiation';
|
||||
|
||||
getKeyName(propertyOrIndex: $FlowFixMe, hasteModuleName: string): string {
|
||||
switch (propertyOrIndex.type) {
|
||||
case 'ObjectTypeProperty':
|
||||
return propertyOrIndex.key.name;
|
||||
case 'ObjectTypeIndexer':
|
||||
// flow index name is optional
|
||||
return propertyOrIndex.id?.name ?? 'key';
|
||||
default:
|
||||
throw new UnsupportedObjectPropertyTypeAnnotationParserError(
|
||||
hasteModuleName,
|
||||
propertyOrIndex,
|
||||
propertyOrIndex.type,
|
||||
this.language(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
getMaybeEnumMemberType(maybeEnumDeclaration: $FlowFixMe): string {
|
||||
return maybeEnumDeclaration.body.type
|
||||
.replace('EnumNumberBody', 'NumberTypeAnnotation')
|
||||
|
|
|
@ -129,10 +129,12 @@ function parseObjectProperty(
|
|||
aliasMap: {...NativeModuleAliasMap},
|
||||
tryParse: ParserErrorCapturer,
|
||||
cxxOnly: boolean,
|
||||
language: ParserType,
|
||||
nullable: boolean,
|
||||
translateTypeAnnotation: $FlowFixMe,
|
||||
parser: Parser,
|
||||
): NamedShape<Nullable<NativeModuleBaseTypeAnnotation>> {
|
||||
const language = parser.language();
|
||||
|
||||
if (!isObjectProperty(property, language)) {
|
||||
throw new UnsupportedObjectPropertyTypeAnnotationParserError(
|
||||
hasteModuleName,
|
||||
|
@ -143,7 +145,7 @@ function parseObjectProperty(
|
|||
}
|
||||
|
||||
const {optional = false} = property;
|
||||
const name = getKeyName(property, hasteModuleName, language);
|
||||
const name = parser.getKeyName(property, hasteModuleName);
|
||||
const languageTypeAnnotation =
|
||||
language === 'TypeScript'
|
||||
? property.typeAnnotation.typeAnnotation
|
||||
|
@ -282,31 +284,6 @@ function translateDefault(
|
|||
);
|
||||
}
|
||||
|
||||
function getKeyName(
|
||||
propertyOrIndex: $FlowFixMe,
|
||||
hasteModuleName: string,
|
||||
language: ParserType,
|
||||
): string {
|
||||
switch (propertyOrIndex.type) {
|
||||
case 'ObjectTypeProperty':
|
||||
case 'TSPropertySignature':
|
||||
return propertyOrIndex.key.name;
|
||||
case 'ObjectTypeIndexer':
|
||||
// flow index name is optional
|
||||
return propertyOrIndex.id?.name ?? 'key';
|
||||
case 'TSIndexSignature':
|
||||
// TypeScript index name is mandatory
|
||||
return propertyOrIndex.parameters[0].name;
|
||||
default:
|
||||
throw new UnsupportedObjectPropertyTypeAnnotationParserError(
|
||||
hasteModuleName,
|
||||
propertyOrIndex,
|
||||
propertyOrIndex.type,
|
||||
language,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
wrapModuleSchema,
|
||||
unwrapNullable,
|
||||
|
@ -316,5 +293,4 @@ module.exports = {
|
|||
parseObjectProperty,
|
||||
emitUnionTypeAnnotation,
|
||||
translateDefault,
|
||||
getKeyName,
|
||||
};
|
||||
|
|
|
@ -272,9 +272,9 @@ function translateTypeAnnotation(
|
|||
aliasMap,
|
||||
tryParse,
|
||||
cxxOnly,
|
||||
language,
|
||||
nullable,
|
||||
translateTypeAnnotation,
|
||||
parser,
|
||||
);
|
||||
});
|
||||
},
|
||||
|
|
|
@ -13,9 +13,29 @@
|
|||
import type {ParserType} from '../errors';
|
||||
import type {Parser} from '../parser';
|
||||
|
||||
const {
|
||||
UnsupportedObjectPropertyTypeAnnotationParserError,
|
||||
} = require('../errors');
|
||||
|
||||
class TypeScriptParser implements Parser {
|
||||
typeParameterInstantiation: string = 'TSTypeParameterInstantiation';
|
||||
|
||||
getKeyName(propertyOrIndex: $FlowFixMe, hasteModuleName: string): string {
|
||||
switch (propertyOrIndex.type) {
|
||||
case 'TSPropertySignature':
|
||||
return propertyOrIndex.key.name;
|
||||
case 'TSIndexSignature':
|
||||
return propertyOrIndex.parameters[0].name;
|
||||
default:
|
||||
throw new UnsupportedObjectPropertyTypeAnnotationParserError(
|
||||
hasteModuleName,
|
||||
propertyOrIndex,
|
||||
propertyOrIndex.type,
|
||||
this.language(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
getMaybeEnumMemberType(maybeEnumDeclaration: $FlowFixMe): string {
|
||||
if (maybeEnumDeclaration.members[0].initializer) {
|
||||
return maybeEnumDeclaration.members[0].initializer.type
|
||||
|
|
Загрузка…
Ссылка в новой задаче