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:
Родитель
6f7428e27b
Коммит
462815001b
|
@ -9,21 +9,28 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
let flowParser, typeScriptParser, RNCodegen;
|
let FlowParser, TypeScriptParser, RNCodegen;
|
||||||
|
|
||||||
const {basename} = require('path');
|
const {basename} = require('path');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
flowParser = require('@react-native/codegen/src/parsers/flow');
|
FlowParser =
|
||||||
typeScriptParser = require('@react-native/codegen/src/parsers/typescript');
|
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');
|
RNCodegen = require('@react-native/codegen/src/generators/RNCodegen');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Fallback to lib when source doesn't exit (e.g. when installed as a dev dependency)
|
// Fallback to lib when source doesn't exit (e.g. when installed as a dev dependency)
|
||||||
flowParser = require('@react-native/codegen/lib/parsers/flow');
|
FlowParser =
|
||||||
typeScriptParser = require('@react-native/codegen/lib/parsers/typescript');
|
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');
|
RNCodegen = require('@react-native/codegen/lib/generators/RNCodegen');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const flowParser = new FlowParser();
|
||||||
|
const typeScriptParser = new TypeScriptParser();
|
||||||
|
|
||||||
function parseFile(filename, code) {
|
function parseFile(filename, code) {
|
||||||
if (filename.endsWith('js')) {
|
if (filename.endsWith('js')) {
|
||||||
return flowParser.parseString(code);
|
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,
|
NativeModuleParamTypeAnnotation,
|
||||||
} from '../../../../CodegenSchema';
|
} from '../../../../CodegenSchema';
|
||||||
|
|
||||||
const {parseString} = require('../../index.js');
|
const invariant = require('invariant');
|
||||||
|
|
||||||
const {unwrapNullable} = require('../../../parsers-commons');
|
const {unwrapNullable} = require('../../../parsers-commons');
|
||||||
const {
|
const {
|
||||||
UnsupportedGenericParserError,
|
UnsupportedGenericParserError,
|
||||||
|
@ -23,7 +24,9 @@ const {
|
||||||
UnnamedFunctionParamParserError,
|
UnnamedFunctionParamParserError,
|
||||||
MissingTypeParameterGenericParserError,
|
MissingTypeParameterGenericParserError,
|
||||||
} = require('../../../errors');
|
} = require('../../../errors');
|
||||||
const invariant = require('invariant');
|
const {FlowParser} = require('../../parser');
|
||||||
|
|
||||||
|
const flowParser = new FlowParser();
|
||||||
|
|
||||||
type PrimitiveTypeAnnotationType =
|
type PrimitiveTypeAnnotationType =
|
||||||
| 'StringTypeAnnotation'
|
| 'StringTypeAnnotation'
|
||||||
|
@ -1229,7 +1232,7 @@ describe('Flow Module Parser', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
function parseModule(source: string) {
|
function parseModule(source: string) {
|
||||||
const schema = parseString(source, `${MODULE_NAME}.js`);
|
const schema = flowParser.parseString(source, `${MODULE_NAME}.js`);
|
||||||
const module = schema.modules.NativeFoo;
|
const module = schema.modules.NativeFoo;
|
||||||
invariant(
|
invariant(
|
||||||
module.type === 'NativeModule',
|
module.type === 'NativeModule',
|
||||||
|
|
|
@ -11,11 +11,13 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const FlowParser = require('../../index.js');
|
const {FlowParser} = require('../../parser');
|
||||||
|
|
||||||
const fixtures = require('../__test_fixtures__/fixtures.js');
|
const fixtures = require('../__test_fixtures__/fixtures.js');
|
||||||
const failureFixtures = require('../__test_fixtures__/failures.js');
|
const failureFixtures = require('../__test_fixtures__/failures.js');
|
||||||
|
|
||||||
|
const flowParser = new FlowParser();
|
||||||
|
|
||||||
jest.mock('fs', () => ({
|
jest.mock('fs', () => ({
|
||||||
readFileSync: filename => {
|
readFileSync: filename => {
|
||||||
// Jest in the OSS does not allow to capture variables in closures.
|
// Jest in the OSS does not allow to capture variables in closures.
|
||||||
|
@ -32,7 +34,7 @@ describe('RN Codegen Flow Parser', () => {
|
||||||
.sort()
|
.sort()
|
||||||
.forEach(fixtureName => {
|
.forEach(fixtureName => {
|
||||||
it(`can generate fixture ${fixtureName}`, () => {
|
it(`can generate fixture ${fixtureName}`, () => {
|
||||||
const schema = FlowParser.parseModuleFixture(fixtureName);
|
const schema = flowParser.parseModuleFixture(fixtureName);
|
||||||
const serializedSchema = JSON.stringify(schema, null, 2).replace(
|
const serializedSchema = JSON.stringify(schema, null, 2).replace(
|
||||||
/"/g,
|
/"/g,
|
||||||
"'",
|
"'",
|
||||||
|
@ -47,7 +49,7 @@ describe('RN Codegen Flow Parser', () => {
|
||||||
.forEach(fixtureName => {
|
.forEach(fixtureName => {
|
||||||
it(`Fails with error message ${fixtureName}`, () => {
|
it(`Fails with error message ${fixtureName}`, () => {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
FlowParser.parseModuleFixture(fixtureName);
|
flowParser.parseModuleFixture(fixtureName);
|
||||||
}).toThrowErrorMatchingSnapshot();
|
}).toThrowErrorMatchingSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -96,6 +96,10 @@ class FlowParser implements Parser {
|
||||||
parseFile(filename: string): SchemaType {
|
parseFile(filename: string): SchemaType {
|
||||||
const contents = fs.readFileSync(filename, 'utf8');
|
const contents = fs.readFileSync(filename, 'utf8');
|
||||||
|
|
||||||
|
return this.parseString(contents, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
parseString(contents: string, filename: ?string): SchemaType {
|
||||||
return buildSchema(
|
return buildSchema(
|
||||||
contents,
|
contents,
|
||||||
filename,
|
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 {
|
getAst(contents: string): $FlowFixMe {
|
||||||
return flowParser.parse(contents, {
|
return flowParser.parse(contents, {
|
||||||
enums: true,
|
enums: true,
|
||||||
|
|
|
@ -78,11 +78,24 @@ export interface Parser {
|
||||||
types: $FlowFixMe,
|
types: $FlowFixMe,
|
||||||
): UnionTypeAnnotationMemberType[];
|
): UnionTypeAnnotationMemberType[];
|
||||||
/**
|
/**
|
||||||
* Given the content of a file and options, it returns an AST.
|
* Given the name of a file, it returns a Schema.
|
||||||
* @parameter contents: the content of the file.
|
* @parameter filename: the name of the file.
|
||||||
* @returns: the AST of the file (given in program property for typescript).
|
* @returns: the Schema of the file.
|
||||||
*/
|
*/
|
||||||
parseFile(filename: string): SchemaType;
|
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.
|
* Given the content of a file, it returns an AST.
|
||||||
|
|
|
@ -26,6 +26,22 @@ const {
|
||||||
UnsupportedObjectPropertyTypeAnnotationParserError,
|
UnsupportedObjectPropertyTypeAnnotationParserError,
|
||||||
} = require('./errors');
|
} = require('./errors');
|
||||||
|
|
||||||
|
const schemaMock = {
|
||||||
|
modules: {
|
||||||
|
StringPropNativeComponentView: {
|
||||||
|
type: 'Component',
|
||||||
|
components: {
|
||||||
|
StringPropNativeComponentView: {
|
||||||
|
extendsProps: [],
|
||||||
|
events: [],
|
||||||
|
props: [],
|
||||||
|
commands: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export class MockedParser implements Parser {
|
export class MockedParser implements Parser {
|
||||||
typeParameterInstantiation: string = 'TypeParameterInstantiation';
|
typeParameterInstantiation: string = 'TypeParameterInstantiation';
|
||||||
|
|
||||||
|
@ -74,21 +90,15 @@ export class MockedParser implements Parser {
|
||||||
}
|
}
|
||||||
|
|
||||||
parseFile(filename: string): SchemaType {
|
parseFile(filename: string): SchemaType {
|
||||||
return {
|
return schemaMock;
|
||||||
modules: {
|
}
|
||||||
StringPropNativeComponentView: {
|
|
||||||
type: 'Component',
|
parseString(contents: string, filename: ?string): SchemaType {
|
||||||
components: {
|
return schemaMock;
|
||||||
StringPropNativeComponentView: {
|
}
|
||||||
extendsProps: [],
|
|
||||||
events: [],
|
parseModuleFixture(filename: string): SchemaType {
|
||||||
props: [],
|
return schemaMock;
|
||||||
commands: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getAst(contents: string): $FlowFixMe {
|
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,
|
NativeModuleParamTypeAnnotation,
|
||||||
} from '../../../../CodegenSchema';
|
} from '../../../../CodegenSchema';
|
||||||
|
|
||||||
const {parseString} = require('../../index.js');
|
const invariant = require('invariant');
|
||||||
|
|
||||||
const {unwrapNullable} = require('../../../parsers-commons');
|
const {unwrapNullable} = require('../../../parsers-commons');
|
||||||
const {
|
const {
|
||||||
UnsupportedGenericParserError,
|
UnsupportedGenericParserError,
|
||||||
|
@ -23,7 +24,9 @@ const {
|
||||||
UnnamedFunctionParamParserError,
|
UnnamedFunctionParamParserError,
|
||||||
MissingTypeParameterGenericParserError,
|
MissingTypeParameterGenericParserError,
|
||||||
} = require('../../../errors');
|
} = require('../../../errors');
|
||||||
const invariant = require('invariant');
|
const {TypeScriptParser} = require('../../parser');
|
||||||
|
|
||||||
|
const typescriptParser = new TypeScriptParser();
|
||||||
|
|
||||||
type PrimitiveTypeAnnotationType =
|
type PrimitiveTypeAnnotationType =
|
||||||
| 'StringTypeAnnotation'
|
| 'StringTypeAnnotation'
|
||||||
|
@ -1228,7 +1231,7 @@ describe('TypeScript Module Parser', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
function parseModule(source: string) {
|
function parseModule(source: string) {
|
||||||
const schema = parseString(source, `${MODULE_NAME}.ts`);
|
const schema = typescriptParser.parseString(source, `${MODULE_NAME}.ts`);
|
||||||
const module = schema.modules.NativeFoo;
|
const module = schema.modules.NativeFoo;
|
||||||
invariant(
|
invariant(
|
||||||
module.type === 'NativeModule',
|
module.type === 'NativeModule',
|
||||||
|
|
|
@ -11,10 +11,13 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const TypeScriptParser = require('../../index.js');
|
const {TypeScriptParser} = require('../../parser');
|
||||||
|
|
||||||
const fixtures = require('../__test_fixtures__/fixtures.js');
|
const fixtures = require('../__test_fixtures__/fixtures.js');
|
||||||
const failureFixtures = require('../__test_fixtures__/failures.js');
|
const failureFixtures = require('../__test_fixtures__/failures.js');
|
||||||
|
|
||||||
|
const typeScriptParser = new TypeScriptParser();
|
||||||
|
|
||||||
jest.mock('fs', () => ({
|
jest.mock('fs', () => ({
|
||||||
readFileSync: filename => {
|
readFileSync: filename => {
|
||||||
// Jest in the OSS does not allow to capture variables in closures.
|
// Jest in the OSS does not allow to capture variables in closures.
|
||||||
|
@ -31,7 +34,7 @@ describe('RN Codegen TypeScript Parser', () => {
|
||||||
.sort()
|
.sort()
|
||||||
.forEach(fixtureName => {
|
.forEach(fixtureName => {
|
||||||
it(`can generate fixture ${fixtureName}`, () => {
|
it(`can generate fixture ${fixtureName}`, () => {
|
||||||
const schema = TypeScriptParser.parseModuleFixture(fixtureName);
|
const schema = typeScriptParser.parseModuleFixture(fixtureName);
|
||||||
const serializedSchema = JSON.stringify(schema, null, 2).replace(
|
const serializedSchema = JSON.stringify(schema, null, 2).replace(
|
||||||
/"/g,
|
/"/g,
|
||||||
"'",
|
"'",
|
||||||
|
@ -46,7 +49,7 @@ describe('RN Codegen TypeScript Parser', () => {
|
||||||
.forEach(fixtureName => {
|
.forEach(fixtureName => {
|
||||||
it(`Fails with error message ${fixtureName}`, () => {
|
it(`Fails with error message ${fixtureName}`, () => {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
TypeScriptParser.parseModuleFixture(fixtureName);
|
typeScriptParser.parseModuleFixture(fixtureName);
|
||||||
}).toThrowErrorMatchingSnapshot();
|
}).toThrowErrorMatchingSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -102,6 +102,10 @@ class TypeScriptParser implements Parser {
|
||||||
parseFile(filename: string): SchemaType {
|
parseFile(filename: string): SchemaType {
|
||||||
const contents = fs.readFileSync(filename, 'utf8');
|
const contents = fs.readFileSync(filename, 'utf8');
|
||||||
|
|
||||||
|
return this.parseString(contents, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
parseString(contents: string, filename: ?string): SchemaType {
|
||||||
return buildSchema(
|
return buildSchema(
|
||||||
contents,
|
contents,
|
||||||
filename,
|
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 {
|
getAst(contents: string): $FlowFixMe {
|
||||||
return babelParser.parse(contents, {
|
return babelParser.parse(contents, {
|
||||||
sourceType: 'module',
|
sourceType: 'module',
|
||||||
|
|
Загрузка…
Ссылка в новой задаче