Add a new babel transformer for inlining regenerator-runtime per file
Reviewed By: davidaurelio Differential Revision: D5364134 fbshipit-source-id: 45aae705f961819d5a8e3a8a23c2e8b9300d3cb5
This commit is contained in:
parent
304dc6bd77
commit
e7c1cf5b7d
|
@ -38,6 +38,7 @@ var base = {
|
||||||
'transform-react-jsx',
|
'transform-react-jsx',
|
||||||
'transform-regenerator',
|
'transform-regenerator',
|
||||||
['transform-es2015-for-of', { loose: true }],
|
['transform-es2015-for-of', { loose: true }],
|
||||||
|
require('../transforms/transform-regenerator-runtime-insertion'),
|
||||||
require('../transforms/transform-symbol-member'),
|
require('../transforms/transform-symbol-member'),
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2013-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const babel = require('babel-core');
|
||||||
|
const t = babel.types;
|
||||||
|
|
||||||
|
const NAME = 'regenerator-runtime';
|
||||||
|
const REGENERATOR_NOT_NEEDED = 'NOT_NEEDED';
|
||||||
|
const REGENERATOR_NEEDED = 'NEEDED';
|
||||||
|
const REGENERATOR_ALREADY_REQUIRED = 'ALREADY_REQUIRED';
|
||||||
|
|
||||||
|
function flagState(state) {
|
||||||
|
if (state !== REGENERATOR_ALREADY_REQUIRED) {
|
||||||
|
state.regeneratorRequired = REGENERATOR_NEEDED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkRequire(node, state) {
|
||||||
|
const method = node.callee.name;
|
||||||
|
const args = node.arguments;
|
||||||
|
|
||||||
|
if (
|
||||||
|
method === 'require' &&
|
||||||
|
t.isStringLiteral(args[0]) &&
|
||||||
|
args[0].value.startsWith(NAME)
|
||||||
|
) {
|
||||||
|
state.regeneratorRequired = REGENERATOR_ALREADY_REQUIRED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkFunction(node, state) {
|
||||||
|
// Method is neither a generator nor an async function; skip.
|
||||||
|
if (!node.generator && !node.async) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will only set the status to needed if it hasn't already been required.
|
||||||
|
if (state.regeneratorRequired === REGENERATOR_NOT_NEEDED) {
|
||||||
|
state.regeneratorRequired = REGENERATOR_NEEDED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const isGeneratorRequired = {
|
||||||
|
CallExpression(path, state) {
|
||||||
|
checkRequire(path.node, state);
|
||||||
|
},
|
||||||
|
|
||||||
|
FunctionDeclaration(path, state) {
|
||||||
|
checkFunction(path.node, state);
|
||||||
|
},
|
||||||
|
|
||||||
|
ClassMethod(path, state) {
|
||||||
|
checkFunction(path.node, state);
|
||||||
|
},
|
||||||
|
|
||||||
|
ArrowFunctionExpression(path, state) {
|
||||||
|
checkFunction(path.node, state);
|
||||||
|
},
|
||||||
|
|
||||||
|
FunctionExpression(path, state) {
|
||||||
|
checkFunction(path.node, state);
|
||||||
|
},
|
||||||
|
|
||||||
|
YieldExpression(path, state) {
|
||||||
|
flagState(state);
|
||||||
|
},
|
||||||
|
|
||||||
|
AwaitExpression(path, state) {
|
||||||
|
flagState(state);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a "const regeneratorRuntime = require('regenerator-runtime') to each
|
||||||
|
* file that does not include regenerator-runtime, but requires it because it
|
||||||
|
* contains async/await or generators.
|
||||||
|
*/
|
||||||
|
module.exports = function() {
|
||||||
|
return {
|
||||||
|
visitor: {
|
||||||
|
Program(path, state) {
|
||||||
|
state.regeneratorRequired = REGENERATOR_NOT_NEEDED;
|
||||||
|
path.traverse(isGeneratorRequired, state);
|
||||||
|
|
||||||
|
if (state.regeneratorRequired === REGENERATOR_NEEDED) {
|
||||||
|
path.node.body.unshift(
|
||||||
|
t.variableDeclaration('const', [
|
||||||
|
t.variableDeclarator(
|
||||||
|
t.identifier('regeneratorRuntime'),
|
||||||
|
t.callExpression(t.identifier('require'), [
|
||||||
|
t.stringLiteral(NAME),
|
||||||
|
])
|
||||||
|
)
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
|
@ -74,6 +74,7 @@
|
||||||
],
|
],
|
||||||
"unmockedModulePathPatterns": [
|
"unmockedModulePathPatterns": [
|
||||||
"node_modules/react/",
|
"node_modules/react/",
|
||||||
|
"node_modules/regenerator-runtime/",
|
||||||
"Libraries/Renderer",
|
"Libraries/Renderer",
|
||||||
"promise",
|
"promise",
|
||||||
"source-map",
|
"source-map",
|
||||||
|
|
Loading…
Reference in New Issue