From 1aa7901c445b93ab53d328c5fb9dfb1ad2c13662 Mon Sep 17 00:00:00 2001 From: Milos Djermanovic Date: Sat, 6 Jul 2024 15:13:48 +0200 Subject: [PATCH 1/2] fix: `Definition#name` in catch patterns should be `Identifier` node --- lib/referencer.js | 2 +- tests/catch-scope.js | 75 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/lib/referencer.js b/lib/referencer.js index 07938c1..2f1295f 100644 --- a/lib/referencer.js +++ b/lib/referencer.js @@ -395,7 +395,7 @@ class Referencer extends esrecurse.Visitor { this.currentScope().__define(pattern, new Definition( Variable.CatchClause, - node.param, + pattern, node, null, null, diff --git a/tests/catch-scope.js b/tests/catch-scope.js index 3ef11e8..f36cb6d 100644 --- a/tests/catch-scope.js +++ b/tests/catch-scope.js @@ -56,9 +56,84 @@ describe("catch", () => { expect(scope.type).to.be.equal("catch"); expect(scope.variables).to.have.length(1); expect(scope.variables[0].name).to.be.equal("e"); + expect(scope.variables[0].defs).to.have.length(1); + expect(scope.variables[0].defs[0].type).to.be.equal("CatchClause"); + expect(scope.variables[0].defs[0].name.type).to.be.equal("Identifier"); + expect(scope.variables[0].defs[0].name.name).to.be.equal("e"); + expect(scope.variables[0].defs[0].node.type).to.be.equal("CatchClause"); + expect(scope.variables[0].defs[0].parent).to.be.equal(null); expect(scope.isArgumentsMaterialized()).to.be.true; expect(scope.references).to.have.length(0); }); + + it("param can be a pattern", () => { + const ast = espree(` + (function () { + const default_id = 0; + try { + } catch ({ message, id = default_id, args: [arg1, arg2] }) { + } + }()); + `); + + const scopeManager = analyze(ast); + + expect(scopeManager.scopes).to.have.length(3); + + const globalScope = scopeManager.scopes[0]; + + expect(globalScope.type).to.be.equal("global"); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + + const functionScope = scopeManager.scopes[1]; + + expect(functionScope.type).to.be.equal("function"); + expect(functionScope.variables).to.have.length(2); + expect(functionScope.variables[0].name).to.be.equal("arguments"); + expect(functionScope.variables[1].name).to.be.equal("default_id"); + expect(functionScope.references).to.have.length(1); + expect(functionScope.references[0].from).to.be.equal(functionScope); + expect(functionScope.references[0].resolved).to.be.equal(functionScope.variables[1]); + + const catchScope = scopeManager.scopes[2]; + + expect(catchScope.type).to.be.equal("catch"); + expect(catchScope.variables).to.have.length(4); + expect(catchScope.variables[0].name).to.be.equal("message"); + expect(catchScope.variables[0].defs).to.have.length(1); + expect(catchScope.variables[0].defs[0].type).to.be.equal("CatchClause"); + expect(catchScope.variables[0].defs[0].name.type).to.be.equal("Identifier"); + expect(catchScope.variables[0].defs[0].name.name).to.be.equal("message"); + expect(catchScope.variables[0].defs[0].node.type).to.be.equal("CatchClause"); + expect(catchScope.variables[0].defs[0].parent).to.be.equal(null); + expect(catchScope.variables[1].name).to.be.equal("id"); + expect(catchScope.variables[1].defs).to.have.length(1); + expect(catchScope.variables[1].defs[0].type).to.be.equal("CatchClause"); + expect(catchScope.variables[1].defs[0].name.type).to.be.equal("Identifier"); + expect(catchScope.variables[1].defs[0].name.name).to.be.equal("id"); + expect(catchScope.variables[1].defs[0].node.type).to.be.equal("CatchClause"); + expect(catchScope.variables[1].defs[0].parent).to.be.equal(null); + expect(catchScope.variables[2].name).to.be.equal("arg1"); + expect(catchScope.variables[2].defs).to.have.length(1); + expect(catchScope.variables[2].defs[0].type).to.be.equal("CatchClause"); + expect(catchScope.variables[2].defs[0].name.type).to.be.equal("Identifier"); + expect(catchScope.variables[2].defs[0].name.name).to.be.equal("arg1"); + expect(catchScope.variables[2].defs[0].node.type).to.be.equal("CatchClause"); + expect(catchScope.variables[2].defs[0].parent).to.be.equal(null); + expect(catchScope.variables[3].name).to.be.equal("arg2"); + expect(catchScope.variables[3].defs).to.have.length(1); + expect(catchScope.variables[3].defs[0].type).to.be.equal("CatchClause"); + expect(catchScope.variables[3].defs[0].name.type).to.be.equal("Identifier"); + expect(catchScope.variables[3].defs[0].name.name).to.be.equal("arg2"); + expect(catchScope.variables[3].defs[0].node.type).to.be.equal("CatchClause"); + expect(catchScope.variables[3].defs[0].parent).to.be.equal(null); + expect(catchScope.references).to.have.length(2); + expect(catchScope.references[0].from).to.be.equal(catchScope); + expect(catchScope.references[0].resolved).to.be.equal(catchScope.variables[1]); + expect(catchScope.references[1].from).to.be.equal(catchScope); + expect(catchScope.references[1].resolved).to.be.equal(functionScope.variables[1]); + }); }); // vim: set sw=4 ts=4 et tw=80 : From b1f4a4b3aed545526e5f815f8c2e7f318aee74e0 Mon Sep 17 00:00:00 2001 From: Milos Djermanovic Date: Sat, 6 Jul 2024 16:13:48 +0200 Subject: [PATCH 2/2] use `ecmaVersion:6` in the test --- tests/catch-scope.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tests/catch-scope.js b/tests/catch-scope.js index f36cb6d..d425468 100644 --- a/tests/catch-scope.js +++ b/tests/catch-scope.js @@ -76,9 +76,9 @@ describe("catch", () => { }()); `); - const scopeManager = analyze(ast); + const scopeManager = analyze(ast, { ecmaVersion: 6 }); - expect(scopeManager.scopes).to.have.length(3); + expect(scopeManager.scopes).to.have.length(5); const globalScope = scopeManager.scopes[0]; @@ -96,7 +96,13 @@ describe("catch", () => { expect(functionScope.references[0].from).to.be.equal(functionScope); expect(functionScope.references[0].resolved).to.be.equal(functionScope.variables[1]); - const catchScope = scopeManager.scopes[2]; + const tryBlockScope = scopeManager.scopes[2]; + + expect(tryBlockScope.type).to.be.equal("block"); + expect(tryBlockScope.variables).to.have.length(0); + expect(tryBlockScope.references).to.have.length(0); + + const catchScope = scopeManager.scopes[3]; expect(catchScope.type).to.be.equal("catch"); expect(catchScope.variables).to.have.length(4); @@ -133,6 +139,12 @@ describe("catch", () => { expect(catchScope.references[0].resolved).to.be.equal(catchScope.variables[1]); expect(catchScope.references[1].from).to.be.equal(catchScope); expect(catchScope.references[1].resolved).to.be.equal(functionScope.variables[1]); + + const catchBlockScope = scopeManager.scopes[4]; + + expect(catchBlockScope.type).to.be.equal("block"); + expect(catchBlockScope.variables).to.have.length(0); + expect(catchBlockScope.references).to.have.length(0); }); });