Skip to content

Commit

Permalink
Share hoisted bindings in Babel transform output
Browse files Browse the repository at this point in the history
  • Loading branch information
kitten committed Jan 8, 2021
1 parent 43d3bf3 commit 0082078
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 5 deletions.
43 changes: 43 additions & 0 deletions src/babel/__snapshots__/plugin.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,48 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`deduplicates hoisted expressions 1`] = `
"import { match, __private } from \\"reghex\\";
const re = /1/;
var _re_expression = __private.pattern(re);
const a = function (state) {
var y1 = state.y,
x1 = state.x;
var node = [];
var x;
if (x = __private.exec(state, _re_expression)) {
node.push(x);
} else {
state.y = y1;
state.x = x1;
return;
}
node.tag = 'a';
return node;
};
const b = function (state) {
var y1 = state.y,
x1 = state.x;
var node = [];
var x;
if (x = __private.exec(state, _re_expression)) {
node.push(x);
} else {
state.y = y1;
state.x = x1;
return;
}
node.tag = 'b';
return node;
};"
`;

exports[`works together with @babel/plugin-transform-modules-commonjs 1`] = `
"\\"use strict\\";
Expand Down
21 changes: 21 additions & 0 deletions src/babel/plugin.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,27 @@ it('works while only minifying', () => {
).toMatchSnapshot();
});

it('deduplicates hoisted expressions', () => {
const code = `
import { match } from 'reghex/macro';
const re = /1/;
const a = match('a')\`
\${re}
\`;
const b = match('b')\`
\${re}
\`;
`;

expect(
transform(code, { babelrc: false, presets: [], plugins: [reghexPlugin] })
.code
).toMatchSnapshot();
});

it('works with local recursion', () => {
// NOTE: A different default name is allowed
const code = `
Expand Down
21 changes: 16 additions & 5 deletions src/babel/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export function makeHelpers({ types: t, template }) {
let _matchId = t.identifier('match');
let _privateId = t.identifier(_private);

const _hoistedExpressions = new Map();

const privateMethod = (name) =>
t.memberExpression(t.identifier(_privateId.name), t.identifier(name));

Expand Down Expand Up @@ -116,19 +118,25 @@ export function makeHelpers({ types: t, template }) {
expression = expression.body.body[0].argument;
}

if (
const isBindingExpression =
t.isIdentifier(expression) &&
path.scope.hasBinding(expression.name)
) {
path.scope.hasBinding(expression.name);
if (isBindingExpression) {
const binding = path.scope.getBinding(expression.name);
if (t.isVariableDeclarator(binding.path.node)) {
const matchPath = binding.path.get('init');
if (this.isMatch(matchPath)) return expression;
if (this.isMatch(matchPath)) {
return expression;
} else if (_hoistedExpressions.has(expression.name)) {
return t.identifier(_hoistedExpressions.get(expression.name));
}
}
}

const id = path.scope.generateUidIdentifier(
`${matchName}_expression`
isBindingExpression
? `${expression.name}_expression`
: `${matchName}_expression`
);

variableDeclarators.push(
Expand All @@ -138,6 +146,9 @@ export function makeHelpers({ types: t, template }) {
)
);

if (t.isIdentifier(expression)) {
_hoistedExpressions.set(expression.name, id.name);
}
return id;
}
);
Expand Down

0 comments on commit 0082078

Please sign in to comment.