diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments-global-undeclared/input.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments-global-undeclared/input.js new file mode 100644 index 000000000000..42903d8904f6 --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments-global-undeclared/input.js @@ -0,0 +1,9 @@ +function fn() { + var foo = () => { + return arguments; + }; +} + +var bar = () => arguments; + +var baz = () => () => arguments; diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments-global-undeclared/output.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments-global-undeclared/output.js new file mode 100644 index 000000000000..7b046216524d --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments-global-undeclared/output.js @@ -0,0 +1,19 @@ +var _arguments2 = typeof arguments === "undefined" ? void 0 : arguments; + +function fn() { + var _arguments = arguments; + + var foo = function () { + return _arguments; + }; +} + +var bar = function () { + return _arguments2; +}; + +var baz = function () { + return function () { + return _arguments2; + }; +}; diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments-global-var/input.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments-global-var/input.js new file mode 100644 index 000000000000..5f7d9826d3d3 --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments-global-var/input.js @@ -0,0 +1,10 @@ +var arguments = 1; +function fn() { + var foo = () => { + return arguments; + }; +} + +var bar = () => arguments; + +var baz = () => () => arguments; diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments-global-var/output.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments-global-var/output.js new file mode 100644 index 000000000000..f19432c82500 --- /dev/null +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments-global-var/output.js @@ -0,0 +1,19 @@ +var _arguments2 = 1; + +function fn() { + var _arguments = _arguments2; + + var foo = function () { + return _arguments; + }; +} + +var bar = function () { + return _arguments2; +}; + +var baz = function () { + return function () { + return _arguments2; + }; +}; diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments/input.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments/input.js index 198ac999f6ae..5d9e7c90913a 100644 --- a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments/input.js +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments/input.js @@ -43,3 +43,39 @@ function six(obj) { return fn(); } six(); + +var seven = () => { + var arguments = 1; + return arguments; +}; +seven(); + +var eight = () => { + var arguments = 1; + return () => arguments; +}; +eight(); + +function nine() { + var arguments = 1; + var foo = () => { + return arguments; + }; +} +nine(); + +var eleven = () => { + var arguments = 2; + return function () { + return () => arguments; + } +}; +eleven()(1,2,3)(); + +var twelve = () => { + var arguments = 2; + return class { + m() { return () => arguments; } + } +}; +twelve(); diff --git a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments/output.js b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments/output.js index 84bbb58be445..9110a69ddc39 100644 --- a/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments/output.js +++ b/packages/babel-plugin-transform-arrow-functions/test/fixtures/arrow-functions/arguments/output.js @@ -81,3 +81,56 @@ function six(obj) { } six(); + +var seven = function () { + var _arguments6 = 1; + return _arguments6; +}; + +seven(); + +var eight = function () { + var _arguments7 = 1; + return function () { + return _arguments7; + }; +}; + +eight(); + +function nine() { + var _arguments8 = 1; + + var foo = function () { + return _arguments8; + }; +} + +nine(); + +var eleven = function () { + var arguments = 2; + return function () { + var _arguments9 = arguments; + return function () { + return _arguments9; + }; + }; +}; + +eleven()(1, 2, 3)(); + +var twelve = function () { + var arguments = 2; + return class { + m() { + var _arguments10 = arguments; + return function () { + return _arguments10; + }; + } + + }; +}; + +twelve(); diff --git a/packages/babel-traverse/src/path/conversion.ts b/packages/babel-traverse/src/path/conversion.ts index d92de9b7e978..484fcbba1de4 100644 --- a/packages/babel-traverse/src/path/conversion.ts +++ b/packages/babel-traverse/src/path/conversion.ts @@ -226,9 +226,22 @@ function hoistFunctionEnvironment( // Convert all "arguments" references in the arrow to point at the alias. if (argumentsPaths.length > 0) { - const argumentsBinding = getBinding(thisEnvFn, "arguments", () => - t.identifier("arguments"), - ); + const argumentsBinding = getBinding(thisEnvFn, "arguments", () => { + const args = () => t.identifier("arguments"); + if (thisEnvFn.scope.path.isProgram()) { + return t.conditionalExpression( + t.binaryExpression( + "===", + t.unaryExpression("typeof", args()), + t.stringLiteral("undefined"), + ), + thisEnvFn.scope.buildUndefinedNode(), + args(), + ); + } else { + return args(); + } + }); argumentsPaths.forEach(argumentsChild => { const argsRef = t.identifier(argumentsBinding); @@ -583,6 +596,17 @@ function getScopeInformation(fnPath) { ReferencedIdentifier(child) { if (child.node.name !== "arguments") return; + let curr = child.scope; + do { + if (curr.hasOwnBinding("arguments")) { + curr.rename("arguments"); + return; + } + if (curr.path.isFunction() && !curr.path.isArrowFunctionExpression()) { + break; + } + } while ((curr = curr.parent)); + argumentsPaths.push(child); }, MetaProperty(child) {