Skip to content

Commit 0a6e78c

Browse files
chore: Extract logic to compute codegen TS extendsProps and props in getProps function
1 parent 9f24df0 commit 0a6e78c

File tree

3 files changed

+90
-68
lines changed

3 files changed

+90
-68
lines changed

packages/react-native-codegen/src/parsers/typescript/components/extends.js

Lines changed: 1 addition & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,8 @@
1010

1111
'use strict';
1212

13-
import type {ExtendsPropsShape} from '../../../CodegenSchema.js';
1413
import type {TypeDeclarationMap} from '../../utils';
1514
const {parseTopLevelType} = require('../parseTopLevelType');
16-
const {flattenProperties} = require('./componentsUtils.js');
17-
18-
function extendsForProp(prop: PropsAST, types: TypeDeclarationMap) {
19-
if (!prop.expression) {
20-
console.log('null', prop);
21-
}
22-
const name = prop.expression.name;
23-
24-
if (types[name] != null) {
25-
// This type is locally defined in the file
26-
return null;
27-
}
28-
29-
switch (name) {
30-
case 'ViewProps':
31-
return {
32-
type: 'ReactNativeBuiltInType',
33-
knownTypeName: 'ReactNativeCoreViewProps',
34-
};
35-
default: {
36-
throw new Error(`Unable to handle prop spread: ${name}`);
37-
}
38-
}
39-
}
4015

