diff --git a/lib/linter.js b/lib/linter.js index acdbb2d64bc..eedcace78a0 100755 --- a/lib/linter.js +++ b/lib/linter.js @@ -708,9 +708,6 @@ const BASE_TRAVERSAL_CONTEXT = Object.freeze( module.exports = class Linter { constructor() { - this.currentConfig = null; - this.scopeManager = null; - this.traverser = null; this.sourceCode = null; this.version = pkg.version; @@ -723,9 +720,6 @@ module.exports = class Linter { * @returns {void} */ reset() { - this.currentConfig = null; - this.scopeManager = null; - this.traverser = null; this.sourceCode = null; } @@ -840,6 +834,17 @@ module.exports = class Linter { } const emitter = new EventEmitter().setMaxListeners(Infinity); + const traverser = new Traverser(); + const ecmaFeatures = config.parserOptions.ecmaFeatures || {}; + const ecmaVersion = config.parserOptions.ecmaVersion || 5; + const scopeManager = eslintScope.analyze(sourceCode.ast, { + ignoreEval: true, + nodejsScope: ecmaFeatures.globalReturn, + impliedStrict: ecmaFeatures.impliedStrict, + ecmaVersion, + sourceType: config.parserOptions.sourceType || "script", + fallback: Traverser.getKeys + }); /* * Create a frozen object with the ruleContext properties and methods that are shared by all rules. @@ -850,12 +855,12 @@ module.exports = class Linter { Object.assign( Object.create(BASE_TRAVERSAL_CONTEXT), { - getAncestors: () => this.traverser.parents(), - getDeclaredVariables: node => this.scopeManager && this.scopeManager.getDeclaredVariables(node) || [], + getAncestors: () => traverser.parents(), + getDeclaredVariables: scopeManager.getDeclaredVariables.bind(scopeManager), getFilename: () => filename, - getScope: () => getScope(this.scopeManager, this.traverser.current(), this.currentConfig.parserOptions.ecmaVersion), + getScope: () => getScope(scopeManager, traverser.current(), config.parserOptions.ecmaVersion), getSourceCode: () => sourceCode, - markVariableAsUsed: name => markVariableAsUsed(this.scopeManager, this.traverser.current(), this.currentConfig.parserOptions, name), + markVariableAsUsed: name => markVariableAsUsed(scopeManager, traverser.current(), config.parserOptions, name), parserOptions: config.parserOptions, parserPath: config.parser, parserServices, @@ -955,25 +960,8 @@ module.exports = class Linter { } }); - // save config so rules can access as necessary - this.currentConfig = config; - this.traverser = new Traverser(); - - const ecmaFeatures = this.currentConfig.parserOptions.ecmaFeatures || {}; - const ecmaVersion = this.currentConfig.parserOptions.ecmaVersion || 5; - - // gather scope data that may be needed by the rules - this.scopeManager = eslintScope.analyze(sourceCode.ast, { - ignoreEval: true, - nodejsScope: ecmaFeatures.globalReturn, - impliedStrict: ecmaFeatures.impliedStrict, - ecmaVersion, - sourceType: this.currentConfig.parserOptions.sourceType || "script", - fallback: Traverser.getKeys - }); - // augment global scope with declared global variables - addDeclaredGlobals(sourceCode.ast, this.scopeManager.scopes[0], this.currentConfig, this.environments); + addDeclaredGlobals(sourceCode.ast, scopeManager.scopes[0], config, this.environments); const eventGenerator = new CodePathAnalyzer(new NodeEventGenerator(emitter)); @@ -983,7 +971,7 @@ module.exports = class Linter { * automatically be informed that this type of node has been found * and react accordingly. */ - this.traverser.traverse(sourceCode.ast, { + traverser.traverse(sourceCode.ast, { enter(node, parent) { node.parent = parent; eventGenerator.enterNode(node);