From 228f92988a0ba58de48a8b825036a39e76956b43 Mon Sep 17 00:00:00 2001 From: Siddarth Kumar Date: Sun, 23 Apr 2023 08:17:27 +0530 Subject: [PATCH] move `extendsForProp` into `parsers-commons.js` --- .../flow/components/componentsUtils.js | 5 +-- .../src/parsers/flow/components/index.js | 2 +- .../src/parsers/flow/components/props.js | 23 ++++++----- .../src/parsers/flow/parser.js | 10 ++++- .../src/parsers/parser.js | 16 +++++++- .../src/parsers/parserMock.js | 10 ++++- .../src/parsers/parsers-commons.js | 38 ++++++++++++++++++- .../typescript/components/componentsUtils.js | 5 +-- .../parsers/typescript/components/index.js | 2 +- .../parsers/typescript/components/props.js | 34 +++-------------- .../src/parsers/typescript/parser.js | 10 ++++- .../react-native-codegen/src/parsers/utils.js | 3 ++ 12 files changed, 105 insertions(+), 53 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/flow/components/componentsUtils.js b/packages/react-native-codegen/src/parsers/flow/components/componentsUtils.js index d694fe2f795e..0ae12c7cbdc4 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/componentsUtils.js +++ b/packages/react-native-codegen/src/parsers/flow/components/componentsUtils.js @@ -13,7 +13,7 @@ import type {ASTNode} from '../utils'; import type {NamedShape} from '../../../CodegenSchema.js'; const {getValueFromTypes} = require('../utils.js'); -import type {TypeDeclarationMap} from '../../utils'; +import type {TypeDeclarationMap, PropAST} from '../../utils'; function getProperties( typeName: string, @@ -499,9 +499,6 @@ function getSchemaInfo( }; } -// $FlowFixMe[unclear-type] there's no flowtype for ASTs -type PropAST = Object; - module.exports = { getProperties, getSchemaInfo, diff --git a/packages/react-native-codegen/src/parsers/flow/components/index.js b/packages/react-native-codegen/src/parsers/flow/components/index.js index 57d75d6d72ce..a86fc9f90165 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/index.js +++ b/packages/react-native-codegen/src/parsers/flow/components/index.js @@ -126,7 +126,7 @@ function buildComponentSchema( const propProperties = getProperties(propsTypeName, types); const commandProperties = getCommandProperties(ast, parser); - const {extendsProps, props} = getProps(propProperties, types); + const {extendsProps, props} = getProps(propProperties, types, parser); const options = getOptions(optionsExpression); const events = getEvents(propProperties, types, parser); diff --git a/packages/react-native-codegen/src/parsers/flow/components/props.js b/packages/react-native-codegen/src/parsers/flow/components/props.js index 38cba3b62851..293384a85f75 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/props.js +++ b/packages/react-native-codegen/src/parsers/flow/components/props.js @@ -15,7 +15,8 @@ import type { NamedShape, PropTypeAnnotation, } from '../../../CodegenSchema.js'; -import type {TypeDeclarationMap} from '../../utils'; +import type {TypeDeclarationMap, PropAST} from '../../utils'; +import type {Parser} from '../../parser'; const { flattenProperties, @@ -23,9 +24,6 @@ const { getTypeAnnotation, } = require('./componentsUtils.js'); -// $FlowFixMe[unclear-type] there's no flowtype for ASTs -type PropAST = Object; - type ExtendsForProp = null | { type: 'ReactNativeBuiltInType', knownTypeName: 'ReactNativeCoreViewProps', @@ -58,11 +56,13 @@ function buildPropSchema( function extendsForProp( prop: PropAST, types: TypeDeclarationMap, + parser: Parser, ): ExtendsForProp { - if (!prop.argument) { + const argument = parser.argumentForProp(prop); + if (argument) { console.log('null', prop); } - const name = prop.argument.id.name; + const name = parser.nameForArgument(prop); if (types[name] != null) { // This type is locally defined in the file @@ -84,21 +84,23 @@ function extendsForProp( function removeKnownExtends( typeDefinition: $ReadOnlyArray, types: TypeDeclarationMap, + parser: Parser, ): $ReadOnlyArray { return typeDefinition.filter( prop => prop.type !== 'ObjectTypeSpreadProperty' || - extendsForProp(prop, types) === null, + extendsForProp(prop, types, parser) === null, ); } function getExtendsProps( typeDefinition: $ReadOnlyArray, types: TypeDeclarationMap, + parser: Parser, ): $ReadOnlyArray { return typeDefinition .filter(prop => prop.type === 'ObjectTypeSpreadProperty') - .map(prop => extendsForProp(prop, types)) + .map(prop => extendsForProp(prop, types, parser)) .filter(Boolean); } /** @@ -108,18 +110,19 @@ function getExtendsProps( function getProps( typeDefinition: $ReadOnlyArray, types: TypeDeclarationMap, + parser: Parser, ): { props: $ReadOnlyArray>, extendsProps: $ReadOnlyArray, } { - const nonExtendsProps = removeKnownExtends(typeDefinition, types); + const nonExtendsProps = removeKnownExtends(typeDefinition, types, parser); const props = flattenProperties(nonExtendsProps, types) .map(property => buildPropSchema(property, types)) .filter(Boolean); return { props, - extendsProps: getExtendsProps(typeDefinition, types), + extendsProps: getExtendsProps(typeDefinition, types, parser), }; } diff --git a/packages/react-native-codegen/src/parsers/flow/parser.js b/packages/react-native-codegen/src/parsers/flow/parser.js index b15fc4b56ab3..626346ab28cd 100644 --- a/packages/react-native-codegen/src/parsers/flow/parser.js +++ b/packages/react-native-codegen/src/parsers/flow/parser.js @@ -23,7 +23,7 @@ import type { } from '../../CodegenSchema'; import type {ParserType} from '../errors'; import type {Parser} from '../parser'; -import type {ParserErrorCapturer, TypeDeclarationMap} from '../utils'; +import type {ParserErrorCapturer, TypeDeclarationMap, PropAST} from '../utils'; const {flowTranslateTypeAnnotation} = require('./modules'); @@ -329,6 +329,14 @@ class FlowParser implements Parser { convertKeywordToTypeAnnotation(keyword: string): string { return keyword; } + + argumentForProp(prop: PropAST): $FlowFixMe { + return prop.argument; + } + + nameForArgument(prop: PropAST): $FlowFixMe { + return prop.argument.id.name; + } } module.exports = { diff --git a/packages/react-native-codegen/src/parsers/parser.js b/packages/react-native-codegen/src/parsers/parser.js index a8c2feccffc4..066ad13293e5 100644 --- a/packages/react-native-codegen/src/parsers/parser.js +++ b/packages/react-native-codegen/src/parsers/parser.js @@ -22,7 +22,7 @@ import type { NativeModuleEnumMap, } from '../CodegenSchema'; import type {ParserType} from './errors'; -import type {ParserErrorCapturer, TypeDeclarationMap} from './utils'; +import type {ParserErrorCapturer, TypeDeclarationMap, PropAST} from './utils'; /** * This is the main interface for Parsers of various languages. @@ -255,4 +255,18 @@ export interface Parser { * @returns: converted TypeAnnotation to Keywords */ convertKeywordToTypeAnnotation(keyword: string): string; + + /** + * Given a prop return its arguments. + * @parameter prop + * @returns: Arguments of the prop + */ + argumentForProp(prop: PropAST): $FlowFixMe; + + /** + * Given a prop return its name. + * @parameter prop + * @returns: name property + */ + nameForArgument(prop: PropAST): $FlowFixMe; } diff --git a/packages/react-native-codegen/src/parsers/parserMock.js b/packages/react-native-codegen/src/parsers/parserMock.js index e31b9de7cc05..1263b469de55 100644 --- a/packages/react-native-codegen/src/parsers/parserMock.js +++ b/packages/react-native-codegen/src/parsers/parserMock.js @@ -23,7 +23,7 @@ import type { NativeModuleAliasMap, NativeModuleEnumMap, } from '../CodegenSchema'; -import type {ParserErrorCapturer, TypeDeclarationMap} from './utils'; +import type {ParserErrorCapturer, PropAST, TypeDeclarationMap} from './utils'; // $FlowFixMe[untyped-import] there's no flowtype flow-parser const flowParser = require('flow-parser'); @@ -243,4 +243,12 @@ export class MockedParser implements Parser { convertKeywordToTypeAnnotation(keyword: string): string { return keyword; } + + argumentForProp(prop: PropAST): $FlowFixMe { + return prop.expression; + } + + nameForArgument(prop: PropAST): $FlowFixMe { + return prop.expression.name; + } } diff --git a/packages/react-native-codegen/src/parsers/parsers-commons.js b/packages/react-native-codegen/src/parsers/parsers-commons.js index 6fbb0baf8e87..e98581ef28bf 100644 --- a/packages/react-native-codegen/src/parsers/parsers-commons.js +++ b/packages/react-native-codegen/src/parsers/parsers-commons.js @@ -27,7 +27,7 @@ import type { import type {Parser} from './parser'; import type {ParserType} from './errors'; -import type {ParserErrorCapturer, TypeDeclarationMap} from './utils'; +import type {ParserErrorCapturer, TypeDeclarationMap, PropAST} from './utils'; import type {ComponentSchemaBuilderConfig} from './schema.js'; const { @@ -69,6 +69,11 @@ export type CommandOptions = $ReadOnly<{ // $FlowFixMe[unclear-type] TODO(T108222691): Use flow-types for @babel/parser type OptionsAST = Object; +type ExtendedPropResult = { + type: 'ReactNativeBuiltInType', + knownTypeName: 'ReactNativeCoreViewProps', +} | null; + function wrapModuleSchema( nativeModuleSchema: NativeModuleSchema, hasteModuleName: string, @@ -817,6 +822,36 @@ function propertyNames( .filter(Boolean); } +function extendsForProp( + prop: PropAST, + types: TypeDeclarationMap, + parser: Parser, +): ExtendedPropResult { + const argument = parser.argumentForProp(prop); + + if (!argument) { + console.log('null', prop); + } + + const name = parser.nameForArgument(prop); + + if (types[name] != null) { + // This type is locally defined in the file + return null; + } + + switch (name) { + case 'ViewProps': + return { + type: 'ReactNativeBuiltInType', + knownTypeName: 'ReactNativeCoreViewProps', + }; + default: { + throw new Error(`Unable to handle prop spread: ${name}`); + } + } +} + module.exports = { wrapModuleSchema, unwrapNullable, @@ -836,4 +871,5 @@ module.exports = { getCommandOptions, getOptions, getCommandTypeNameAndOptionsExpression, + extendsForProp, }; diff --git a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js index 8adc7e586dfc..763b85b874ce 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js @@ -15,7 +15,7 @@ const { parseTopLevelType, flattenIntersectionType, } = require('../parseTopLevelType'); -import type {TypeDeclarationMap} from '../../utils'; +import type {TypeDeclarationMap, PropAST} from '../../utils'; function getProperties( typeName: string, @@ -463,9 +463,6 @@ function getSchemaInfo( }; } -// $FlowFixMe[unclear-type] TODO(T108222691): Use flow-types for @babel/parser -type PropAST = Object; - function verifyPropNotAlreadyDefined( props: $ReadOnlyArray, needleProp: PropAST, diff --git a/packages/react-native-codegen/src/parsers/typescript/components/index.js b/packages/react-native-codegen/src/parsers/typescript/components/index.js index 2e1ea1f72951..eb54a9e930c9 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/index.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/index.js @@ -135,7 +135,7 @@ function buildComponentSchema( const componentEventAsts: Array = []; categorizeProps(propProperties, types, componentEventAsts); - const {props, extendsProps} = getProps(propProperties, types); + const {props, extendsProps} = getProps(propProperties, types, parser); const events = getEvents(componentEventAsts, types, parser); const commands = getCommands(commandProperties, types); diff --git a/packages/react-native-codegen/src/parsers/typescript/components/props.js b/packages/react-native-codegen/src/parsers/typescript/components/props.js index 36bb16c6eeef..ab989186cc4d 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/props.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/props.js @@ -9,17 +9,17 @@ */ 'use strict'; + const {getSchemaInfo, getTypeAnnotation} = require('./componentsUtils.js'); import type {NamedShape, PropTypeAnnotation} from '../../../CodegenSchema.js'; -import type {TypeDeclarationMap} from '../../utils'; +import type {TypeDeclarationMap, PropAST} from '../../utils'; import type {ExtendsPropsShape} from '../../../CodegenSchema.js'; +import type {Parser} from '../../parser'; const {flattenProperties} = require('./componentsUtils.js'); const {parseTopLevelType} = require('../parseTopLevelType'); - -// $FlowFixMe[unclear-type] there's no flowtype for ASTs -type PropAST = Object; +const {extendsForProp} = require('../../parsers-commons'); function buildPropSchema( property: PropAST, @@ -59,32 +59,10 @@ function isProp(name: string, typeAnnotation: $FlowFixMe): boolean { return !isStyle; } -function extendsForProp(prop: PropAST, types: TypeDeclarationMap) { - if (!prop.expression) { - console.log('null', prop); - } - const name = prop.expression.name; - - if (types[name] != null) { - // This type is locally defined in the file - return null; - } - - switch (name) { - case 'ViewProps': - return { - type: 'ReactNativeBuiltInType', - knownTypeName: 'ReactNativeCoreViewProps', - }; - default: { - throw new Error(`Unable to handle prop spread: ${name}`); - } - } -} - function getProps( typeDefinition: $ReadOnlyArray, types: TypeDeclarationMap, + parser: Parser, ): { props: $ReadOnlyArray>, extendsProps: $ReadOnlyArray, @@ -96,7 +74,7 @@ function getProps( for (const prop of typeDefinition) { // find extends if (prop.type === 'TSExpressionWithTypeArguments') { - const extend = extendsForProp(prop, types); + const extend = extendsForProp(prop, types, parser); if (extend) { extendsProps.push(extend); continue; diff --git a/packages/react-native-codegen/src/parsers/typescript/parser.js b/packages/react-native-codegen/src/parsers/typescript/parser.js index 7e496af2d13f..86534b5cbdd8 100644 --- a/packages/react-native-codegen/src/parsers/typescript/parser.js +++ b/packages/react-native-codegen/src/parsers/typescript/parser.js @@ -23,7 +23,7 @@ import type { } from '../../CodegenSchema'; import type {ParserType} from '../errors'; import type {Parser} from '../parser'; -import type {ParserErrorCapturer, TypeDeclarationMap} from '../utils'; +import type {ParserErrorCapturer, TypeDeclarationMap, PropAST} from '../utils'; const {typeScriptTranslateTypeAnnotation} = require('./modules'); @@ -328,6 +328,14 @@ class TypeScriptParser implements Parser { return keyword; } + + argumentForProp(prop: PropAST): $FlowFixMe { + return prop.expression; + } + + nameForArgument(prop: PropAST): $FlowFixMe { + return prop.expression.name; + } } module.exports = { diff --git a/packages/react-native-codegen/src/parsers/utils.js b/packages/react-native-codegen/src/parsers/utils.js index ca939b04af27..56d934912732 100644 --- a/packages/react-native-codegen/src/parsers/utils.js +++ b/packages/react-native-codegen/src/parsers/utils.js @@ -34,6 +34,9 @@ function extractNativeModuleName(filename: string): string { export type ParserErrorCapturer = (fn: () => T) => ?T; +// $FlowFixMe[unclear-type] there's no flowtype for ASTs +export type PropAST = Object; + function createParserErrorCapturer(): [ Array, ParserErrorCapturer,