Fix scope of function body when var redeclares param (#11158)
* Fix scope of function body when var redeclares param * Fix empty var declarations * Apply suggestions
This commit is contained in:
parent
a39beda58b
commit
9015fda3c1
@ -18,7 +18,11 @@ const visitor = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function(path: NodePath, scope = path.scope) {
|
export default function(
|
||||||
|
path: NodePath,
|
||||||
|
scope = path.scope,
|
||||||
|
shouldHoistVariables = true,
|
||||||
|
) {
|
||||||
const { node } = path;
|
const { node } = path;
|
||||||
const container = t.functionExpression(
|
const container = t.functionExpression(
|
||||||
null,
|
null,
|
||||||
@ -31,8 +35,9 @@ export default function(path: NodePath, scope = path.scope) {
|
|||||||
let callee = container;
|
let callee = container;
|
||||||
let args = [];
|
let args = [];
|
||||||
|
|
||||||
// todo: only hoist if necessary
|
if (shouldHoistVariables) {
|
||||||
hoistVariables(path, id => scope.push({ id }));
|
hoistVariables(path, id => scope.push({ id }));
|
||||||
|
}
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
foundThis: false,
|
foundThis: false,
|
||||||
|
|||||||
@ -64,6 +64,31 @@ export default function convertFunctionParams(path, loose) {
|
|||||||
for (let i = 0; i < params.length; i++) {
|
for (let i = 0; i < params.length; i++) {
|
||||||
const param = params[i];
|
const param = params[i];
|
||||||
|
|
||||||
|
for (const name of Object.keys(param.getBindingIdentifiers())) {
|
||||||
|
const constantViolations = scope.bindings[name]?.constantViolations;
|
||||||
|
if (constantViolations) {
|
||||||
|
for (const redeclarator of constantViolations) {
|
||||||
|
const node = redeclarator.node;
|
||||||
|
// If a constant violation is a var or a function declaration,
|
||||||
|
// we first check to see if it's a var without an init.
|
||||||
|
// If so, we remove that declarator.
|
||||||
|
// Otherwise, we have to wrap it in an IIFE.
|
||||||
|
switch (node.type) {
|
||||||
|
case "VariableDeclarator":
|
||||||
|
if (node.init === null) {
|
||||||
|
redeclarator.remove();
|
||||||
|
} else {
|
||||||
|
state.iife = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "FunctionDeclaration":
|
||||||
|
state.iife = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const paramIsAssignmentPattern = param.isAssignmentPattern();
|
const paramIsAssignmentPattern = param.isAssignmentPattern();
|
||||||
if (paramIsAssignmentPattern && (loose || node.kind === "set")) {
|
if (paramIsAssignmentPattern && (loose || node.kind === "set")) {
|
||||||
const left = param.get("left");
|
const left = param.get("left");
|
||||||
@ -146,7 +171,8 @@ export default function convertFunctionParams(path, loose) {
|
|||||||
path.ensureBlock();
|
path.ensureBlock();
|
||||||
|
|
||||||
if (state.iife) {
|
if (state.iife) {
|
||||||
body.push(callDelegate(path, scope));
|
// we don't want to hoist the inner declarations up
|
||||||
|
body.push(callDelegate(path, scope, false));
|
||||||
path.set("body", t.blockStatement(body));
|
path.set("body", t.blockStatement(body));
|
||||||
} else {
|
} else {
|
||||||
path.get("body").unshiftContainer("body", body);
|
path.get("body").unshiftContainer("body", body);
|
||||||
|
|||||||
@ -0,0 +1,5 @@
|
|||||||
|
function foo(a = 2) {
|
||||||
|
function a() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
function foo() {
|
||||||
|
var a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 2;
|
||||||
|
return function () {
|
||||||
|
function a() {}
|
||||||
|
}();
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
function f(a = 2, b = 3) {
|
||||||
|
var a, b = 4;
|
||||||
|
var a;
|
||||||
|
var b;
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
function f() {
|
||||||
|
var a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 2;
|
||||||
|
var b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 3;
|
||||||
|
return function () {
|
||||||
|
var b = 4;
|
||||||
|
return a + b;
|
||||||
|
}();
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
function f(a = 2, b = 3) {
|
||||||
|
var a;
|
||||||
|
var { a } = { a: 4 };
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
function f() {
|
||||||
|
var a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 2;
|
||||||
|
var b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 3;
|
||||||
|
return function () {
|
||||||
|
var _a = {
|
||||||
|
a: 4
|
||||||
|
},
|
||||||
|
a = _a.a;
|
||||||
|
return a + b;
|
||||||
|
}();
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
function foo({a, b}) {
|
||||||
|
var a = 3;
|
||||||
|
var c = 2;
|
||||||
|
var d = a + b + c;
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
function foo(_ref) {
|
||||||
|
var a = _ref.a,
|
||||||
|
b = _ref.b;
|
||||||
|
return function () {
|
||||||
|
var a = 3;
|
||||||
|
var c = 2;
|
||||||
|
var d = a + b + c;
|
||||||
|
}();
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
function foo([a, b]) {
|
||||||
|
var a = 3;
|
||||||
|
var c = 2;
|
||||||
|
var d = a + b + c;
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
function foo(_ref) {
|
||||||
|
var _ref2 = babelHelpers.slicedToArray(_ref, 2),
|
||||||
|
a = _ref2[0],
|
||||||
|
b = _ref2[1];
|
||||||
|
|
||||||
|
return function () {
|
||||||
|
var a = 3;
|
||||||
|
var c = 2;
|
||||||
|
var d = a + b + c;
|
||||||
|
}();
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
var x = 1
|
||||||
|
function foo(x, y = function () { x = 2 }) {
|
||||||
|
var x = 3
|
||||||
|
y()
|
||||||
|
expect(x).toBe(3);
|
||||||
|
}
|
||||||
|
foo()
|
||||||
|
expect(x).toBe(1);
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
function foo(a = 2) {
|
||||||
|
var a = 1;
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
function foo() {
|
||||||
|
var a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 2;
|
||||||
|
return function () {
|
||||||
|
var a = 1;
|
||||||
|
}();
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
function f(a = 2, b = 3) {
|
||||||
|
var { a } = { a: 4 };
|
||||||
|
var a;
|
||||||
|
var b;
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
function f() {
|
||||||
|
var a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 2;
|
||||||
|
var b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 3;
|
||||||
|
return function () {
|
||||||
|
var _a = {
|
||||||
|
a: 4
|
||||||
|
},
|
||||||
|
a = _a.a;
|
||||||
|
return a + b;
|
||||||
|
}();
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user