Skip to content

Commit

Permalink
Reduce transform-block-scoping loops output size (babel#15746)
Browse files Browse the repository at this point in the history
Co-authored-by: Nicolò Ribaudo <[email protected]>
  • Loading branch information
liuxingbaoyu and nicolo-ribaudo authored Jul 18, 2023
1 parent 11844c1 commit b798a69
Show file tree
Hide file tree
Showing 20 changed files with 451 additions and 182 deletions.
94 changes: 71 additions & 23 deletions packages/babel-plugin-transform-block-scoping/src/loop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,45 +254,92 @@ export function wrapLoopBody(
}
}
if (varNames.length) {
bodyStmts.push(
t.variableDeclaration(
"var",
varNames.map(name => t.variableDeclarator(t.identifier(name))),
),
varPath.pushContainer(
"declarations",
varNames.map(name => t.variableDeclarator(t.identifier(name))),
);
}

if (state.breaksContinues.length === 0 && state.returns.length === 0) {
const labelNum = state.breaksContinues.length;
const returnNum = state.returns.length;
if (labelNum + returnNum === 0) {
bodyStmts.push(t.expressionStatement(call));
} else if (labelNum === 1 && returnNum === 0) {
for (const path of state.breaksContinues) {
const { node } = path;
const { type, label } = node;
let name = type === "BreakStatement" ? "break" : "continue";
if (label) name += " " + label.name;
path.replaceWith(
t.addComment(
t.returnStatement(t.numericLiteral(1)),
"trailing",
" " + name,
true,
),
);
if (updaterNode) path.insertBefore(t.cloneNode(updaterNode));

bodyStmts.push(
template.statement.ast`
if (${call}) ${node}
`,
);
}
} else {
const completionId = loopPath.scope.generateUid("ret");
bodyStmts.push(
t.variableDeclaration("var", [
t.variableDeclarator(t.identifier(completionId), call),
]),
);

const injected = new Set<string>();
if (varPath.isVariableDeclaration()) {
varPath.pushContainer("declarations", [
t.variableDeclarator(t.identifier(completionId)),
]);
bodyStmts.push(
t.expressionStatement(
t.assignmentExpression("=", t.identifier(completionId), call),
),
);
} else {
bodyStmts.push(
t.variableDeclaration("var", [
t.variableDeclarator(t.identifier(completionId), call),
]),
);
}

const injected: string[] = [];
for (const path of state.breaksContinues) {
const { node } = path;
const { type, label } = node;
let name = type === "BreakStatement" ? "break" : "continue";
if (label) name += "|" + label.name;
path.replaceWith(t.returnStatement(t.stringLiteral(name)));
if (label) name += " " + label.name;

let i = injected.indexOf(name);
const hasInjected = i !== -1;
if (!hasInjected) {
injected.push(name);
i = injected.length - 1;
}

path.replaceWith(
t.addComment(
t.returnStatement(t.numericLiteral(i)),
"trailing",
" " + name,
true,
),
);
if (updaterNode) path.insertBefore(t.cloneNode(updaterNode));

if (injected.has(name)) continue;
injected.add(name);
if (hasInjected) continue;

bodyStmts.push(
template.statement.ast`
if (
${t.identifier(completionId)} === ${t.stringLiteral(name)}
) ${node}
if (${t.identifier(completionId)} === ${t.numericLiteral(i)}) ${node}
`,
);
}
if (state.returns.length) {

if (returnNum) {
for (const path of state.returns) {
const arg = path.node.argument || path.scope.buildUndefinedNode();
path.replaceWith(
Expand All @@ -304,9 +351,10 @@ export function wrapLoopBody(

bodyStmts.push(
template.statement.ast`
if (typeof ${t.identifier(completionId)} === "object")
return ${t.identifier(completionId)}.v;
`,
if (${t.identifier(completionId)}) return ${t.identifier(
completionId,
)}.v;
`,
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var j = 0;
var _loop2 = function () {
switch (i) {
case 0:
return "continue";
return 1; // continue
}
j++;
var z = 3;
Expand All @@ -29,37 +29,35 @@ var _loop2 = function () {
});
};
for (i = 0; i < 10; i++) {
var _ret = _loop2();
if (_ret === "continue") continue;
if (_loop2()) continue;
}
expect(j).toBe(9);

// it should work with loops nested within switch
j = 0;
var _loop3 = function () {
switch (i) {
case 0:
var _loop4 = function () {
var z = 3;
(function () {
return z;
});
j++;
return "break";
};
for (k = 0; k < 10; k++) {
var _ret2 = _loop4();
if (_ret2 === "break") break;
}
break;
}
var z = 3;
(function () {
return z;
});
};
switch (i) {
case 0:
var _loop4 = function () {
var z = 3;
(function () {
return z;
});
j++;
return 1; // break
};
for (k = 0; k < 10; k++) {
if (_loop4()) break;
}
break;
}
var z = 3;
(function () {
return z;
});
},
k;
for (i = 0; i < 10; i++) {
var k;
_loop3();
}
expect(j).toBe(1);
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
function* a() {
var _loop = function* () {
var x = yield "iteration";
fn = function () {
return x;
};
};
var x = yield "iteration";
fn = function () {
return x;
};
},
fn;
do {
var fn;
yield* _loop();
} while (false);
return fn;
}
async function b() {
var _loop2 = async function () {
var x = await "iteration";
fn = function () {
return x;
};
};
var x = await "iteration";
fn = function () {
return x;
};
},
fn;
do {
var fn;
await _loop2();
} while (false);
return fn;
}
async function* c() {
var _loop3 = async function* () {
var x = yield "iteration";
fn = function () {
return x;
};
};
var x = yield "iteration";
fn = function () {
return x;
};
},
fn;
do {
var fn;
yield* _loop3();
} while (false);
return fn;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ var _loop = function () {
return b;
});
if (true) break;
return "continue";
return 1; // continue
}
case false:
{
Expand All @@ -16,6 +16,5 @@ var _loop = function () {
}
};
for (var a of [1]) {
var _ret = _loop();
if (_ret === "continue") continue;
if (_loop()) continue;
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
(function () {
var _loop = function (i) {
fns.push(function () {
return i;
});
if (i === 1) {
return "continue";
} else if (i === 2) {
return "break";
} else if (i === 3) {
return {
v: i
};
}
};
fns.push(function () {
return i;
});
if (i === 1) {
return 0; // continue
} else if (i === 2) {
return 1; // break
} else if (i === 3) {
return {
v: i
};
}
},
_ret;
for (var i in nums) {
var _ret = _loop(i);
if (_ret === "continue") continue;
if (_ret === "break") break;
if (typeof _ret === "object") return _ret.v;
_ret = _loop(i);
if (_ret === 0) continue;
if (_ret === 1) break;
if (_ret) return _ret.v;
}
})();
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ var _loop = function (i) {
fns.push(function () {
return i;
});
return "break";
return 1; // break
};
for (var i in nums) {
var _ret = _loop(i);
if (_ret === "break") break;
if (_loop(i)) break;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ var _loop = function (i) {
fns.push(function () {
return i;
});
return "continue";
return 1; // continue
};
for (var i in nums) {
var _ret = _loop(i);
if (_ret === "continue") continue;
if (_loop(i)) continue;
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
(function () {
var _loop = function (i) {
fns.push(function () {
return i;
});
return {
v: void 0
};
};
fns.push(function () {
return i;
});
return {
v: void 0
};
},
_ret;
for (var i in nums) {
var _ret = _loop(i);
if (typeof _ret === "object") return _ret.v;
_ret = _loop(i);
if (_ret) return _ret.v;
}
})();
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
(function () {
var _loop = function (i) {
fns.push(function () {
return i;
});
return {
v: i
};
};
fns.push(function () {
return i;
});
return {
v: i
};
},
_ret;
for (var i in nums) {
var _ret = _loop(i);
if (typeof _ret === "object") return _ret.v;
_ret = _loop(i);
if (_ret) return _ret.v;
}
})();
Loading

0 comments on commit b798a69

Please sign in to comment.