extract Visitor to parsers primitives (#36459)

Summary:
Part of Codegen Issue https://github.com/facebook/react-native/issues/34872
> [Codegen 88] Move the Visitor.js file from parsers/flow/Visitor.js to parser-promitives.js. Copy the TSInterfaceDeclaration(node: $FlowFixMe) function and add it to the Visitor.js just copied. Remove the parsers/typescript/Visitor.js. Make sure we use the same Visitor in both parsers. (We will end up with a Visitor that is the union of the two, being able to handle both Flow and TS. In this specific case, this trade-off make sense as it allows us to remove one file, several duplicated lines for a small price.)

## 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 Visitor function to parsers primitives and remove both parsers visitor files

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

Test Plan:
```
yarn jest
yarn flow
yarn lint
yarn format-check
```

Reviewed By: cortinico

Differential Revision: D44021825

Pulled By: cipolleschi

fbshipit-source-id: ea465404830402c44081143ee0539107dc75776c
This commit is contained in:
Tarun Chauhan
2023-03-15 07:14:26 -07:00
committed by Facebook GitHub Bot
parent 347d6f8d89
commit d9f2cbe455
7 changed files with 140 additions and 91 deletions
@@ -24,7 +24,7 @@ import {
} from '../parsers-commons';
import type {ParserType} from '../errors';
const {Visitor} = require('../flow/Visitor');
const {Visitor} = require('../parsers-primitives');
const {wrapComponentSchema} = require('../schema.js');
const {buildComponentSchema} = require('../flow/components');
const {buildModuleSchema} = require('../parsers-commons.js');
@@ -30,6 +30,7 @@ const {
emitMixed,
typeAliasResolution,
typeEnumResolution,
Visitor,
} = require('../parsers-primitives.js');
const {MockedParser} = require('../parserMock');
const {emitUnion} = require('../parsers-primitives');
@@ -1155,3 +1156,102 @@ describe('emitArrayType', () => {
});
});
});
describe('Visitor', () => {
describe('CallExpression', () => {
it('sets isComponent to true if callee type is Identifier and callee name is codegenNativeComponent', () => {
const infoMap = {isComponent: false, isModule: false};
const node = {
callee: {type: 'Identifier', name: 'codegenNativeComponent'},
};
const visitor = Visitor(infoMap);
visitor.CallExpression(node);
expect(infoMap.isComponent).toBe(true);
});
it('should not set isComponent to true if callee type is not Identifier or callee name is not codegenNativeComponent', () => {
const infoMap = {isComponent: false, isModule: false};
const node = {
callee: {type: '', name: ''},
};
const visitor = Visitor(infoMap);
visitor.CallExpression(node);
expect(infoMap.isComponent).toBe(false);
});
it('sets isModule to true if isModuleRegistryCall', () => {
const infoMap = {isComponent: false, isModule: false};
const node = {
type: 'CallExpression',
callee: {
type: 'MemberExpression',
object: {type: 'Identifier', name: 'TurboModuleRegistry'},
property: {type: 'Identifier', name: 'getEnforcing'},
},
};
const visitor = Visitor(infoMap);
visitor.CallExpression(node);
expect(infoMap.isModule).toBe(true);
});
it('should not set isModule to true if not isModuleRegistryCall', () => {
const infoMap = {isComponent: false, isModule: false};
const node = {
callee: {
type: 'Expression',
},
};
const visitor = Visitor(infoMap);
visitor.CallExpression(node);
expect(infoMap.isModule).toBe(false);
});
});
describe('InterfaceExtends', () => {
it('sets isModule to true if module interface extends TurboModule', () => {
const infoMap = {isComponent: false, isModule: false};
const node = {id: {name: 'TurboModule'}};
const visitor = Visitor(infoMap);
visitor.InterfaceExtends(node);
expect(infoMap.isModule).toBe(true);
});
it('should not set isModule to true if module interface does not extends TurboModule', () => {
const infoMap = {isComponent: false, isModule: false};
const node = {id: {name: ''}};
const visitor = Visitor(infoMap);
visitor.InterfaceExtends(node);
expect(infoMap.isModule).toBe(false);
});
});
describe('TSInterfaceDeclaration', () => {
it('sets isModule to true if TypeScript Interface Declaration extends TurboModule', () => {
const infoMap = {isComponent: false, isModule: false};
const node = {extends: [{expression: {name: 'TurboModule'}}]};
const visitor = Visitor(infoMap);
visitor.TSInterfaceDeclaration(node);
expect(infoMap.isModule).toBe(true);
});
it('should not set isModule to true if TypeScript Interface Declaration does not extends TurboModule', () => {
const infoMap = {isComponent: false, isModule: false};
const node = {extends: [{expression: {name: ''}}]};
const visitor = Visitor(infoMap);
visitor.TSInterfaceDeclaration(node);
expect(infoMap.isModule).toBe(false);
});
});
});
@@ -1,41 +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';
const {isModuleRegistryCall} = require('../utils');
function Visitor(infoMap: {isComponent: boolean, isModule: boolean}): {
[type: string]: (node: $FlowFixMe) => void,
} {
return {
CallExpression(node: $FlowFixMe) {
if (
node.callee.type === 'Identifier' &&
node.callee.name === 'codegenNativeComponent'
) {
infoMap.isComponent = true;
}
if (isModuleRegistryCall(node)) {
infoMap.isModule = true;
}
},
InterfaceExtends(node: $FlowFixMe) {
if (node.id.name === 'TurboModule') {
infoMap.isModule = true;
}
},
};
}
module.exports = {
Visitor,
};
+1 -1
View File
@@ -31,7 +31,7 @@ const {flowTranslateTypeAnnotation} = require('./modules');
const flowParser = require('flow-parser');
const {buildSchema} = require('../parsers-commons');
const {Visitor} = require('./Visitor');
const {Visitor} = require('../parsers-primitives');
const {buildComponentSchema} = require('./components');
const {wrapComponentSchema} = require('../schema.js');
const {buildModuleSchema} = require('../parsers-commons.js');
@@ -59,6 +59,8 @@ const {
translateFunctionTypeAnnotation,
} = require('./parsers-commons');
const {isModuleRegistryCall} = require('./utils');
function emitBoolean(nullable: boolean): Nullable<BooleanTypeAnnotation> {
return wrapNullable(nullable, {
type: 'BooleanTypeAnnotation',
@@ -439,6 +441,40 @@ function emitArrayType(
);
}
function Visitor(infoMap: {isComponent: boolean, isModule: boolean}): {
[type: string]: (node: $FlowFixMe) => void,
} {
return {
CallExpression(node: $FlowFixMe) {
if (
node.callee.type === 'Identifier' &&
node.callee.name === 'codegenNativeComponent'
) {
infoMap.isComponent = true;
}
if (isModuleRegistryCall(node)) {
infoMap.isModule = true;
}
},
InterfaceExtends(node: $FlowFixMe) {
if (node.id.name === 'TurboModule') {
infoMap.isModule = true;
}
},
TSInterfaceDeclaration(node: $FlowFixMe) {
if (
Array.isArray(node.extends) &&
node.extends.some(
extension => extension.expression.name === 'TurboModule',
)
) {
infoMap.isModule = true;
}
},
};
}
module.exports = {
emitArrayType,
emitBoolean,
@@ -459,4 +495,5 @@ module.exports = {
typeAliasResolution,
typeEnumResolution,
translateArrayTypeAnnotation,
Visitor,
};
@@ -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';
const {isModuleRegistryCall} = require('../utils');
function Visitor(infoMap: {isComponent: boolean, isModule: boolean}): {
[type: string]: (node: $FlowFixMe) => void,
} {
return {
CallExpression(node: $FlowFixMe) {
if (
node.callee.type === 'Identifier' &&
node.callee.name === 'codegenNativeComponent'
) {
infoMap.isComponent = true;
}
if (isModuleRegistryCall(node)) {
infoMap.isModule = true;
}
},
TSInterfaceDeclaration(node: $FlowFixMe) {
if (
Array.isArray(node.extends) &&
node.extends.some(
extension => extension.expression.name === 'TurboModule',
)
) {
infoMap.isModule = true;
}
},
};
}
module.exports = {
Visitor,
};
@@ -31,7 +31,7 @@ const {typeScriptTranslateTypeAnnotation} = require('./modules');
const babelParser = require('@babel/parser');
const {buildSchema} = require('../parsers-commons');
const {Visitor} = require('./Visitor');
const {Visitor} = require('../parsers-primitives');
const {buildComponentSchema} = require('./components');
const {wrapComponentSchema} = require('../schema.js');
const {buildModuleSchema} = require('../parsers-commons.js');