Skip to content

Commit

Permalink
Create File class for babel helpers (#10575)
Browse files Browse the repository at this point in the history
* add test

* fix: pass File to helper traverser

* pass babel.File to helpers.ensure
  • Loading branch information
JLHwung committed Mar 17, 2020
1 parent 748897b commit 4bf36e6
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 10 deletions.
2 changes: 2 additions & 0 deletions packages/babel-core/src/tools/build-external-helpers.js
Expand Up @@ -2,6 +2,7 @@ import * as helpers from "@babel/helpers";
import generator from "@babel/generator";
import template from "@babel/template";
import * as t from "@babel/types";
import File from "../transformation/file/file";

// Wrapped to avoid wasting time parsing this when almost no-one uses
// build-external-helpers.
Expand Down Expand Up @@ -136,6 +137,7 @@ function buildHelpers(body, namespace, whitelist) {

const ref = (refs[name] = getHelperReference(name));

helpers.ensure(name, File);
const { nodes } = helpers.get(name, getHelperReference, ref);

body.push(...nodes);
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-core/src/transformation/file/file.js
Expand Up @@ -174,7 +174,7 @@ export default class File {
}

// make sure that the helper exists
helpers.ensure(name);
helpers.ensure(name, File);

const uid = (this.declarations[name] = this.scope.generateUidIdentifier(
name,
Expand Down
37 changes: 28 additions & 9 deletions packages/babel-helpers/src/index.js
Expand Up @@ -13,6 +13,7 @@ function makePath(path) {
return parts.reverse().join(".");
}

let fileClass = undefined;
/**
* Given a file AST for a given helper, get a bunch of metadata about it so that Babel can quickly render
* the helper is whatever context it is needed in.
Expand All @@ -29,7 +30,7 @@ function getHelperMetadata(file) {
const importPaths = [];
const importBindingsReferences = [];

traverse(file, {
const dependencyVisitor = {
ImportDeclaration(child) {
const name = child.node.source.value;
if (!helpers[name]) {
Expand Down Expand Up @@ -72,9 +73,9 @@ function getHelperMetadata(file) {

child.skip();
},
});
};

traverse(file, {
const referenceVisitor = {
Program(path) {
const bindings = path.scope.getAllBindings();

Expand Down Expand Up @@ -111,7 +112,10 @@ function getHelperMetadata(file) {
exportBindingAssignments.push(makePath(child));
}
},
});
};

traverse(file.ast, dependencyVisitor, file.scope);
traverse(file.ast, referenceVisitor, file.scope);

if (!exportPath) throw new Error("Helpers must default-export something.");

Expand Down Expand Up @@ -170,7 +174,7 @@ function permuteHelperAST(file, metadata, id, localBindings, getDependency) {
toRename[exportName] = id.name;
}

traverse(file, {
const visitor = {
Program(path) {
// We need to compute these in advance because removing nodes would
// invalidate the paths.
Expand Down Expand Up @@ -223,7 +227,8 @@ function permuteHelperAST(file, metadata, id, localBindings, getDependency) {
// actually doing the traversal.
path.stop();
},
});
};
traverse(file.ast, visitor, file.scope);
}

const helperData = Object.create(null);
Expand All @@ -238,7 +243,16 @@ function loadHelper(name) {
}

const fn = () => {
return t.file(helper.ast());
const file = { ast: t.file(helper.ast()) };
if (fileClass) {
return new fileClass(
{
filename: `babel-helper://${name}`,
},
file,
);
}
return file;
};

const metadata = getHelperMetadata(fn());
Expand All @@ -249,7 +263,7 @@ function loadHelper(name) {
permuteHelperAST(file, metadata, id, localBindings, getDependency);

return {
nodes: file.program.body,
nodes: file.ast.program.body,
globals: metadata.globals,
};
},
Expand Down Expand Up @@ -280,7 +294,12 @@ export function getDependencies(name: string): $ReadOnlyArray<string> {
return Array.from(loadHelper(name).dependencies.values());
}

export function ensure(name: string) {
export function ensure(name: string, newFileClass?) {
if (!fileClass) {
// optional fileClass used to wrap helper snippets into File instance,
// offering `path.hub` support during traversal
fileClass = newFileClass;
}
loadHelper(name);
}

Expand Down
@@ -0,0 +1 @@
REPLACE_ME;
@@ -0,0 +1,3 @@
{
"plugins": ["./plugin"]
}
@@ -0,0 +1,3 @@
function _$_9496_main_hub_is_found() {}

_$_9496_main_hub_is_found;
22 changes: 22 additions & 0 deletions packages/babel-helpers/test/fixtures/regression/9496/plugin.js
@@ -0,0 +1,22 @@
const defineHelper = require("../../../helpers/define-helper").default;

const main = defineHelper(__dirname, "main", `
export default function helper() {}
`);

module.exports = function() {
return {
visitor: {
Identifier(path) {
if (path.node.name !== "REPLACE_ME") {
if (path.hub) {
path.node.name += "_hub_is_found";
}
return;
}
const helper = this.addHelper(main);
path.replaceWith(helper);
},
},
};
};
Expand Up @@ -134,6 +134,7 @@ function buildHelper(

if (!esm) {
bindings = [];
helpers.ensure(helperName, babel.File);
for (const dep of helpers.getDependencies(helperName)) {
const id = (dependencies[dep] = t.identifier(t.toIdentifier(dep)));
tree.body.push(template.statement.ast`
Expand Down

0 comments on commit 4bf36e6

Please sign in to comment.