4116
function isEvent(typeAnnotation: $FlowFixMe): boolean {
4217
if (typeAnnotation.type !== 'TSTypeReference') {
@@ -46,43 +21,16 @@ function isEvent(typeAnnotation: $FlowFixMe): boolean {
4621
return eventNames.has(typeAnnotation.typeName.name);
4722
}
4823

49-
function isProp(name: string, typeAnnotation: $FlowFixMe): boolean {
50-
if (typeAnnotation.type !== 'TSTypeReference') {
51-
return true;
52-
}
53-
const isStyle =
54-
name === 'style' &&
55-
typeAnnotation.type === 'GenericTypeAnnotation' &&
56-
typeAnnotation.typeName.name === 'ViewStyleProp';
57-
return !isStyle;
58-
}
59-
6024
// $FlowFixMe[unclear-type] TODO(T108222691): Use flow-types for @babel/parser
6125
type PropsAST = Object;
6226

6327
function categorizeProps(
6428
typeDefinition: $ReadOnlyArray<PropsAST>,
6529
types: TypeDeclarationMap,
66-
extendsProps: Array<ExtendsPropsShape>,
67-
props: Array<PropsAST>,
6830
events: Array<PropsAST>,
6931
): void {
70-
const remaining: Array<PropsAST> = [];
32+
// find events
7133
for (const prop of typeDefinition) {
72-
// find extends
73-
if (prop.type === 'TSExpressionWithTypeArguments') {
74-
const extend = extendsForProp(prop, types);
75-
if (extend) {
76-
extendsProps.push(extend);
77-
continue;
78-
}
79-
}
80-
81-
remaining.push(prop);
82-
}
83-
84-
// find events and props
85-
for (const prop of flattenProperties(remaining, types)) {
8634
if (prop.type === 'TSPropertySignature') {
8735
const topLevelType = parseTopLevelType(
8836
prop.typeAnnotation.typeAnnotation,
@@ -91,8 +39,6 @@ function categorizeProps(
9139

9240
if (isEvent(topLevelType.type)) {
9341
events.push(prop);
94-
} else if (isProp(prop.key.name, prop)) {
95-
props.push(prop);
9642
}
9743
}
9844
}

packages/react-native-codegen/src/parsers/typescript/components/index.js

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
*/
1010

1111
'use strict';
12-
import type {ExtendsPropsShape} from '../../../CodegenSchema.js';
1312
import type {Parser} from '../../parser';
1413
import type {ComponentSchemaBuilderConfig} from '../../schema.js';
1514

@@ -134,17 +133,9 @@ function buildComponentSchema(
134133

135134
const options = getOptions(optionsExpression);
136135

137-
const extendsProps: Array<ExtendsPropsShape> = [];
138-
const componentPropAsts: Array<PropsAST> = [];
139136
const componentEventAsts: Array<PropsAST> = [];
140-
categorizeProps(
141-
propProperties,
142-
types,
143-
extendsProps,
144-
componentPropAsts,
145-
componentEventAsts,
146-
);
147-
const props = getProps(componentPropAsts, types);
137+
categorizeProps(propProperties, types, componentEventAsts);
138+
const {props, extendsProps} = getProps(propProperties, types);
148139
const events = getEvents(componentEventAsts, types);
149140
const commands = getCommands(commandProperties, types);
150141

packages/react-native-codegen/src/parsers/typescript/components/props.js

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ const {getSchemaInfo, getTypeAnnotation} = require('./componentsUtils.js');
1313

1414
import type {NamedShape, PropTypeAnnotation} from '../../../CodegenSchema.js';
1515
import type {TypeDeclarationMap} from '../../utils';
16+
import type {ExtendsPropsShape} from '../../../CodegenSchema.js';
17+
18+
const {flattenProperties} = require('./componentsUtils.js');
19+
const {parseTopLevelType} = require('../parseTopLevelType');
1620

1721
// $FlowFixMe[unclear-type] there's no flowtype for ASTs
1822
type PropAST = Object;
@@ -36,11 +40,92 @@ function buildPropSchema(
3640
};
3741
}
3842

43+
function isEvent(typeAnnotation: $FlowFixMe): boolean {
44+
if (typeAnnotation.type !== 'TSTypeReference') {
45+
return false;
46+
}
47+
const eventNames = new Set(['BubblingEventHandler', 'DirectEventHandler']);
48+
return eventNames.has(typeAnnotation.typeName.name);
49+
}
50+
51+
function isProp(name: string, typeAnnotation: $FlowFixMe): boolean {
52+
if (typeAnnotation.type !== 'TSTypeReference') {
53+
return true;
54+
}
55+
const isStyle =
56+
name === 'style' &&
57+
typeAnnotation.type === 'GenericTypeAnnotation' &&
58+
typeAnnotation.typeName.name === 'ViewStyleProp';
59+
return !isStyle;
60+
}
61+
62+
function extendsForProp(prop: PropAST, types: TypeDeclarationMap) {
63+
if (!prop.expression) {
64+
console.log('null', prop);
65+
}
66+
const name = prop.expression.name;
67+
68+
if (types[name] != null) {
69+
// This type is locally defined in the file
70+
return null;
71+
}
72+
73+
switch (name) {
74+
case 'ViewProps':
75+
return {
76+
type: 'ReactNativeBuiltInType',
77+
knownTypeName: 'ReactNativeCoreViewProps',
78+
};
79+
default: {
80+
throw new Error(`Unable to handle prop spread: ${name}`);
81+
}
82+
}
83+
}
84+
3985
function getProps(
4086
typeDefinition: $ReadOnlyArray<PropAST>,
4187
types: TypeDeclarationMap,
42-
): $ReadOnlyArray<NamedShape<PropTypeAnnotation>> {
43-
return typeDefinition.map(property => buildPropSchema(property, types));
88+
): {
89+
props: $ReadOnlyArray<NamedShape<PropTypeAnnotation>>,
90+
extendsProps: $ReadOnlyArray<ExtendsPropsShape>,
91+
} {
92+
const extendsProps: Array<ExtendsPropsShape> = [];
93+
const componentPropAsts: Array<PropAST> = [];
94+
const remaining: Array<PropAST> = [];
95+
96+
for (const prop of typeDefinition) {
97+
// find extends
98+
if (prop.type === 'TSExpressionWithTypeArguments') {
99+
const extend = extendsForProp(prop, types);
100+
if (extend) {
101+
extendsProps.push(extend);
102+
continue;
103+
}
104+
}
105+
106+
remaining.push(prop);
107+
}
108+
109+
// find events and props
110+
for (const prop of flattenProperties(remaining, types)) {
111+
const topLevelType = parseTopLevelType(
112+
prop.typeAnnotation.typeAnnotation,
113+
types,
114+
);
115+
116+
if (
117+
prop.type === 'TSPropertySignature' &&
118+
!isEvent(topLevelType.type) &&
119+
isProp(prop.key.name, prop)
120+
) {
121+
componentPropAsts.push(prop);
122+
}
123+
}
124+
125+
return {
126+
props: componentPropAsts.map(property => buildPropSchema(property, types)),
127+
extendsProps,
128+
};
44129
}
45130

46131
module.exports = {

0 commit comments

Comments
 (0)