Skip to content

Commit

Permalink
fix: skip method scope for decorator expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung committed Mar 22, 2022
1 parent a3a8e10 commit 5717af3
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 5 deletions.
9 changes: 7 additions & 2 deletions packages/babel-traverse/src/path/context.ts
Expand Up @@ -132,8 +132,13 @@ export function setScope(this: NodePath) {

let path = this.parentPath;

// Skip method scope if is computed method key
if (this.key === "key" && path.isMethod()) path = path.parentPath;
// Skip method scope if is computed method key or decorator expression
if (
(this.key === "key" || this.listKey === "decorators") &&
path.isMethod()
) {
path = path.parentPath;
}

let target;
while (path && !target) {
Expand Down
6 changes: 3 additions & 3 deletions packages/babel-traverse/src/scope/index.ts
Expand Up @@ -419,10 +419,10 @@ export default class Scope {
let parent,
path = this.path;
do {
// Skip method scope if coming from inside computed key
const isKey = path.key === "key";
// Skip method scope if coming from inside computed key or decorator expression
const shouldSkip = path.key === "key" || path.listKey === "decorators";
path = path.parentPath;
if (isKey && path.isMethod()) path = path.parentPath;
if (shouldSkip && path.isMethod()) path = path.parentPath;
if (path && path.isScope()) parent = path;
} while (path && !parent);

Expand Down
26 changes: 26 additions & 0 deletions packages/babel-traverse/test/scope.js
Expand Up @@ -256,6 +256,32 @@ describe("scope", () => {
});
});

describe("decorator", () => {
const parserOptions = {
plugins: [["decorators", { decoratorsBeforeExport: true }]],
};
it("should not have visibility of declarations inside method body", () => {
expect(
getPath(
`var a = "outside"; class foo { @(() => () => a) m() { let a = "inside"; } }`,
parserOptions,
)
.get("body.1.body.body.0.decorators.0.expression.body.body")
.scope.getBinding("a").path.node.init.value,
).toBe("outside");
});
it("should not have visibility on parameter bindings", () => {
expect(
getPath(
`var a = "outside"; class foo { @(() => () => a) m(a = "inside") {} }`,
parserOptions,
)
.get("body.1.body.body.0.decorators.0.expression.body.body")
.scope.getBinding("a").path.node.init.value,
).toBe("outside");
});
});

it("variable declaration", function () {
expect(getPath("var foo = null;").scope.getBinding("foo").path.type).toBe(
"VariableDeclarator",
Expand Down

0 comments on commit 5717af3

Please sign in to comment.