Skip to content

Commit

Permalink
fix: do not skip pattern binding referencing id
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung committed Oct 13, 2021
1 parent 4130dc5 commit 947c7e1
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 13 deletions.
9 changes: 7 additions & 2 deletions packages/babel-traverse/src/scope/index.ts
Expand Up @@ -1125,9 +1125,14 @@ export default class Scope {
// 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,
// declarations in the function body. If the binding is not a `param`-kind (as function parameters)
// or `local`-kind (as id in function expression),
// then it must be defined inside the function body, thus it should be skipped
if (previousPath?.isPattern() && binding.kind !== "param") {
if (
previousPath?.isPattern() &&
binding.kind !== "param" &&
binding.kind !== "local"
) {
// do nothing
} else {
return binding;
Expand Down
59 changes: 48 additions & 11 deletions packages/babel-traverse/test/scope.js
Expand Up @@ -432,17 +432,54 @@ describe("scope", () => {
).toBe("_foo3");
});

it("reference paths", function () {
const path = getIdentifierPath("function square(n) { return n * n}");
const referencePaths = path.context.scope.bindings.n.referencePaths;
expect(referencePaths).toHaveLength(2);
expect(referencePaths[0].node.loc.start).toEqual({
line: 1,
column: 28,
});
expect(referencePaths[1].node.loc.start).toEqual({
line: 1,
column: 32,
describe("reference paths", () => {
it("param referenced in function body", function () {
const path = getIdentifierPath("function square(n) { return n * n}");
const referencePaths = path.context.scope.bindings.n.referencePaths;
expect(referencePaths).toHaveLength(2);
expect(referencePaths[0].node.loc.start).toEqual({
line: 1,
column: 28,
});
expect(referencePaths[1].node.loc.start).toEqual({
line: 1,
column: 32,
});
});
it("id referenced in function body", () => {
const path = getIdentifierPath("(function n(m) { return n })");
const { referencePaths, identifier } = path.scope.getOwnBinding("n");
expect(identifier.start).toMatchInlineSnapshot(`10`);
expect(referencePaths).toHaveLength(1);
expect(referencePaths[0].node.start).toMatchInlineSnapshot(`24`);
});
it("id referenced in param initializer - function expression", () => {
const path = getIdentifierPath("(function n(m = n) {})");
const { referencePaths, identifier } = path.scope.getOwnBinding("n");
expect(identifier.start).toMatchInlineSnapshot(`10`);
expect(referencePaths).toHaveLength(1);
expect(referencePaths[0].node.start).toMatchInlineSnapshot(`16`);
});
it("id referenced in param initializer - function declaration", () => {
const path = getIdentifierPath("function n(m = n) {}");
const { referencePaths, identifier } = path.scope.getBinding("n");
expect(identifier.start).toMatchInlineSnapshot(`9`);
expect(referencePaths).toHaveLength(1);
expect(referencePaths[0].node.start).toMatchInlineSnapshot(`15`);
});
it("param referenced in function body with id collision", () => {
const path = getIdentifierPath("(function n(n) { return n })");
const { referencePaths, identifier } = path.scope.getOwnBinding("n");
expect(identifier.start).toMatchInlineSnapshot(`12`);
expect(referencePaths).toHaveLength(1);
expect(referencePaths[0].node.start).toMatchInlineSnapshot(`24`);
});
it("param referenced in param initializer with id collision", () => {
const path = getIdentifierPath("(function n(n, m = n) {})");
const { referencePaths, identifier } = path.scope.getOwnBinding("n");
expect(identifier.start).toMatchInlineSnapshot(`12`);
expect(referencePaths).toHaveLength(1);
expect(referencePaths[0].node.start).toMatchInlineSnapshot(`19`);
});
});

Expand Down

0 comments on commit 947c7e1

Please sign in to comment.