Skip to content

Commit

Permalink
fix: mark Pattern in CatchClause as scope (#12119)
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung committed Sep 29, 2020
1 parent afc0358 commit e0b2bfb
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 14 deletions.
13 changes: 6 additions & 7 deletions packages/babel-traverse/src/scope/index.js
Expand Up @@ -996,15 +996,14 @@ export default class Scope {
const binding = scope.getOwnBinding(name);
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
// Note: for performance reason we skip checking previousPath.parentPath.isFunction()
// because `scope.path` is validated as scope in packages/babel-types/src/validators/isScope.js
// That is, if a scope path is pattern, its parent must be Function/CatchClause

// Spec 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"
) {
if (previousPath?.isPattern() && binding.kind !== "param") {
// do nothing
} else {
return binding;
Expand Down
@@ -0,0 +1 @@
try {} catch ({ a }) {}
@@ -0,0 +1,3 @@
{
"plugins": ["./plugin"]
}
@@ -0,0 +1,3 @@
try {} catch ({
a: z
}) {}
@@ -0,0 +1,9 @@
module.exports = function () {
return {
visitor: {
CatchClause(path) {
path.scope.rename("a", "z");
},
},
};
};
@@ -0,0 +1,5 @@
let [a] = ["outside"];

try {} catch ({ g = () => a }) {
let [a] = ["inside"];
}
@@ -0,0 +1,3 @@
{
"plugins": ["./plugin"]
}
@@ -0,0 +1,7 @@
let [a] = ["outside"];

try {} catch ({
g = () => a
}) {
let [z] = ["inside"];
}
@@ -0,0 +1,9 @@
module.exports = function () {
return {
visitor: {
CatchClause(path) {
path.scope.rename("a", "z");
},
},
};
};
12 changes: 5 additions & 7 deletions packages/babel-types/src/validators/isScope.js
Expand Up @@ -11,17 +11,15 @@ import {
* Check if the input `node` is a scope.
*/
export default function isScope(node: Object, parent: Object): boolean {
if (isBlockStatement(node) && isFunction(parent, { body: node })) {
return false;
}

if (isBlockStatement(node) && isCatchClause(parent, { body: node })) {
// If a BlockStatement is an immediate descendent of a Function/CatchClause, it must be in the body.
// Hence we skipped the parentKey === "params" check
if (isBlockStatement(node) && (isFunction(parent) || isCatchClause(parent))) {
return false;
}

// If a Pattern is an immediate descendent of a Function, it must be in the params.
// If a Pattern is an immediate descendent of a Function/CatchClause, it must be in the params.
// Hence we skipped the parentKey === "params" check
if (isPattern(node) && isFunction(parent)) {
if (isPattern(node) && (isFunction(parent) || isCatchClause(parent))) {
return true;
}

Expand Down

0 comments on commit e0b2bfb

Please sign in to comment.