diff --git a/lib/rules/one-var.js b/lib/rules/one-var.js index b370c6d5e19..e3df8320f8b 100644 --- a/lib/rules/one-var.js +++ b/lib/rules/one-var.js @@ -5,6 +5,25 @@ "use strict"; +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("./utils/ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Determines whether the given node is in a statement list. + * @param {ASTNode} node node to check + * @returns {boolean} `true` if the given node is in a statement list + */ +function isInStatementList(node) { + return astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type); +} + //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ @@ -268,8 +287,8 @@ module.exports = { /** * Fixer to join VariableDeclaration's into a single declaration - * @param {VariableDeclarator[]} declarations The `VariableDeclaration` to join - * @returns {Function} The fixer function + * @param {VariableDeclarator[]} declarations The `VariableDeclaration` to join + * @returns {Function} The fixer function */ function joinDeclarations(declarations) { const declaration = declarations[0]; @@ -297,10 +316,17 @@ module.exports = { /** * Fixer to split a VariableDeclaration into individual declarations - * @param {VariableDeclaration} declaration The `VariableDeclaration` to split - * @returns {Function} The fixer function + * @param {VariableDeclaration} declaration The `VariableDeclaration` to split + * @returns {Function|null} The fixer function */ function splitDeclarations(declaration) { + const { parent } = declaration; + + // don't autofix code such as: if (foo) var x, y; + if (!isInStatementList(parent.type === "ExportNamedDeclaration" ? parent : declaration)) { + return null; + } + return fixer => declaration.declarations.map(declarator => { const tokenAfterDeclarator = sourceCode.getTokenAfter(declarator); diff --git a/tests/lib/rules/one-var.js b/tests/lib/rules/one-var.js index 026862e10a7..3388c9d6489 100644 --- a/tests/lib/rules/one-var.js +++ b/tests/lib/rules/one-var.js @@ -492,6 +492,16 @@ ruleTester.run("one-var", rule, { } ], invalid: [ + { + code: "var bar = true, baz = false;", + output: "var bar = true; var baz = false;", + options: ["never"], + errors: [{ + messageId: "split", + data: { type: "var" }, + type: "VariableDeclaration" + }] + }, { code: "function foo() { var bar = true, baz = false; }", output: "function foo() { var bar = true; var baz = false; }", @@ -502,6 +512,36 @@ ruleTester.run("one-var", rule, { type: "VariableDeclaration" }] }, + { + code: "if (foo) { var bar = true, baz = false; }", + output: "if (foo) { var bar = true; var baz = false; }", + options: ["never"], + errors: [{ + messageId: "split", + data: { type: "var" }, + type: "VariableDeclaration" + }] + }, + { + code: "switch (foo) { case bar: var baz = true, quux = false; }", + output: "switch (foo) { case bar: var baz = true; var quux = false; }", + options: ["never"], + errors: [{ + messageId: "split", + data: { type: "var" }, + type: "VariableDeclaration" + }] + }, + { + code: "switch (foo) { default: var baz = true, quux = false; }", + output: "switch (foo) { default: var baz = true; var quux = false; }", + options: ["never"], + errors: [{ + messageId: "split", + data: { type: "var" }, + type: "VariableDeclaration" + }] + }, { code: "function foo() { var bar = true; var baz = false; }", output: "function foo() { var bar = true, baz = false; }", @@ -1942,6 +1982,138 @@ ruleTester.run("one-var", rule, { data: { type: "const" }, type: "VariableDeclaration" }] + }, + + // "never" should not autofix declarations in a block position + { + code: "if (foo) var x, y;", + output: null, + options: ["never"], + errors: [{ + messageId: "split", + data: { type: "var" }, + type: "VariableDeclaration" + }] + }, + { + code: "if (foo) var x, y;", + output: null, + options: [{ var: "never" }], + errors: [{ + messageId: "split", + data: { type: "var" }, + type: "VariableDeclaration" + }] + }, + { + code: "if (foo) var x, y;", + output: null, + options: [{ uninitialized: "never" }], + errors: [{ + messageId: "splitUninitialized", + data: { type: "var" }, + type: "VariableDeclaration" + }] + }, + { + code: "if (foo) var x = 1, y = 1;", + output: null, + options: [{ initialized: "never" }], + errors: [{ + messageId: "splitInitialized", + data: { type: "var" }, + type: "VariableDeclaration" + }] + }, + { + code: "if (foo) {} else var x, y;", + output: null, + options: ["never"], + errors: [{ + messageId: "split", + data: { type: "var" }, + type: "VariableDeclaration" + }] + }, + { + code: "while (foo) var x, y;", + output: null, + options: ["never"], + errors: [{ + messageId: "split", + data: { type: "var" }, + type: "VariableDeclaration" + }] + }, + { + code: "do var x, y; while (foo);", + output: null, + options: ["never"], + errors: [{ + messageId: "split", + data: { type: "var" }, + type: "VariableDeclaration" + }] + }, + { + code: "do var x = f(), y = b(); while (x < y);", + output: null, + options: ["never"], + errors: [{ + messageId: "split", + data: { type: "var" }, + type: "VariableDeclaration" + }] + }, + { + code: "for (;;) var x, y;", + output: null, + options: ["never"], + errors: [{ + messageId: "split", + data: { type: "var" }, + type: "VariableDeclaration" + }] + }, + { + code: "for (foo in bar) var x, y;", + output: null, + options: ["never"], + errors: [{ + messageId: "split", + data: { type: "var" }, + type: "VariableDeclaration" + }] + }, + { + code: "for (foo of bar) var x, y;", + output: null, + options: ["never"], + errors: [{ + messageId: "split", + data: { type: "var" }, + type: "VariableDeclaration" + }] + }, + { + code: "with (foo) var x, y;", + output: null, + options: ["never"], + errors: [{ + messageId: "split", + data: { type: "var" }, + type: "VariableDeclaration" + }] + }, + { + code: "label: var x, y;", + output: null, + options: ["never"], + errors: [{ + messageId: "split", + data: { type: "var" }, + type: "VariableDeclaration" + }] } ] });