From fc5365fe4a3b9acf7116d63df6a23193e5a40ed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Tue, 24 Dec 2019 15:18:46 -0500 Subject: [PATCH] Fix parameter expression get binding (#10912) * fix: parameter expression closure should not have access to the declaration inside function body * fix: renameVisitor should skip when a pattern is a scope * address review comments --- .../src/path/lib/virtual-types.js | 3 ++- packages/babel-traverse/src/scope/index.js | 19 ++++++++++++++++++- .../rename/parameter-default-1/input.js | 7 +++++++ .../rename/parameter-default-1/options.json | 3 +++ .../rename/parameter-default-1/output.js | 6 ++++++ .../rename/parameter-default-1/plugin.js | 9 +++++++++ .../rename/parameter-default-10/input.js | 5 +++++ .../rename/parameter-default-10/options.json | 3 +++ .../rename/parameter-default-10/output.js | 11 +++++++++++ .../rename/parameter-default-10/plugin.js | 9 +++++++++ .../rename/parameter-default-2/input.js | 5 +++++ .../rename/parameter-default-2/options.json | 3 +++ .../rename/parameter-default-2/output.js | 5 +++++ .../rename/parameter-default-2/plugin.js | 9 +++++++++ .../rename/parameter-default-3/input.js | 6 ++++++ .../rename/parameter-default-3/options.json | 3 +++ .../rename/parameter-default-3/output.js | 6 ++++++ .../rename/parameter-default-3/plugin.js | 9 +++++++++ .../rename/parameter-default-4/input.js | 8 ++++++++ .../rename/parameter-default-4/options.json | 3 +++ .../rename/parameter-default-4/output.js | 8 ++++++++ .../rename/parameter-default-4/plugin.js | 9 +++++++++ .../rename/parameter-default-5/input.js | 8 ++++++++ .../rename/parameter-default-5/options.json | 3 +++ .../rename/parameter-default-5/output.js | 8 ++++++++ .../rename/parameter-default-5/plugin.js | 9 +++++++++ .../rename/parameter-default-6/input.js | 5 +++++ .../rename/parameter-default-6/options.json | 3 +++ .../rename/parameter-default-6/output.js | 5 +++++ .../rename/parameter-default-6/plugin.js | 9 +++++++++ .../rename/parameter-default-7/input.js | 5 +++++ .../rename/parameter-default-7/options.json | 3 +++ .../rename/parameter-default-7/output.js | 5 +++++ .../rename/parameter-default-7/plugin.js | 9 +++++++++ .../rename/parameter-default-8/input.js | 5 +++++ .../rename/parameter-default-8/options.json | 3 +++ .../rename/parameter-default-8/output.js | 5 +++++ .../rename/parameter-default-8/plugin.js | 9 +++++++++ .../rename/parameter-default-9/input.js | 5 +++++ .../rename/parameter-default-9/options.json | 3 +++ .../rename/parameter-default-9/output.js | 5 +++++ .../rename/parameter-default-9/plugin.js | 9 +++++++++ packages/babel-traverse/test/scope.js | 19 +++++++++++++++++++ .../babel-types/src/validators/isScope.js | 7 +++++++ 44 files changed, 289 insertions(+), 2 deletions(-) create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-1/input.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-1/options.json create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-1/output.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-1/plugin.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-10/input.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-10/options.json create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-10/output.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-10/plugin.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-2/input.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-2/options.json create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-2/output.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-2/plugin.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-3/input.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-3/options.json create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-3/output.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-3/plugin.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-4/input.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-4/options.json create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-4/output.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-4/plugin.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-5/input.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-5/options.json create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-5/output.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-5/plugin.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-6/input.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-6/options.json create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-6/output.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-6/plugin.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-7/input.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-7/options.json create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-7/output.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-7/plugin.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-8/input.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-8/options.json create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-8/output.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-8/plugin.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-9/input.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-9/options.json create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-9/output.js create mode 100644 packages/babel-traverse/test/fixtures/rename/parameter-default-9/plugin.js diff --git a/packages/babel-traverse/src/path/lib/virtual-types.js b/packages/babel-traverse/src/path/lib/virtual-types.js index 97cec0e3af..d7072d6f6e 100644 --- a/packages/babel-traverse/src/path/lib/virtual-types.js +++ b/packages/babel-traverse/src/path/lib/virtual-types.js @@ -64,7 +64,8 @@ export const Expression = { }; export const Scope = { - types: ["Scopable"], + // When pattern is inside the function params, it is a scope + types: ["Scopable", "Pattern"], checkPath(path) { return t.isScope(path.node, path.parent); }, diff --git a/packages/babel-traverse/src/scope/index.js b/packages/babel-traverse/src/scope/index.js index b26b59ce18..9f9d786673 100644 --- a/packages/babel-traverse/src/scope/index.js +++ b/packages/babel-traverse/src/scope/index.js @@ -897,10 +897,27 @@ export default class Scope { getBinding(name: string) { let scope = this; + let previousPath; do { const binding = scope.getOwnBinding(name); - if (binding) return binding; + if (binding) { + // Check if a pattern is a part of parameter expressions. + // 9.2.10.28: The closure created by this expression should not have visibility of + // declarations in the function body. If the binding is not a `param`-kind, + // then it must be defined inside the function body, thus it should be skipped + if ( + previousPath && + previousPath.isPattern() && + previousPath.parentPath.isFunction() && + binding.kind !== "param" + ) { + // do nothing + } else { + return binding; + } + } + previousPath = scope.path; } while ((scope = scope.parent)); } diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-1/input.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-1/input.js new file mode 100644 index 0000000000..c40f808feb --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-1/input.js @@ -0,0 +1,7 @@ +let a = "outside"; + +function f(g = () => a) { + let a = "inside"; + return g(); +} + diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-1/options.json b/packages/babel-traverse/test/fixtures/rename/parameter-default-1/options.json new file mode 100644 index 0000000000..14af0e5fea --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-1/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["./plugin"] +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-1/output.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-1/output.js new file mode 100644 index 0000000000..32d258e83c --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-1/output.js @@ -0,0 +1,6 @@ +let a = "outside"; + +function f(g = () => a) { + let z = "inside"; + return g(); +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-1/plugin.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-1/plugin.js new file mode 100644 index 0000000000..8304815881 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-1/plugin.js @@ -0,0 +1,9 @@ +module.exports = function() { + return { + visitor: { + FunctionDeclaration(path) { + path.scope.rename("a", "z"); + } + } + }; +}; diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-10/input.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-10/input.js new file mode 100644 index 0000000000..60898eb184 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-10/input.js @@ -0,0 +1,5 @@ +let a = "outside"; + +function r({ a: b }, { [a]: { c } = a }) { + g(a); +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-10/options.json b/packages/babel-traverse/test/fixtures/rename/parameter-default-10/options.json new file mode 100644 index 0000000000..14af0e5fea --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-10/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["./plugin"] +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-10/output.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-10/output.js new file mode 100644 index 0000000000..91af3aed83 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-10/output.js @@ -0,0 +1,11 @@ +let z = "outside"; + +function r({ + a: b +}, { + [z]: { + c + } = z +}) { + g(z); +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-10/plugin.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-10/plugin.js new file mode 100644 index 0000000000..8304815881 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-10/plugin.js @@ -0,0 +1,9 @@ +module.exports = function() { + return { + visitor: { + FunctionDeclaration(path) { + path.scope.rename("a", "z"); + } + } + }; +}; diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-2/input.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-2/input.js new file mode 100644 index 0000000000..f80651d806 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-2/input.js @@ -0,0 +1,5 @@ +let a = "outside"; + +function h(a, g = () => a) { + return g(); +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-2/options.json b/packages/babel-traverse/test/fixtures/rename/parameter-default-2/options.json new file mode 100644 index 0000000000..14af0e5fea --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-2/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["./plugin"] +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-2/output.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-2/output.js new file mode 100644 index 0000000000..dd64606a5b --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-2/output.js @@ -0,0 +1,5 @@ +let a = "outside"; + +function h(z, g = () => z) { + return g(); +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-2/plugin.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-2/plugin.js new file mode 100644 index 0000000000..8304815881 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-2/plugin.js @@ -0,0 +1,9 @@ +module.exports = function() { + return { + visitor: { + FunctionDeclaration(path) { + path.scope.rename("a", "z"); + } + } + }; +}; diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-3/input.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-3/input.js new file mode 100644 index 0000000000..a6a4bdd4c3 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-3/input.js @@ -0,0 +1,6 @@ +let a = "outside"; + +function j(g = a) { + let a = "inside"; + return g; +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-3/options.json b/packages/babel-traverse/test/fixtures/rename/parameter-default-3/options.json new file mode 100644 index 0000000000..14af0e5fea --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-3/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["./plugin"] +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-3/output.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-3/output.js new file mode 100644 index 0000000000..a5cb0dab0c --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-3/output.js @@ -0,0 +1,6 @@ +let a = "outside"; + +function j(g = a) { + let z = "inside"; + return g; +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-3/plugin.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-3/plugin.js new file mode 100644 index 0000000000..8304815881 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-3/plugin.js @@ -0,0 +1,9 @@ +module.exports = function() { + return { + visitor: { + FunctionDeclaration(path) { + path.scope.rename("a", "z"); + } + } + }; +}; diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-4/input.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-4/input.js new file mode 100644 index 0000000000..0f7ddb008e --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-4/input.js @@ -0,0 +1,8 @@ +let a = "outside"; + +function k([{ + g = a +}]) { + let a = "inside"; + return g; +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-4/options.json b/packages/babel-traverse/test/fixtures/rename/parameter-default-4/options.json new file mode 100644 index 0000000000..14af0e5fea --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-4/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["./plugin"] +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-4/output.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-4/output.js new file mode 100644 index 0000000000..65ab1aa82f --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-4/output.js @@ -0,0 +1,8 @@ +let a = "outside"; + +function k([{ + g = a +}]) { + let z = "inside"; + return g; +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-4/plugin.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-4/plugin.js new file mode 100644 index 0000000000..8304815881 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-4/plugin.js @@ -0,0 +1,9 @@ +module.exports = function() { + return { + visitor: { + FunctionDeclaration(path) { + path.scope.rename("a", "z"); + } + } + }; +}; diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-5/input.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-5/input.js new file mode 100644 index 0000000000..9586b93c5f --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-5/input.js @@ -0,0 +1,8 @@ +let a = "outside"; + +function f([{ + [a]: g +}]) { + let a = "inside"; + return g; +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-5/options.json b/packages/babel-traverse/test/fixtures/rename/parameter-default-5/options.json new file mode 100644 index 0000000000..14af0e5fea --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-5/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["./plugin"] +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-5/output.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-5/output.js new file mode 100644 index 0000000000..f703a83d60 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-5/output.js @@ -0,0 +1,8 @@ +let a = "outside"; + +function f([{ + [a]: g +}]) { + let z = "inside"; + return g; +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-5/plugin.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-5/plugin.js new file mode 100644 index 0000000000..8304815881 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-5/plugin.js @@ -0,0 +1,9 @@ +module.exports = function() { + return { + visitor: { + FunctionDeclaration(path) { + path.scope.rename("a", "z"); + } + } + }; +}; diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-6/input.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-6/input.js new file mode 100644 index 0000000000..d33571e9a0 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-6/input.js @@ -0,0 +1,5 @@ +let a = "outside"; + +function n(g = (a = a) => {}) { + let a = "inside"; +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-6/options.json b/packages/babel-traverse/test/fixtures/rename/parameter-default-6/options.json new file mode 100644 index 0000000000..14af0e5fea --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-6/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["./plugin"] +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-6/output.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-6/output.js new file mode 100644 index 0000000000..917b0bb1c7 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-6/output.js @@ -0,0 +1,5 @@ +let a = "outside"; + +function n(g = (a = a) => {}) { + let z = "inside"; +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-6/plugin.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-6/plugin.js new file mode 100644 index 0000000000..8304815881 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-6/plugin.js @@ -0,0 +1,9 @@ +module.exports = function() { + return { + visitor: { + FunctionDeclaration(path) { + path.scope.rename("a", "z"); + } + } + }; +}; diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-7/input.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-7/input.js new file mode 100644 index 0000000000..273324bf46 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-7/input.js @@ -0,0 +1,5 @@ +let a = "outside"; + +function n(a, g = (a = a) => {}) { + a = "inside"; +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-7/options.json b/packages/babel-traverse/test/fixtures/rename/parameter-default-7/options.json new file mode 100644 index 0000000000..14af0e5fea --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-7/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["./plugin"] +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-7/output.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-7/output.js new file mode 100644 index 0000000000..5d6b373983 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-7/output.js @@ -0,0 +1,5 @@ +let a = "outside"; + +function n(z, g = (a = a) => {}) { + z = "inside"; +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-7/plugin.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-7/plugin.js new file mode 100644 index 0000000000..8304815881 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-7/plugin.js @@ -0,0 +1,9 @@ +module.exports = function() { + return { + visitor: { + FunctionDeclaration(path) { + path.scope.rename("a", "z"); + } + } + }; +}; diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-8/input.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-8/input.js new file mode 100644 index 0000000000..3349776fcb --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-8/input.js @@ -0,0 +1,5 @@ +let a = "outside"; + +function q(a, g = (b = a) => b) { + g(a); +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-8/options.json b/packages/babel-traverse/test/fixtures/rename/parameter-default-8/options.json new file mode 100644 index 0000000000..14af0e5fea --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-8/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["./plugin"] +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-8/output.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-8/output.js new file mode 100644 index 0000000000..3894a8a761 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-8/output.js @@ -0,0 +1,5 @@ +let a = "outside"; + +function q(z, g = (b = z) => b) { + g(z); +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-8/plugin.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-8/plugin.js new file mode 100644 index 0000000000..8304815881 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-8/plugin.js @@ -0,0 +1,9 @@ +module.exports = function() { + return { + visitor: { + FunctionDeclaration(path) { + path.scope.rename("a", "z"); + } + } + }; +}; diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-9/input.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-9/input.js new file mode 100644 index 0000000000..4a57005f1d --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-9/input.js @@ -0,0 +1,5 @@ +let a = "outside"; + +function r(a, g = (a, b = a) => a) { + g(a); +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-9/options.json b/packages/babel-traverse/test/fixtures/rename/parameter-default-9/options.json new file mode 100644 index 0000000000..14af0e5fea --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-9/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["./plugin"] +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-9/output.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-9/output.js new file mode 100644 index 0000000000..886bfcd113 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-9/output.js @@ -0,0 +1,5 @@ +let a = "outside"; + +function r(z, g = (a, b = a) => a) { + g(z); +} diff --git a/packages/babel-traverse/test/fixtures/rename/parameter-default-9/plugin.js b/packages/babel-traverse/test/fixtures/rename/parameter-default-9/plugin.js new file mode 100644 index 0000000000..8304815881 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/rename/parameter-default-9/plugin.js @@ -0,0 +1,9 @@ +module.exports = function() { + return { + visitor: { + FunctionDeclaration(path) { + path.scope.rename("a", "z"); + } + } + }; +}; diff --git a/packages/babel-traverse/test/scope.js b/packages/babel-traverse/test/scope.js index aa7c0dba27..b796dbf682 100644 --- a/packages/babel-traverse/test/scope.js +++ b/packages/babel-traverse/test/scope.js @@ -73,6 +73,25 @@ describe("scope", () => { ).toBe("Identifier"); }); + describe("function parameter expression", function() { + it("should not have visibility of declarations inside function body", () => { + expect( + getPath( + `var a = "outside"; (function foo(b = a) { let a = "inside" })`, + ) + .get("body.1.expression.params.0") + .scope.getBinding("a").path.node.init.value, + ).toBe("outside"); + }); + it("should have visibility on parameter bindings", () => { + expect( + getPath(`var a = "outside"; (function foo(b = a, a = "inside") {})`) + .get("body.1.expression.params.0") + .scope.getBinding("a").path.node.right.value, + ).toBe("inside"); + }); + }); + it("variable declaration", function() { expect(getPath("var foo = null;").scope.getBinding("foo").path.type).toBe( "VariableDeclarator", diff --git a/packages/babel-types/src/validators/isScope.js b/packages/babel-types/src/validators/isScope.js index 51d6c91924..dfd2f5edd9 100644 --- a/packages/babel-types/src/validators/isScope.js +++ b/packages/babel-types/src/validators/isScope.js @@ -4,6 +4,7 @@ import { isCatchClause, isBlockStatement, isScopable, + isPattern, } from "./generated"; /** @@ -18,5 +19,11 @@ export default function isScope(node: Object, parent: Object): boolean { return false; } + // If a Pattern is an immediate descendent of a Function, it must be in the params. + // Hence we skipped the parentKey === "params" check + if (isPattern(node) && isFunction(parent)) { + return true; + } + return isScopable(node); }