mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Make parser return empty schema when parsing non-spec files
Summary: Right now, running the codegen parser on regular JavaScript files causes it to throw an error: https://www.internalfb.com/intern/diffusion/FBS/browsefile/master/xplat/js/react-native-github/packages/react-native-codegen/src/parsers/flow/index.js?commit=1e93f27aac8890f1731650fdcc38b702ae8874e2&lines=59-63%2C106-107 This makes the parser less usable, because you can't simply loop over a list of JavaScript files, and run codegen on them. You need to do some filtering beforehand, or surround each invocation of the parser with a try/catch. Our codegen schema supports the idea of an empty schema: ``` { modules: {} } ``` To improve the parser's ergonomics, this diff migrates the codegen parser over to returning the empty schema when it cannot detect a Component or NativeModule spec inside a JavaScript file. Changelog: [Internal] Reviewed By: JoshuaGross Differential Revision: D26034052 fbshipit-source-id: c2f15aba9c0e052012396eaed2034537f5918e33
This commit is contained in:
committed by
Facebook GitHub Bot
parent
595b569ead
commit
3dab9a0d01
+20
-9
@@ -19,13 +19,17 @@ const {buildComponentSchema} = require('./components');
|
||||
const {wrapComponentSchema} = require('./components/schema');
|
||||
const {buildModuleSchema} = require('./modules');
|
||||
const {wrapModuleSchema} = require('./modules/schema');
|
||||
const {createParserErrorCapturer, visit} = require('./utils');
|
||||
const {
|
||||
createParserErrorCapturer,
|
||||
visit,
|
||||
isModuleRegistryCall,
|
||||
} = require('./utils');
|
||||
const invariant = require('invariant');
|
||||
|
||||
function getConfigType(
|
||||
// TODO(T71778680): Flow-type this node.
|
||||
ast: $FlowFixMe,
|
||||
): 'module' | 'component' {
|
||||
): 'module' | 'component' | 'none' {
|
||||
let isComponent = false;
|
||||
let isModule = false;
|
||||
|
||||
@@ -37,6 +41,10 @@ function getConfigType(
|
||||
) {
|
||||
isComponent = true;
|
||||
}
|
||||
|
||||
if (isModuleRegistryCall(node)) {
|
||||
isModule = true;
|
||||
}
|
||||
},
|
||||
InterfaceExtends(node) {
|
||||
if (node.id.name === 'TurboModule') {
|
||||
@@ -56,15 +64,19 @@ function getConfigType(
|
||||
} else if (isComponent) {
|
||||
return 'component';
|
||||
} else {
|
||||
throw new Error(
|
||||
'File neither contains a module declaration, nor a component declaration. ' +
|
||||
'For module declarations, please make sure your file has an InterfaceDeclaration extending TurboModule. ' +
|
||||
'For component declarations, please make sure your file has a default export calling the codegenNativeComponent<Props>(...) macro.',
|
||||
);
|
||||
return 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function buildSchema(contents: string, filename: ?string): SchemaType {
|
||||
// Early return for non-Spec JavaScript files
|
||||
if (
|
||||
!contents.includes('codegenNativeComponent') &&
|
||||
!contents.includes('TurboModule')
|
||||
) {
|
||||
return {modules: {}};
|
||||
}
|
||||
|
||||
const ast = flowParser.parse(contents);
|
||||
const configType = getConfigType(ast);
|
||||
|
||||
@@ -103,8 +115,7 @@ function buildSchema(contents: string, filename: ?string): SchemaType {
|
||||
return wrapModuleSchema(schema, hasteModuleName);
|
||||
}
|
||||
default:
|
||||
(configType: empty);
|
||||
throw new Error(`Unsupported config type '${configType}'`);
|
||||
return {modules: {}};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_UNN
|
||||
|
||||
exports[`RN Codegen Flow Parser Fails with error message TWO_NATIVE_EXTENDING_TURBO_MODULE 1`] = `"Module NativeSampleTurboModule: Every NativeModule spec file must declare exactly one NativeModule Flow interface. This file declares 2: 'Spec', and 'Spec2'. Please remove the extraneous Flow interface declarations."`;
|
||||
|
||||
exports[`RN Codegen Flow Parser Fails with error message TWO_NATIVE_MODULES_EXPORTED_WITH_DEFAULT 1`] = `"File neither contains a module declaration, nor a component declaration. For module declarations, please make sure your file has an InterfaceDeclaration extending TurboModule. For component declarations, please make sure your file has a default export calling the codegenNativeComponent<Props>(...) macro."`;
|
||||
exports[`RN Codegen Flow Parser Fails with error message TWO_NATIVE_MODULES_EXPORTED_WITH_DEFAULT 1`] = `"Module NativeSampleTurboModule: No Flow interfaces extending TurboModule were detected in this NativeModule spec."`;
|
||||
|
||||
exports[`RN Codegen Flow Parser can generate fixture ANDROID_ONLY_NATIVE_MODULE 1`] = `
|
||||
"{
|
||||
|
||||
@@ -26,7 +26,12 @@ import type {TypeDeclarationMap} from '../utils.js';
|
||||
import type {ParserErrorCapturer} from '../utils';
|
||||
import type {NativeModuleTypeAnnotation} from '../../../CodegenSchema.js';
|
||||
|
||||
const {resolveTypeAnnotation, getTypes, visit} = require('../utils.js');
|
||||
const {
|
||||
resolveTypeAnnotation,
|
||||
getTypes,
|
||||
visit,
|
||||
isModuleRegistryCall,
|
||||
} = require('../utils.js');
|
||||
const {unwrapNullable, wrapNullable} = require('./utils');
|
||||
const {
|
||||
IncorrectlyParameterizedFlowGenericParserError,
|
||||
@@ -528,39 +533,6 @@ function buildPropertySchema(
|
||||
};
|
||||
}
|
||||
|
||||
function isModuleRegistryCall(node) {
|
||||
if (node.type !== 'CallExpression') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const callExpression = node;
|
||||
|
||||
if (callExpression.callee.type !== 'MemberExpression') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const memberExpression = callExpression.callee;
|
||||
if (
|
||||
!(
|
||||
memberExpression.object.type === 'Identifier' &&
|
||||
memberExpression.object.name === 'TurboModuleRegistry'
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!(
|
||||
memberExpression.property.type === 'Identifier' &&
|
||||
(memberExpression.property.name === 'get' ||
|
||||
memberExpression.property.name === 'getEnforcing')
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function isModuleInterface(node) {
|
||||
return (
|
||||
node.type === 'InterfaceDeclaration' &&
|
||||
|
||||
@@ -166,10 +166,45 @@ function visit(
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(T71778680): Flow-type ASTNodes.
|
||||
function isModuleRegistryCall(node: $FlowFixMe): boolean {
|
||||
if (node.type !== 'CallExpression') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const callExpression = node;
|
||||
|
||||
if (callExpression.callee.type !== 'MemberExpression') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const memberExpression = callExpression.callee;
|
||||
if (
|
||||
!(
|
||||
memberExpression.object.type === 'Identifier' &&
|
||||
memberExpression.object.name === 'TurboModuleRegistry'
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!(
|
||||
memberExpression.property.type === 'Identifier' &&
|
||||
(memberExpression.property.name === 'get' ||
|
||||
memberExpression.property.name === 'getEnforcing')
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getValueFromTypes,
|
||||
resolveTypeAnnotation,
|
||||
createParserErrorCapturer,
|
||||
getTypes,
|
||||
visit,
|
||||
isModuleRegistryCall,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user