Browse Source

tools: update ESLint to 3.4.0

PR-URL: https://github.com/nodejs/node/pull/8296
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Roman Reiss <me@silverwind.io>
v7.x
Rich Trott 8 years ago
parent
commit
201115812e
  1. 3
      tools/eslint/README.md
  2. 77
      tools/eslint/bin/eslint.js
  3. 2
      tools/eslint/conf/eslint.json
  4. 36
      tools/eslint/lib/ast-utils.js
  5. 32
      tools/eslint/lib/cli-engine.js
  6. 2
      tools/eslint/lib/cli.js
  7. 6
      tools/eslint/lib/code-path-analysis/code-path-analyzer.js
  8. 2
      tools/eslint/lib/code-path-analysis/code-path-segment.js
  9. 100
      tools/eslint/lib/code-path-analysis/code-path-state.js
  10. 6
      tools/eslint/lib/code-path-analysis/code-path.js
  11. 2
      tools/eslint/lib/code-path-analysis/debug-helpers.js
  12. 14
      tools/eslint/lib/code-path-analysis/fork-context.js
  13. 2
      tools/eslint/lib/config.js
  14. 22
      tools/eslint/lib/config/autoconfig.js
  15. 22
      tools/eslint/lib/config/config-file.js
  16. 22
      tools/eslint/lib/config/config-initializer.js
  17. 16
      tools/eslint/lib/config/config-ops.js
  18. 14
      tools/eslint/lib/config/config-rule.js
  19. 6
      tools/eslint/lib/config/config-validator.js
  20. 52
      tools/eslint/lib/config/plugins.js
  21. 56
      tools/eslint/lib/eslint.js
  22. 8
      tools/eslint/lib/formatters/html.js
  23. 2
      tools/eslint/lib/formatters/stylish.js
  24. 4
      tools/eslint/lib/formatters/table.js
  25. 57
      tools/eslint/lib/ignored-paths.js
  26. 8
      tools/eslint/lib/internal-rules/internal-no-invalid-meta.js
  27. 4
      tools/eslint/lib/logging.js
  28. 4
      tools/eslint/lib/rule-context.js
  29. 24
      tools/eslint/lib/rules.js
  30. 4
      tools/eslint/lib/rules/accessor-pairs.js
  31. 20
      tools/eslint/lib/rules/array-bracket-spacing.js
  32. 14
      tools/eslint/lib/rules/array-callback-return.js
  33. 8
      tools/eslint/lib/rules/arrow-body-style.js
  34. 20
      tools/eslint/lib/rules/arrow-parens.js
  35. 14
      tools/eslint/lib/rules/arrow-spacing.js
  36. 4
      tools/eslint/lib/rules/block-scoped-var.js
  37. 10
      tools/eslint/lib/rules/block-spacing.js
  38. 2
      tools/eslint/lib/rules/brace-style.js
  39. 4
      tools/eslint/lib/rules/callback-return.js
  40. 4
      tools/eslint/lib/rules/camelcase.js
  41. 80
      tools/eslint/lib/rules/class-methods-use-this.js
  42. 6
      tools/eslint/lib/rules/comma-dangle.js
  43. 8
      tools/eslint/lib/rules/comma-spacing.js
  44. 2
      tools/eslint/lib/rules/comma-style.js
  45. 4
      tools/eslint/lib/rules/complexity.js
  46. 18
      tools/eslint/lib/rules/computed-property-spacing.js
  47. 18
      tools/eslint/lib/rules/consistent-return.js
  48. 10
      tools/eslint/lib/rules/consistent-this.js
  49. 28
      tools/eslint/lib/rules/constructor-super.js
  50. 26
      tools/eslint/lib/rules/curly.js
  51. 4
      tools/eslint/lib/rules/default-case.js
  52. 2
      tools/eslint/lib/rules/dot-location.js
  53. 4
      tools/eslint/lib/rules/dot-notation.js
  54. 6
      tools/eslint/lib/rules/eol-last.js
  55. 8
      tools/eslint/lib/rules/eqeqeq.js
  56. 14
      tools/eslint/lib/rules/func-call-spacing.js
  57. 4
      tools/eslint/lib/rules/func-names.js
  58. 12
      tools/eslint/lib/rules/func-style.js
  59. 8
      tools/eslint/lib/rules/generator-star-spacing.js
  60. 4
      tools/eslint/lib/rules/global-require.js
  61. 4
      tools/eslint/lib/rules/guard-for-in.js
  62. 2
      tools/eslint/lib/rules/handle-callback-err.js
  63. 4
      tools/eslint/lib/rules/id-blacklist.js
  64. 10
      tools/eslint/lib/rules/id-length.js
  65. 6
      tools/eslint/lib/rules/id-match.js
  66. 47
      tools/eslint/lib/rules/indent.js
  67. 4
      tools/eslint/lib/rules/init-declarations.js
  68. 10
      tools/eslint/lib/rules/jsx-quotes.js
  69. 8
      tools/eslint/lib/rules/key-spacing.js
  70. 10
      tools/eslint/lib/rules/keyword-spacing.js
  71. 4
      tools/eslint/lib/rules/linebreak-style.js
  72. 14
      tools/eslint/lib/rules/lines-around-comment.js
  73. 4
      tools/eslint/lib/rules/max-depth.js
  74. 2
      tools/eslint/lib/rules/max-len.js
  75. 6
      tools/eslint/lib/rules/max-lines.js
  76. 2
      tools/eslint/lib/rules/max-nested-callbacks.js
  77. 2
      tools/eslint/lib/rules/max-params.js
  78. 6
      tools/eslint/lib/rules/max-statements-per-line.js
  79. 8
      tools/eslint/lib/rules/max-statements.js
  80. 33
      tools/eslint/lib/rules/multiline-ternary.js
  81. 2
      tools/eslint/lib/rules/new-cap.js
  82. 4
      tools/eslint/lib/rules/new-parens.js
  83. 2
      tools/eslint/lib/rules/newline-after-var.js
  84. 6
      tools/eslint/lib/rules/newline-before-return.js
  85. 4
      tools/eslint/lib/rules/newline-per-chained-call.js
  86. 6
      tools/eslint/lib/rules/no-alert.js
  87. 2
      tools/eslint/lib/rules/no-array-constructor.js
  88. 2
      tools/eslint/lib/rules/no-bitwise.js
  89. 4
      tools/eslint/lib/rules/no-caller.js
  90. 6
      tools/eslint/lib/rules/no-case-declarations.js
  91. 4
      tools/eslint/lib/rules/no-catch-shadow.js
  92. 2
      tools/eslint/lib/rules/no-class-assign.js
  93. 8
      tools/eslint/lib/rules/no-cond-assign.js
  94. 2
      tools/eslint/lib/rules/no-confusing-arrow.js
  95. 4
      tools/eslint/lib/rules/no-console.js
  96. 4
      tools/eslint/lib/rules/no-const-assign.js
  97. 2
      tools/eslint/lib/rules/no-constant-condition.js
  98. 4
      tools/eslint/lib/rules/no-continue.js
  99. 4
      tools/eslint/lib/rules/no-control-regex.js
  100. 4
      tools/eslint/lib/rules/no-debugger.js

3
tools/eslint/README.md

