Merge pull request #6379 from nicolo-ribaudo/helper-runtime-dependencies
Fix helper dependencies in babel runtime
This commit is contained in:
commit
c87cc18586
4
.gitignore
vendored
4
.gitignore
vendored
@ -15,12 +15,16 @@ package-lock.json
|
||||
!/packages/babel-runtime/core-js/map.js
|
||||
/packages/babel-runtime/helpers/*.js
|
||||
!/packages/babel-runtime/helpers/toArray.js
|
||||
!/packages/babel-runtime/helpers/temporalRef.js
|
||||
/packages/babel-runtime/helpers/builtin/*.js
|
||||
!/packages/babel-runtime/helpers/builtin/toArray.js
|
||||
!/packages/babel-runtime/helpers/builtin/temporalRef.js
|
||||
/packages/babel-runtime/helpers/builtin/es6/*.js
|
||||
!/packages/babel-runtime/helpers/builtin/es6/toArray.js
|
||||
!/packages/babel-runtime/helpers/builtin/es6/temporalRef.js
|
||||
/packages/babel-runtime/helpers/es6/*.js
|
||||
!/packages/babel-runtime/helpers/es6/toArray.js
|
||||
!/packages/babel-runtime/helpers/es6/temporalRef.js
|
||||
/packages/babel-register/test/.babel
|
||||
/packages/babel-cli/test/tmp
|
||||
/packages/babel-node/test/tmp
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// @flow
|
||||
|
||||
import getHelper from "@babel/helpers";
|
||||
import * as helpers from "@babel/helpers";
|
||||
import { NodePath, Hub, Scope } from "@babel/traverse";
|
||||
import { codeFrameColumns } from "@babel/code-frame";
|
||||
import traverse from "@babel/traverse";
|
||||
@ -132,11 +132,16 @@ export default class File {
|
||||
name,
|
||||
));
|
||||
|
||||
const { nodes, globals } = getHelper(
|
||||
const dependencies = {};
|
||||
for (const dep of helpers.getDependencies(name)) {
|
||||
dependencies[dep] = this.addHelper(dep);
|
||||
}
|
||||
|
||||
const { nodes, globals } = helpers.get(
|
||||
name,
|
||||
name => this.addHelper(name),
|
||||
dep => dependencies[dep],
|
||||
uid,
|
||||
() => Object.keys(this.scope.getAllBindings()),
|
||||
Object.keys(this.scope.getAllBindings()),
|
||||
);
|
||||
|
||||
globals.forEach(name => {
|
||||
|
||||
@ -600,7 +600,9 @@ helpers.taggedTemplateLiteralLoose = defineHelper(`
|
||||
`);
|
||||
|
||||
helpers.temporalRef = defineHelper(`
|
||||
export default function _temporalRef(val, name, undef) {
|
||||
import undef from "temporalUndefined";
|
||||
|
||||
export default function _temporalRef(val, name) {
|
||||
if (val === undef) {
|
||||
throw new ReferenceError(name + " is not defined - temporal dead zone");
|
||||
} else {
|
||||
|
||||
@ -134,8 +134,8 @@ function getHelperMetadata(file) {
|
||||
/**
|
||||
* Given a helper AST and information about how it will be used, update the AST to match the usage.
|
||||
*/
|
||||
function permuteHelperAST(file, metadata, id, getLocalBindings, getDependency) {
|
||||
if (getLocalBindings && !id) {
|
||||
function permuteHelperAST(file, metadata, id, localBindings, getDependency) {
|
||||
if (localBindings && !id) {
|
||||
throw new Error("Unexpected local bindings for module-based helpers.");
|
||||
}
|
||||
|
||||
@ -154,11 +154,11 @@ function permuteHelperAST(file, metadata, id, getLocalBindings, getDependency) {
|
||||
const dependenciesRefs = {};
|
||||
dependencies.forEach((name, id) => {
|
||||
dependenciesRefs[id.name] =
|
||||
typeof getDependency === "function" ? getDependency(name) : id;
|
||||
(typeof getDependency === "function" && getDependency(name)) || id;
|
||||
});
|
||||
|
||||
const toRename = {};
|
||||
const bindings = new Set((getLocalBindings && getLocalBindings()) || []);
|
||||
const bindings = new Set(localBindings || []);
|
||||
localBindingNames.forEach(name => {
|
||||
let newName = name;
|
||||
while (bindings.has(newName)) newName = "_" + newName;
|
||||
@ -237,17 +237,17 @@ function loadHelper(name) {
|
||||
|
||||
const metadata = getHelperMetadata(fn());
|
||||
|
||||
// Preload dependencies
|
||||
metadata.dependencies.forEach(loadHelper);
|
||||
helperData[name] = {
|
||||
build(getDependency, id, localBindings) {
|
||||
const file = fn();
|
||||
permuteHelperAST(file, metadata, id, localBindings, getDependency);
|
||||
|
||||
helperData[name] = function(getDependency, id, getLocalBindings) {
|
||||
const file = fn();
|
||||
permuteHelperAST(file, metadata, id, getLocalBindings, getDependency);
|
||||
|
||||
return {
|
||||
nodes: file.program.body,
|
||||
globals: metadata.globals,
|
||||
};
|
||||
return {
|
||||
nodes: file.program.body,
|
||||
globals: metadata.globals,
|
||||
};
|
||||
},
|
||||
dependencies: metadata.dependencies,
|
||||
};
|
||||
}
|
||||
|
||||
@ -256,12 +256,15 @@ function loadHelper(name) {
|
||||
|
||||
export function get(
|
||||
name,
|
||||
getDependency?: string => t.Expression,
|
||||
getDependency?: string => ?t.Expression,
|
||||
id?,
|
||||
getLocalBindings?: () => string[],
|
||||
localBindings?: string[],
|
||||
) {
|
||||
const helper = loadHelper(name);
|
||||
return helper(getDependency, id, getLocalBindings);
|
||||
return loadHelper(name).build(getDependency, id, localBindings);
|
||||
}
|
||||
|
||||
export function getDependencies(name: string): $ReadOnlyArray<string> {
|
||||
return Array.from(loadHelper(name).dependencies.values());
|
||||
}
|
||||
|
||||
export const list = Object.keys(helpers)
|
||||
|
||||
@ -16,7 +16,6 @@ function buildTDZAssert(node, file) {
|
||||
return t.callExpression(file.addHelper("temporalRef"), [
|
||||
node,
|
||||
t.stringLiteral(node.name),
|
||||
file.addHelper("temporalUndefined"),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
import undef from "./temporalUndefined";
|
||||
export default function _temporalRef(val, name) {
|
||||
if (val === undef) {
|
||||
throw new ReferenceError(name + " is not defined - temporal dead zone");
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
11
packages/babel-runtime/helpers/builtin/temporalRef.js
Normal file
11
packages/babel-runtime/helpers/builtin/temporalRef.js
Normal file
@ -0,0 +1,11 @@
|
||||
var temporalUndefined = require("./temporalUndefined");
|
||||
|
||||
function _temporalRef(val, name) {
|
||||
if (val === temporalUndefined) {
|
||||
throw new ReferenceError(name + " is not defined - temporal dead zone");
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = _temporalRef;
|
||||
8
packages/babel-runtime/helpers/es6/temporalRef.js
Normal file
8
packages/babel-runtime/helpers/es6/temporalRef.js
Normal file
@ -0,0 +1,8 @@
|
||||
import undef from "./temporalUndefined";
|
||||
export default function _temporalRef(val, name) {
|
||||
if (val === undef) {
|
||||
throw new ReferenceError(name + " is not defined - temporal dead zone");
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
11
packages/babel-runtime/helpers/temporalRef.js
Normal file
11
packages/babel-runtime/helpers/temporalRef.js
Normal file
@ -0,0 +1,11 @@
|
||||
var temporalUndefined = require("./temporalUndefined");
|
||||
|
||||
function _temporalRef(val, name) {
|
||||
if (val === temporalUndefined) {
|
||||
throw new ReferenceError(name + " is not defined - temporal dead zone");
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = _temporalRef;
|
||||
@ -99,6 +99,15 @@ function buildRuntimeRewritePlugin(relativePath, helperName, dependencies) {
|
||||
};
|
||||
}
|
||||
|
||||
function buildRequireCall(id, dep) {
|
||||
return t.variableDeclaration("var", [
|
||||
t.variableDeclarator(
|
||||
id,
|
||||
t.callExpression(t.identifier("require"), [t.stringLiteral(dep)])
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
function buildHelper(helperName, modules, useBuiltIns) {
|
||||
const id =
|
||||
modules === "commonjs"
|
||||
@ -106,12 +115,31 @@ function buildHelper(helperName, modules, useBuiltIns) {
|
||||
: null;
|
||||
const sourceType = modules === "commonjs" ? "script" : "module";
|
||||
|
||||
const helper = helpers.get(helperName, null, id);
|
||||
const tree = t.program(helper.nodes, [], sourceType);
|
||||
const tree = t.program([], [], sourceType);
|
||||
const dependencies = {};
|
||||
let bindings = null;
|
||||
|
||||
if (modules === "commonjs") {
|
||||
bindings = [];
|
||||
for (const dep of helpers.getDependencies(helperName)) {
|
||||
const id = dependencies[dep] = t.identifier(t.toIdentifier(dep));
|
||||
tree.body.push(buildRequireCall(id, dep));
|
||||
bindings.push(id.name);
|
||||
}
|
||||
}
|
||||
|
||||
const helper = helpers.get(
|
||||
helperName,
|
||||
dep => dependencies[dep],
|
||||
id,
|
||||
bindings
|
||||
);
|
||||
tree.body.push.apply(tree.body, helper.nodes);
|
||||
|
||||
const transformOpts = makeTransformOpts(modules, useBuiltIns);
|
||||
|
||||
const relative = useBuiltIns ? "../.." : "..";
|
||||
|
||||
|
||||
return babel.transformFromAst(tree, null, {
|
||||
presets: transformOpts.presets,
|
||||
plugins: transformOpts.plugins.concat([
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user