Skip to content

Commit 1df040a

Browse files
committed
add ScopeManager#addGlobals
1 parent 0deff30 commit 1df040a

File tree

3 files changed

+135
-0
lines changed

3 files changed

+135
-0
lines changed

packages/eslint-scope/lib/scope-manager.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,18 @@ class ScopeManager {
182182
return null;
183183
}
184184

185+
/**
186+
* Add global variables and resolve their references.
187+
* @function ScopeManager#addGlobals
188+
* @param {string[]} names Names of global variables to add.
189+
* @returns {void}
190+
*/
191+
addGlobals(names) {
192+
const globalScope = this.scopes[0];
193+
194+
globalScope.__addVariables(names);
195+
}
196+
185197
attach() { } // eslint-disable-line class-methods-use-this -- Desired as instance method
186198

187199
detach() { } // eslint-disable-line class-methods-use-this -- Desired as instance method

packages/eslint-scope/lib/scope.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,51 @@ class GlobalScope extends Scope {
538538
);
539539
}
540540
}
541+
542+
__addVariables(names) {
543+
for (const name of names) {
544+
this.__defineGeneric(
545+
name,
546+
this.set,
547+
this.variables,
548+
null,
549+
null
550+
);
551+
}
552+
553+
const namesSet = new Set(names);
554+
555+
this.through = this.through.filter(reference => {
556+
const name = reference.identifier.name;
557+
558+
if (namesSet.has(name)) {
559+
const variable = this.set.get(name);
560+
561+
reference.resolved = variable;
562+
variable.references.push(reference);
563+
564+
return false;
565+
}
566+
567+
return true;
568+
});
569+
570+
this.implicit.variables = this.implicit.variables.filter(variable => {
571+
const name = variable.name;
572+
573+
if (namesSet.has(name)) {
574+
this.implicit.set.delete(name);
575+
576+
return false;
577+
}
578+
579+
return true;
580+
});
581+
582+
this.implicit.left = this.implicit.left.filter(
583+
reference => !namesSet.has(reference.identifier.name)
584+
);
585+
}
541586
}
542587

543588
/**
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/**
2+
* @fileoverview Tests for ScopeManager#addGlobals method.
3+
* @author Milos Djermanovic
4+
*/
5+
6+
import { expect } from "chai";
7+
import espree from "./util/espree.js";
8+
import { analyze } from "../lib/index.js";
9+
10+
describe("ScopeManager#addGlobals", () => {
11+
it("adds variables to the global scope and closes references from the global scope", () => {
12+
const ast = espree(`
13+
foo = bar + bar;
14+
`);
15+
16+
const scopeManager = analyze(ast);
17+
18+
expect(scopeManager.scopes).to.have.length(1);
19+
20+
const globalScope = scopeManager.scopes[0];
21+
22+
expect(globalScope.type).to.be.equal("global");
23+
24+
expect(globalScope.variables).to.have.length(0);
25+
expect(globalScope.references).to.have.length(3);
26+
expect(globalScope.references[0].identifier.name).to.be.equal("foo");
27+
expect(globalScope.references[0].resolved).to.be.null;
28+
expect(globalScope.references[1].identifier.name).to.be.equal("bar");
29+
expect(globalScope.references[1].resolved).to.be.null;
30+
expect(globalScope.references[2].identifier.name).to.be.equal("bar");
31+
expect(globalScope.references[2].resolved).to.be.null;
32+
expect(globalScope.references[1]).to.not.be.equal(globalScope.references[2]);
33+
expect(globalScope.through).to.have.length(3);
34+
expect(globalScope.through[0]).to.be.equal(globalScope.references[0]);
35+
expect(globalScope.through[1]).to.be.equal(globalScope.references[1]);
36+
expect(globalScope.through[2]).to.be.equal(globalScope.references[2]);
37+
expect(globalScope.implicit.variables).to.have.length(1);
38+
expect(globalScope.implicit.variables[0].name).to.be.equal("foo");
39+
expect(globalScope.implicit.set.size).to.be.equal(1);
40+
expect(globalScope.implicit.set.get("foo")).to.be.equal(globalScope.implicit.variables[0]);
41+
expect(globalScope.implicit.left).to.have.length(3);
42+
expect(globalScope.implicit.left[0]).to.be.equal(globalScope.references[0]);
43+
expect(globalScope.implicit.left[1]).to.be.equal(globalScope.references[1]);
44+
expect(globalScope.implicit.left[2]).to.be.equal(globalScope.references[2]);
45+
46+
scopeManager.addGlobals(["foo", "bar"]);
47+
48+
expect(globalScope.variables).to.have.length(2);
49+
expect(globalScope.variables[0].name).to.be.equal("foo");
50+
expect(globalScope.variables[0].scope).to.be.equal(globalScope);
51+
expect(globalScope.variables[0].defs).to.have.length(0);
52+
expect(globalScope.variables[0].identifiers).to.have.length(0);
53+
expect(globalScope.variables[1].name).to.be.equal("bar");
54+
expect(globalScope.variables[1].scope).to.be.equal(globalScope);
55+
expect(globalScope.variables[1].defs).to.have.length(0);
56+
expect(globalScope.variables[1].identifiers).to.have.length(0);
57+
expect(globalScope.set.size).to.be.equal(2);
58+
expect(globalScope.set.get("foo")).to.be.equal(globalScope.variables[0]);
59+
expect(globalScope.set.get("bar")).to.be.equal(globalScope.variables[1]);
60+
expect(globalScope.references).to.have.length(3);
61+
expect(globalScope.references[0].identifier.name).to.be.equal("foo");
62+
expect(globalScope.references[0].resolved).to.be.equal(globalScope.variables[0]);
63+
expect(globalScope.variables[0].references).to.have.length(1);
64+
expect(globalScope.variables[0].references[0]).to.be.equal(globalScope.references[0]);
65+
expect(globalScope.references[1].identifier.name).to.be.equal("bar");
66+
expect(globalScope.references[1].resolved).to.be.equal(globalScope.variables[1]);
67+
expect(globalScope.references[2].identifier.name).to.be.equal("bar");
68+
expect(globalScope.references[2].resolved).to.be.equal(globalScope.variables[1]);
69+
expect(globalScope.variables[1].references).to.have.length(2);
70+
expect(globalScope.variables[1].references[0]).to.be.equal(globalScope.references[1]);
71+
expect(globalScope.variables[1].references[1]).to.be.equal(globalScope.references[2]);
72+
expect(globalScope.through).to.have.length(0);
73+
expect(globalScope.implicit.variables).to.have.length(0);
74+
expect(globalScope.implicit.set.size).to.be.equal(0);
75+
expect(globalScope.implicit.left).to.have.length(0);
76+
});
77+
78+
});

0 commit comments

Comments
 (0)