@ -155,13 +155,14 @@ ESLint follows [semantic versioning](http://semver.org). However, due to the nat
* Minor release (might break your lint build) * Minor release (might break your lint build)
* A bug fix in a rule that results in ESLint reporting more errors. * A bug fix in a rule that results in ESLint reporting more errors.
* A new rule is created. * A new rule is created.
* A new option to an existing rule is created. * A new option to an existing rule that does not result in ESLint reporting more errors by default.
* An existing rule is deprecated. * An existing rule is deprecated.
* A new CLI capability is created. * A new CLI capability is created.
* New capabilities to the public API are added (new classes, new methods, new arguments to existing methods, etc.). * New capabilities to the public API are added (new classes, new methods, new arguments to existing methods, etc.).
* A new formatter is created. * A new formatter is created.
* Major release (likely to break your lint build) * Major release (likely to break your lint build)
* `eslint:recommended` is updated. * `eslint:recommended` is updated.
* A new option to an existing rule that results in ESLint reporting more errors by default.
* An existing rule is removed. * An existing rule is removed.
* An existing formatter is removed. * An existing formatter is removed.
* Part of the public API is removed or changed in an incompatible way. * Part of the public API is removed or changed in an incompatible way.

77
tools/eslint/bin/eslint.js

@ -0,0 +1,77 @@
#!/usr/bin/env node
/**
* @fileoverview Main CLI that is run via the eslint command.
* @author Nicholas C. Zakas
*/
"use strict";
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
var useStdIn = (process.argv.indexOf("--stdin") > -1),
init = (process.argv.indexOf("--init") > -1),
debug = (process.argv.indexOf("--debug") > -1);
// must do this initialization *before* other requires in order to work
if (debug) {
require("debug").enable("eslint:*,-eslint:code-path");
}
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
// now we can safely include the other modules that use debug
var concat = require("concat-stream"),
cli = require("../lib/cli"),
path = require("path"),
fs = require("fs");
//------------------------------------------------------------------------------
// Execution
//------------------------------------------------------------------------------
process.on("uncaughtException", function(err){
// lazy load
var lodash = require("lodash");
if (typeof err.messageTemplate === "string" && err.messageTemplate.length > 0) {
var template = lodash.template(fs.readFileSync(path.resolve(__dirname, "../messages/" + err.messageTemplate + ".txt"), "utf-8"));
console.log("\nOops! Something went wrong! :(");
console.log("\n" + template(err.messageData || {}));
} else {
console.log(err.message);
console.log(err.stack);
}
process.exit(1);
});
if (useStdIn) {
process.stdin.pipe(concat({ encoding: "string" }, function(text) {
try {
process.exitCode = cli.execute(process.argv, text);
} catch (ex) {
console.error(ex.message);
console.error(ex.stack);
process.exitCode = 1;
}
}));
} else if (init) {
var configInit = require("../lib/config/config-initializer");
configInit.initializeConfig(function(err) {
if (err) {
process.exitCode = 1;
console.error(err.message);
console.error(err.stack);
} else {
process.exitCode = 0;
}
});
} else {
process.exitCode = cli.execute(process.argv);
}

2
tools/eslint/conf/eslint.json

@ -140,6 +140,7 @@
"brace-style": "off", "brace-style": "off",
"callback-return": "off", "callback-return": "off",
"camelcase": "off", "camelcase": "off",
"class-methods-use-this": "off",
"comma-dangle": "off", "comma-dangle": "off",
"comma-spacing": "off", "comma-spacing": "off",
"comma-style": "off", "comma-style": "off",
@ -217,6 +218,7 @@
"space-unary-ops": "off", "space-unary-ops": "off",
"spaced-comment": "off", "spaced-comment": "off",
"strict": "off", "strict": "off",
"symbol-description": "off",
"template-curly-spacing": "off", "template-curly-spacing": "off",
"unicode-bom": "off", "unicode-bom": "off",
"use-isnan": "error", "use-isnan": "error",

36
tools/eslint/lib/ast-utils.js

@ -210,23 +210,23 @@ module.exports = {
* @returns {boolean} Whether or not the tokens are on the same line. * @returns {boolean} Whether or not the tokens are on the same line.
* @public * @public
*/ */
isTokenOnSameLine: function(left, right) { isTokenOnSameLine(left, right) {
return left.loc.end.line === right.loc.start.line; return left.loc.end.line === right.loc.start.line;
}, },
isNullOrUndefined: isNullOrUndefined, isNullOrUndefined,
isCallee: isCallee, isCallee,
isES5Constructor: isES5Constructor, isES5Constructor,
getUpperFunction: getUpperFunction, getUpperFunction,
isArrayFromMethod: isArrayFromMethod, isArrayFromMethod,
isParenthesised: isParenthesised, isParenthesised,
/** /**
* Checks whether or not a given node is a string literal. * Checks whether or not a given node is a string literal.
* @param {ASTNode} node - A node to check. * @param {ASTNode} node - A node to check.
* @returns {boolean} `true` if the node is a string literal. * @returns {boolean} `true` if the node is a string literal.
*/ */
isStringLiteral: function(node) { isStringLiteral(node) {
return ( return (
(node.type === "Literal" && typeof node.value === "string") || (node.type === "Literal" && typeof node.value === "string") ||
node.type === "TemplateLiteral" node.type === "TemplateLiteral"
@ -247,7 +247,7 @@ module.exports = {
* @param {ASTNode} node - A node to check. * @param {ASTNode} node - A node to check.
* @returns {boolean} `true` if the node is breakable. * @returns {boolean} `true` if the node is breakable.
*/ */
isBreakableStatement: function(node) { isBreakableStatement(node) {
return breakableTypePattern.test(node.type); return breakableTypePattern.test(node.type);
}, },
@ -257,7 +257,7 @@ module.exports = {
* @param {ASTNode} node - A node to get. * @param {ASTNode} node - A node to get.
* @returns {string|null} The label or `null`. * @returns {string|null} The label or `null`.
*/ */
getLabel: function(node) { getLabel(node) {
if (node.parent.type === "LabeledStatement") { if (node.parent.type === "LabeledStatement") {
return node.parent.label.name; return node.parent.label.name;
} }
@ -270,7 +270,7 @@ module.exports = {
* @returns {Reference[]} An array of only references which are non initializer and writable. * @returns {Reference[]} An array of only references which are non initializer and writable.
* @public * @public
*/ */
getModifyingReferences: function(references) { getModifyingReferences(references) {
return references.filter(isModifyingReference); return references.filter(isModifyingReference);
}, },
@ -281,7 +281,7 @@ module.exports = {
* @returns {boolean} True if the text is surrounded by the character, false if not. * @returns {boolean} True if the text is surrounded by the character, false if not.
* @private * @private
*/ */
isSurroundedBy: function(val, character) { isSurroundedBy(val, character) {
return val[0] === character && val[val.length - 1] === character; return val[0] === character && val[val.length - 1] === character;
}, },
@ -290,7 +290,7 @@ module.exports = {
* @param {LineComment|BlockComment} node The node to be checked * @param {LineComment|BlockComment} node The node to be checked
* @returns {boolean} `true` if the node is an ESLint directive comment * @returns {boolean} `true` if the node is an ESLint directive comment
*/ */
isDirectiveComment: function(node) { isDirectiveComment(node) {
const comment = node.value.trim(); const comment = node.value.trim();
return ( return (
@ -323,7 +323,7 @@ module.exports = {
* @param {string} name - A variable name to find. * @param {string} name - A variable name to find.
* @returns {escope.Variable|null} A found variable or `null`. * @returns {escope.Variable|null} A found variable or `null`.
*/ */
getVariableByName: function(initScope, name) { getVariableByName(initScope, name) {
let scope = initScope; let scope = initScope;
while (scope) { while (scope) {
@ -360,7 +360,7 @@ module.exports = {
* @param {SourceCode} sourceCode - A SourceCode instance to get comments. * @param {SourceCode} sourceCode - A SourceCode instance to get comments.
* @returns {boolean} The function node is the default `this` binding. * @returns {boolean} The function node is the default `this` binding.
*/ */
isDefaultThisBinding: function(node, sourceCode) { isDefaultThisBinding(node, sourceCode) {
if (isES5Constructor(node) || hasJSDocThisTag(node, sourceCode)) { if (isES5Constructor(node) || hasJSDocThisTag(node, sourceCode)) {
return false; return false;
} }
@ -496,7 +496,7 @@ module.exports = {
* @returns {int} precedence level * @returns {int} precedence level
* @private * @private
*/ */
getPrecedence: function(node) { getPrecedence(node) {
switch (node.type) { switch (node.type) {
case "SequenceExpression": case "SequenceExpression":
return 0; return 0;
@ -594,7 +594,7 @@ module.exports = {
* @param {ASTNode|null} node - A node to check. * @param {ASTNode|null} node - A node to check.
* @returns {boolean} `true` if the node is a loop node. * @returns {boolean} `true` if the node is a loop node.
*/ */
isLoop: function(node) { isLoop(node) {
return Boolean(node && anyLoopPattern.test(node.type)); return Boolean(node && anyLoopPattern.test(node.type));
}, },
@ -609,7 +609,7 @@ module.exports = {
* @param {ASTNode|null} node - A node to check. * @param {ASTNode|null} node - A node to check.
* @returns {boolean} `true` if the node is a function node. * @returns {boolean} `true` if the node is a function node.
*/ */
isFunction: function(node) { isFunction(node) {
return Boolean(node && anyFunctionPattern.test(node.type)); return Boolean(node && anyFunctionPattern.test(node.type));
}, },

32
tools/eslint/lib/cli-engine.js

@ -241,8 +241,8 @@ function processText(text, configHelper, filename, fix, allowInlineConfig) {
parsedBlocks.forEach(function(block) { parsedBlocks.forEach(function(block) {
unprocessedMessages.push(eslint.verify(block, config, { unprocessedMessages.push(eslint.verify(block, config, {
filename: filename, filename,
allowInlineConfig: allowInlineConfig allowInlineConfig
})); }));
}); });
@ -254,14 +254,14 @@ function processText(text, configHelper, filename, fix, allowInlineConfig) {
if (fix) { if (fix) {
fixedResult = multipassFix(text, config, { fixedResult = multipassFix(text, config, {
filename: filename, filename,
allowInlineConfig: allowInlineConfig allowInlineConfig
}); });
messages = fixedResult.messages; messages = fixedResult.messages;
} else { } else {
messages = eslint.verify(text, config, { messages = eslint.verify(text, config, {
filename: filename, filename,
allowInlineConfig: allowInlineConfig allowInlineConfig
}); });
} }
} }
@ -270,7 +270,7 @@ function processText(text, configHelper, filename, fix, allowInlineConfig) {
const result = { const result = {
filePath: filename, filePath: filename,
messages: messages, messages,
errorCount: stats.errorCount, errorCount: stats.errorCount,
warningCount: stats.warningCount warningCount: stats.warningCount
}; };
@ -329,7 +329,7 @@ function createIgnoreResult(filePath, baseDir) {
{ {
fatal: false, fatal: false,
severity: 1, severity: 1,
message: message message
} }
], ],
errorCount: 0, errorCount: 0,
@ -559,7 +559,7 @@ CLIEngine.prototype = {
* @param {Object} pluginobject Plugin configuration object. * @param {Object} pluginobject Plugin configuration object.
* @returns {void} * @returns {void}
*/ */
addPlugin: function(name, pluginobject) { addPlugin(name, pluginobject) {
Plugins.define(name, pluginobject); Plugins.define(name, pluginobject);
}, },
@ -569,7 +569,7 @@ CLIEngine.prototype = {
* @param {string[]} patterns The file patterns passed on the command line. * @param {string[]} patterns The file patterns passed on the command line.
* @returns {string[]} The equivalent glob patterns. * @returns {string[]} The equivalent glob patterns.
*/ */
resolveFileGlobPatterns: function(patterns) { resolveFileGlobPatterns(patterns) {
return globUtil.resolveFileGlobPatterns(patterns, this.options); return globUtil.resolveFileGlobPatterns(patterns, this.options);
}, },
@ -578,7 +578,7 @@ CLIEngine.prototype = {
* @param {string[]} patterns An array of file and directory names. * @param {string[]} patterns An array of file and directory names.
* @returns {Object} The results for all files that were linted. * @returns {Object} The results for all files that were linted.
*/ */
executeOnFiles: function(patterns) { executeOnFiles(patterns) {
const results = [], const results = [],
options = this.options, options = this.options,
fileCache = this._fileCache, fileCache = this._fileCache,
@ -716,7 +716,7 @@ CLIEngine.prototype = {
debug("Linting complete in: " + (Date.now() - startTime) + "ms"); debug("Linting complete in: " + (Date.now() - startTime) + "ms");
return { return {
results: results, results,
errorCount: stats.errorCount, errorCount: stats.errorCount,
warningCount: stats.warningCount warningCount: stats.warningCount
}; };
@ -729,7 +729,7 @@ CLIEngine.prototype = {
* @param {boolean} warnIgnored Always warn when a file is ignored * @param {boolean} warnIgnored Always warn when a file is ignored
* @returns {Object} The results for the linting. * @returns {Object} The results for the linting.
*/ */
executeOnText: function(text, filename, warnIgnored) { executeOnText(text, filename, warnIgnored) {
const results = [], const results = [],
options = this.options, options = this.options,
@ -752,7 +752,7 @@ CLIEngine.prototype = {
const stats = calculateStatsPerRun(results); const stats = calculateStatsPerRun(results);
return { return {
results: results, results,
errorCount: stats.errorCount, errorCount: stats.errorCount,
warningCount: stats.warningCount warningCount: stats.warningCount
}; };
@ -765,7 +765,7 @@ CLIEngine.prototype = {
* @param {string} filePath The path of the file to retrieve a config object for. * @param {string} filePath The path of the file to retrieve a config object for.
* @returns {Object} A configuration object for the file. * @returns {Object} A configuration object for the file.
*/ */
getConfigForFile: function(filePath) { getConfigForFile(filePath) {
const configHelper = new Config(this.options); const configHelper = new Config(this.options);
return configHelper.getConfig(filePath); return configHelper.getConfig(filePath);
@ -776,7 +776,7 @@ CLIEngine.prototype = {
* @param {string} filePath The path of the file to check. * @param {string} filePath The path of the file to check.
* @returns {boolean} Whether or not the given path is ignored. * @returns {boolean} Whether or not the given path is ignored.
*/ */
isPathIgnored: function(filePath) { isPathIgnored(filePath) {
const resolvedPath = path.resolve(this.options.cwd, filePath); const resolvedPath = path.resolve(this.options.cwd, filePath);
const ignoredPaths = new IgnoredPaths(this.options); const ignoredPaths = new IgnoredPaths(this.options);

2
tools/eslint/lib/cli.js

@ -120,7 +120,7 @@ const cli = {
* @param {string} [text] The text to lint (used for TTY). * @param {string} [text] The text to lint (used for TTY).
* @returns {int} The exit code for the operation. * @returns {int} The exit code for the operation.
*/ */
execute: function(args, text) { execute(args, text) {
let currentOptions; let currentOptions;

6
tools/eslint/lib/code-path-analysis/code-path-analyzer.js

@ -592,7 +592,7 @@ CodePathAnalyzer.prototype = {
* @param {ASTNode} node - A node which is entering. * @param {ASTNode} node - A node which is entering.
* @returns {void} * @returns {void}
*/ */
enterNode: function(node) { enterNode(node) {
this.currentNode = node; this.currentNode = node;
// Updates the code path due to node's position in its parent node. // Updates the code path due to node's position in its parent node.
@ -617,7 +617,7 @@ CodePathAnalyzer.prototype = {
* @param {ASTNode} node - A node which is leaving. * @param {ASTNode} node - A node which is leaving.
* @returns {void} * @returns {void}
*/ */
leaveNode: function(node) { leaveNode(node) {
this.currentNode = node; this.currentNode = node;
// Updates the code path. // Updates the code path.
@ -641,7 +641,7 @@ CodePathAnalyzer.prototype = {
* @param {CodePathSegment} toSegment - A segment of next. * @param {CodePathSegment} toSegment - A segment of next.
* @returns {void} * @returns {void}
*/ */
onLooped: function(fromSegment, toSegment) { onLooped(fromSegment, toSegment) {
if (fromSegment.reachable && toSegment.reachable) { if (fromSegment.reachable && toSegment.reachable) {
debug.dump("onCodePathSegmentLoop " + fromSegment.id + " -> " + toSegment.id); debug.dump("onCodePathSegmentLoop " + fromSegment.id + " -> " + toSegment.id);
this.emitter.emit( this.emitter.emit(

2
tools/eslint/lib/code-path-analysis/code-path-segment.js

@ -138,7 +138,7 @@ CodePathSegment.prototype = {
* @param {CodePathSegment} segment - A previous segment to check. * @param {CodePathSegment} segment - A previous segment to check.
* @returns {boolean} `true` if the segment is coming from the end of a loop. * @returns {boolean} `true` if the segment is coming from the end of a loop.
*/ */
isLoopedPrevSegment: function(segment) { isLoopedPrevSegment(segment) {
return this.internal.loopedPrevSegments.indexOf(segment) !== -1; return this.internal.loopedPrevSegments.indexOf(segment) !== -1;
} }
}; };

100
tools/eslint/lib/code-path-analysis/code-path-state.js

@ -278,7 +278,7 @@ CodePathState.prototype = {
* "finally" block. * "finally" block.
* @returns {ForkContext} The created context. * @returns {ForkContext} The created context.
*/ */
pushForkContext: function(forkLeavingPath) { pushForkContext(forkLeavingPath) {
this.forkContext = ForkContext.newEmpty( this.forkContext = ForkContext.newEmpty(
this.forkContext, this.forkContext,
forkLeavingPath forkLeavingPath
@ -291,7 +291,7 @@ CodePathState.prototype = {
* Pops and merges the last forking context. * Pops and merges the last forking context.
* @returns {ForkContext} The last context. * @returns {ForkContext} The last context.
*/ */
popForkContext: function() { popForkContext() {
const lastContext = this.forkContext; const lastContext = this.forkContext;
this.forkContext = lastContext.upper; this.forkContext = lastContext.upper;
@ -304,7 +304,7 @@ CodePathState.prototype = {
* Creates a new path. * Creates a new path.
* @returns {void} * @returns {void}
*/ */
forkPath: function() { forkPath() {
this.forkContext.add(this.parentForkContext.makeNext(-1, -1)); this.forkContext.add(this.parentForkContext.makeNext(-1, -1));
}, },
@ -314,7 +314,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
forkBypassPath: function() { forkBypassPath() {
this.forkContext.add(this.parentForkContext.head); this.forkContext.add(this.parentForkContext.head);
}, },
@ -353,11 +353,11 @@ CodePathState.prototype = {
* paths between `true` and `false`. * paths between `true` and `false`.
* @returns {void} * @returns {void}
*/ */
pushChoiceContext: function(kind, isForkingAsResult) { pushChoiceContext(kind, isForkingAsResult) {
this.choiceContext = { this.choiceContext = {
upper: this.choiceContext, upper: this.choiceContext,
kind: kind, kind,
isForkingAsResult: isForkingAsResult, isForkingAsResult,
trueForkContext: ForkContext.newEmpty(this.forkContext), trueForkContext: ForkContext.newEmpty(this.forkContext),
falseForkContext: ForkContext.newEmpty(this.forkContext), falseForkContext: ForkContext.newEmpty(this.forkContext),
processed: false processed: false
@ -369,7 +369,7 @@ CodePathState.prototype = {
* *
* @returns {ChoiceContext} The popped context. * @returns {ChoiceContext} The popped context.
*/ */
popChoiceContext: function() { popChoiceContext() {
const context = this.choiceContext; const context = this.choiceContext;
this.choiceContext = context.upper; this.choiceContext = context.upper;
@ -457,7 +457,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
makeLogicalRight: function() { makeLogicalRight() {
const context = this.choiceContext; const context = this.choiceContext;
const forkContext = this.forkContext; const forkContext = this.forkContext;
@ -501,7 +501,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
makeIfConsequent: function() { makeIfConsequent() {
const context = this.choiceContext; const context = this.choiceContext;
const forkContext = this.forkContext; const forkContext = this.forkContext;
@ -528,7 +528,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
makeIfAlternate: function() { makeIfAlternate() {
const context = this.choiceContext; const context = this.choiceContext;
const forkContext = this.forkContext; const forkContext = this.forkContext;
@ -558,10 +558,10 @@ CodePathState.prototype = {
* @param {string|null} label - The label text. * @param {string|null} label - The label text.
* @returns {void} * @returns {void}
*/ */
pushSwitchContext: function(hasCase, label) { pushSwitchContext(hasCase, label) {
this.switchContext = { this.switchContext = {
upper: this.switchContext, upper: this.switchContext,
hasCase: hasCase, hasCase,
defaultSegments: null, defaultSegments: null,
defaultBodySegments: null, defaultBodySegments: null,
foundDefault: false, foundDefault: false,
@ -582,7 +582,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
popSwitchContext: function() { popSwitchContext() {
const context = this.switchContext; const context = this.switchContext;
this.switchContext = context.upper; this.switchContext = context.upper;
@ -658,7 +658,7 @@ CodePathState.prototype = {
* @param {boolean} isDefault - `true` if the body is the default case. * @param {boolean} isDefault - `true` if the body is the default case.
* @returns {void} * @returns {void}
*/ */
makeSwitchCaseBody: function(isEmpty, isDefault) { makeSwitchCaseBody(isEmpty, isDefault) {
const context = this.switchContext; const context = this.switchContext;
if (!context.hasCase) { if (!context.hasCase) {
@ -709,11 +709,11 @@ CodePathState.prototype = {
* `finally` block. * `finally` block.
* @returns {void} * @returns {void}
*/ */
pushTryContext: function(hasFinalizer) { pushTryContext(hasFinalizer) {
this.tryContext = { this.tryContext = {
upper: this.tryContext, upper: this.tryContext,
position: "try", position: "try",
hasFinalizer: hasFinalizer, hasFinalizer,
returnedForkContext: hasFinalizer returnedForkContext: hasFinalizer
? ForkContext.newEmpty(this.forkContext) ? ForkContext.newEmpty(this.forkContext)
@ -730,7 +730,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
popTryContext: function() { popTryContext() {
const context = this.tryContext; const context = this.tryContext;
this.tryContext = context.upper; this.tryContext = context.upper;
@ -784,7 +784,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
makeCatchBlock: function() { makeCatchBlock() {
const context = this.tryContext; const context = this.tryContext;
const forkContext = this.forkContext; const forkContext = this.forkContext;
const thrown = context.thrownForkContext; const thrown = context.thrownForkContext;
@ -813,7 +813,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
makeFinallyBlock: function() { makeFinallyBlock() {
const context = this.tryContext; const context = this.tryContext;
let forkContext = this.forkContext; let forkContext = this.forkContext;
const returned = context.returnedForkContext; const returned = context.returnedForkContext;
@ -871,7 +871,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
makeFirstThrowablePathInTryBlock: function() { makeFirstThrowablePathInTryBlock() {
const forkContext = this.forkContext; const forkContext = this.forkContext;
if (!forkContext.reachable) { if (!forkContext.reachable) {
@ -904,7 +904,7 @@ CodePathState.prototype = {
* @param {string|null} label - A label of the node which was triggered. * @param {string|null} label - A label of the node which was triggered.
* @returns {void} * @returns {void}
*/ */
pushLoopContext: function(type, label) { pushLoopContext(type, label) {
const forkContext = this.forkContext; const forkContext = this.forkContext;
const breakContext = this.pushBreakContext(true, label); const breakContext = this.pushBreakContext(true, label);
@ -913,8 +913,8 @@ CodePathState.prototype = {
this.pushChoiceContext("loop", false); this.pushChoiceContext("loop", false);
this.loopContext = { this.loopContext = {
upper: this.loopContext, upper: this.loopContext,
type: type, type,
label: label, label,
test: void 0, test: void 0,
continueDestSegments: null, continueDestSegments: null,
brokenForkContext: breakContext.brokenForkContext brokenForkContext: breakContext.brokenForkContext
@ -925,8 +925,8 @@ CodePathState.prototype = {
this.pushChoiceContext("loop", false); this.pushChoiceContext("loop", false);
this.loopContext = { this.loopContext = {
upper: this.loopContext, upper: this.loopContext,
type: type, type,
label: label, label,
test: void 0, test: void 0,
entrySegments: null, entrySegments: null,
continueForkContext: ForkContext.newEmpty(forkContext), continueForkContext: ForkContext.newEmpty(forkContext),
@ -938,8 +938,8 @@ CodePathState.prototype = {
this.pushChoiceContext("loop", false); this.pushChoiceContext("loop", false);
this.loopContext = { this.loopContext = {
upper: this.loopContext, upper: this.loopContext,
type: type, type,
label: label, label,
test: void 0, test: void 0,
endOfInitSegments: null, endOfInitSegments: null,
testSegments: null, testSegments: null,
@ -955,8 +955,8 @@ CodePathState.prototype = {
case "ForOfStatement": case "ForOfStatement":
this.loopContext = { this.loopContext = {
upper: this.loopContext, upper: this.loopContext,
type: type, type,
label: label, label,
prevSegments: null, prevSegments: null,
leftSegments: null, leftSegments: null,
endOfLeftSegments: null, endOfLeftSegments: null,
@ -976,7 +976,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
popLoopContext: function() { popLoopContext() {
const context = this.loopContext; const context = this.loopContext;
this.loopContext = context.upper; this.loopContext = context.upper;
@ -1047,7 +1047,7 @@ CodePathState.prototype = {
* @param {boolean|undefined} test - The test value (only when constant). * @param {boolean|undefined} test - The test value (only when constant).
* @returns {void} * @returns {void}
*/ */
makeWhileTest: function(test) { makeWhileTest(test) {
const context = this.loopContext; const context = this.loopContext;
const forkContext = this.forkContext; const forkContext = this.forkContext;
const testSegments = forkContext.makeNext(0, -1); const testSegments = forkContext.makeNext(0, -1);
@ -1063,7 +1063,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
makeWhileBody: function() { makeWhileBody() {
const context = this.loopContext; const context = this.loopContext;
const choiceContext = this.choiceContext; const choiceContext = this.choiceContext;
const forkContext = this.forkContext; const forkContext = this.forkContext;
@ -1085,7 +1085,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
makeDoWhileBody: function() { makeDoWhileBody() {
const context = this.loopContext; const context = this.loopContext;
const forkContext = this.forkContext; const forkContext = this.forkContext;
const bodySegments = forkContext.makeNext(-1, -1); const bodySegments = forkContext.makeNext(-1, -1);
@ -1101,7 +1101,7 @@ CodePathState.prototype = {
* @param {boolean|undefined} test - The test value (only when constant). * @param {boolean|undefined} test - The test value (only when constant).
* @returns {void} * @returns {void}
*/ */
makeDoWhileTest: function(test) { makeDoWhileTest(test) {
const context = this.loopContext; const context = this.loopContext;
const forkContext = this.forkContext; const forkContext = this.forkContext;
@ -1122,7 +1122,7 @@ CodePathState.prototype = {
* @param {boolean|undefined} test - The test value (only when constant). * @param {boolean|undefined} test - The test value (only when constant).
* @returns {void} * @returns {void}
*/ */
makeForTest: function(test) { makeForTest(test) {
const context = this.loopContext; const context = this.loopContext;
const forkContext = this.forkContext; const forkContext = this.forkContext;
const endOfInitSegments = forkContext.head; const endOfInitSegments = forkContext.head;
@ -1140,7 +1140,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
makeForUpdate: function() { makeForUpdate() {
const context = this.loopContext; const context = this.loopContext;
const choiceContext = this.choiceContext; const choiceContext = this.choiceContext;
const forkContext = this.forkContext; const forkContext = this.forkContext;
@ -1167,7 +1167,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
makeForBody: function() { makeForBody() {
const context = this.loopContext; const context = this.loopContext;
const choiceContext = this.choiceContext; const choiceContext = this.choiceContext;
const forkContext = this.forkContext; const forkContext = this.forkContext;
@ -1219,7 +1219,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
makeForInOfLeft: function() { makeForInOfLeft() {
const context = this.loopContext; const context = this.loopContext;
const forkContext = this.forkContext; const forkContext = this.forkContext;
const leftSegments = forkContext.makeDisconnected(-1, -1); const leftSegments = forkContext.makeDisconnected(-1, -1);
@ -1236,7 +1236,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
makeForInOfRight: function() { makeForInOfRight() {
const context = this.loopContext; const context = this.loopContext;
const forkContext = this.forkContext; const forkContext = this.forkContext;
const temp = ForkContext.newEmpty(forkContext); const temp = ForkContext.newEmpty(forkContext);
@ -1255,7 +1255,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
makeForInOfBody: function() { makeForInOfBody() {
const context = this.loopContext; const context = this.loopContext;
const forkContext = this.forkContext; const forkContext = this.forkContext;
const temp = ForkContext.newEmpty(forkContext); const temp = ForkContext.newEmpty(forkContext);
@ -1283,11 +1283,11 @@ CodePathState.prototype = {
* @param {string|null} label - The label of this context. * @param {string|null} label - The label of this context.
* @returns {Object} The new context. * @returns {Object} The new context.
*/ */
pushBreakContext: function(breakable, label) { pushBreakContext(breakable, label) {
this.breakContext = { this.breakContext = {
upper: this.breakContext, upper: this.breakContext,
breakable: breakable, breakable,
label: label, label,
brokenForkContext: ForkContext.newEmpty(this.forkContext) brokenForkContext: ForkContext.newEmpty(this.forkContext)
}; };
return this.breakContext; return this.breakContext;
@ -1298,7 +1298,7 @@ CodePathState.prototype = {
* *
* @returns {Object} The removed context. * @returns {Object} The removed context.
*/ */
popBreakContext: function() { popBreakContext() {
const context = this.breakContext; const context = this.breakContext;
const forkContext = this.forkContext; const forkContext = this.forkContext;
@ -1326,7 +1326,7 @@ CodePathState.prototype = {
* @param {string} label - A label of the break statement. * @param {string} label - A label of the break statement.
* @returns {void} * @returns {void}
*/ */
makeBreak: function(label) { makeBreak(label) {
const forkContext = this.forkContext; const forkContext = this.forkContext;
if (!forkContext.reachable) { if (!forkContext.reachable) {
@ -1352,7 +1352,7 @@ CodePathState.prototype = {
* @param {string} label - A label of the continue statement. * @param {string} label - A label of the continue statement.
* @returns {void} * @returns {void}
*/ */
makeContinue: function(label) { makeContinue(label) {
const forkContext = this.forkContext; const forkContext = this.forkContext;
if (!forkContext.reachable) { if (!forkContext.reachable) {
@ -1387,7 +1387,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
makeReturn: function() { makeReturn() {
const forkContext = this.forkContext; const forkContext = this.forkContext;
if (forkContext.reachable) { if (forkContext.reachable) {
@ -1404,7 +1404,7 @@ CodePathState.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
makeThrow: function() { makeThrow() {
const forkContext = this.forkContext; const forkContext = this.forkContext;
if (forkContext.reachable) { if (forkContext.reachable) {
@ -1417,7 +1417,7 @@ CodePathState.prototype = {
* Makes the final path. * Makes the final path.
* @returns {void} * @returns {void}
*/ */
makeFinal: function() { makeFinal() {
const segments = this.currentSegments; const segments = this.currentSegments;
if (segments.length > 0 && segments[0].reachable) { if (segments.length > 0 && segments[0].reachable) {

6
tools/eslint/lib/code-path-analysis/code-path.js

@ -123,7 +123,7 @@ CodePath.prototype = {
* @param {Function} callback - A callback function. * @param {Function} callback - A callback function.
* @returns {void} * @returns {void}
*/ */
traverseSegments: function(options, callback) { traverseSegments(options, callback) {
if (typeof options === "function") { if (typeof options === "function") {
callback = options; callback = options;
options = null; options = null;
@ -142,14 +142,14 @@ CodePath.prototype = {
let skippedSegment = null; let skippedSegment = null;
let broken = false; let broken = false;
const controller = { const controller = {
skip: function() { skip() {
if (stack.length <= 1) { if (stack.length <= 1) {
broken = true; broken = true;
} else { } else {
skippedSegment = stack[stack.length - 2][0]; skippedSegment = stack[stack.length - 2][0];
} }
}, },
break: function() { break() {
broken = true; broken = true;
} }
}; };

2
tools/eslint/lib/code-path-analysis/debug-helpers.js

@ -143,7 +143,7 @@ module.exports = {
* @param {Object} traceMap - Optional. A map to check whether or not segments had been done. * @param {Object} traceMap - Optional. A map to check whether or not segments had been done.
* @returns {string} A DOT code of the code path. * @returns {string} A DOT code of the code path.
*/ */
makeDotArrows: function(codePath, traceMap) { makeDotArrows(codePath, traceMap) {
const stack = [[codePath.initialSegment, 0]]; const stack = [[codePath.initialSegment, 0]];
const done = traceMap || Object.create(null); const done = traceMap || Object.create(null);
let lastId = codePath.initialSegment.id; let lastId = codePath.initialSegment.id;

14
tools/eslint/lib/code-path-analysis/fork-context.js

@ -150,7 +150,7 @@ ForkContext.prototype = {
* @param {number} end - The last index of previous segments. * @param {number} end - The last index of previous segments.
* @returns {CodePathSegment[]} New segments. * @returns {CodePathSegment[]} New segments.
*/ */
makeNext: function(begin, end) { makeNext(begin, end) {
return makeSegments(this, begin, end, CodePathSegment.newNext); return makeSegments(this, begin, end, CodePathSegment.newNext);
}, },
@ -162,7 +162,7 @@ ForkContext.prototype = {
* @param {number} end - The last index of previous segments. * @param {number} end - The last index of previous segments.
* @returns {CodePathSegment[]} New segments. * @returns {CodePathSegment[]} New segments.
*/ */
makeUnreachable: function(begin, end) { makeUnreachable(begin, end) {
return makeSegments(this, begin, end, CodePathSegment.newUnreachable); return makeSegments(this, begin, end, CodePathSegment.newUnreachable);
}, },
@ -175,7 +175,7 @@ ForkContext.prototype = {
* @param {number} end - The last index of previous segments. * @param {number} end - The last index of previous segments.
* @returns {CodePathSegment[]} New segments. * @returns {CodePathSegment[]} New segments.
*/ */
makeDisconnected: function(begin, end) { makeDisconnected(begin, end) {
return makeSegments(this, begin, end, CodePathSegment.newDisconnected); return makeSegments(this, begin, end, CodePathSegment.newDisconnected);
}, },
@ -186,7 +186,7 @@ ForkContext.prototype = {
* @param {CodePathSegment[]} segments - Segments to add. * @param {CodePathSegment[]} segments - Segments to add.
* @returns {void} * @returns {void}
*/ */
add: function(segments) { add(segments) {
assert(segments.length >= this.count, segments.length + " >= " + this.count); assert(segments.length >= this.count, segments.length + " >= " + this.count);
this.segmentsList.push(mergeExtraSegments(this, segments)); this.segmentsList.push(mergeExtraSegments(this, segments));
@ -199,7 +199,7 @@ ForkContext.prototype = {
* @param {CodePathSegment[]} segments - Segments to add. * @param {CodePathSegment[]} segments - Segments to add.
* @returns {void} * @returns {void}
*/ */
replaceHead: function(segments) { replaceHead(segments) {
assert(segments.length >= this.count, segments.length + " >= " + this.count); assert(segments.length >= this.count, segments.length + " >= " + this.count);
this.segmentsList.splice(-1, 1, mergeExtraSegments(this, segments)); this.segmentsList.splice(-1, 1, mergeExtraSegments(this, segments));
@ -211,7 +211,7 @@ ForkContext.prototype = {
* @param {ForkContext} context - A fork context to add. * @param {ForkContext} context - A fork context to add.
* @returns {void} * @returns {void}
*/ */
addAll: function(context) { addAll(context) {
assert(context.count === this.count); assert(context.count === this.count);
const source = context.segmentsList; const source = context.segmentsList;
@ -226,7 +226,7 @@ ForkContext.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
clear: function() { clear() {
this.segmentsList = []; this.segmentsList = [];
} }
}; };

2
tools/eslint/lib/config.js

@ -163,7 +163,7 @@ function getLocalConfig(thisConfig, directory) {
noConfigError.messageTemplate = "no-config-found"; noConfigError.messageTemplate = "no-config-found";
noConfigError.messageData = { noConfigError.messageData = {
directory: directory, directory,
filesExamined: localConfigFiles filesExamined: localConfigFiles
}; };

22
tools/eslint/lib/config/autoconfig.js

@ -52,7 +52,7 @@ function makeRegistryItems(rulesConfig) {
return Object.keys(rulesConfig).reduce(function(accumulator, ruleId) { return Object.keys(rulesConfig).reduce(function(accumulator, ruleId) {
accumulator[ruleId] = rulesConfig[ruleId].map(function(config) { accumulator[ruleId] = rulesConfig[ruleId].map(function(config) {
return { return {
config: config, config,
specificity: config.length || 1, specificity: config.length || 1,
errorCount: void 0 errorCount: void 0
}; };
@ -87,7 +87,7 @@ Registry.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
populateFromCoreRules: function() { populateFromCoreRules() {
const rulesConfig = configRule.createCoreRuleConfigs(); const rulesConfig = configRule.createCoreRuleConfigs();
this.rules = makeRegistryItems(rulesConfig); this.rules = makeRegistryItems(rulesConfig);
@ -107,7 +107,7 @@ Registry.prototype = {
* @param {Object} registry The autoconfig registry * @param {Object} registry The autoconfig registry
* @returns {Object[]} "rules" configurations to use for linting * @returns {Object[]} "rules" configurations to use for linting
*/ */
buildRuleSets: function() { buildRuleSets() {
let idx = 0; let idx = 0;
const ruleIds = Object.keys(this.rules), const ruleIds = Object.keys(this.rules),
ruleSets = []; ruleSets = [];
@ -168,7 +168,7 @@ Registry.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
stripFailingConfigs: function() { stripFailingConfigs() {
const ruleIds = Object.keys(this.rules), const ruleIds = Object.keys(this.rules),
newRegistry = new Registry(); newRegistry = new Registry();
@ -193,7 +193,7 @@ Registry.prototype = {
* *
* @returns {void} * @returns {void}
*/ */
stripExtraConfigs: function() { stripExtraConfigs() {
const ruleIds = Object.keys(this.rules), const ruleIds = Object.keys(this.rules),
newRegistry = new Registry(); newRegistry = new Registry();
@ -214,7 +214,7 @@ Registry.prototype = {
* *
* @returns {Registry} A registry of failing rules. * @returns {Registry} A registry of failing rules.
*/ */
getFailingRulesRegistry: function() { getFailingRulesRegistry() {
const ruleIds = Object.keys(this.rules), const ruleIds = Object.keys(this.rules),
failingRegistry = new Registry(); failingRegistry = new Registry();
@ -237,7 +237,7 @@ Registry.prototype = {
* *
* @returns {Object} An eslint config with rules section populated * @returns {Object} An eslint config with rules section populated
*/ */
createConfig: function() { createConfig() {
const ruleIds = Object.keys(this.rules), const ruleIds = Object.keys(this.rules),
config = {rules: {}}; config = {rules: {}};
@ -256,7 +256,7 @@ Registry.prototype = {
* @param {number} specificity Only keep configs with this specificity * @param {number} specificity Only keep configs with this specificity
* @returns {Registry} A registry of rules * @returns {Registry} A registry of rules
*/ */
filterBySpecificity: function(specificity) { filterBySpecificity(specificity) {
const ruleIds = Object.keys(this.rules), const ruleIds = Object.keys(this.rules),
newRegistry = new Registry(); newRegistry = new Registry();
@ -278,7 +278,7 @@ Registry.prototype = {
* @param {progressCallback} [cb] Optional callback for reporting execution status * @param {progressCallback} [cb] Optional callback for reporting execution status
* @returns {Registry} New registry with errorCount populated * @returns {Registry} New registry with errorCount populated
*/ */
lintSourceCode: function(sourceCodes, config, cb) { lintSourceCode(sourceCodes, config, cb) {
let ruleSetIdx, let ruleSetIdx,
lintedRegistry; lintedRegistry;
@ -361,6 +361,6 @@ function extendFromRecommended(config) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = { module.exports = {
Registry: Registry, Registry,
extendFromRecommended: extendFromRecommended extendFromRecommended
}; };

22
tools/eslint/lib/config/config-file.js

@ -471,12 +471,12 @@ function resolve(filePath, relativeTo) {
normalizedPackageName = normalizePackageName(packagePath, "eslint-plugin"); normalizedPackageName = normalizePackageName(packagePath, "eslint-plugin");
debug("Attempting to resolve " + normalizedPackageName); debug("Attempting to resolve " + normalizedPackageName);
filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo)); filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
return { filePath: filePath, configName: configName }; return { filePath, configName };
} else { } else {
normalizedPackageName = normalizePackageName(filePath, "eslint-config"); normalizedPackageName = normalizePackageName(filePath, "eslint-config");
debug("Attempting to resolve " + normalizedPackageName); debug("Attempting to resolve " + normalizedPackageName);
filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo)); filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
return { filePath: filePath }; return { filePath };
} }
} }
@ -546,14 +546,14 @@ function load(filePath, applyEnvironments, relativeTo) {
module.exports = { module.exports = {
getBaseDir: getBaseDir, getBaseDir,
getLookupPath: getLookupPath, getLookupPath,
load: load, load,
resolve: resolve, resolve,
write: write, write,
applyExtends: applyExtends, applyExtends,
normalizePackageName: normalizePackageName, normalizePackageName,
CONFIG_FILES: CONFIG_FILES, CONFIG_FILES,
/** /**
* Retrieves the configuration filename for a given directory. It loops over all * Retrieves the configuration filename for a given directory. It loops over all
@ -562,7 +562,7 @@ module.exports = {
* @returns {?string} The filename of the configuration file for the directory * @returns {?string} The filename of the configuration file for the directory
* or null if there is no configuration file in the directory. * or null if there is no configuration file in the directory.
*/ */
getFilenameForDirectory: function(directory) { getFilenameForDirectory(directory) {
for (let i = 0, len = CONFIG_FILES.length; i < len; i++) { for (let i = 0, len = CONFIG_FILES.length; i < len; i++) {
const filename = path.join(directory, CONFIG_FILES[i]); const filename = path.join(directory, CONFIG_FILES[i]);

22
tools/eslint/lib/config/config-initializer.js

@ -305,8 +305,8 @@ function promptUser(callback) {
type: "list", type: "list",
name: "styleguide", name: "styleguide",
message: "Which style guide do you want to follow?", message: "Which style guide do you want to follow?",
choices: [{name: "Google", value: "google"}, {name: "AirBnB", value: "airbnb"}, {name: "Standard", value: "standard"}], choices: [{name: "Google", value: "google"}, {name: "Airbnb", value: "airbnb"}, {name: "Standard", value: "standard"}],
when: function(answers) { when(answers) {
answers.packageJsonExists = npmUtil.checkPackageJson(); answers.packageJsonExists = npmUtil.checkPackageJson();
return answers.source === "guide" && answers.packageJsonExists; return answers.source === "guide" && answers.packageJsonExists;
} }
@ -315,10 +315,10 @@ function promptUser(callback) {
type: "input", type: "input",
name: "patterns", name: "patterns",
message: "Which file(s), path(s), or glob(s) should be examined?", message: "Which file(s), path(s), or glob(s) should be examined?",
when: function(answers) { when(answers) {
return (answers.source === "auto"); return (answers.source === "auto");
}, },
validate: function(input) { validate(input) {
if (input.trim().length === 0 && input.trim() !== ",") { if (input.trim().length === 0 && input.trim() !== ",") {
return "You must tell us what code to examine. Try again."; return "You must tell us what code to examine. Try again.";
} }
@ -331,7 +331,7 @@ function promptUser(callback) {
message: "What format do you want your config file to be in?", message: "What format do you want your config file to be in?",
default: "JavaScript", default: "JavaScript",
choices: ["JavaScript", "YAML", "JSON"], choices: ["JavaScript", "YAML", "JSON"],
when: function(answers) { when(answers) {
return ((answers.source === "guide" && answers.packageJsonExists) || answers.source === "auto"); return ((answers.source === "guide" && answers.packageJsonExists) || answers.source === "auto");
} }
} }
@ -367,7 +367,7 @@ function promptUser(callback) {
name: "modules", name: "modules",
message: "Are you using ES6 modules?", message: "Are you using ES6 modules?",
default: false, default: false,
when: function(answers) { when(answers) {
return answers.es6 === true; return answers.es6 === true;
} }
}, },
@ -383,7 +383,7 @@ function promptUser(callback) {
name: "commonjs", name: "commonjs",
message: "Do you use CommonJS?", message: "Do you use CommonJS?",
default: false, default: false,
when: function(answers) { when(answers) {
return answers.env.some(function(env) { return answers.env.some(function(env) {
return env === "browser"; return env === "browser";
}); });
@ -400,7 +400,7 @@ function promptUser(callback) {
name: "react", name: "react",
message: "Do you use React", message: "Do you use React",
default: false, default: false,
when: function(answers) { when(answers) {
return answers.jsx; return answers.jsx;
} }
} }
@ -479,9 +479,9 @@ function promptUser(callback) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
const init = { const init = {
getConfigForStyleGuide: getConfigForStyleGuide, getConfigForStyleGuide,
processAnswers: processAnswers, processAnswers,
initializeConfig: /* istanbul ignore next */ function(callback) { /* istanbul ignore next */initializeConfig(callback) {
promptUser(callback); promptUser(callback);
} }
}; };

16
tools/eslint/lib/config/config-ops.js

@ -34,7 +34,7 @@ module.exports = {
* Creates an empty configuration object suitable for merging as a base. * Creates an empty configuration object suitable for merging as a base.
* @returns {Object} A configuration object. * @returns {Object} A configuration object.
*/ */
createEmptyConfig: function() { createEmptyConfig() {
return { return {
globals: {}, globals: {},
env: {}, env: {},
@ -49,7 +49,7 @@ module.exports = {
* @returns {Object} A configuration object with the appropriate rules and globals * @returns {Object} A configuration object with the appropriate rules and globals
* set. * set.
*/ */
createEnvironmentConfig: function(env) { createEnvironmentConfig(env) {
const envConfig = this.createEmptyConfig(); const envConfig = this.createEmptyConfig();
@ -84,7 +84,7 @@ module.exports = {
* @param {Object} config The configuration information. * @param {Object} config The configuration information.
* @returns {Object} The updated configuration information. * @returns {Object} The updated configuration information.
*/ */
applyEnvironments: function(config) { applyEnvironments(config) {
if (config.env && typeof config.env === "object") { if (config.env && typeof config.env === "object") {
debug("Apply environment settings to config"); debug("Apply environment settings to config");
return this.merge(this.createEnvironmentConfig(config.env), config); return this.merge(this.createEnvironmentConfig(config.env), config);
@ -196,7 +196,7 @@ module.exports = {
* @param {Object} config The config object to normalize. * @param {Object} config The config object to normalize.
* @returns {void} * @returns {void}
*/ */
normalize: function(config) { normalize(config) {
if (config.rules) { if (config.rules) {
Object.keys(config.rules).forEach(function(ruleId) { Object.keys(config.rules).forEach(function(ruleId) {
@ -218,7 +218,7 @@ module.exports = {
* @param {Object} config The config object to normalize. * @param {Object} config The config object to normalize.
* @returns {void} * @returns {void}
*/ */
normalizeToStrings: function(config) { normalizeToStrings(config) {
if (config.rules) { if (config.rules) {
Object.keys(config.rules).forEach(function(ruleId) { Object.keys(config.rules).forEach(function(ruleId) {
@ -238,7 +238,7 @@ module.exports = {
* @param {int|string|Array} ruleConfig The configuration for an individual rule. * @param {int|string|Array} ruleConfig The configuration for an individual rule.
* @returns {boolean} True if the rule represents an error, false if not. * @returns {boolean} True if the rule represents an error, false if not.
*/ */
isErrorSeverity: function(ruleConfig) { isErrorSeverity(ruleConfig) {
let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig;
@ -254,7 +254,7 @@ module.exports = {
* @param {number|string|Array} ruleConfig - The configuration for an individual rule. * @param {number|string|Array} ruleConfig - The configuration for an individual rule.
* @returns {boolean} `true` if the configuration has valid severity. * @returns {boolean} `true` if the configuration has valid severity.
*/ */
isValidSeverity: function(ruleConfig) { isValidSeverity(ruleConfig) {
let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig;
if (typeof severity === "string") { if (typeof severity === "string") {
@ -268,7 +268,7 @@ module.exports = {
* @param {Object} config - The configuration for rules. * @param {Object} config - The configuration for rules.
* @returns {boolean} `true` if the configuration has valid severity. * @returns {boolean} `true` if the configuration has valid severity.
*/ */
isEverySeverityValid: function(config) { isEverySeverityValid(config) {
return Object.keys(config).every(function(ruleId) { return Object.keys(config).every(function(ruleId) {
return this.isValidSeverity(config[ruleId]); return this.isValidSeverity(config[ruleId]);
}, this); }, this);

14
tools/eslint/lib/config/config-rule.js

@ -202,7 +202,7 @@ RuleConfigSet.prototype = {
* @param {number} [severity=2] The level of severity for the rule (0, 1, 2) * @param {number} [severity=2] The level of severity for the rule (0, 1, 2)
* @returns {void} * @returns {void}
*/ */
addErrorSeverity: function(severity) { addErrorSeverity(severity) {
severity = severity || 2; severity = severity || 2;
this.ruleConfigs = this.ruleConfigs.map(function(config) { this.ruleConfigs = this.ruleConfigs.map(function(config) {
@ -219,7 +219,7 @@ RuleConfigSet.prototype = {
* @param {string[]} enums Array of valid rule options (e.g. ["always", "never"]) * @param {string[]} enums Array of valid rule options (e.g. ["always", "never"])
* @returns {void} * @returns {void}
*/ */
addEnums: function(enums) { addEnums(enums) {
this.ruleConfigs = this.ruleConfigs.concat(combineArrays(this.ruleConfigs, enums)); this.ruleConfigs = this.ruleConfigs.concat(combineArrays(this.ruleConfigs, enums));
}, },
@ -228,10 +228,10 @@ RuleConfigSet.prototype = {
* @param {Object} obj Schema item with type === "object" * @param {Object} obj Schema item with type === "object"
* @returns {void} * @returns {void}
*/ */
addObject: function(obj) { addObject(obj) {
const objectConfigSet = { const objectConfigSet = {
objectConfigs: [], objectConfigs: [],
add: function(property, values) { add(property, values) {
for (let idx = 0; idx < values.length; idx++) { for (let idx = 0; idx < values.length; idx++) {
const optionObj = {}; const optionObj = {};
@ -240,7 +240,7 @@ RuleConfigSet.prototype = {
} }
}, },
combine: function() { combine() {
this.objectConfigs = groupByProperty(this.objectConfigs).reduce(function(accumulator, objArr) { this.objectConfigs = groupByProperty(this.objectConfigs).reduce(function(accumulator, objArr) {
return combinePropertyObjects(accumulator, objArr); return combinePropertyObjects(accumulator, objArr);
}, []); }, []);
@ -317,6 +317,6 @@ function createCoreRuleConfigs() {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = { module.exports = {
generateConfigsFromSchema: generateConfigsFromSchema, generateConfigsFromSchema,
createCoreRuleConfigs: createCoreRuleConfigs createCoreRuleConfigs
}; };

6
tools/eslint/lib/config/config-validator.js

@ -171,7 +171,7 @@ function validate(config, source) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
module.exports = { module.exports = {
getRuleOptionsSchema: getRuleOptionsSchema, getRuleOptionsSchema,
validate: validate, validate,
validateRuleOptions: validateRuleOptions validateRuleOptions
}; };

52
tools/eslint/lib/config/plugins.js

@ -9,7 +9,7 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
const Environments = require("./environments"), const Environments = require("./environments"),
rules = require("../rules"); Rules = require("../rules");
const debug = require("debug")("eslint:plugins"); const debug = require("debug")("eslint:plugins");
@ -55,9 +55,9 @@ function removeNamespace(pluginName) {
module.exports = { module.exports = {
removePrefix: removePrefix, removePrefix,
getNamespace: getNamespace, getNamespace,
removeNamespace: removeNamespace, removeNamespace,
/** /**
* Defines a plugin with a given name rather than loading from disk. * Defines a plugin with a given name rather than loading from disk.
@ -65,18 +65,22 @@ module.exports = {
* @param {Object} plugin The plugin object. * @param {Object} plugin The plugin object.
* @returns {void} * @returns {void}
*/ */
define: function(pluginName, plugin) { define(pluginName, plugin) {
const pluginNameWithoutNamespace = removeNamespace(pluginName), const pluginNamespace = getNamespace(pluginName),
pluginNameWithoutPrefix = removePrefix(pluginNameWithoutNamespace); pluginNameWithoutNamespace = removeNamespace(pluginName),
pluginNameWithoutPrefix = removePrefix(pluginNameWithoutNamespace),
plugins[pluginNameWithoutPrefix] = plugin; shortName = pluginNamespace + pluginNameWithoutPrefix;
// load up environments and rules // load up environments and rules
Environments.importPlugin(plugin, pluginNameWithoutPrefix); plugins[shortName] = plugin;
Environments.importPlugin(plugin, shortName);
Rules.importPlugin(plugin, shortName);
if (plugin.rules) { // load up environments and rules for the name that '@scope/' was omitted
rules.import(plugin.rules, pluginNameWithoutPrefix); // 3 lines below will be removed by 4.0.0
} plugins[pluginNameWithoutPrefix] = plugin;
Environments.importPlugin(plugin, pluginNameWithoutPrefix);
Rules.importPlugin(plugin, pluginNameWithoutPrefix);
}, },
/** /**
@ -84,7 +88,7 @@ module.exports = {
* @param {string} pluginName The name of the plugin to retrieve. * @param {string} pluginName The name of the plugin to retrieve.
* @returns {Object} The plugin or null if not loaded. * @returns {Object} The plugin or null if not loaded.
*/ */
get: function(pluginName) { get(pluginName) {
return plugins[pluginName] || null; return plugins[pluginName] || null;
}, },
@ -92,7 +96,7 @@ module.exports = {
* Returns all plugins that are loaded. * Returns all plugins that are loaded.
* @returns {Object} The plugins cache. * @returns {Object} The plugins cache.
*/ */
getAll: function() { getAll() {
return plugins; return plugins;
}, },
@ -102,21 +106,23 @@ module.exports = {
* @returns {void} * @returns {void}
* @throws {Error} If the plugin cannot be loaded. * @throws {Error} If the plugin cannot be loaded.
*/ */
load: function(pluginName) { load(pluginName) {
const pluginNamespace = getNamespace(pluginName), const pluginNamespace = getNamespace(pluginName),
pluginNameWithoutNamespace = removeNamespace(pluginName), pluginNameWithoutNamespace = removeNamespace(pluginName),
pluginNameWithoutPrefix = removePrefix(pluginNameWithoutNamespace); pluginNameWithoutPrefix = removePrefix(pluginNameWithoutNamespace),
shortName = pluginNamespace + pluginNameWithoutPrefix,
longName = pluginNamespace + PLUGIN_NAME_PREFIX + pluginNameWithoutPrefix;
let plugin = null; let plugin = null;
if (!plugins[pluginNameWithoutPrefix]) { if (!plugins[shortName]) {
try { try {
plugin = require(pluginNamespace + PLUGIN_NAME_PREFIX + pluginNameWithoutPrefix); plugin = require(longName);
} catch (err) { } catch (err) {
debug("Failed to load plugin eslint-plugin-" + pluginNameWithoutPrefix + ". Proceeding without it."); debug("Failed to load plugin " + longName + ".");
err.message = "Failed to load plugin " + pluginName + ": " + err.message; err.message = "Failed to load plugin " + pluginName + ": " + err.message;
err.messageTemplate = "plugin-missing"; err.messageTemplate = "plugin-missing";
err.messageData = { err.messageData = {
pluginName: pluginNameWithoutPrefix pluginName: longName
}; };
throw err; throw err;
} }
@ -131,7 +137,7 @@ module.exports = {
* @returns {void} * @returns {void}
* @throws {Error} If a plugin cannot be loaded. * @throws {Error} If a plugin cannot be loaded.
*/ */
loadAll: function(pluginNames) { loadAll(pluginNames) {
pluginNames.forEach(this.load, this); pluginNames.forEach(this.load, this);
}, },
@ -139,7 +145,7 @@ module.exports = {
* Resets plugin information. Use for tests only. * Resets plugin information. Use for tests only.
* @returns {void} * @returns {void}
*/ */
testReset: function() { testReset() {
plugins = Object.create(null); plugins = Object.create(null);
} }
}; };

56
tools/eslint/lib/eslint.js

@ -59,7 +59,7 @@ function parseBooleanConfig(string, comment) {
items[name] = { items[name] = {
value: (value === "true"), value: (value === "true"),
comment: comment comment
}; };
}); });
@ -240,14 +240,14 @@ function disableReporting(reportingConfig, start, rulesToDisable) {
if (rulesToDisable.length) { if (rulesToDisable.length) {
rulesToDisable.forEach(function(rule) { rulesToDisable.forEach(function(rule) {
reportingConfig.push({ reportingConfig.push({
start: start, start,
end: null, end: null,
rule: rule rule
}); });
}); });
} else { } else {
reportingConfig.push({ reportingConfig.push({
start: start, start,
end: null, end: null,
rule: null rule: null
}); });
@ -406,6 +406,28 @@ function isDisabledByReportingConfig(reportingConfig, ruleId, location) {
return false; return false;
} }
/**
* Normalize ECMAScript version from the initial config
* @param {number} ecmaVersion ECMAScript version from the initial config
* @param {boolean} isModule Whether the source type is module or not
* @returns {number} normalized ECMAScript version
*/
function normalizeEcmaVersion(ecmaVersion, isModule) {
// Need at least ES6 for modules
if (isModule && (!ecmaVersion || ecmaVersion < 6)) {
ecmaVersion = 6;
}
// Calculate ECMAScript edition number from official year version starting with
// ES2015, which corresponds with ES6 (or a difference of 2009).
if (ecmaVersion >= 2015) {
ecmaVersion -= 2009;
}
return ecmaVersion;
}
/** /**
* Process initial config to make it safe to extend by file comment config * Process initial config to make it safe to extend by file comment config
* @param {Object} config Initial config * @param {Object} config Initial config
@ -453,21 +475,19 @@ function prepareConfig(config) {
settings: ConfigOps.merge({}, config.settings || {}), settings: ConfigOps.merge({}, config.settings || {}),
parserOptions: ConfigOps.merge(parserOptions, config.parserOptions || {}) parserOptions: ConfigOps.merge(parserOptions, config.parserOptions || {})
}; };
const isModule = preparedConfig.parserOptions.sourceType === "module";
if (preparedConfig.parserOptions.sourceType === "module") { if (isModule) {
if (!preparedConfig.parserOptions.ecmaFeatures) { if (!preparedConfig.parserOptions.ecmaFeatures) {
preparedConfig.parserOptions.ecmaFeatures = {}; preparedConfig.parserOptions.ecmaFeatures = {};
} }
// can't have global return inside of modules // can't have global return inside of modules
preparedConfig.parserOptions.ecmaFeatures.globalReturn = false; preparedConfig.parserOptions.ecmaFeatures.globalReturn = false;
// also need at least ES6 for modules
if (!preparedConfig.parserOptions.ecmaVersion || preparedConfig.parserOptions.ecmaVersion < 6) {
preparedConfig.parserOptions.ecmaVersion = 6;
}
} }
preparedConfig.parserOptions.ecmaVersion = normalizeEcmaVersion(preparedConfig.parserOptions.ecmaVersion, isModule);
return preparedConfig; return preparedConfig;
} }
@ -485,7 +505,7 @@ function createStubRule(message) {
*/ */
function createRuleModule(context) { function createRuleModule(context) {
return { return {
Program: function(node) { Program(node) {
context.report(node, message); context.report(node, message);
} }
}; };
@ -632,7 +652,7 @@ module.exports = (function() {
ruleId: null, ruleId: null,
fatal: true, fatal: true,
severity: 2, severity: 2,
source: source, source,
message: "Parsing error: " + message, message: "Parsing error: " + message,
line: ex.lineNumber, line: ex.lineNumber,
@ -841,7 +861,7 @@ module.exports = (function() {
ignoreEval: true, ignoreEval: true,
nodejsScope: ecmaFeatures.globalReturn, nodejsScope: ecmaFeatures.globalReturn,
impliedStrict: ecmaFeatures.impliedStrict, impliedStrict: ecmaFeatures.impliedStrict,
ecmaVersion: ecmaVersion, ecmaVersion,
sourceType: currentConfig.parserOptions.sourceType || "script", sourceType: currentConfig.parserOptions.sourceType || "script",
fallback: Traverser.getKeys fallback: Traverser.getKeys
}); });
@ -890,11 +910,11 @@ module.exports = (function() {
* and react accordingly. * and react accordingly.
*/ */
traverser.traverse(ast, { traverser.traverse(ast, {
enter: function(node, parent) { enter(node, parent) {
node.parent = parent; node.parent = parent;
eventGenerator.enterNode(node); eventGenerator.enterNode(node);
}, },
leave: function(node) { leave(node) {
eventGenerator.leaveNode(node); eventGenerator.leaveNode(node);
} }
}); });
@ -965,9 +985,9 @@ module.exports = (function() {
} }
const problem = { const problem = {
ruleId: ruleId, ruleId,
severity: severity, severity,
message: message, message,
line: location.line, line: location.line,
column: location.column + 1, // switch to 1-base instead of 0-base column: location.column + 1, // switch to 1-base instead of 0-base
nodeType: node && node.type, nodeType: node && node.type,

8
tools/eslint/lib/formatters/html.js

@ -75,9 +75,9 @@ function renderMessages(messages, parentIndex) {
const columnNumber = message.column || 0; const columnNumber = message.column || 0;
return messageTemplate({ return messageTemplate({
parentIndex: parentIndex, parentIndex,
lineNumber: lineNumber, lineNumber,
columnNumber: columnNumber, columnNumber,
severityNumber: message.severity, severityNumber: message.severity,
severityName: message.severity === 1 ? "Warning" : "Error", severityName: message.severity === 1 ? "Warning" : "Error",
message: message.message, message: message.message,
@ -93,7 +93,7 @@ function renderMessages(messages, parentIndex) {
function renderResults(results) { function renderResults(results) {
return lodash.map(results, function(result, index) { return lodash.map(results, function(result, index) {
return resultTemplate({ return resultTemplate({
index: index, index,
color: renderColor(result.errorCount, result.warningCount), color: renderColor(result.errorCount, result.warningCount),
filePath: result.filePath, filePath: result.filePath,
summary: renderSummary(result.errorCount, result.warningCount) summary: renderSummary(result.errorCount, result.warningCount)

2
tools/eslint/lib/formatters/stylish.js

@ -67,7 +67,7 @@ module.exports = function(results) {
}), }),
{ {
align: ["", "r", "l"], align: ["", "r", "l"],
stringLength: function(str) { stringLength(str) {
return chalk.stripColor(str).length; return chalk.stripColor(str).length;
} }
} }

4
tools/eslint/lib/formatters/table.js

@ -78,7 +78,7 @@ function drawTable(messages) {
wrapWord: true wrapWord: true
} }
}, },
drawHorizontalLine: function(index) { drawHorizontalLine(index) {
return index === 1; return index === 1;
} }
}); });
@ -143,7 +143,7 @@ module.exports = function(report) {
wrapWord: true wrapWord: true
} }
}, },
drawHorizontalLine: function() { drawHorizontalLine() {
return true; return true;
} }
}); });

57
tools/eslint/lib/ignored-paths.js

@ -23,9 +23,15 @@ const debug = require("debug")("eslint:ignored-paths");
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
const ESLINT_IGNORE_FILENAME = ".eslintignore"; const ESLINT_IGNORE_FILENAME = ".eslintignore";
/**
* Adds `"*"` at the end of `"node_modules/"`,
* so that subtle directories could be re-included by .gitignore patterns
* such as `"!node_modules/should_not_ignored"`
*/
const DEFAULT_IGNORE_DIRS = [ const DEFAULT_IGNORE_DIRS = [
"node_modules/", "/node_modules/*",
"bower_components/" "/bower_components/*"
]; ];
const DEFAULT_OPTIONS = { const DEFAULT_OPTIONS = {
dotfiles: false, dotfiles: false,
@ -40,7 +46,7 @@ const DEFAULT_OPTIONS = {
/** /**
* Find an ignore file in the current directory. * Find an ignore file in the current directory.
* @param {stirng} cwd Current working directory * @param {string} cwd Current working directory
* @returns {string} Path of ignore file or an empty string. * @returns {string} Path of ignore file or an empty string.
*/ */
function findIgnoreFile(cwd) { function findIgnoreFile(cwd) {
@ -96,9 +102,7 @@ function IgnoredPaths(options) {
return ig.add(fs.readFileSync(filepath, "utf8")); return ig.add(fs.readFileSync(filepath, "utf8"));
} }
this.defaultPatterns = DEFAULT_IGNORE_DIRS.map(function(dir) { this.defaultPatterns = [].concat(DEFAULT_IGNORE_DIRS, options.patterns || []);
return "/" + dir + "*";
}).concat(options.patterns || []);
this.baseDir = options.cwd; this.baseDir = options.cwd;
this.ig = { this.ig = {
@ -191,34 +195,37 @@ IgnoredPaths.prototype.contains = function(filepath, category) {
/** /**
* Returns a list of dir patterns for glob to ignore * Returns a list of dir patterns for glob to ignore
* @returns {string[]} list of glob ignore patterns * @returns {function()} method to check whether a folder should be ignored by glob.
*/ */
IgnoredPaths.prototype.getIgnoredFoldersGlobPatterns = function() { IgnoredPaths.prototype.getIgnoredFoldersGlobChecker = function() {
let dirs = DEFAULT_IGNORE_DIRS;
const ig = ignore().add(DEFAULT_IGNORE_DIRS);
if (this.options.ignore) { if (this.options.ignore) {
ig.add(this.ig.custom);
}
/* eslint-disable no-underscore-dangle */ const filter = ig.createFilter();
const patterns = this.ig.custom._rules.filter(function(rule) { /**
return rule.negative; * TODO
}).map(function(rule) { * 1.
return rule.origin; * Actually, it should be `this.options.baseDir`, which is the base dir of `ignore-path`,
}); * as well as Line 177.
* But doing this leads to a breaking change and fails tests.
* Related to #6759
*/
const base = this.options.cwd;
/* eslint-enable no-underscore-dangle */ return function(absolutePath) {
const relative = pathUtil.getRelativePath(absolutePath, base);
dirs = dirs.filter(function(dir) { if (!relative) {
return patterns.every(function(p) { return false;
return (p.indexOf("!" + dir) !== 0 && p.indexOf("!/" + dir) !== 0);
});
});
} }
return !filter(relative);
return dirs.map(function(dir) { };
return dir + "**";
});
}; };
module.exports = IgnoredPaths; module.exports = IgnoredPaths;

8
tools/eslint/lib/internal-rules/internal-no-invalid-meta.js

@ -176,12 +176,12 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
let exportsNode; let exportsNode;
let ruleIsFixable = false; let ruleIsFixable = false;
return { return {
AssignmentExpression: function(node) { AssignmentExpression(node) {
if (node.left && if (node.left &&
node.right && node.right &&
node.left.type === "MemberExpression" && node.left.type === "MemberExpression" &&
@ -192,7 +192,7 @@ module.exports = {
} }
}, },
CallExpression: function(node) { CallExpression(node) {
// If the rule has a call for `context.report` and a property `fix` // If the rule has a call for `context.report` and a property `fix`
// is being passed in, then we consider that the rule is fixable. // is being passed in, then we consider that the rule is fixable.
@ -214,7 +214,7 @@ module.exports = {
} }
}, },
"Program:exit": function() { "Program:exit"() {
if (!isCorrectExportsFormat(exportsNode)) { if (!isCorrectExportsFormat(exportsNode)) {
context.report(exportsNode, "Rule does not export an Object. Make sure the rule follows the new rule format."); context.report(exportsNode, "Rule does not export an Object. Make sure the rule follows the new rule format.");
return; return;

4
tools/eslint/lib/logging.js

@ -14,7 +14,7 @@ module.exports = {
* Cover for console.log * Cover for console.log
* @returns {void} * @returns {void}
*/ */
info: function() { info() {
console.log.apply(console, Array.prototype.slice.call(arguments)); console.log.apply(console, Array.prototype.slice.call(arguments));
}, },
@ -22,7 +22,7 @@ module.exports = {
* Cover for console.error * Cover for console.error
* @returns {void} * @returns {void}
*/ */
error: function() { error() {
console.error.apply(console, Array.prototype.slice.call(arguments)); console.error.apply(console, Array.prototype.slice.call(arguments));
} }
}; };

4
tools/eslint/lib/rule-context.js

@ -96,7 +96,7 @@ RuleContext.prototype = {
* Passthrough to eslint.getSourceCode(). * Passthrough to eslint.getSourceCode().
* @returns {SourceCode} The SourceCode object for the code. * @returns {SourceCode} The SourceCode object for the code.
*/ */
getSourceCode: function() { getSourceCode() {
return this.eslint.getSourceCode(); return this.eslint.getSourceCode();
}, },
@ -110,7 +110,7 @@ RuleContext.prototype = {
* with symbols being replaced by this object's values. * with symbols being replaced by this object's values.
* @returns {void} * @returns {void}
*/ */
report: function(nodeOrDescriptor, location, message, opts) { report(nodeOrDescriptor, location, message, opts) {
// check to see if it's a new style call // check to see if it's a new style call
if (arguments.length === 1) { if (arguments.length === 1) {

24
tools/eslint/lib/rules.js

@ -47,25 +47,27 @@ function load(rulesDir, cwd) {
/** /**
* Registers all given rules of a plugin. * Registers all given rules of a plugin.
* @param {Object} pluginRules A key/value map of rule definitions. * @param {Object} plugin The plugin object to import.
* @param {string} pluginName The name of the plugin without prefix (`eslint-plugin-`). * @param {string} pluginName The name of the plugin without prefix (`eslint-plugin-`).
* @returns {void} * @returns {void}
*/ */
function importPlugin(pluginRules, pluginName) { function importPlugin(plugin, pluginName) {
Object.keys(pluginRules).forEach(function(ruleId) { if (plugin.rules) {
Object.keys(plugin.rules).forEach(function(ruleId) {
const qualifiedRuleId = pluginName + "/" + ruleId, const qualifiedRuleId = pluginName + "/" + ruleId,
rule = pluginRules[ruleId]; rule = plugin.rules[ruleId];
define(qualifiedRuleId, rule); define(qualifiedRuleId, rule);
}); });
} }
}
/** /**
* Access rule handler by id (file name). * Access rule handler by id (file name).
* @param {string} ruleId Rule id (file name). * @param {string} ruleId Rule id (file name).
* @returns {Function} Rule handler. * @returns {Function} Rule handler.
*/ */
function get(ruleId) { function getHandler(ruleId) {
if (typeof rules[ruleId] === "string") { if (typeof rules[ruleId] === "string") {
return require(rules[ruleId]); return require(rules[ruleId]);
} else { } else {
@ -83,17 +85,17 @@ function testClear() {
} }
module.exports = { module.exports = {
define: define, define,
load: load, load,
import: importPlugin, importPlugin,
get: get, get: getHandler,
testClear: testClear, testClear,
/** /**
* Resets rules to its starting state. Use for tests only. * Resets rules to its starting state. Use for tests only.
* @returns {void} * @returns {void}
*/ */
testReset: function() { testReset() {
testClear(); testClear();
load(); load();
} }

4
tools/eslint/lib/rules/accessor-pairs.js

@ -90,7 +90,7 @@ module.exports = {
additionalProperties: false additionalProperties: false
}] }]
}, },
create: function(context) { create(context) {
const config = context.options[0] || {}; const config = context.options[0] || {};
const checkGetWithoutSet = config.getWithoutSet === true; const checkGetWithoutSet = config.getWithoutSet === true;
const checkSetWithoutGet = config.setWithoutGet !== false; const checkSetWithoutGet = config.setWithoutGet !== false;
@ -146,7 +146,7 @@ module.exports = {
} }
return { return {
ObjectExpression: function(node) { ObjectExpression(node) {
if (checkSetWithoutGet || checkGetWithoutSet) { if (checkSetWithoutGet || checkGetWithoutSet) {
checkLonelySetGet(node); checkLonelySetGet(node);
} }

20
tools/eslint/lib/rules/array-bracket-spacing.js

@ -39,7 +39,7 @@ module.exports = {
} }
] ]
}, },
create: function(context) { create(context) {
const spaced = context.options[0] === "always", const spaced = context.options[0] === "always",
sourceCode = context.getSourceCode(); sourceCode = context.getSourceCode();
@ -55,7 +55,7 @@ module.exports = {
} }
const options = { const options = {
spaced: spaced, spaced,
singleElementException: isOptionSet("singleValue"), singleElementException: isOptionSet("singleValue"),
objectsInArraysException: isOptionSet("objectsInArrays"), objectsInArraysException: isOptionSet("objectsInArrays"),
arraysInArraysException: isOptionSet("arraysInArrays") arraysInArraysException: isOptionSet("arraysInArrays")
@ -73,10 +73,10 @@ module.exports = {
*/ */
function reportNoBeginningSpace(node, token) { function reportNoBeginningSpace(node, token) {
context.report({ context.report({
node: node, node,
loc: token.loc.start, loc: token.loc.start,
message: "There should be no space after '" + token.value + "'.", message: "There should be no space after '" + token.value + "'.",
fix: function(fixer) { fix(fixer) {
const nextToken = sourceCode.getTokenAfter(token); const nextToken = sourceCode.getTokenAfter(token);
return fixer.removeRange([token.range[1], nextToken.range[0]]); return fixer.removeRange([token.range[1], nextToken.range[0]]);
@ -92,10 +92,10 @@ module.exports = {
*/ */
function reportNoEndingSpace(node, token) { function reportNoEndingSpace(node, token) {
context.report({ context.report({
node: node, node,
loc: token.loc.start, loc: token.loc.start,
message: "There should be no space before '" + token.value + "'.", message: "There should be no space before '" + token.value + "'.",
fix: function(fixer) { fix(fixer) {
const previousToken = sourceCode.getTokenBefore(token); const previousToken = sourceCode.getTokenBefore(token);
return fixer.removeRange([previousToken.range[1], token.range[0]]); return fixer.removeRange([previousToken.range[1], token.range[0]]);
@ -111,10 +111,10 @@ module.exports = {
*/ */
function reportRequiredBeginningSpace(node, token) { function reportRequiredBeginningSpace(node, token) {
context.report({ context.report({
node: node, node,
loc: token.loc.start, loc: token.loc.start,
message: "A space is required after '" + token.value + "'.", message: "A space is required after '" + token.value + "'.",
fix: function(fixer) { fix(fixer) {
return fixer.insertTextAfter(token, " "); return fixer.insertTextAfter(token, " ");
} }
}); });
@ -128,10 +128,10 @@ module.exports = {
*/ */
function reportRequiredEndingSpace(node, token) { function reportRequiredEndingSpace(node, token) {
context.report({ context.report({
node: node, node,
loc: token.loc.start, loc: token.loc.start,
message: "A space is required before '" + token.value + "'.", message: "A space is required before '" + token.value + "'.",
fix: function(fixer) { fix(fixer) {
return fixer.insertTextBefore(token, " "); return fixer.insertTextBefore(token, " ");
} }
}); });

14
tools/eslint/lib/rules/array-callback-return.js

@ -142,7 +142,7 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
let funcInfo = { let funcInfo = {
upper: null, upper: null,
codePath: null, codePath: null,
@ -165,7 +165,7 @@ module.exports = {
funcInfo.codePath.currentSegments.some(isReachable) funcInfo.codePath.currentSegments.some(isReachable)
) { ) {
context.report({ context.report({
node: node, node,
loc: getLocation(node, context.getSourceCode()).loc.start, loc: getLocation(node, context.getSourceCode()).loc.start,
message: funcInfo.hasReturn message: funcInfo.hasReturn
? "Expected to return a value at the end of this function." ? "Expected to return a value at the end of this function."
@ -177,10 +177,10 @@ module.exports = {
return { return {
// Stacks this function's information. // Stacks this function's information.
onCodePathStart: function(codePath, node) { onCodePathStart(codePath, node) {
funcInfo = { funcInfo = {
upper: funcInfo, upper: funcInfo,
codePath: codePath, codePath,
hasReturn: false, hasReturn: false,
shouldCheck: shouldCheck:
TARGET_NODE_TYPE.test(node.type) && TARGET_NODE_TYPE.test(node.type) &&
@ -190,18 +190,18 @@ module.exports = {
}, },
// Pops this function's information. // Pops this function's information.
onCodePathEnd: function() { onCodePathEnd() {
funcInfo = funcInfo.upper; funcInfo = funcInfo.upper;
}, },
// Checks the return statement is valid. // Checks the return statement is valid.
ReturnStatement: function(node) { ReturnStatement(node) {
if (funcInfo.shouldCheck) { if (funcInfo.shouldCheck) {
funcInfo.hasReturn = true; funcInfo.hasReturn = true;
if (!node.argument) { if (!node.argument) {
context.report({ context.report({
node: node, node,
message: "Expected a return value." message: "Expected a return value."
}); });
} }

8
tools/eslint/lib/rules/arrow-body-style.js

@ -49,7 +49,7 @@ module.exports = {
} }
}, },
create: function(context) { create(context) {
const options = context.options; const options = context.options;
const always = options[0] === "always"; const always = options[0] === "always";
const asNeeded = !options[0] || options[0] === "as-needed"; const asNeeded = !options[0] || options[0] === "as-needed";
@ -67,7 +67,7 @@ module.exports = {
if (arrowBody.type === "BlockStatement") { if (arrowBody.type === "BlockStatement") {
if (never) { if (never) {
context.report({ context.report({
node: node, node,
loc: arrowBody.loc.start, loc: arrowBody.loc.start,
message: "Unexpected block statement surrounding arrow body." message: "Unexpected block statement surrounding arrow body."
}); });
@ -85,7 +85,7 @@ module.exports = {
if (asNeeded && blockBody[0].type === "ReturnStatement") { if (asNeeded && blockBody[0].type === "ReturnStatement") {
context.report({ context.report({
node: node, node,
loc: arrowBody.loc.start, loc: arrowBody.loc.start,
message: "Unexpected block statement surrounding arrow body." message: "Unexpected block statement surrounding arrow body."
}); });
@ -94,7 +94,7 @@ module.exports = {
} else { } else {
if (always || (asNeeded && requireReturnForObjectLiteral && arrowBody.type === "ObjectExpression")) { if (always || (asNeeded && requireReturnForObjectLiteral && arrowBody.type === "ObjectExpression")) {
context.report({ context.report({
node: node, node,
loc: arrowBody.loc.start, loc: arrowBody.loc.start,
message: "Expected block statement surrounding arrow body." message: "Expected block statement surrounding arrow body."
}); });

20
tools/eslint/lib/rules/arrow-parens.js

@ -34,7 +34,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const message = "Expected parentheses around arrow function argument."; const message = "Expected parentheses around arrow function argument.";
const asNeededMessage = "Unexpected parentheses around single function argument."; const asNeededMessage = "Unexpected parentheses around single function argument.";
const asNeeded = context.options[0] === "as-needed"; const asNeeded = context.options[0] === "as-needed";
@ -62,9 +62,9 @@ module.exports = {
) { ) {
if (token.type === "Punctuator" && token.value === "(") { if (token.type === "Punctuator" && token.value === "(") {
context.report({ context.report({
node: node, node,
message: requireForBlockBodyMessage, message: requireForBlockBodyMessage,
fix: function(fixer) { fix(fixer) {
const paramToken = context.getTokenAfter(token); const paramToken = context.getTokenAfter(token);
const closingParenToken = context.getTokenAfter(paramToken); const closingParenToken = context.getTokenAfter(paramToken);
@ -84,9 +84,9 @@ module.exports = {
) { ) {
if (token.type !== "Punctuator" || token.value !== "(") { if (token.type !== "Punctuator" || token.value !== "(") {
context.report({ context.report({
node: node, node,
message: requireForBlockBodyNoParensMessage, message: requireForBlockBodyNoParensMessage,
fix: function(fixer) { fix(fixer) {
return fixer.replaceText(token, "(" + token.value + ")"); return fixer.replaceText(token, "(" + token.value + ")");
} }
}); });
@ -98,9 +98,9 @@ module.exports = {
if (asNeeded && node.params.length === 1 && node.params[0].type === "Identifier") { if (asNeeded && node.params.length === 1 && node.params[0].type === "Identifier") {
if (token.type === "Punctuator" && token.value === "(") { if (token.type === "Punctuator" && token.value === "(") {
context.report({ context.report({
node: node, node,
message: asNeededMessage, message: asNeededMessage,
fix: function(fixer) { fix(fixer) {
const paramToken = context.getTokenAfter(token); const paramToken = context.getTokenAfter(token);
const closingParenToken = context.getTokenAfter(paramToken); const closingParenToken = context.getTokenAfter(paramToken);
@ -120,9 +120,9 @@ module.exports = {
// (x) => x // (x) => x
if (after.value !== ")") { if (after.value !== ")") {
context.report({ context.report({
node: node, node,
message: message, message,
fix: function(fixer) { fix(fixer) {
return fixer.replaceText(token, "(" + token.value + ")"); return fixer.replaceText(token, "(" + token.value + ")");
} }
}); });

14
tools/eslint/lib/rules/arrow-spacing.js

@ -34,7 +34,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
// merge rules with default // merge rules with default
const rule = { before: true, after: true }, const rule = { before: true, after: true },
@ -60,7 +60,7 @@ module.exports = {
} }
const after = sourceCode.getTokenAfter(t); const after = sourceCode.getTokenAfter(t);
return { before: before, arrow: t, after: after }; return { before, arrow: t, after };
} }
/** /**
@ -72,7 +72,7 @@ module.exports = {
const before = tokens.arrow.range[0] - tokens.before.range[1]; const before = tokens.arrow.range[0] - tokens.before.range[1];
const after = tokens.after.range[0] - tokens.arrow.range[1]; const after = tokens.after.range[0] - tokens.arrow.range[1];
return { before: before, after: after }; return { before, after };
} }
/** /**
@ -93,7 +93,7 @@ module.exports = {
context.report({ context.report({
node: tokens.before, node: tokens.before,
message: "Missing space before =>.", message: "Missing space before =>.",
fix: function(fixer) { fix(fixer) {
return fixer.insertTextBefore(tokens.arrow, " "); return fixer.insertTextBefore(tokens.arrow, " ");
} }
}); });
@ -105,7 +105,7 @@ module.exports = {
context.report({ context.report({
node: tokens.before, node: tokens.before,
message: "Unexpected space before =>.", message: "Unexpected space before =>.",
fix: function(fixer) { fix(fixer) {
return fixer.removeRange([tokens.before.range[1], tokens.arrow.range[0]]); return fixer.removeRange([tokens.before.range[1], tokens.arrow.range[0]]);
} }
}); });
@ -119,7 +119,7 @@ module.exports = {
context.report({ context.report({
node: tokens.after, node: tokens.after,
message: "Missing space after =>.", message: "Missing space after =>.",
fix: function(fixer) { fix(fixer) {
return fixer.insertTextAfter(tokens.arrow, " "); return fixer.insertTextAfter(tokens.arrow, " ");
} }
}); });
@ -131,7 +131,7 @@ module.exports = {
context.report({ context.report({
node: tokens.after, node: tokens.after,
message: "Unexpected space after =>.", message: "Unexpected space after =>.",
fix: function(fixer) { fix(fixer) {
return fixer.removeRange([tokens.arrow.range[1], tokens.after.range[0]]); return fixer.removeRange([tokens.arrow.range[1], tokens.after.range[0]]);
} }
}); });

4
tools/eslint/lib/rules/block-scoped-var.js

@ -19,7 +19,7 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
let stack = []; let stack = [];
/** /**
@ -92,7 +92,7 @@ module.exports = {
} }
return { return {
Program: function(node) { Program(node) {
stack = [node.range]; stack = [node.range];
}, },

10
tools/eslint/lib/rules/block-spacing.js

@ -26,7 +26,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const always = (context.options[0] !== "never"), const always = (context.options[0] !== "never"),
message = always ? "Requires a space" : "Unexpected space(s)", message = always ? "Requires a space" : "Unexpected space(s)",
sourceCode = context.getSourceCode(); sourceCode = context.getSourceCode();
@ -95,10 +95,10 @@ module.exports = {
// Check. // Check.
if (!isValid(openBrace, firstToken)) { if (!isValid(openBrace, firstToken)) {
context.report({ context.report({
node: node, node,
loc: openBrace.loc.start, loc: openBrace.loc.start,
message: message + " after '{'.", message: message + " after '{'.",
fix: function(fixer) { fix(fixer) {
if (always) { if (always) {
return fixer.insertTextBefore(firstToken, " "); return fixer.insertTextBefore(firstToken, " ");
} }
@ -109,10 +109,10 @@ module.exports = {
} }
if (!isValid(lastToken, closeBrace)) { if (!isValid(lastToken, closeBrace)) {
context.report({ context.report({
node: node, node,
loc: closeBrace.loc.start, loc: closeBrace.loc.start,
message: message + " before '}'.", message: message + " before '}'.",
fix: function(fixer) { fix(fixer) {
if (always) { if (always) {
return fixer.insertTextAfter(lastToken, " "); return fixer.insertTextAfter(lastToken, " ");
} }

2
tools/eslint/lib/rules/brace-style.js

@ -33,7 +33,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const style = context.options[0] || "1tbs", const style = context.options[0] || "1tbs",
params = context.options[1] || {}, params = context.options[1] || {},
sourceCode = context.getSourceCode(); sourceCode = context.getSourceCode();

4
tools/eslint/lib/rules/callback-return.js

@ -22,7 +22,7 @@ module.exports = {
}] }]
}, },
create: function(context) { create(context) {
const callbacks = context.options[0] || ["callback", "cb", "next"], const callbacks = context.options[0] || ["callback", "cb", "next"],
sourceCode = context.getSourceCode(); sourceCode = context.getSourceCode();
@ -110,7 +110,7 @@ module.exports = {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
CallExpression: function(node) { CallExpression(node) {
// if we're not a callback we can return // if we're not a callback we can return
if (!isCallback(node)) { if (!isCallback(node)) {

4
tools/eslint/lib/rules/camelcase.js

@ -30,7 +30,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Helpers // Helpers
@ -73,7 +73,7 @@ module.exports = {
return { return {
Identifier: function(node) { Identifier(node) {
/* /*
* Leading and trailing underscores are commonly used to flag * Leading and trailing underscores are commonly used to flag

80
tools/eslint/lib/rules/class-methods-use-this.js

@ -0,0 +1,80 @@
/**
* @fileoverview Rule to enforce that all class methods use 'this'.
* @author Patrick Williams
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
meta: {
docs: {
description: "enforce that class methods utilize `this`",
category: "Best Practices",
recommended: false
},
schema: []
},
create(context) {
const stack = [];
/**
* Initializes the current context to false and pushes it onto the stack.
* These booleans represent whether 'this' has been used in the context.
* @returns {void}
* @private
*/
function enterFunction() {
stack.push(false);
}
/**
* Check if the node is an instance method
* @param {ASTNode} node - node to check
* @returns {boolean} True if its an instance method
* @private
*/
function isInstanceMethod(node) {
return !node.static && node.kind !== "constructor" && node.type === "MethodDefinition";
}
/**
* Checks if we are leaving a function that is a method, and reports if 'this' has not been used.
* Static methods and the constructor are exempt.
* Then pops the context off the stack.
* @param {ASTNode} node - A function node that was entered.
* @returns {void}
* @private
*/
function exitFunction(node) {
const methodUsesThis = stack.pop();
if (isInstanceMethod(node.parent) && !methodUsesThis) {
context.report(node, "Expected 'this' to be used by class method '" + node.parent.key.name + "'.");
}
}
/**
* Mark the current context as having used 'this'.
* @returns {void}
* @private
*/
function markThisUsed() {
if (stack.length) {
stack[stack.length - 1] = true;
}
}
return {
FunctionDeclaration: enterFunction,
"FunctionDeclaration:exit": exitFunction,
FunctionExpression: enterFunction,
"FunctionExpression:exit": exitFunction,
ThisExpression: markThisUsed,
Super: markThisUsed
};
}
};

6
tools/eslint/lib/rules/comma-dangle.js

@ -44,7 +44,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const mode = context.options[0]; const mode = context.options[0];
const UNEXPECTED_MESSAGE = "Unexpected trailing comma."; const UNEXPECTED_MESSAGE = "Unexpected trailing comma.";
const MISSING_MESSAGE = "Missing trailing comma."; const MISSING_MESSAGE = "Missing trailing comma.";
@ -112,7 +112,7 @@ module.exports = {
node: lastItem, node: lastItem,
loc: trailingToken.loc.start, loc: trailingToken.loc.start,
message: UNEXPECTED_MESSAGE, message: UNEXPECTED_MESSAGE,
fix: function(fixer) { fix(fixer) {
return fixer.remove(trailingToken); return fixer.remove(trailingToken);
} }
}); });
@ -157,7 +157,7 @@ module.exports = {
node: lastItem, node: lastItem,
loc: lastItem.loc.end, loc: lastItem.loc.end,
message: MISSING_MESSAGE, message: MISSING_MESSAGE,
fix: function(fixer) { fix(fixer) {
return fixer.insertTextAfter(penultimateToken, ","); return fixer.insertTextAfter(penultimateToken, ",");
} }
}); });

8
tools/eslint/lib/rules/comma-spacing.js

@ -36,7 +36,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const sourceCode = context.getSourceCode(); const sourceCode = context.getSourceCode();
const tokensAndComments = sourceCode.tokensAndComments; const tokensAndComments = sourceCode.tokensAndComments;
@ -73,8 +73,8 @@ module.exports = {
*/ */
function report(node, dir, otherNode) { function report(node, dir, otherNode) {
context.report({ context.report({
node: node, node,
fix: function(fixer) { fix(fixer) {
if (options[dir]) { if (options[dir]) {
if (dir === "before") { if (dir === "before") {
return fixer.insertTextBefore(node, " "); return fixer.insertTextBefore(node, " ");
@ -160,7 +160,7 @@ module.exports = {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
"Program:exit": function() { "Program:exit"() {
tokensAndComments.forEach(function(token, i) { tokensAndComments.forEach(function(token, i) {
if (!isComma(token)) { if (!isComma(token)) {

2
tools/eslint/lib/rules/comma-style.js

@ -38,7 +38,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const style = context.options[0] || "last", const style = context.options[0] || "last",
sourceCode = context.getSourceCode(); sourceCode = context.getSourceCode();
let exceptions = {}; let exceptions = {};

4
tools/eslint/lib/rules/complexity.js

@ -44,7 +44,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const option = context.options[0]; const option = context.options[0];
let THRESHOLD = 20; let THRESHOLD = 20;
@ -91,7 +91,7 @@ module.exports = {
} }
if (complexity > THRESHOLD) { if (complexity > THRESHOLD) {
context.report(node, "Function '{{name}}' has a complexity of {{complexity}}.", { name: name, complexity: complexity }); context.report(node, "Function '{{name}}' has a complexity of {{complexity}}.", { name, complexity });
} }
} }

18
tools/eslint/lib/rules/computed-property-spacing.js

@ -27,7 +27,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const sourceCode = context.getSourceCode(); const sourceCode = context.getSourceCode();
const propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never" const propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never"
@ -44,10 +44,10 @@ module.exports = {
*/ */
function reportNoBeginningSpace(node, token, tokenAfter) { function reportNoBeginningSpace(node, token, tokenAfter) {
context.report({ context.report({
node: node, node,
loc: token.loc.start, loc: token.loc.start,
message: "There should be no space after '" + token.value + "'.", message: "There should be no space after '" + token.value + "'.",
fix: function(fixer) { fix(fixer) {
return fixer.removeRange([token.range[1], tokenAfter.range[0]]); return fixer.removeRange([token.range[1], tokenAfter.range[0]]);
} }
}); });
@ -62,10 +62,10 @@ module.exports = {
*/ */
function reportNoEndingSpace(node, token, tokenBefore) { function reportNoEndingSpace(node, token, tokenBefore) {
context.report({ context.report({
node: node, node,
loc: token.loc.start, loc: token.loc.start,
message: "There should be no space before '" + token.value + "'.", message: "There should be no space before '" + token.value + "'.",
fix: function(fixer) { fix(fixer) {
return fixer.removeRange([tokenBefore.range[1], token.range[0]]); return fixer.removeRange([tokenBefore.range[1], token.range[0]]);
} }
}); });
@ -79,10 +79,10 @@ module.exports = {
*/ */
function reportRequiredBeginningSpace(node, token) { function reportRequiredBeginningSpace(node, token) {
context.report({ context.report({
node: node, node,
loc: token.loc.start, loc: token.loc.start,
message: "A space is required after '" + token.value + "'.", message: "A space is required after '" + token.value + "'.",
fix: function(fixer) { fix(fixer) {
return fixer.insertTextAfter(token, " "); return fixer.insertTextAfter(token, " ");
} }
}); });
@ -96,10 +96,10 @@ module.exports = {
*/ */
function reportRequiredEndingSpace(node, token) { function reportRequiredEndingSpace(node, token) {
context.report({ context.report({
node: node, node,
loc: token.loc.start, loc: token.loc.start,
message: "A space is required before '" + token.value + "'.", message: "A space is required before '" + token.value + "'.",
fix: function(fixer) { fix(fixer) {
return fixer.insertTextBefore(token, " "); return fixer.insertTextBefore(token, " ");
} }
}); });

18
tools/eslint/lib/rules/consistent-return.js

@ -56,7 +56,7 @@ module.exports = {
}] }]
}, },
create: function(context) { create(context) {
const options = context.options[0] || {}; const options = context.options[0] || {};
const treatUndefinedAsUnspecified = options.treatUndefinedAsUnspecified === true; const treatUndefinedAsUnspecified = options.treatUndefinedAsUnspecified === true;
let funcInfo = null; let funcInfo = null;
@ -110,31 +110,31 @@ module.exports = {
// Reports. // Reports.
context.report({ context.report({
node: node, node,
loc: loc, loc,
message: "Expected to return a value at the end of this {{type}}.", message: "Expected to return a value at the end of this {{type}}.",
data: {type: type} data: {type}
}); });
} }
return { return {
// Initializes/Disposes state of each code path. // Initializes/Disposes state of each code path.
onCodePathStart: function(codePath) { onCodePathStart(codePath) {
funcInfo = { funcInfo = {
upper: funcInfo, upper: funcInfo,
codePath: codePath, codePath,
hasReturn: false, hasReturn: false,
hasReturnValue: false, hasReturnValue: false,
message: "" message: ""
}; };
}, },
onCodePathEnd: function() { onCodePathEnd() {
funcInfo = funcInfo.upper; funcInfo = funcInfo.upper;
}, },
// Reports a given return statement if it's inconsistent. // Reports a given return statement if it's inconsistent.
ReturnStatement: function(node) { ReturnStatement(node) {
const argument = node.argument; const argument = node.argument;
let hasReturnValue = Boolean(argument); let hasReturnValue = Boolean(argument);
@ -147,7 +147,7 @@ module.exports = {
funcInfo.hasReturnValue = hasReturnValue; funcInfo.hasReturnValue = hasReturnValue;
funcInfo.message = "Expected " + (hasReturnValue ? "a" : "no") + " return value."; funcInfo.message = "Expected " + (hasReturnValue ? "a" : "no") + " return value.";
} else if (funcInfo.hasReturnValue !== hasReturnValue) { } else if (funcInfo.hasReturnValue !== hasReturnValue) {
context.report({node: node, message: funcInfo.message}); context.report({node, message: funcInfo.message});
} }
}, },

10
tools/eslint/lib/rules/consistent-this.js

@ -26,7 +26,7 @@ module.exports = {
} }
}, },
create: function(context) { create(context) {
let aliases = []; let aliases = [];
if (context.options.length === 0) { if (context.options.length === 0) {
@ -45,7 +45,7 @@ module.exports = {
function reportBadAssignment(node, alias) { function reportBadAssignment(node, alias) {
context.report(node, context.report(node,
"Designated alias '{{alias}}' is not assigned to 'this'.", "Designated alias '{{alias}}' is not assigned to 'this'.",
{ alias: alias }); { alias });
} }
/** /**
@ -65,7 +65,7 @@ module.exports = {
} }
} else if (isThis) { } else if (isThis) {
context.report(node, context.report(node,
"Unexpected alias '{{name}}' for 'this'.", { name: name }); "Unexpected alias '{{name}}' for 'this'.", { name });
} }
} }
@ -127,7 +127,7 @@ module.exports = {
"FunctionExpression:exit": ensureWasAssigned, "FunctionExpression:exit": ensureWasAssigned,
"FunctionDeclaration:exit": ensureWasAssigned, "FunctionDeclaration:exit": ensureWasAssigned,
VariableDeclarator: function(node) { VariableDeclarator(node) {
const id = node.id; const id = node.id;
const isDestructuring = const isDestructuring =
id.type === "ArrayPattern" || id.type === "ObjectPattern"; id.type === "ArrayPattern" || id.type === "ObjectPattern";
@ -137,7 +137,7 @@ module.exports = {
} }
}, },
AssignmentExpression: function(node) { AssignmentExpression(node) {
if (node.left.type === "Identifier") { if (node.left.type === "Identifier") {
checkAssignment(node, node.left.name, node.right); checkAssignment(node, node.left.name, node.right);
} }

28
tools/eslint/lib/rules/constructor-super.js

@ -101,7 +101,7 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
/* /*
* {{hasExtends: boolean, scope: Scope, codePath: CodePath}[]} * {{hasExtends: boolean, scope: Scope, codePath: CodePath}[]}
@ -160,7 +160,7 @@ module.exports = {
* @param {ASTNode} node - The current node. * @param {ASTNode} node - The current node.
* @returns {void} * @returns {void}
*/ */
onCodePathStart: function(codePath, node) { onCodePathStart(codePath, node) {
if (isConstructorFunction(node)) { if (isConstructorFunction(node)) {
// Class > ClassBody > MethodDefinition > FunctionExpression // Class > ClassBody > MethodDefinition > FunctionExpression
@ -172,7 +172,7 @@ module.exports = {
isConstructor: true, isConstructor: true,
hasExtends: Boolean(superClass), hasExtends: Boolean(superClass),
superIsConstructor: isPossibleConstructor(superClass), superIsConstructor: isPossibleConstructor(superClass),
codePath: codePath codePath
}; };
} else { } else {
funcInfo = { funcInfo = {
@ -180,7 +180,7 @@ module.exports = {
isConstructor: false, isConstructor: false,
hasExtends: false, hasExtends: false,
superIsConstructor: false, superIsConstructor: false,
codePath: codePath codePath
}; };
} }
}, },
@ -192,7 +192,7 @@ module.exports = {
* @param {ASTNode} node - The current node. * @param {ASTNode} node - The current node.
* @returns {void} * @returns {void}
*/ */
onCodePathEnd: function(codePath, node) { onCodePathEnd(codePath, node) {
const hasExtends = funcInfo.hasExtends; const hasExtends = funcInfo.hasExtends;
// Pop. // Pop.
@ -222,7 +222,7 @@ module.exports = {
* @param {CodePathSegment} segment - A code path segment to initialize. * @param {CodePathSegment} segment - A code path segment to initialize.
* @returns {void} * @returns {void}
*/ */
onCodePathSegmentStart: function(segment) { onCodePathSegmentStart(segment) {
if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) {
return; return;
} }
@ -252,7 +252,7 @@ module.exports = {
* of a loop. * of a loop.
* @returns {void} * @returns {void}
*/ */
onCodePathSegmentLoop: function(fromSegment, toSegment) { onCodePathSegmentLoop(fromSegment, toSegment) {
if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) {
return; return;
} }
@ -281,7 +281,7 @@ module.exports = {
context.report({ context.report({
message: "Unexpected duplicate 'super()'.", message: "Unexpected duplicate 'super()'.",
node: node node
}); });
} }
} }
@ -294,7 +294,7 @@ module.exports = {
* @param {ASTNode} node - A CallExpression node to check. * @param {ASTNode} node - A CallExpression node to check.
* @returns {void} * @returns {void}
*/ */
"CallExpression:exit": function(node) { "CallExpression:exit"(node) {
if (!(funcInfo && funcInfo.isConstructor)) { if (!(funcInfo && funcInfo.isConstructor)) {
return; return;
} }
@ -325,12 +325,12 @@ module.exports = {
if (duplicate) { if (duplicate) {
context.report({ context.report({
message: "Unexpected duplicate 'super()'.", message: "Unexpected duplicate 'super()'.",
node: node node
}); });
} else if (!funcInfo.superIsConstructor) { } else if (!funcInfo.superIsConstructor) {
context.report({ context.report({
message: "Unexpected 'super()' because 'super' is not a constructor.", message: "Unexpected 'super()' because 'super' is not a constructor.",
node: node node
}); });
} else { } else {
info.validNodes.push(node); info.validNodes.push(node);
@ -339,7 +339,7 @@ module.exports = {
} else if (funcInfo.codePath.currentSegments.some(isReachable)) { } else if (funcInfo.codePath.currentSegments.some(isReachable)) {
context.report({ context.report({
message: "Unexpected 'super()'.", message: "Unexpected 'super()'.",
node: node node
}); });
} }
}, },
@ -349,7 +349,7 @@ module.exports = {
* @param {ASTNode} node - A ReturnStatement node to check. * @param {ASTNode} node - A ReturnStatement node to check.
* @returns {void} * @returns {void}
*/ */
ReturnStatement: function(node) { ReturnStatement(node) {
if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) {
return; return;
} }
@ -377,7 +377,7 @@ module.exports = {
* Resets state. * Resets state.
* @returns {void} * @returns {void}
*/ */
"Program:exit": function() { "Program:exit"() {
segInfoMap = Object.create(null); segInfoMap = Object.create(null);
} }
}; };

26
tools/eslint/lib/rules/curly.js

@ -51,7 +51,7 @@ module.exports = {
} }
}, },
create: function(context) { create(context) {
const multiOnly = (context.options[0] === "multi"); const multiOnly = (context.options[0] === "multi");
const multiLine = (context.options[0] === "multi-line"); const multiLine = (context.options[0] === "multi-line");
@ -144,11 +144,11 @@ module.exports = {
*/ */
function reportExpectedBraceError(node, name, suffix) { function reportExpectedBraceError(node, name, suffix) {
context.report({ context.report({
node: node, node,
loc: (name !== "else" ? node : getElseKeyword(node)).loc.start, loc: (name !== "else" ? node : getElseKeyword(node)).loc.start,
message: "Expected { after '{{name}}'{{suffix}}.", message: "Expected { after '{{name}}'{{suffix}}.",
data: { data: {
name: name, name,
suffix: (suffix ? " " + suffix : "") suffix: (suffix ? " " + suffix : "")
} }
}); });
@ -164,11 +164,11 @@ module.exports = {
*/ */
function reportUnnecessaryBraceError(node, name, suffix) { function reportUnnecessaryBraceError(node, name, suffix) {
context.report({ context.report({
node: node, node,
loc: (name !== "else" ? node : getElseKeyword(node)).loc.start, loc: (name !== "else" ? node : getElseKeyword(node)).loc.start,
message: "Unnecessary { after '{{name}}'{{suffix}}.", message: "Unnecessary { after '{{name}}'{{suffix}}.",
data: { data: {
name: name, name,
suffix: (suffix ? " " + suffix : "") suffix: (suffix ? " " + suffix : "")
} }
}); });
@ -214,8 +214,8 @@ module.exports = {
return { return {
actual: hasBlock, actual: hasBlock,
expected: expected, expected,
check: function() { check() {
if (this.expected !== null && this.expected !== this.actual) { if (this.expected !== null && this.expected !== this.actual) {
if (this.expected) { if (this.expected) {
reportExpectedBraceError(node, name, suffix); reportExpectedBraceError(node, name, suffix);
@ -272,7 +272,7 @@ module.exports = {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
IfStatement: function(node) { IfStatement(node) {
if (node.parent.type !== "IfStatement") { if (node.parent.type !== "IfStatement") {
prepareIfChecks(node).forEach(function(preparedCheck) { prepareIfChecks(node).forEach(function(preparedCheck) {
preparedCheck.check(); preparedCheck.check();
@ -280,23 +280,23 @@ module.exports = {
} }
}, },
WhileStatement: function(node) { WhileStatement(node) {
prepareCheck(node, node.body, "while", "condition").check(); prepareCheck(node, node.body, "while", "condition").check();
}, },
DoWhileStatement: function(node) { DoWhileStatement(node) {
prepareCheck(node, node.body, "do").check(); prepareCheck(node, node.body, "do").check();
}, },
ForStatement: function(node) { ForStatement(node) {
prepareCheck(node, node.body, "for", "condition").check(); prepareCheck(node, node.body, "for", "condition").check();
}, },
ForInStatement: function(node) { ForInStatement(node) {
prepareCheck(node, node.body, "for-in").check(); prepareCheck(node, node.body, "for-in").check();
}, },
ForOfStatement: function(node) { ForOfStatement(node) {
prepareCheck(node, node.body, "for-of").check(); prepareCheck(node, node.body, "for-of").check();
} }
}; };

4
tools/eslint/lib/rules/default-case.js

@ -29,7 +29,7 @@ module.exports = {
}] }]
}, },
create: function(context) { create(context) {
const options = context.options[0] || {}; const options = context.options[0] || {};
const commentPattern = options.commentPattern ? const commentPattern = options.commentPattern ?
new RegExp(options.commentPattern) : new RegExp(options.commentPattern) :
@ -56,7 +56,7 @@ module.exports = {
return { return {
SwitchStatement: function(node) { SwitchStatement(node) {
if (!node.cases.length) { if (!node.cases.length) {

2
tools/eslint/lib/rules/dot-location.js

@ -26,7 +26,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const config = context.options[0]; const config = context.options[0];

4
tools/eslint/lib/rules/dot-notation.js

@ -35,7 +35,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const options = context.options[0] || {}; const options = context.options[0] || {};
const allowKeywords = options.allowKeywords === void 0 || !!options.allowKeywords; const allowKeywords = options.allowKeywords === void 0 || !!options.allowKeywords;
@ -46,7 +46,7 @@ module.exports = {
} }
return { return {
MemberExpression: function(node) { MemberExpression(node) {
if ( if (
node.computed && node.computed &&
node.property.type === "Literal" && node.property.type === "Literal" &&

6
tools/eslint/lib/rules/eol-last.js

@ -25,7 +25,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Public // Public
@ -46,10 +46,10 @@ module.exports = {
// file is not newline-terminated // file is not newline-terminated
location.line = src.split(/\n/g).length; location.line = src.split(/\n/g).length;
context.report({ context.report({
node: node, node,
loc: location, loc: location,
message: "Newline required at end of file but not found.", message: "Newline required at end of file but not found.",
fix: function(fixer) { fix(fixer) {
return fixer.insertTextAfterRange([0, src.length], linebreak); return fixer.insertTextAfterRange([0, src.length], linebreak);
} }
}); });

8
tools/eslint/lib/rules/eqeqeq.js

@ -50,7 +50,7 @@ module.exports = {
} }
}, },
create: function(context) { create(context) {
const config = context.options[0] || "always"; const config = context.options[0] || "always";
const options = context.options[1] || {}; const options = context.options[1] || {};
const sourceCode = context.getSourceCode(); const sourceCode = context.getSourceCode();
@ -124,15 +124,15 @@ module.exports = {
*/ */
function report(node, message) { function report(node, message) {
context.report({ context.report({
node: node, node,
loc: getOperatorLocation(node), loc: getOperatorLocation(node),
message: message, message,
data: { op: node.operator.charAt(0) } data: { op: node.operator.charAt(0) }
}); });
} }
return { return {
BinaryExpression: function(node) { BinaryExpression(node) {
const isNull = isNullCheck(node); const isNull = isNullCheck(node);
if (node.operator !== "==" && node.operator !== "!=") { if (node.operator !== "==" && node.operator !== "!=") {

14
tools/eslint/lib/rules/func-call-spacing.js

@ -53,7 +53,7 @@ module.exports = {
} }
}, },
create: function(context) { create(context) {
const never = context.options[0] !== "always"; const never = context.options[0] !== "always";
const allowNewlines = !never && context.options[1] && context.options[1].allowNewlines; const allowNewlines = !never && context.options[1] && context.options[1].allowNewlines;
@ -116,28 +116,28 @@ module.exports = {
if (never && hasWhitespace) { if (never && hasWhitespace) {
context.report({ context.report({
node: node, node,
loc: lastCalleeToken.loc.start, loc: lastCalleeToken.loc.start,
message: "Unexpected space between function name and paren.", message: "Unexpected space between function name and paren.",
fix: function(fixer) { fix(fixer) {
return fixer.removeRange([prevToken.range[1], parenToken.range[0]]); return fixer.removeRange([prevToken.range[1], parenToken.range[0]]);
} }
}); });
} else if (!never && !hasWhitespace) { } else if (!never && !hasWhitespace) {
context.report({ context.report({
node: node, node,
loc: lastCalleeToken.loc.start, loc: lastCalleeToken.loc.start,
message: "Missing space between function name and paren.", message: "Missing space between function name and paren.",
fix: function(fixer) { fix(fixer) {
return fixer.insertTextBefore(parenToken, " "); return fixer.insertTextBefore(parenToken, " ");
} }
}); });
} else if (!never && !allowNewlines && hasNewline) { } else if (!never && !allowNewlines && hasNewline) {
context.report({ context.report({
node: node, node,
loc: lastCalleeToken.loc.start, loc: lastCalleeToken.loc.start,
message: "Unexpected newline between function name and paren.", message: "Unexpected newline between function name and paren.",
fix: function(fixer) { fix(fixer) {
return fixer.replaceTextRange([prevToken.range[1], parenToken.range[0]], " "); return fixer.replaceTextRange([prevToken.range[1], parenToken.range[0]], " ");
} }
}); });

4
tools/eslint/lib/rules/func-names.js

@ -33,7 +33,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const never = context.options[0] === "never"; const never = context.options[0] === "never";
/** /**
@ -54,7 +54,7 @@ module.exports = {
} }
return { return {
"FunctionExpression:exit": function(node) { "FunctionExpression:exit"(node) {
// Skip recursive functions. // Skip recursive functions.
const nameVar = context.getDeclaredVariables(node)[0]; const nameVar = context.getDeclaredVariables(node)[0];

12
tools/eslint/lib/rules/func-style.js

@ -32,7 +32,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const style = context.options[0], const style = context.options[0],
allowArrowFunctions = context.options[1] && context.options[1].allowArrowFunctions === true, allowArrowFunctions = context.options[1] && context.options[1].allowArrowFunctions === true,
@ -40,29 +40,29 @@ module.exports = {
stack = []; stack = [];
const nodesToCheck = { const nodesToCheck = {
FunctionDeclaration: function(node) { FunctionDeclaration(node) {
stack.push(false); stack.push(false);
if (!enforceDeclarations && node.parent.type !== "ExportDefaultDeclaration") { if (!enforceDeclarations && node.parent.type !== "ExportDefaultDeclaration") {
context.report(node, "Expected a function expression."); context.report(node, "Expected a function expression.");
} }
}, },
"FunctionDeclaration:exit": function() { "FunctionDeclaration:exit"() {
stack.pop(); stack.pop();
}, },
FunctionExpression: function(node) { FunctionExpression(node) {
stack.push(false); stack.push(false);
if (enforceDeclarations && node.parent.type === "VariableDeclarator") { if (enforceDeclarations && node.parent.type === "VariableDeclarator") {
context.report(node.parent, "Expected a function declaration."); context.report(node.parent, "Expected a function declaration.");
} }
}, },
"FunctionExpression:exit": function() { "FunctionExpression:exit"() {
stack.pop(); stack.pop();
}, },
ThisExpression: function() { ThisExpression() {
if (stack.length > 0) { if (stack.length > 0) {
stack[stack.length - 1] = true; stack[stack.length - 1] = true;
} }

8
tools/eslint/lib/rules/generator-star-spacing.js

@ -38,7 +38,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const mode = (function(option) { const mode = (function(option) {
if (!option || typeof option === "string") { if (!option || typeof option === "string") {
@ -90,9 +90,9 @@ module.exports = {
const message = type + " space " + side + " *."; const message = type + " space " + side + " *.";
context.report({ context.report({
node: node, node,
message: message, message,
fix: function(fixer) { fix(fixer) {
if (spaceRequired) { if (spaceRequired) {
if (after) { if (after) {
return fixer.insertTextAfter(node, " "); return fixer.insertTextAfter(node, " ");

4
tools/eslint/lib/rules/global-require.js

@ -59,9 +59,9 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
return { return {
CallExpression: function(node) { CallExpression(node) {
const currentScope = context.getScope(); const currentScope = context.getScope();
if (node.callee.name === "require" && !isShadowed(currentScope, node.callee)) { if (node.callee.name === "require" && !isShadowed(currentScope, node.callee)) {

4
tools/eslint/lib/rules/guard-for-in.js

@ -20,11 +20,11 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
return { return {
ForInStatement: function(node) { ForInStatement(node) {
/* /*
* If the for-in statement has {}, then the real body is the body * If the for-in statement has {}, then the real body is the body

2
tools/eslint/lib/rules/handle-callback-err.js

@ -24,7 +24,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const errorArgument = context.options[0] || "err"; const errorArgument = context.options[0] || "err";

4
tools/eslint/lib/rules/id-blacklist.js

@ -27,7 +27,7 @@ module.exports = {
} }
}, },
create: function(context) { create(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@ -74,7 +74,7 @@ module.exports = {
return { return {
Identifier: function(node) { Identifier(node) {
const name = node.name, const name = node.name,
effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent; effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent;

10
tools/eslint/lib/rules/id-length.js

@ -44,7 +44,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const options = context.options[0] || {}; const options = context.options[0] || {};
const minLength = typeof options.min !== "undefined" ? options.min : 2; const minLength = typeof options.min !== "undefined" ? options.min : 2;
const maxLength = typeof options.max !== "undefined" ? options.max : Infinity; const maxLength = typeof options.max !== "undefined" ? options.max : Infinity;
@ -66,10 +66,10 @@ module.exports = {
parent.parent.parent.type === "ObjectPattern" && parent.parent.parent.parent.left === parent.parent.parent) parent.parent.parent.type === "ObjectPattern" && parent.parent.parent.parent.left === parent.parent.parent)
); );
}, },
AssignmentPattern: function(parent, node) { AssignmentPattern(parent, node) {
return parent.left === node; return parent.left === node;
}, },
VariableDeclarator: function(parent, node) { VariableDeclarator(parent, node) {
return parent.id === node; return parent.id === node;
}, },
Property: properties && function(parent, node) { Property: properties && function(parent, node) {
@ -86,7 +86,7 @@ module.exports = {
}; };
return { return {
Identifier: function(node) { Identifier(node) {
const name = node.name; const name = node.name;
const parent = node.parent; const parent = node.parent;
@ -105,7 +105,7 @@ module.exports = {
isShort ? isShort ?
"Identifier name '{{name}}' is too short (< {{min}})." : "Identifier name '{{name}}' is too short (< {{min}})." :
"Identifier name '{{name}}' is too long (> {{max}}).", "Identifier name '{{name}}' is too long (> {{max}}).",
{ name: name, min: minLength, max: maxLength } { name, min: minLength, max: maxLength }
); );
} }
} }

6
tools/eslint/lib/rules/id-match.js

@ -32,7 +32,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Helpers // Helpers
@ -77,13 +77,13 @@ module.exports = {
function report(node) { function report(node) {
context.report(node, "Identifier '{{name}}' does not match the pattern '{{pattern}}'.", { context.report(node, "Identifier '{{name}}' does not match the pattern '{{pattern}}'.", {
name: node.name, name: node.name,
pattern: pattern pattern
}); });
} }
return { return {
Identifier: function(node) { Identifier(node) {
const name = node.name, const name = node.name,
parent = node.parent, parent = node.parent,
effectiveParent = (parent.type === "MemberExpression") ? parent.parent : parent; effectiveParent = (parent.type === "MemberExpression") ? parent.parent : parent;

47
tools/eslint/lib/rules/indent.js

@ -80,7 +80,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const MESSAGE = "Expected indentation of {{needed}} {{type}} {{characters}} but found {{gotten}}."; const MESSAGE = "Expected indentation of {{needed}} {{type}} {{characters}} but found {{gotten}}.";
const DEFAULT_VARIABLE_INDENT = 1; const DEFAULT_VARIABLE_INDENT = 1;
@ -152,10 +152,10 @@ module.exports = {
*/ */
function report(node, needed, gotten, loc, isLastNodeCheck) { function report(node, needed, gotten, loc, isLastNodeCheck) {
const msgContext = { const msgContext = {
needed: needed, needed,
type: indentType, type: indentType,
characters: needed === 1 ? "character" : "characters", characters: needed === 1 ? "character" : "characters",
gotten: gotten gotten
}; };
const indentChar = indentType === "space" ? " " : "\t"; const indentChar = indentType === "space" ? " " : "\t";
@ -206,15 +206,15 @@ module.exports = {
if (loc) { if (loc) {
context.report({ context.report({
node: node, node,
loc: loc, loc,
message: MESSAGE, message: MESSAGE,
data: msgContext, data: msgContext,
fix: getFixerFunction() fix: getFixerFunction()
}); });
} else { } else {
context.report({ context.report({
node: node, node,
message: MESSAGE, message: MESSAGE,
data: msgContext, data: msgContext,
fix: getFixerFunction() fix: getFixerFunction()
@ -268,6 +268,16 @@ module.exports = {
) { ) {
report(node, indent, nodeIndent); report(node, indent, nodeIndent);
} }
if (node.type === "IfStatement" && node.alternate) {
const elseToken = sourceCode.getTokenBefore(node.alternate);
checkNodeIndent(elseToken, indent, excludeCommas);
if (!isNodeFirstInLine(node.alternate)) {
checkNodeIndent(node.alternate, indent, excludeCommas);
}
}
} }
/** /**
@ -278,14 +288,7 @@ module.exports = {
* @returns {void} * @returns {void}
*/ */
function checkNodesIndent(nodes, indent, excludeCommas) { function checkNodesIndent(nodes, indent, excludeCommas) {
nodes.forEach(function(node) { nodes.forEach(node => checkNodeIndent(node, indent, excludeCommas));
if (node.type === "IfStatement" && node.alternate) {
const elseToken = sourceCode.getTokenBefore(node.alternate);
checkNodeIndent(elseToken, indent, excludeCommas);
}
checkNodeIndent(node, indent, excludeCommas);
});
} }
/** /**
@ -784,7 +787,7 @@ module.exports = {
} }
return { return {
Program: function(node) { Program(node) {
if (node.body.length > 0) { if (node.body.length > 0) {
// Root nodes should have no indent // Root nodes should have no indent
@ -806,27 +809,27 @@ module.exports = {
DoWhileStatement: blockLessNodes, DoWhileStatement: blockLessNodes,
IfStatement: function(node) { IfStatement(node) {
if (node.consequent.type !== "BlockStatement" && node.consequent.loc.start.line > node.loc.start.line) { if (node.consequent.type !== "BlockStatement" && node.consequent.loc.start.line > node.loc.start.line) {
blockIndentationCheck(node); blockIndentationCheck(node);
} }
}, },
VariableDeclaration: function(node) { VariableDeclaration(node) {
if (node.declarations[node.declarations.length - 1].loc.start.line > node.declarations[0].loc.start.line) { if (node.declarations[node.declarations.length - 1].loc.start.line > node.declarations[0].loc.start.line) {
checkIndentInVariableDeclarations(node); checkIndentInVariableDeclarations(node);
} }
}, },
ObjectExpression: function(node) { ObjectExpression(node) {
checkIndentInArrayOrObjectBlock(node); checkIndentInArrayOrObjectBlock(node);
}, },
ArrayExpression: function(node) { ArrayExpression(node) {
checkIndentInArrayOrObjectBlock(node); checkIndentInArrayOrObjectBlock(node);
}, },
MemberExpression: function(node) { MemberExpression(node) {
if (typeof options.MemberExpression === "undefined") { if (typeof options.MemberExpression === "undefined") {
return; return;
} }
@ -860,7 +863,7 @@ module.exports = {
checkNodesIndent(checkNodes, propertyIndent); checkNodesIndent(checkNodes, propertyIndent);
}, },
SwitchStatement: function(node) { SwitchStatement(node) {
// Switch is not a 'BlockStatement' // Switch is not a 'BlockStatement'
const switchIndent = getNodeIndent(node); const switchIndent = getNodeIndent(node);
@ -872,7 +875,7 @@ module.exports = {
checkLastNodeLineIndent(node, switchIndent); checkLastNodeLineIndent(node, switchIndent);
}, },
SwitchCase: function(node) { SwitchCase(node) {
// Skip inline cases // Skip inline cases
if (isSingleLineNode(node)) { if (isSingleLineNode(node)) {

4
tools/eslint/lib/rules/init-declarations.js

@ -85,7 +85,7 @@ module.exports = {
} }
}, },
create: function(context) { create(context) {
const MODE_ALWAYS = "always", const MODE_ALWAYS = "always",
MODE_NEVER = "never"; MODE_NEVER = "never";
@ -98,7 +98,7 @@ module.exports = {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
"VariableDeclaration:exit": function(node) { "VariableDeclaration:exit"(node) {
const kind = node.kind, const kind = node.kind,
declarations = node.declarations; declarations = node.declarations;

10
tools/eslint/lib/rules/jsx-quotes.js

@ -19,14 +19,14 @@ const QUOTE_SETTINGS = {
"prefer-double": { "prefer-double": {
quote: "\"", quote: "\"",
description: "singlequote", description: "singlequote",
convert: function(str) { convert(str) {
return str.replace(/'/g, "\""); return str.replace(/'/g, "\"");
} }
}, },
"prefer-single": { "prefer-single": {
quote: "'", quote: "'",
description: "doublequote", description: "doublequote",
convert: function(str) { convert(str) {
return str.replace(/"/g, "'"); return str.replace(/"/g, "'");
} }
} }
@ -53,7 +53,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const quoteOption = context.options[0] || "prefer-double", const quoteOption = context.options[0] || "prefer-double",
setting = QUOTE_SETTINGS[quoteOption]; setting = QUOTE_SETTINGS[quoteOption];
@ -68,14 +68,14 @@ module.exports = {
} }
return { return {
JSXAttribute: function(node) { JSXAttribute(node) {
const attributeValue = node.value; const attributeValue = node.value;
if (attributeValue && astUtils.isStringLiteral(attributeValue) && !usesExpectedQuotes(attributeValue)) { if (attributeValue && astUtils.isStringLiteral(attributeValue) && !usesExpectedQuotes(attributeValue)) {
context.report({ context.report({
node: attributeValue, node: attributeValue,
message: "Unexpected usage of " + setting.description + ".", message: "Unexpected usage of " + setting.description + ".",
fix: function(fixer) { fix(fixer) {
return fixer.replaceText(attributeValue, setting.convert(attributeValue.raw)); return fixer.replaceText(attributeValue, setting.convert(attributeValue.raw));
} }
}); });

8
tools/eslint/lib/rules/key-spacing.js

@ -323,7 +323,7 @@ module.exports = {
}] }]
}, },
create: function(context) { create(context) {
/** /**
* OPTIONS * OPTIONS
@ -464,7 +464,7 @@ module.exports = {
computed: property.computed ? "computed " : "", computed: property.computed ? "computed " : "",
key: getKey(property) key: getKey(property)
}, },
fix: fix fix
}); });
} }
} }
@ -616,7 +616,7 @@ module.exports = {
if (alignmentOptions) { // Verify vertical alignment if (alignmentOptions) { // Verify vertical alignment
return { return {
ObjectExpression: function(node) { ObjectExpression(node) {
if (isSingleLine(node)) { if (isSingleLine(node)) {
verifyListSpacing(node.properties.filter(isKeyValueProperty)); verifyListSpacing(node.properties.filter(isKeyValueProperty));
} else { } else {
@ -628,7 +628,7 @@ module.exports = {
} else { // Obey beforeColon and afterColon in each property as configured } else { // Obey beforeColon and afterColon in each property as configured
return { return {
Property: function(node) { Property(node) {
verifySpacing(node, isSingleLine(node.parent) ? singleLineOptions : multiLineOptions); verifySpacing(node, isSingleLine(node.parent) ? singleLineOptions : multiLineOptions);
} }
}; };

10
tools/eslint/lib/rules/keyword-spacing.js

@ -100,7 +100,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const sourceCode = context.getSourceCode(); const sourceCode = context.getSourceCode();
/** /**
@ -126,7 +126,7 @@ module.exports = {
loc: token.loc.start, loc: token.loc.start,
message: "Expected space(s) before \"{{value}}\".", message: "Expected space(s) before \"{{value}}\".",
data: token, data: token,
fix: function(fixer) { fix(fixer) {
return fixer.insertTextBefore(token, " "); return fixer.insertTextBefore(token, " ");
} }
}); });
@ -156,7 +156,7 @@ module.exports = {
loc: token.loc.start, loc: token.loc.start,
message: "Unexpected space(s) before \"{{value}}\".", message: "Unexpected space(s) before \"{{value}}\".",
data: token, data: token,
fix: function(fixer) { fix(fixer) {
return fixer.removeRange([prevToken.range[1], token.range[0]]); return fixer.removeRange([prevToken.range[1], token.range[0]]);
} }
}); });
@ -186,7 +186,7 @@ module.exports = {
loc: token.loc.start, loc: token.loc.start,
message: "Expected space(s) after \"{{value}}\".", message: "Expected space(s) after \"{{value}}\".",
data: token, data: token,
fix: function(fixer) { fix(fixer) {
return fixer.insertTextAfter(token, " "); return fixer.insertTextAfter(token, " ");
} }
}); });
@ -216,7 +216,7 @@ module.exports = {
loc: token.loc.start, loc: token.loc.start,
message: "Unexpected space(s) after \"{{value}}\".", message: "Unexpected space(s) after \"{{value}}\".",
data: token, data: token,
fix: function(fixer) { fix(fixer) {
return fixer.removeRange([token.range[1], nextToken.range[0]]); return fixer.removeRange([token.range[1], nextToken.range[0]]);
} }
}); });

4
tools/eslint/lib/rules/linebreak-style.js

@ -26,7 +26,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const EXPECTED_LF_MSG = "Expected linebreaks to be 'LF' but found 'CRLF'.", const EXPECTED_LF_MSG = "Expected linebreaks to be 'LF' but found 'CRLF'.",
EXPECTED_CRLF_MSG = "Expected linebreaks to be 'CRLF' but found 'LF'."; EXPECTED_CRLF_MSG = "Expected linebreaks to be 'CRLF' but found 'LF'.";
@ -75,7 +75,7 @@ module.exports = {
const range = [index, index + match[0].length]; const range = [index, index + match[0].length];
context.report({ context.report({
node: node, node,
loc: { loc: {
line: i, line: i,
column: sourceCode.lines[i - 1].length column: sourceCode.lines[i - 1].length

14
tools/eslint/lib/rules/lines-around-comment.js

@ -106,7 +106,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const options = context.options[0] ? Object.assign({}, context.options[0]) : {}; const options = context.options[0] ? Object.assign({}, context.options[0]) : {};
@ -316,9 +316,9 @@ module.exports = {
const range = [lineStart, lineStart]; const range = [lineStart, lineStart];
context.report({ context.report({
node: node, node,
message: "Expected line before comment.", message: "Expected line before comment.",
fix: function(fixer) { fix(fixer) {
return fixer.insertTextBeforeRange(range, "\n"); return fixer.insertTextBeforeRange(range, "\n");
} }
}); });
@ -328,9 +328,9 @@ module.exports = {
if (!exceptionEndAllowed && after && !lodash.includes(commentAndEmptyLines, nextLineNum) && if (!exceptionEndAllowed && after && !lodash.includes(commentAndEmptyLines, nextLineNum) &&
!(isCommentNodeType(nextTokenOrComment) && astUtils.isTokenOnSameLine(node, nextTokenOrComment))) { !(isCommentNodeType(nextTokenOrComment) && astUtils.isTokenOnSameLine(node, nextTokenOrComment))) {
context.report({ context.report({
node: node, node,
message: "Expected line after comment.", message: "Expected line after comment.",
fix: function(fixer) { fix(fixer) {
return fixer.insertTextAfter(node, "\n"); return fixer.insertTextAfter(node, "\n");
} }
}); });
@ -344,7 +344,7 @@ module.exports = {
return { return {
LineComment: function(node) { LineComment(node) {
if (options.beforeLineComment || options.afterLineComment) { if (options.beforeLineComment || options.afterLineComment) {
checkForEmptyLine(node, { checkForEmptyLine(node, {
after: options.afterLineComment, after: options.afterLineComment,
@ -353,7 +353,7 @@ module.exports = {
} }
}, },
BlockComment: function(node) { BlockComment(node) {
if (options.beforeBlockComment || options.afterBlockComment) { if (options.beforeBlockComment || options.afterBlockComment) {
checkForEmptyLine(node, { checkForEmptyLine(node, {
after: options.afterBlockComment, after: options.afterBlockComment,

4
tools/eslint/lib/rules/max-depth.js

@ -43,7 +43,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Helpers // Helpers
@ -115,7 +115,7 @@ module.exports = {
FunctionExpression: startFunction, FunctionExpression: startFunction,
ArrowFunctionExpression: startFunction, ArrowFunctionExpression: startFunction,
IfStatement: function(node) { IfStatement(node) {
if (node.parent.type !== "IfStatement") { if (node.parent.type !== "IfStatement") {
pushBlock(node); pushBlock(node);
} }

2
tools/eslint/lib/rules/max-len.js

@ -69,7 +69,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
/* /*
* Inspired by http://tools.ietf.org/html/rfc3986#appendix-B, however: * Inspired by http://tools.ietf.org/html/rfc3986#appendix-B, however:

6
tools/eslint/lib/rules/max-lines.js

@ -51,7 +51,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const option = context.options[0]; const option = context.options[0];
let max = 300; let max = 300;
@ -113,9 +113,9 @@ module.exports = {
} }
return { return {
"Program:exit": function() { "Program:exit"() {
let lines = sourceCode.lines.map(function(text, i) { let lines = sourceCode.lines.map(function(text, i) {
return { lineNumber: i + 1, text: text }; return { lineNumber: i + 1, text };
}); });
if (skipBlankLines) { if (skipBlankLines) {

2
tools/eslint/lib/rules/max-nested-callbacks.js

@ -43,7 +43,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Constants // Constants

2
tools/eslint/lib/rules/max-params.js

@ -43,7 +43,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const option = context.options[0]; const option = context.options[0];
let numParams = 3; let numParams = 3;

6
tools/eslint/lib/rules/max-statements-per-line.js

@ -30,7 +30,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const sourceCode = context.getSourceCode(), const sourceCode = context.getSourceCode(),
options = context.options[0] || {}, options = context.options[0] || {},
@ -89,7 +89,7 @@ module.exports = {
// Reports if the node violated this rule. // Reports if the node violated this rule.
if (numberOfStatementsOnThisLine === maxStatementsPerLine + 1) { if (numberOfStatementsOnThisLine === maxStatementsPerLine + 1) {
context.report({node: node, message: message}); context.report({node, message});
} }
} }
@ -166,7 +166,7 @@ module.exports = {
// Empty blocks should be warned if `{max: 0}` was given. // Empty blocks should be warned if `{max: 0}` was given.
BlockStatement: function reportIfZero(node) { BlockStatement: function reportIfZero(node) {
if (maxStatementsPerLine === 0 && node.body.length === 0) { if (maxStatementsPerLine === 0 && node.body.length === 0) {
context.report({node: node, message: message}); context.report({node, message});
} }
} }
}; };

8
tools/eslint/lib/rules/max-statements.js

@ -52,7 +52,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Helpers // Helpers
@ -87,7 +87,7 @@ module.exports = {
context.report( context.report(
node, node,
"This function has too many statements ({{count}}). Maximum allowed is {{max}}.", "This function has too many statements ({{count}}). Maximum allowed is {{max}}.",
{ count: count, max: max }); { count, max });
} }
} }
@ -110,7 +110,7 @@ module.exports = {
const count = functionStack.pop(); const count = functionStack.pop();
if (ignoreTopLevelFunctions && functionStack.length === 0) { if (ignoreTopLevelFunctions && functionStack.length === 0) {
topLevelFunctions.push({ node: node, count: count}); topLevelFunctions.push({ node, count});
} else { } else {
reportIfTooManyStatements(node, count, maxStatements); reportIfTooManyStatements(node, count, maxStatements);
} }
@ -141,7 +141,7 @@ module.exports = {
"FunctionExpression:exit": endFunction, "FunctionExpression:exit": endFunction,
"ArrowFunctionExpression:exit": endFunction, "ArrowFunctionExpression:exit": endFunction,
"Program:exit": function() { "Program:exit"() {
if (topLevelFunctions.length === 1) { if (topLevelFunctions.length === 1) {
return; return;
} }

33
tools/eslint/lib/rules/multiline-ternary.js

@ -18,10 +18,15 @@ module.exports = {
category: "Stylistic Issues", category: "Stylistic Issues",
recommended: false recommended: false
}, },
schema: [] schema: [
{
enum: ["always", "never"]
}
]
}, },
create: function(context) { create(context) {
const multiline = context.options[0] !== "never";
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Helpers // Helpers
@ -31,14 +36,16 @@ module.exports = {
* Tests whether node is preceded by supplied tokens * Tests whether node is preceded by supplied tokens
* @param {ASTNode} node - node to check * @param {ASTNode} node - node to check
* @param {ASTNode} parentNode - parent of node to report * @param {ASTNode} parentNode - parent of node to report
* @param {boolean} expected - whether newline was expected or not
* @returns {void} * @returns {void}
* @private * @private
*/ */
function reportError(node, parentNode) { function reportError(node, parentNode, expected) {
context.report({ context.report({
node: node, node,
message: "Expected newline between {{typeOfError}} of ternary expression.", message: "{{expected}} newline between {{typeOfError}} of ternary expression.",
data: { data: {
expected: expected ? "Expected" : "Unexpected",
typeOfError: node === parentNode.test ? "test and consequent" : "consequent and alternate" typeOfError: node === parentNode.test ? "test and consequent" : "consequent and alternate"
} }
}); });
@ -49,16 +56,26 @@ module.exports = {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
ConditionalExpression: function(node) { ConditionalExpression(node) {
const areTestAndConsequentOnSameLine = astUtils.isTokenOnSameLine(node.test, node.consequent); const areTestAndConsequentOnSameLine = astUtils.isTokenOnSameLine(node.test, node.consequent);
const areConsequentAndAlternateOnSameLine = astUtils.isTokenOnSameLine(node.consequent, node.alternate); const areConsequentAndAlternateOnSameLine = astUtils.isTokenOnSameLine(node.consequent, node.alternate);
if (!multiline) {
if (!areTestAndConsequentOnSameLine) {
reportError(node.test, node, false);
}
if (!areConsequentAndAlternateOnSameLine) {
reportError(node.consequent, node, false);
}
} else {
if (areTestAndConsequentOnSameLine) { if (areTestAndConsequentOnSameLine) {
reportError(node.test, node); reportError(node.test, node, true);
} }
if (areConsequentAndAlternateOnSameLine) { if (areConsequentAndAlternateOnSameLine) {
reportError(node.consequent, node); reportError(node.consequent, node, true);
}
} }
} }
}; };

2
tools/eslint/lib/rules/new-cap.js

@ -117,7 +117,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const config = context.options[0] ? Object.assign({}, context.options[0]) : {}; const config = context.options[0] ? Object.assign({}, context.options[0]) : {};

4
tools/eslint/lib/rules/new-parens.js

@ -20,12 +20,12 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
const sourceCode = context.getSourceCode(); const sourceCode = context.getSourceCode();
return { return {
NewExpression: function(node) { NewExpression(node) {
const tokens = sourceCode.getTokens(node); const tokens = sourceCode.getTokens(node);
const prenticesTokens = tokens.filter(function(token) { const prenticesTokens = tokens.filter(function(token) {
return token.value === "(" || token.value === ")"; return token.value === "(" || token.value === ")";

2
tools/eslint/lib/rules/newline-after-var.js

@ -24,7 +24,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const ALWAYS_MESSAGE = "Expected blank line after variable declarations.", const ALWAYS_MESSAGE = "Expected blank line after variable declarations.",
NEVER_MESSAGE = "Unexpected blank line after variable declarations."; NEVER_MESSAGE = "Unexpected blank line after variable declarations.";

6
tools/eslint/lib/rules/newline-before-return.js

@ -19,7 +19,7 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
const sourceCode = context.getSourceCode(); const sourceCode = context.getSourceCode();
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@ -137,10 +137,10 @@ module.exports = {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
return { return {
ReturnStatement: function(node) { ReturnStatement(node) {
if (!isFirstNode(node) && !hasNewlineBefore(node)) { if (!isFirstNode(node) && !hasNewlineBefore(node)) {
context.report({ context.report({
node: node, node,
message: "Expected newline before return statement." message: "Expected newline before return statement."
}); });
} }

4
tools/eslint/lib/rules/newline-per-chained-call.js

@ -31,7 +31,7 @@ module.exports = {
}] }]
}, },
create: function(context) { create(context) {
const options = context.options[0] || {}, const options = context.options[0] || {},
ignoreChainWithDepth = options.ignoreChainWithDepth || 2; ignoreChainWithDepth = options.ignoreChainWithDepth || 2;
@ -54,7 +54,7 @@ module.exports = {
} }
return { return {
"CallExpression:exit": function(node) { "CallExpression:exit"(node) {
if (!node.callee || node.callee.type !== "MemberExpression") { if (!node.callee || node.callee.type !== "MemberExpression") {
return; return;
} }

6
tools/eslint/lib/rules/no-alert.js

@ -97,16 +97,16 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
let globalScope; let globalScope;
return { return {
Program: function() { Program() {
globalScope = context.getScope(); globalScope = context.getScope();
}, },
CallExpression: function(node) { CallExpression(node) {
const callee = node.callee, const callee = node.callee,
currentScope = context.getScope(); currentScope = context.getScope();

2
tools/eslint/lib/rules/no-array-constructor.js

@ -20,7 +20,7 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
/** /**
* Disallow construction of dense arrays using the Array constructor * Disallow construction of dense arrays using the Array constructor

2
tools/eslint/lib/rules/no-bitwise.js

@ -46,7 +46,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const options = context.options[0] || {}; const options = context.options[0] || {};
const allowed = options.allow || []; const allowed = options.allow || [];
const int32Hint = options.int32Hint === true; const int32Hint = options.int32Hint === true;

4
tools/eslint/lib/rules/no-caller.js

@ -20,11 +20,11 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
return { return {
MemberExpression: function(node) { MemberExpression(node) {
const objectName = node.object.name, const objectName = node.object.name,
propertyName = node.property.name; propertyName = node.property.name;

6
tools/eslint/lib/rules/no-case-declarations.js

@ -19,7 +19,7 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
/** /**
* Checks whether or not a node is a lexical declaration. * Checks whether or not a node is a lexical declaration.
@ -39,13 +39,13 @@ module.exports = {
} }
return { return {
SwitchCase: function(node) { SwitchCase(node) {
for (let i = 0; i < node.consequent.length; i++) { for (let i = 0; i < node.consequent.length; i++) {
const statement = node.consequent[i]; const statement = node.consequent[i];
if (isLexicalDeclaration(statement)) { if (isLexicalDeclaration(statement)) {
context.report({ context.report({
node: node, node,
message: "Unexpected lexical declaration in case block." message: "Unexpected lexical declaration in case block."
}); });
} }

4
tools/eslint/lib/rules/no-catch-shadow.js

@ -26,7 +26,7 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Helpers // Helpers
@ -48,7 +48,7 @@ module.exports = {
return { return {
CatchClause: function(node) { CatchClause(node) {
let scope = context.getScope(); let scope = context.getScope();
// When blockBindings is enabled, CatchClause creates its own scope // When blockBindings is enabled, CatchClause creates its own scope

2
tools/eslint/lib/rules/no-class-assign.js

@ -22,7 +22,7 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
/** /**
* Finds and reports references that are non initializer and writable. * Finds and reports references that are non initializer and writable.

8
tools/eslint/lib/rules/no-cond-assign.js

@ -4,6 +4,8 @@
*/ */
"use strict"; "use strict";
const astUtils = require("../ast-utils");
const NODE_DESCRIPTIONS = { const NODE_DESCRIPTIONS = {
DoWhileStatement: "a 'do...while' statement", DoWhileStatement: "a 'do...while' statement",
ForStatement: "a 'for' statement", ForStatement: "a 'for' statement",
@ -30,7 +32,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const prohibitAssign = (context.options[0] || "except-parens"); const prohibitAssign = (context.options[0] || "except-parens");
@ -59,7 +61,7 @@ module.exports = {
if (isConditionalTestExpression(currentAncestor)) { if (isConditionalTestExpression(currentAncestor)) {
return currentAncestor.parent; return currentAncestor.parent;
} }
} while ((currentAncestor = currentAncestor.parent)); } while ((currentAncestor = currentAncestor.parent) && !astUtils.isFunction(currentAncestor));
return null; return null;
} }
@ -107,7 +109,7 @@ module.exports = {
// must match JSHint's error message // must match JSHint's error message
context.report({ context.report({
node: node, node,
loc: node.test.loc.start, loc: node.test.loc.start,
message: "Expected a conditional expression and instead saw an assignment." message: "Expected a conditional expression and instead saw an assignment."
}); });

2
tools/eslint/lib/rules/no-confusing-arrow.js

@ -42,7 +42,7 @@ module.exports = {
}] }]
}, },
create: function(context) { create(context) {
const config = context.options[0] || {}; const config = context.options[0] || {};
const sourceCode = context.getSourceCode(); const sourceCode = context.getSourceCode();

4
tools/eslint/lib/rules/no-console.js

@ -35,11 +35,11 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
return { return {
MemberExpression: function(node) { MemberExpression(node) {
if (node.object.name === "console") { if (node.object.name === "console") {
let blockConsole = true; let blockConsole = true;

4
tools/eslint/lib/rules/no-const-assign.js

@ -22,7 +22,7 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
/** /**
* Finds and reports references that are non initializer and writable. * Finds and reports references that are non initializer and writable.
@ -39,7 +39,7 @@ module.exports = {
} }
return { return {
VariableDeclaration: function(node) { VariableDeclaration(node) {
if (node.kind === "const") { if (node.kind === "const") {
context.getDeclaredVariables(node).forEach(checkVariable); context.getDeclaredVariables(node).forEach(checkVariable);
} }

2
tools/eslint/lib/rules/no-constant-condition.js

@ -31,7 +31,7 @@ module.exports = {
] ]
}, },
create: function(context) { create(context) {
const options = context.options[0] || {}, const options = context.options[0] || {},
checkLoops = options.checkLoops !== false; checkLoops = options.checkLoops !== false;

4
tools/eslint/lib/rules/no-continue.js

@ -20,10 +20,10 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
return { return {
ContinueStatement: function(node) { ContinueStatement(node) {
context.report(node, "Unexpected use of continue statement."); context.report(node, "Unexpected use of continue statement.");
} }
}; };

4
tools/eslint/lib/rules/no-control-regex.js

@ -20,7 +20,7 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
/** /**
* Get the regex expression * Get the regex expression
@ -99,7 +99,7 @@ module.exports = {
} }
return { return {
Literal: function(node) { Literal(node) {
const regex = getRegExp(node); const regex = getRegExp(node);
if (regex) { if (regex) {

4
tools/eslint/lib/rules/no-debugger.js

@ -20,10 +20,10 @@ module.exports = {
schema: [] schema: []
}, },
create: function(context) { create(context) {
return { return {
DebuggerStatement: function(node) { DebuggerStatement(node) {
context.report(node, "Unexpected 'debugger' statement."); context.report(node, "Unexpected 'debugger' statement.");
} }
}; };

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save