Skip to content

Commit

Permalink
Chore: create report translators lazily (#9221)
Browse files Browse the repository at this point in the history
  • Loading branch information
not-an-aardvark committed Sep 5, 2017
1 parent 2eedc1f commit bf1e344
Showing 1 changed file with 46 additions and 32 deletions.
78 changes: 46 additions & 32 deletions lib/linter.js
Expand Up @@ -12,7 +12,6 @@
const EventEmitter = require("events").EventEmitter,
eslintScope = require("eslint-scope"),
levn = require("levn"),
lodash = require("lodash"),
blankScriptAST = require("../conf/blank-script.json"),
defaultConfig = require("../conf/default-config-options.js"),
replacements = require("../conf/replacements.json"),
Expand Down Expand Up @@ -870,10 +869,11 @@ class Linter {
}

const problems = [];
const sourceCode = this.sourceCode;

// parse global comments and modify config
if (allowInlineConfig !== false) {
const modifyConfigResult = modifyConfigsFromComments(filename, this.sourceCode.ast, config, this);
const modifyConfigResult = modifyConfigsFromComments(filename, sourceCode.ast, config, this);

config = modifyConfigResult.config;
modifyConfigResult.problems.forEach(problem => problems.push(problem));
Expand All @@ -894,7 +894,7 @@ class Linter {
getDeclaredVariables: this.getDeclaredVariables.bind(this),
getFilename: () => filename,
getScope: this.getScope.bind(this),
getSourceCode: () => this.sourceCode,
getSourceCode: () => sourceCode,
markVariableAsUsed: this.markVariableAsUsed.bind(this),
parserOptions: config.parserOptions,
parserPath: config.parser,
Expand Down Expand Up @@ -937,39 +937,53 @@ class Linter {
this.rules.define(ruleId, ruleCreator);
}

let reportTranslator = null;
const ruleContext = Object.freeze(
Object.assign(
Object.create(sharedTraversalContext),
{
id: ruleId,
options: getRuleOptions(config.rules[ruleId]),
report: lodash.flow([
createReportTranslator({ ruleId, severity, sourceCode: this.sourceCode }),
problem => {
if (problem.fix && ruleCreator.meta && !ruleCreator.meta.fixable) {
throw new Error("Fixable rules should export a `meta.fixable` property.");
}
problems.push(problem);

/*
* This is used to avoid breaking rules that used monkeypatch Linter, and relied on
* `linter.report` getting called with report info every time a rule reports a problem.
* To continue to support this, make sure that `context._linter.report` is called every
* time a problem is reported by a rule, even though `context._linter` is no longer a
* `Linter` instance.
*
* This should be removed in a major release after we create a better way to
* lint for unused disable comments.
* https://github.com/eslint/eslint/issues/9193
*/
sharedTraversalContext._linter.report( // eslint-disable-line no-underscore-dangle
ruleId,
severity,
{ loc: { start: { line: problem.line, column: problem.column - 1 } } },
problem.message
);
report() {

/*
* Create a report translator lazily.
* In a vast majority of cases, any given rule reports zero errors on a given
* piece of code. Creating a translator lazily avoids the performance cost of
* creating a new translator function for each rule that usually doesn't get
* called.
*
* Using lazy report translators improves end-to-end performance by about 3%
* with Node 8.4.0.
*/
if (reportTranslator === null) {
reportTranslator = createReportTranslator({ ruleId, severity, sourceCode });
}
])
const problem = reportTranslator.apply(null, arguments);

if (problem.fix && ruleCreator.meta && !ruleCreator.meta.fixable) {
throw new Error("Fixable rules should export a `meta.fixable` property.");
}
problems.push(problem);

/*
* This is used to avoid breaking rules that used monkeypatch Linter, and relied on
* `linter.report` getting called with report info every time a rule reports a problem.
* To continue to support this, make sure that `context._linter.report` is called every
* time a problem is reported by a rule, even though `context._linter` is no longer a
* `Linter` instance.
*
* This should be removed in a major release after we create a better way to
* lint for unused disable comments.
* https://github.com/eslint/eslint/issues/9193
*/
sharedTraversalContext._linter.report( // eslint-disable-line no-underscore-dangle
problem.ruleId,
problem.severity,
{ loc: { start: { line: problem.line, column: problem.column - 1 } } },
problem.message
);
}
}
)
);
Expand Down Expand Up @@ -1001,7 +1015,7 @@ class Linter {
const ecmaVersion = this.currentConfig.parserOptions.ecmaVersion || 5;

// gather scope data that may be needed by the rules
this.scopeManager = eslintScope.analyze(this.sourceCode.ast, {
this.scopeManager = eslintScope.analyze(sourceCode.ast, {
ignoreEval: true,
nodejsScope: ecmaFeatures.globalReturn,
impliedStrict: ecmaFeatures.impliedStrict,
Expand All @@ -1011,7 +1025,7 @@ class Linter {
});

// augment global scope with declared global variables
addDeclaredGlobals(this.sourceCode.ast, this.scopeManager.scopes[0], this.currentConfig, this.environments);
addDeclaredGlobals(sourceCode.ast, this.scopeManager.scopes[0], this.currentConfig, this.environments);

const eventGenerator = new CodePathAnalyzer(new NodeEventGenerator(emitter));

Expand All @@ -1021,7 +1035,7 @@ class Linter {
* automatically be informed that this type of node has been found
* and react accordingly.
*/
this.traverser.traverse(this.sourceCode.ast, {
this.traverser.traverse(sourceCode.ast, {
enter(node, parent) {
node.parent = parent;
eventGenerator.enterNode(node);
Expand Down

0 comments on commit bf1e344

Please sign in to comment.