mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Remove existing Commands export
Reviewed By: rickhanlonii Differential Revision: D16039151 fbshipit-source-id: f307697ad44f2ce1471144fc7fd0c38eb5f6c34f
This commit is contained in:
committed by
Facebook Github Bot
parent
7104c1f3ce
commit
c38d6f26e0
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const COMMANDS_EXPORTED_WITH_DIFFERENT_NAME = `
|
||||
// @flow
|
||||
|
||||
const codegenNativeComponent = require('codegenNativeComponent');
|
||||
|
||||
import type {ViewProps} from 'ViewPropTypes';
|
||||
|
||||
type ModuleProps = $ReadOnly<{|
|
||||
...ViewProps,
|
||||
|}>;
|
||||
|
||||
interface NativeCommands {
|
||||
+hotspotUpdate: (viewRef: React.Ref<'Module'>) => void;
|
||||
}
|
||||
|
||||
export const Foo = codegenNativeCommands<NativeCommands>();
|
||||
|
||||
export default codegenNativeComponent<ModuleProps>('Module');
|
||||
`;
|
||||
|
||||
const OTHER_COMMANDS_EXPORT = `
|
||||
// @flow
|
||||
|
||||
const codegenNativeComponent = require('codegenNativeComponent');
|
||||
|
||||
import type {ViewProps} from 'ViewPropTypes';
|
||||
|
||||
type ModuleProps = $ReadOnly<{|
|
||||
...ViewProps,
|
||||
|}>;
|
||||
|
||||
interface NativeCommands {
|
||||
+hotspotUpdate: (viewRef: React.Ref<'Module'>) => void;
|
||||
}
|
||||
|
||||
export const Commands = 4;
|
||||
|
||||
export default codegenNativeComponent<ModuleProps>('Module');
|
||||
`;
|
||||
|
||||
const COMMANDS_EXPORTED_WITH_SHORTHAND = `
|
||||
// @flow
|
||||
|
||||
const codegenNativeComponent = require('codegenNativeComponent');
|
||||
|
||||
import type {ViewProps} from 'ViewPropTypes';
|
||||
|
||||
type ModuleProps = $ReadOnly<{|
|
||||
...ViewProps,
|
||||
|}>;
|
||||
|
||||
interface NativeCommands {
|
||||
+hotspotUpdate: (viewRef: React.Ref<'Module'>) => void;
|
||||
}
|
||||
|
||||
const Commands = 4;
|
||||
|
||||
export {Commands};
|
||||
|
||||
export default codegenNativeComponent<ModuleProps>('Module');
|
||||
`;
|
||||
|
||||
module.exports = {
|
||||
'CommandsExportedWithDifferentNameNativeComponent.js': COMMANDS_EXPORTED_WITH_DIFFERENT_NAME,
|
||||
'CommandsExportedWithShorthandNativeComponent.js': COMMANDS_EXPORTED_WITH_SHORTHAND,
|
||||
'OtherCommandsExportNativeComponent.js': OTHER_COMMANDS_EXPORT,
|
||||
};
|
||||
+6
-1
@@ -19,7 +19,6 @@ type ModuleProps = $ReadOnly<{| ...ViewProps,
|
||||
onDirectEventDefinedInlineNull: DirectEventHandler<null>,
|
||||
onBubblingEventDefinedInlineNull: BubblingEventHandler<null>,
|
||||
|}>;
|
||||
export const Commands = codegenNativeCommands<NativeCommands>();
|
||||
|
||||
const registerGeneratedViewConfig = require('registerGeneratedViewConfig');
|
||||
|
||||
@@ -73,3 +72,9 @@ exports[`Babel plugin inline view configs can inline config for NotANativeCompon
|
||||
|
||||
export default 'Not a view config';"
|
||||
`;
|
||||
|
||||
exports[`Babel plugin inline view configs fails on inline config for CommandsExportedWithDifferentNameNativeComponent.js 1`] = `"Native commands must be exported with the name 'Commands'"`;
|
||||
|
||||
exports[`Babel plugin inline view configs fails on inline config for CommandsExportedWithShorthandNativeComponent.js 1`] = `"'Commands' is a reserved export and may only be used to export the result of codegenNativeCommands."`;
|
||||
|
||||
exports[`Babel plugin inline view configs fails on inline config for OtherCommandsExportNativeComponent.js 1`] = `"'Commands' is a reserved export and may only be used to export the result of codegenNativeCommands."`;
|
||||
|
||||
@@ -12,9 +12,10 @@
|
||||
|
||||
const {transform: babelTransform} = require('@babel/core');
|
||||
const fixtures = require('../__test_fixtures__/fixtures.js');
|
||||
const failures = require('../__test_fixtures__/failures.js');
|
||||
|
||||
function transform(filename) {
|
||||
return babelTransform(fixtures[filename], {
|
||||
function transform(fixture, filename) {
|
||||
return babelTransform(fixture, {
|
||||
plugins: [require('@babel/plugin-syntax-flow'), require('../index')],
|
||||
babelrc: false,
|
||||
filename,
|
||||
@@ -26,7 +27,17 @@ describe('Babel plugin inline view configs', () => {
|
||||
.sort()
|
||||
.forEach(fixtureName => {
|
||||
it(`can inline config for ${fixtureName}`, () => {
|
||||
expect(transform(fixtureName)).toMatchSnapshot();
|
||||
expect(transform(fixtures[fixtureName], fixtureName)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
Object.keys(failures)
|
||||
.sort()
|
||||
.forEach(fixtureName => {
|
||||
it(`fails on inline config for ${fixtureName}`, () => {
|
||||
expect(() => {
|
||||
transform(failures[fixtureName], fixtureName);
|
||||
}).toThrowErrorMatchingSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,14 +51,83 @@ module.exports = function(context) {
|
||||
pre(state) {
|
||||
this.code = state.code;
|
||||
this.filename = state.opts.filename;
|
||||
this.defaultExport = null;
|
||||
this.commandsExport = null;
|
||||
this.codeInserted = false;
|
||||
},
|
||||
visitor: {
|
||||
ExportNamedDeclaration(nodePath) {
|
||||
if (this.codeInserted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
nodePath.node.declaration &&
|
||||
nodePath.node.declaration.declarations &&
|
||||
nodePath.node.declaration.declarations[0]
|
||||
) {
|
||||
const firstDeclaration = nodePath.node.declaration.declarations[0];
|
||||
|
||||
if (firstDeclaration.type === 'VariableDeclarator') {
|
||||
if (
|
||||
firstDeclaration.init.type === 'CallExpression' &&
|
||||
firstDeclaration.init.callee.type === 'Identifier' &&
|
||||
firstDeclaration.init.callee.name === 'codegenNativeCommands'
|
||||
) {
|
||||
if (
|
||||
firstDeclaration.id.type === 'Identifier' &&
|
||||
firstDeclaration.id.name !== 'Commands'
|
||||
) {
|
||||
throw new Error(
|
||||
"Native commands must be exported with the name 'Commands'",
|
||||
);
|
||||
}
|
||||
this.commandsExport = nodePath;
|
||||
return;
|
||||
} else {
|
||||
if (firstDeclaration.id.name === 'Commands') {
|
||||
throw new Error(
|
||||
"'Commands' is a reserved export and may only be used to export the result of codegenNativeCommands.",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
nodePath.node.specifiers &&
|
||||
nodePath.node.specifiers.length > 0
|
||||
) {
|
||||
nodePath.node.specifiers.forEach(specifier => {
|
||||
if (
|
||||
specifier.type === 'ExportSpecifier' &&
|
||||
specifier.local.type === 'Identifier' &&
|
||||
specifier.local.name === 'Commands'
|
||||
) {
|
||||
throw new Error(
|
||||
"'Commands' is a reserved export and may only be used to export the result of codegenNativeCommands.",
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
ExportDefaultDeclaration(nodePath, state) {
|
||||
if (isCodegenDeclaration(nodePath.node.declaration)) {
|
||||
const viewConfig = generateViewConfig(this.filename, this.code);
|
||||
nodePath.replaceWithMultiple(context.parse(viewConfig).program.body);
|
||||
this.defaultExport = nodePath;
|
||||
}
|
||||
},
|
||||
Program: {
|
||||
exit() {
|
||||
if (this.defaultExport) {
|
||||
const viewConfig = generateViewConfig(this.filename, this.code);
|
||||
this.defaultExport.replaceWithMultiple(
|
||||
context.parse(viewConfig).program.body,
|
||||
);
|
||||
if (this.commandsExport != null) {
|
||||
this.commandsExport.remove();
|
||||
}
|
||||
this.codeInserted = true;
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.2",
|
||||
"name": "babel-plugin-inline-view-configs",
|
||||
"description": "Babel plugin to inline view configs for React Native",
|
||||
"repository": {
|
||||
|
||||
Reference in New Issue
Block a user