From 2a7a7a6b8691a9e496214745c3f51d5bb34f3ac5 Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Tue, 16 Nov 2021 09:31:37 -0800 Subject: [PATCH 1/2] feat: Add sourceType:commonjs support --- lib/scope-manager.js | 2 +- tests/nodejs-scope.js | 29 ++++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/scope-manager.js b/lib/scope-manager.js index c6058f7..e41d471 100644 --- a/lib/scope-manager.js +++ b/lib/scope-manager.js @@ -66,7 +66,7 @@ class ScopeManager { } __isNodejsScope() { - return this.__options.nodejsScope; + return this.__options.nodejsScope || this.__options.sourceType === "commonjs"; } isModule() { diff --git a/tests/nodejs-scope.js b/tests/nodejs-scope.js index c3a90ca..609ba00 100644 --- a/tests/nodejs-scope.js +++ b/tests/nodejs-scope.js @@ -28,7 +28,8 @@ import espree from "./util/espree.js"; import { analyze } from "../lib/index.js"; describe("nodejsScope option", () => { - it("creates a function scope following the global scope immediately", () => { + + it("creates a function scope following the global scope immediately when nodejscope: true", () => { const ast = espree(` "use strict"; var hello = 20; @@ -54,6 +55,32 @@ describe("nodejsScope option", () => { expect(scope.variables[1].name).to.be.equal("hello"); }); + it("creates a function scope following the global scope immediately when sourceType:commonjs", () => { + const ast = espree(` + "use strict"; + var hello = 20; + `); + + const scopeManager = analyze(ast, { ecmaVersion: 6, sourceType: "commonjs" }); + + expect(scopeManager.scopes).to.have.length(2); + + let scope = scopeManager.scopes[0]; + + expect(scope.type).to.be.equal("global"); + expect(scope.block.type).to.be.equal("Program"); + expect(scope.isStrict).to.be.false; + expect(scope.variables).to.have.length(0); + + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal("function"); + expect(scope.block.type).to.be.equal("Program"); + expect(scope.isStrict).to.be.true; + expect(scope.variables).to.have.length(2); + expect(scope.variables[0].name).to.be.equal("arguments"); + expect(scope.variables[1].name).to.be.equal("hello"); + }); + it("creates a function scope following the global scope immediately and creates module scope", () => { const ast = espree("import {x as v} from 'mod';"); From 58c50784d48d5c6747828bc57d738eba0eccf830 Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Fri, 19 Nov 2021 12:43:13 -0800 Subject: [PATCH 2/2] Update sourceType references --- lib/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/index.js b/lib/index.js index ac386ad..cd0678d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -66,7 +66,7 @@ function defaultOptions() { directive: false, nodejsScope: false, impliedStrict: false, - sourceType: "script", // one of ['script', 'module'] + sourceType: "script", // one of ['script', 'module', 'commonjs'] ecmaVersion: 5, childVisitorKeys: null, fallback: "iteration" @@ -122,7 +122,7 @@ function updateDeeply(target, override) { * a function scope immediately following the global scope. * @param {boolean} [providedOptions.impliedStrict=false] implied strict mode * (if ecmaVersion >= 5). - * @param {string} [providedOptions.sourceType='script'] the source type of the script. one of 'script' and 'module' + * @param {string} [providedOptions.sourceType='script'] the source type of the script. one of 'script', 'module', and 'commonjs' * @param {number} [providedOptions.ecmaVersion=5] which ECMAScript version is considered * @param {Object} [providedOptions.childVisitorKeys=null] Additional known visitor keys. See [esrecurse](https://github.com/estools/esrecurse)'s the `childVisitorKeys` option. * @param {string} [providedOptions.fallback='iteration'] A kind of the fallback in order to encounter with unknown node. See [esrecurse](https://github.com/estools/esrecurse)'s the `fallback` option.