Extract parseString and parseModuleFixture functions in typescript and flow parsers (#35928)

Summary:
This PR aims to extract parseString and parseModuleFixture functions into the typescript and flow parsers. This task was proposed in https://github.com/facebook/react-native/issues/35158 and helps https://github.com/facebook/react-native/issues/34872.

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->
[Internal] [Changed] - Extract parseString and parseModuleFixture functions in typescript and flow parsers

Pull Request resolved: https://github.com/facebook/react-native/pull/35928

Test Plan:
yarn test:
<img width="386" alt="image" src="https://user-images.githubusercontent.com/40902940/213889984-f0cadaff-4472-42d6-b55b-4901023aad1e.png">

yarn flow:
<img width="166" alt="image" src="https://user-images.githubusercontent.com/40902940/213889974-21ac2483-2731-4cb1-a2b5-195d98619649.png">

yarn lint:
<img width="514" alt="image" src="https://user-images.githubusercontent.com/40902940/213889980-090af354-346f-4a9c-90bc-7006899f0819.png">

Reviewed By: jacdebug

Differential Revision: D42673866

Pulled By: cipolleschi

fbshipit-source-id: f1b5f8a7b3944e7e8223b25c0fb9bf4e8b512aa7
This commit is contained in:
MaeIg 2023-01-25 12:38:52 -08:00 коммит произвёл Facebook GitHub Bot
Родитель 6f7428e27b
Коммит 462815001b
11 изменённых файлов: 96 добавлений и 129 удалений

Просмотреть файл

@ -9,21 +9,28 @@
'use strict';
let flowParser, typeScriptParser, RNCodegen;
let FlowParser, TypeScriptParser, RNCodegen;
const {basename} = require('path');
try {
flowParser = require('@react-native/codegen/src/parsers/flow');
typeScriptParser = require('@react-native/codegen/src/parsers/typescript');
FlowParser =
require('@react-native/codegen/src/parsers/flow/parser').FlowParser;
TypeScriptParser =
require('@react-native/codegen/src/parsers/typescript/parser').TypeScriptParser;
RNCodegen = require('@react-native/codegen/src/generators/RNCodegen');
} catch (e) {
// Fallback to lib when source doesn't exit (e.g. when installed as a dev dependency)
flowParser = require('@react-native/codegen/lib/parsers/flow');
typeScriptParser = require('@react-native/codegen/lib/parsers/typescript');
FlowParser =
require('@react-native/codegen/lib/parsers/flow/parser').FlowParser;
TypeScriptParser =
require('@react-native/codegen/lib/parsers/typescript/parser').TypeScriptParser;
RNCodegen = require('@react-native/codegen/lib/generators/RNCodegen');
}
const flowParser = new FlowParser();
const typeScriptParser = new TypeScriptParser();
function parseFile(filename, code) {
if (filename.endsWith('js')) {
return flowParser.parseString(code);

Просмотреть файл

@ -1,47 +0,0 @@
/**
* 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
* @format
*/
'use strict';
import type {SchemaType} from '../../CodegenSchema.js';
const fs = require('fs');
const {buildSchema} = require('../parsers-commons');
const {Visitor} = require('./Visitor');
const {FlowParser} = require('./parser');
const {buildComponentSchema} = require('./components');
const {wrapComponentSchema} = require('./components/schema');
const {buildModuleSchema} = require('./modules');
const parser = new FlowParser();
function parseModuleFixture(filename: string): SchemaType {
const contents = fs.readFileSync(filename, 'utf8');
return parseString(contents, 'path/NativeSampleTurboModule.js');
}
function parseString(contents: string, filename: ?string): SchemaType {
return buildSchema(
contents,
filename,
wrapComponentSchema,
buildComponentSchema,
buildModuleSchema,
Visitor,
parser,
);
}
module.exports = {
parseModuleFixture,
parseString,
};

Просмотреть файл

@ -15,7 +15,8 @@ import type {
NativeModuleParamTypeAnnotation,
} from '../../../../CodegenSchema';
const {parseString} = require('../../index.js');
const invariant = require('invariant');
const {unwrapNullable} = require('../../../parsers-commons');
const {
UnsupportedGenericParserError,
@ -23,7 +24,9 @@ const {
UnnamedFunctionParamParserError,
MissingTypeParameterGenericParserError,
} = require('../../../errors');
const invariant = require('invariant');
const {FlowParser} = require('../../parser');
const flowParser = new FlowParser();
type PrimitiveTypeAnnotationType =
| 'StringTypeAnnotation'
@ -1229,7 +1232,7 @@ describe('Flow Module Parser', () => {
});
function parseModule(source: string) {
const schema = parseString(source, `${MODULE_NAME}.js`);
const schema = flowParser.parseString(source, `${MODULE_NAME}.js`);
const module = schema.modules.NativeFoo;
invariant(
module.type === 'NativeModule',

Просмотреть файл

@ -11,11 +11,13 @@
'use strict';
const FlowParser = require('../../index.js');
const {FlowParser} = require('../../parser');
const fixtures = require('../__test_fixtures__/fixtures.js');
const failureFixtures = require('../__test_fixtures__/failures.js');
const flowParser = new FlowParser();
jest.mock('fs', () => ({
readFileSync: filename => {
// Jest in the OSS does not allow to capture variables in closures.
@ -32,7 +34,7 @@ describe('RN Codegen Flow Parser', () => {
.sort()
.forEach(fixtureName => {
it(`can generate fixture ${fixtureName}`, () => {
const schema = FlowParser.parseModuleFixture(fixtureName);
const schema = flowParser.parseModuleFixture(fixtureName);
const serializedSchema = JSON.stringify(schema, null, 2).replace(
/"/g,
"'",
@ -47,7 +49,7 @@ describe('RN Codegen Flow Parser', () => {
.forEach(fixtureName => {
it(`Fails with error message ${fixtureName}`, () => {
expect(() => {
FlowParser.parseModuleFixture(fixtureName);
flowParser.parseModuleFixture(fixtureName);
}).toThrowErrorMatchingSnapshot();
});
});

Просмотреть файл

@ -96,6 +96,10 @@ class FlowParser implements Parser {
parseFile(filename: string): SchemaType {
const contents = fs.readFileSync(filename, 'utf8');
return this.parseString(contents, filename);
}
parseString(contents: string, filename: ?string): SchemaType {
return buildSchema(
contents,
filename,
@ -107,6 +111,12 @@ class FlowParser implements Parser {
);
}
parseModuleFixture(filename: string): SchemaType {
const contents = fs.readFileSync(filename, 'utf8');
return this.parseString(contents, 'path/NativeSampleTurboModule.js');
}
getAst(contents: string): $FlowFixMe {
return flowParser.parse(contents, {
enums: true,

Просмотреть файл

@ -78,11 +78,24 @@ export interface Parser {
types: $FlowFixMe,
): UnionTypeAnnotationMemberType[];
/**
* Given the content of a file and options, it returns an AST.
* @parameter contents: the content of the file.
* @returns: the AST of the file (given in program property for typescript).
* Given the name of a file, it returns a Schema.
* @parameter filename: the name of the file.
* @returns: the Schema of the file.
*/
parseFile(filename: string): SchemaType;
/**
* Given the content of a file, it returns a Schema.
* @parameter contents: the content of the file.
* @parameter filename: the name of the file.
* @returns: the Schema of the file.
*/
parseString(contents: string, filename: ?string): SchemaType;
/**
* Given the name of a file, it returns a Schema.
* @parameter filename: the name of the file.
* @returns: the Schema of the file.
*/
parseModuleFixture(filename: string): SchemaType;
/**
* Given the content of a file, it returns an AST.

Просмотреть файл

@ -26,6 +26,22 @@ const {
UnsupportedObjectPropertyTypeAnnotationParserError,
} = require('./errors');
const schemaMock = {
modules: {
StringPropNativeComponentView: {
type: 'Component',
components: {
StringPropNativeComponentView: {
extendsProps: [],
events: [],
props: [],
commands: [],
},
},
},
},
};
export class MockedParser implements Parser {
typeParameterInstantiation: string = 'TypeParameterInstantiation';
@ -74,21 +90,15 @@ export class MockedParser implements Parser {
}
parseFile(filename: string): SchemaType {
return {
modules: {
StringPropNativeComponentView: {
type: 'Component',
components: {
StringPropNativeComponentView: {
extendsProps: [],
events: [],
props: [],
commands: [],
},
},
},
},
};
return schemaMock;
}
parseString(contents: string, filename: ?string): SchemaType {
return schemaMock;
}
parseModuleFixture(filename: string): SchemaType {
return schemaMock;
}
getAst(contents: string): $FlowFixMe {

Просмотреть файл

@ -1,47 +0,0 @@
/**
* 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
* @format
*/
'use strict';
import type {SchemaType} from '../../CodegenSchema.js';
const fs = require('fs');
const {buildSchema} = require('../parsers-commons');
const {Visitor} = require('./Visitor');
const {TypeScriptParser} = require('./parser');
const {buildComponentSchema} = require('./components');
const {wrapComponentSchema} = require('./components/schema');
const {buildModuleSchema} = require('./modules');
const parser = new TypeScriptParser();
function parseModuleFixture(filename: string): SchemaType {
const contents = fs.readFileSync(filename, 'utf8');
return parseString(contents, 'path/NativeSampleTurboModule.ts');
}
function parseString(contents: string, filename: ?string): SchemaType {
return buildSchema(
contents,
filename,
wrapComponentSchema,
buildComponentSchema,
buildModuleSchema,
Visitor,
parser,
);
}
module.exports = {
parseModuleFixture,
parseString,
};

Просмотреть файл

@ -15,7 +15,8 @@ import type {
NativeModuleParamTypeAnnotation,
} from '../../../../CodegenSchema';
const {parseString} = require('../../index.js');
const invariant = require('invariant');
const {unwrapNullable} = require('../../../parsers-commons');
const {
UnsupportedGenericParserError,
@ -23,7 +24,9 @@ const {
UnnamedFunctionParamParserError,
MissingTypeParameterGenericParserError,
} = require('../../../errors');
const invariant = require('invariant');
const {TypeScriptParser} = require('../../parser');
const typescriptParser = new TypeScriptParser();
type PrimitiveTypeAnnotationType =
| 'StringTypeAnnotation'
@ -1228,7 +1231,7 @@ describe('TypeScript Module Parser', () => {
});
function parseModule(source: string) {
const schema = parseString(source, `${MODULE_NAME}.ts`);
const schema = typescriptParser.parseString(source, `${MODULE_NAME}.ts`);
const module = schema.modules.NativeFoo;
invariant(
module.type === 'NativeModule',

Просмотреть файл

@ -11,10 +11,13 @@
'use strict';
const TypeScriptParser = require('../../index.js');
const {TypeScriptParser} = require('../../parser');
const fixtures = require('../__test_fixtures__/fixtures.js');
const failureFixtures = require('../__test_fixtures__/failures.js');
const typeScriptParser = new TypeScriptParser();
jest.mock('fs', () => ({
readFileSync: filename => {
// Jest in the OSS does not allow to capture variables in closures.
@ -31,7 +34,7 @@ describe('RN Codegen TypeScript Parser', () => {
.sort()
.forEach(fixtureName => {
it(`can generate fixture ${fixtureName}`, () => {
const schema = TypeScriptParser.parseModuleFixture(fixtureName);
const schema = typeScriptParser.parseModuleFixture(fixtureName);
const serializedSchema = JSON.stringify(schema, null, 2).replace(
/"/g,
"'",
@ -46,7 +49,7 @@ describe('RN Codegen TypeScript Parser', () => {
.forEach(fixtureName => {
it(`Fails with error message ${fixtureName}`, () => {
expect(() => {
TypeScriptParser.parseModuleFixture(fixtureName);
typeScriptParser.parseModuleFixture(fixtureName);
}).toThrowErrorMatchingSnapshot();
});
});

Просмотреть файл

@ -102,6 +102,10 @@ class TypeScriptParser implements Parser {
parseFile(filename: string): SchemaType {
const contents = fs.readFileSync(filename, 'utf8');
return this.parseString(contents, filename);
}
parseString(contents: string, filename: ?string): SchemaType {
return buildSchema(
contents,
filename,
@ -113,6 +117,12 @@ class TypeScriptParser implements Parser {
);
}
parseModuleFixture(filename: string): SchemaType {
const contents = fs.readFileSync(filename, 'utf8');
return this.parseString(contents, 'path/NativeSampleTurboModule.ts');
}
getAst(contents: string): $FlowFixMe {
return babelParser.parse(contents, {
sourceType: 'module',