From 55a15936346def8ddc0c5023431df20bec798fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=96=9B=E5=AE=9A=E8=B0=94=E7=9A=84=E7=8C=AB?= Date: Sat, 17 Mar 2018 03:46:49 +0800 Subject: [PATCH] Update: consecutive option for one-var (fixes #4680) (#9994) * Update: consecutive option for one-var (fixes #4680) * fix failing test cases. * aceept review suggestions * accept review suggestions --- docs/rules/one-var.md | 199 +++++++- lib/rules/one-var.js | 237 ++++++---- tests/lib/rules/one-var.js | 912 +++++++++++++++++++++++++++++++++++++ 3 files changed, 1249 insertions(+), 99 deletions(-) diff --git a/docs/rules/one-var.md b/docs/rules/one-var.md index e7e440333f2..53851ab5b20 100644 --- a/docs/rules/one-var.md +++ b/docs/rules/one-var.md @@ -5,7 +5,7 @@ Variables can be declared at any point in JavaScript code using `var`, `let`, or There are two schools of thought in this regard: 1. There should be just one variable declaration for all variables in the function. That declaration typically appears at the top of the function. -2. You should use one variable declaration for each variable you want to define. +1. You should use one variable declaration for each variable you want to define. For instance: @@ -36,23 +36,29 @@ String option: * `"always"` (default) requires one variable declaration per scope * `"never"` requires multiple variable declarations per scope +* `"consecutive"` allows multiple variable declarations per scope but requires consecutive variable declarations to be combined into a single declaration Object option: * `"var": "always"` requires one `var` declaration per function * `"var": "never"` requires multiple `var` declarations per function +* `"var": "consecutive"` requires consecutive `var` declarations to be a single declaration * `"let": "always"` requires one `let` declaration per block * `"let": "never"` requires multiple `let` declarations per block +* `"let": "consecutive"` requires consecutive `let` declarations to be a single declaration * `"const": "always"` requires one `const` declaration per block * `"const": "never"` requires multiple `const` declarations per block +* `"const": "consecutive"` requires consecutive `const` declarations to be a single declaration * `"separateRequires": true` enforces `requires` to be separate from declarations Alternate object option: * `"initialized": "always"` requires one variable declaration for initialized variables per scope * `"initialized": "never"` requires multiple variable declarations for initialized variables per scope +* `"initialized": "consecutive"` requires consecutive variable declarations for initialized variables to be a single declaration * `"uninitialized": "always"` requires one variable declaration for uninitialized variables per scope * `"uninitialized": "never"` requires multiple variable declarations for uninitialized variables per scope +* `"uninitialized": "consecutive"` requires consecutive variable declarations for uninitialized variables to be a single declaration ### always @@ -181,6 +187,53 @@ function foo() { } ``` +### consecutive + +Examples of **incorrect** code for this rule with the `"consecutive"` option: + +```js +/*eslint one-var: ["error", "consecutive"]*/ +/*eslint-env es6*/ + +function foo() { + var bar; + var baz; +} + +function foo(){ + var bar = 1; + var baz = 2; + + qux(); + + var qux = 3; + var quux; +} +``` + +Examples of **correct** code for this rule with the `"consecutive"` option: + +```js +/*eslint one-var: ["error", "consecutive"]*/ +/*eslint-env es6*/ + + +function foo() { + var bar, + baz; +} + +function foo(){ + var bar = 1, + baz = 2; + + qux(); + + var qux = 3, + quux; +} +``` + ### var, let, and const Examples of **incorrect** code for this rule with the `{ var: "always", let: "never", const: "never" }` option: @@ -276,6 +329,86 @@ var foo = require("foo"), bar = require("bar"); ``` +Examples of **incorrect** code for this rule with the `{ var: "never", let: "consecutive", const: "consecutive" }` option: + +```js +/*eslint one-var: ["error", { var: "never", let: "consecutive", const: "consecutive" }]*/ +/*eslint-env es6*/ + +function foo() { + let a, + b; + let c; + + var d, + e; +} + +function foo() { + const a = 1, + b = 2; + const c = 3; + + var d, + e; +} +``` + +Examples of **correct** code for this rule with the `{ var: "never", let: "consecutive", const: "consecutive" }` option: + +```js +/*eslint one-var: ["error", { var: "never", let: "consecutive", const: "consecutive" }]*/ +/*eslint-env es6*/ + +function foo() { + let a, + b; + + var d; + var e; + + let f; +} + +function foo() { + const a = 1, + b = 2; + + var c; + var d; + + const e = 3; +} +``` + +Examples of **incorrect** code for this rule with the `{ var: "consecutive" }` option: + +```js +/*eslint one-var: ["error", { var: "consecutive" }]*/ +/*eslint-env es6*/ + +function foo() { + var a; + var b; +} +``` + +Examples of **correct** code for this rule with the `{ var: "consecutive" }` option: + +```js +/*eslint one-var: ["error", { var: "consecutive" }]*/ +/*eslint-env es6*/ + +function foo() { + var a, + b; + const c = 1; // `const` and `let` declarations are ignored if they are not specified + const d = 2; + let e; + let f; +} +``` + ### initialized and uninitialized Examples of **incorrect** code for this rule with the `{ "initialized": "always", "uninitialized": "never" }` option: @@ -329,7 +462,7 @@ function foo() { Examples of **correct** code for this rule with the `{ "initialized": "never" }` option: ```js -/*eslint one-var: ["error", { initialized: "never" }]*/ +/*eslint one-var: ["error", { "initialized": "never" }]*/ function foo() { var foo = true; @@ -338,6 +471,68 @@ function foo() { } ``` +Examples of **incorrect** code for this rule with the `{ "initialized": "consecutive", "uninitialized": "never" }` option: + +```js +/*eslint one-var: ["error", { "initialized": "consecutive", "uninitialized": "never" }]*/ + +function foo() { + var a = 1; + var b = 2; + var c, + d; + var e = 3; + var f = 4; +} +``` + +Examples of **correct** code for this rule with the `{ "initialized": "consecutive", "uninitialized": "never" }` option: + +```js +/*eslint one-var: ["error", { "initialized": "consecutive", "uninitialized": "never" }]*/ + +function foo() { + var a = 1, + b = 2; + var c; + var d; + var e = 3, + f = 4; +} +``` + +Examples of **incorrect** code for this rule with the `{ "initialized": "consecutive" }` option: + +```js +/*eslint one-var: ["error", { "initialized": "consecutive" }]*/ + +function foo() { + var a = 1; + var b = 2; + + foo(); + + var c = 3; + var d = 4; +} +``` + +Examples of **correct** code for this rule with the `{ "initialized": "consecutive" }` option: + +```js +/*eslint one-var: ["error", { "initialized": "consecutive" }]*/ + +function foo() { + var a = 1, + b = 2; + + foo(); + + var c = 3, + d = 4; +} +``` + ## Compatibility * **JSHint**: This rule maps to the `onevar` JSHint rule, but allows `let` and `const` to be configured separately. diff --git a/lib/rules/one-var.js b/lib/rules/one-var.js index cd094444b6a..40b5f0f0aab 100644 --- a/lib/rules/one-var.js +++ b/lib/rules/one-var.js @@ -22,7 +22,7 @@ module.exports = { { oneOf: [ { - enum: ["always", "never"] + enum: ["always", "never", "consecutive"] }, { type: "object", @@ -31,13 +31,13 @@ module.exports = { type: "boolean" }, var: { - enum: ["always", "never"] + enum: ["always", "never", "consecutive"] }, let: { - enum: ["always", "never"] + enum: ["always", "never", "consecutive"] }, const: { - enum: ["always", "never"] + enum: ["always", "never", "consecutive"] } }, additionalProperties: false @@ -46,10 +46,10 @@ module.exports = { type: "object", properties: { initialized: { - enum: ["always", "never"] + enum: ["always", "never", "consecutive"] }, uninitialized: { - enum: ["always", "never"] + enum: ["always", "never", "consecutive"] } }, additionalProperties: false @@ -60,10 +60,9 @@ module.exports = { }, create(context) { - - const MODE_ALWAYS = "always", - MODE_NEVER = "never"; - + const MODE_ALWAYS = "always"; + const MODE_NEVER = "never"; + const MODE_CONSECUTIVE = "consecutive"; const mode = context.options[0] || MODE_ALWAYS; const options = {}; @@ -273,119 +272,163 @@ module.exports = { return true; } + /** + * Checks a given VariableDeclaration node for errors. + * @param {ASTNode} node The VariableDeclaration node to check + * @returns {void} + * @private + */ + function checkVariableDeclaration(node) { + const parent = node.parent; + const type = node.kind; - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- + if (!options[type]) { + return; + } - return { - Program: startFunction, - FunctionDeclaration: startFunction, - FunctionExpression: startFunction, - ArrowFunctionExpression: startFunction, - BlockStatement: startBlock, - ForStatement: startBlock, - ForInStatement: startBlock, - ForOfStatement: startBlock, - SwitchStatement: startBlock, + const declarations = node.declarations; + const declarationCounts = countDeclarations(declarations); + const mixedRequires = declarations.some(isRequire) && !declarations.every(isRequire); + + if (options[type].initialized === MODE_ALWAYS) { + if (options.separateRequires && mixedRequires) { + context.report({ + node, + message: "Split requires to be separated into a single block." + }); + } + } - VariableDeclaration(node) { - const parent = node.parent; - const type = node.kind; + // consecutive + const nodeIndex = (parent.body && parent.body.length > 0 && parent.body.indexOf(node)) || 0; - if (!options[type]) { - return; - } + if (nodeIndex > 0) { + const previousNode = parent.body[nodeIndex - 1]; + const isPreviousNodeDeclaration = previousNode.type === "VariableDeclaration"; - const declarations = node.declarations; - const declarationCounts = countDeclarations(declarations); - const mixedRequires = declarations.some(isRequire) && !declarations.every(isRequire); + if (isPreviousNodeDeclaration && previousNode.kind === type) { + const previousDeclCounts = countDeclarations(previousNode.declarations); - if (options[type].initialized === MODE_ALWAYS) { - if (options.separateRequires && mixedRequires) { + if (options[type].initialized === MODE_CONSECUTIVE && options[type].uninitialized === MODE_CONSECUTIVE) { + context.report({ + node, + message: "Combine this with the previous '{{type}}' statement.", + data: { + type + } + }); + } else if (options[type].initialized === MODE_CONSECUTIVE && declarationCounts.initialized > 0 && previousDeclCounts.initialized > 0) { context.report({ node, - message: "Split requires to be separated into a single block." + message: "Combine this with the previous '{{type}}' statement with initialized variables.", + data: { + type + } + }); + } else if (options[type].uninitialized === MODE_CONSECUTIVE && + declarationCounts.uninitialized > 0 && + previousDeclCounts.uninitialized > 0) { + context.report({ + node, + message: "Combine this with the previous '{{type}}' statement with uninitialized variables.", + data: { + type + } }); } } + } - // always - if (!hasOnlyOneStatement(type, declarations)) { - if (options[type].initialized === MODE_ALWAYS && options[type].uninitialized === MODE_ALWAYS) { + // always + if (!hasOnlyOneStatement(type, declarations)) { + if (options[type].initialized === MODE_ALWAYS && options[type].uninitialized === MODE_ALWAYS) { + context.report({ + node, + message: "Combine this with the previous '{{type}}' statement.", + data: { + type + } + }); + } else { + if (options[type].initialized === MODE_ALWAYS && declarationCounts.initialized > 0) { context.report({ node, - message: "Combine this with the previous '{{type}}' statement.", + message: "Combine this with the previous '{{type}}' statement with initialized variables.", data: { type } }); - } else { - if (options[type].initialized === MODE_ALWAYS) { - context.report({ - node, - message: "Combine this with the previous '{{type}}' statement with initialized variables.", - data: { - type - } - }); + } + if (options[type].uninitialized === MODE_ALWAYS && declarationCounts.uninitialized > 0) { + if (node.parent.left === node && (node.parent.type === "ForInStatement" || node.parent.type === "ForOfStatement")) { + return; } - if (options[type].uninitialized === MODE_ALWAYS) { - if (node.parent.left === node && (node.parent.type === "ForInStatement" || node.parent.type === "ForOfStatement")) { - return; + context.report({ + node, + message: "Combine this with the previous '{{type}}' statement with uninitialized variables.", + data: { + type } - context.report({ - node, - message: "Combine this with the previous '{{type}}' statement with uninitialized variables.", - data: { - type - } - }); - } + }); } } + } - // never - if (parent.type !== "ForStatement" || parent.init !== node) { - const totalDeclarations = declarationCounts.uninitialized + declarationCounts.initialized; - - if (totalDeclarations > 1) { - - if (options[type].initialized === MODE_NEVER && options[type].uninitialized === MODE_NEVER) { - - // both initialized and uninitialized - context.report({ - node, - message: "Split '{{type}}' declarations into multiple statements.", - data: { - type - } - }); - } else if (options[type].initialized === MODE_NEVER && declarationCounts.initialized > 0) { - - // initialized - context.report({ - node, - message: "Split initialized '{{type}}' declarations into multiple statements.", - data: { - type - } - }); - } else if (options[type].uninitialized === MODE_NEVER && declarationCounts.uninitialized > 0) { - - // uninitialized - context.report({ - node, - message: "Split uninitialized '{{type}}' declarations into multiple statements.", - data: { - type - } - }); - } + // never + if (parent.type !== "ForStatement" || parent.init !== node) { + const totalDeclarations = declarationCounts.uninitialized + declarationCounts.initialized; + + if (totalDeclarations > 1) { + if (options[type].initialized === MODE_NEVER && options[type].uninitialized === MODE_NEVER) { + + // both initialized and uninitialized + context.report({ + node, + message: "Split '{{type}}' declarations into multiple statements.", + data: { + type + } + }); + } else if (options[type].initialized === MODE_NEVER && declarationCounts.initialized > 0) { + + // initialized + context.report({ + node, + message: "Split initialized '{{type}}' declarations into multiple statements.", + data: { + type + } + }); + } else if (options[type].uninitialized === MODE_NEVER && declarationCounts.uninitialized > 0) { + + // uninitialized + context.report({ + node, + message: "Split uninitialized '{{type}}' declarations into multiple statements.", + data: { + type + } + }); } } - }, + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + return { + Program: startFunction, + FunctionDeclaration: startFunction, + FunctionExpression: startFunction, + ArrowFunctionExpression: startFunction, + BlockStatement: startBlock, + ForStatement: startBlock, + ForInStatement: startBlock, + ForOfStatement: startBlock, + SwitchStatement: startBlock, + VariableDeclaration: checkVariableDeclaration, "ForStatement:exit": endBlock, "ForOfStatement:exit": endBlock, "ForInStatement:exit": endBlock, diff --git a/tests/lib/rules/one-var.js b/tests/lib/rules/one-var.js index ce56e3cb530..b8f3a913f92 100644 --- a/tests/lib/rules/one-var.js +++ b/tests/lib/rules/one-var.js @@ -213,7 +213,268 @@ ruleTester.run("one-var", rule, { code: "var foo = require('foo'); var bar = 'bar';", options: [{ separateRequires: true, var: "always" }], parserOptions: { env: { node: true } } + }, + + // https://github.com/eslint/eslint/issues/4680 + { + code: "var a = 0, b, c;", + options: ["consecutive"] + }, + { + code: "var a = 0, b = 1, c = 2;", + options: ["consecutive"] + }, + { + code: "var a = 0, b = 1; foo(); var c = 2;", + options: ["consecutive"] + }, + { + code: "let a = 0, b, c;", + options: ["consecutive"], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "let a = 0, b = 1, c = 2;", + options: ["consecutive"], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "let a = 0, b = 1; foo(); let c = 2;", + options: ["consecutive"], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "const a = 0, b = 1; foo(); const c = 2;", + options: ["consecutive"], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "const a = 0; var b = 1;", + options: ["consecutive"], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "const a = 0; let b = 1;", + options: ["consecutive"], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "let a = 0; const b = 1; var c = 2;", + options: ["consecutive"], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "var a = 0, b = 1; var c, d;", + options: [{ initialized: "consecutive", uninitialized: "always" }] + }, + { + code: "var a = 0; var b, c; var d = 1;", + options: [{ initialized: "consecutive", uninitialized: "always" }] + }, + { + code: "let a = 0, b = 1; let c, d;", + options: [{ initialized: "consecutive", uninitialized: "always" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "let a = 0; let b, c; let d = 1;", + options: [{ initialized: "consecutive", uninitialized: "always" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "const a = 0, b = 1; let c, d;", + options: [{ initialized: "consecutive", uninitialized: "always" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "const a = 0; let b, c; const d = 1;", + options: [{ initialized: "consecutive", uninitialized: "always" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "var a = 0, b = 1; var c; var d;", + options: [{ initialized: "consecutive", uninitialized: "never" }] + }, + { + code: "var a = 0; var b; var c; var d = 1;", + options: [{ initialized: "consecutive", uninitialized: "never" }] + }, + { + code: "let a = 0, b = 1; let c; let d;", + options: [{ initialized: "consecutive", uninitialized: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "let a = 0; let b; let c; let d = 1;", + options: [{ initialized: "consecutive", uninitialized: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "const a = 0, b = 1; let c; let d;", + options: [{ initialized: "consecutive", uninitialized: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "const a = 0; let b; let c; const d = 1;", + options: [{ initialized: "consecutive", uninitialized: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "var a, b; var c = 0, d = 1;", + options: [{ uninitialized: "consecutive", initialized: "always" }] + }, + { + code: "var a; var b = 0, c = 1; var d;", + options: [{ uninitialized: "consecutive", initialized: "always" }] + }, + { + code: "let a, b; let c = 0, d = 1;", + options: [{ uninitialized: "consecutive", initialized: "always" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "let a; let b = 0, c = 1; let d;", + options: [{ uninitialized: "consecutive", initialized: "always" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "let a, b; const c = 0, d = 1;", + options: [{ uninitialized: "consecutive", initialized: "always" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "let a; const b = 0, c = 1; let d;", + options: [{ uninitialized: "consecutive", initialized: "always" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "var a, b; var c = 0; var d = 1;", + options: [{ uninitialized: "consecutive", initialized: "never" }] + }, + { + code: "var a; var b = 0; var c = 1; var d;", + options: [{ uninitialized: "consecutive", initialized: "never" }] + }, + { + code: "let a, b; let c = 0; let d = 1;", + options: [{ uninitialized: "consecutive", initialized: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "let a; let b = 0; let c = 1; let d;", + options: [{ uninitialized: "consecutive", initialized: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "let a, b; const c = 0; const d = 1;", + options: [{ uninitialized: "consecutive", initialized: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "let a; const b = 0; const c = 1; let d;", + options: [{ uninitialized: "consecutive", initialized: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "var a = 0, b = 1;", + options: [{ var: "consecutive" }] + }, + { + code: "var a = 0; foo; var b = 1;", + options: [{ var: "consecutive" }] + }, + { + code: "let a = 0, b = 1;", + options: [{ let: "consecutive" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "let a = 0; foo; let b = 1;", + options: [{ let: "consecutive" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "const a = 0, b = 1;", + options: [{ const: "consecutive" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "const a = 0; foo; const b = 1;", + options: [{ const: "consecutive" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "let a, b; const c = 0, d = 1;", + options: [{ let: "consecutive", const: "always" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "let a; const b = 0, c = 1; let d;", + options: [{ let: "consecutive", const: "always" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "let a, b; const c = 0; const d = 1;", + options: [{ let: "consecutive", const: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "let a; const b = 0; const c = 1; let d;", + options: [{ let: "consecutive", const: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "const a = 0, b = 1; let c, d;", + options: [{ const: "consecutive", let: "always" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "const a = 0; let b, c; const d = 1;", + options: [{ const: "consecutive", let: "always" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "const a = 0, b = 1; let c; let d;", + options: [{ const: "consecutive", let: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "const a = 0; let b; let c; const d = 1;", + options: [{ const: "consecutive", let: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "var a = 1, b = 2; foo(); var c = 3, d = 4;", + options: [{ initialized: "consecutive" }] + }, + { + code: "var bar, baz;", + options: ["consecutive"] + }, + { + code: "var bar = 1, baz = 2; qux(); var qux = 3, quux;", + options: ["consecutive"] + }, + { + code: "let a, b; var c; var d; let e;", + options: [{ var: "never", let: "consecutive", const: "consecutive" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "const a = 1, b = 2; var d; var e; const f = 3;", + options: [{ var: "never", let: "consecutive", const: "consecutive" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "var a, b; const c = 1; const d = 2; let e; let f; ", + options: [{ var: "consecutive" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "var a = 1, b = 2; var c; var d; var e = 3, f = 4;", + options: [{ initialized: "consecutive", uninitialized: "never" }] } + ], invalid: [ { @@ -608,6 +869,657 @@ ruleTester.run("one-var", rule, { line: 1, column: 29 }] + }, + + // https://github.com/eslint/eslint/issues/4680 + { + code: "var a = 1, b; var c;", + options: ["consecutive"], + errors: [{ + message: "Combine this with the previous 'var' statement.", + type: "VariableDeclaration", + line: 1, + column: 15 + }] + }, + { + code: "var a = 0, b = 1; var c = 2;", + options: ["consecutive"], + errors: [{ + message: "Combine this with the previous 'var' statement.", + type: "VariableDeclaration", + line: 1, + column: 19 + }] + }, + { + code: "let a = 1, b; let c;", + options: ["consecutive"], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement.", + type: "VariableDeclaration", + line: 1, + column: 15 + }] + }, + { + code: "let a = 0, b = 1; let c = 2;", + options: ["consecutive"], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement.", + type: "VariableDeclaration", + line: 1, + column: 19 + }] + }, + { + code: "const a = 0, b = 1; const c = 2;", + options: ["consecutive"], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'const' statement.", + type: "VariableDeclaration", + line: 1, + column: 21 + }] + }, + { + code: "const a = 0; var b = 1; var c = 2; const d = 3;", + options: ["consecutive"], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'var' statement.", + type: "VariableDeclaration", + line: 1, + column: 25 + }] + }, + { + code: "const a = 0; let b = 1; let c = 2; const d = 3;", + options: ["consecutive"], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement.", + type: "VariableDeclaration", + line: 1, + column: 25 + }] + }, + { + code: "let a = 0; const b = 1; const c = 1; var d = 2;", + options: ["consecutive"], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'const' statement.", + type: "VariableDeclaration", + line: 1, + column: 25 + }] + }, + { + code: "var a = 0; var b; var c; var d = 1", + options: [{ initialized: "consecutive", uninitialized: "always" }], + errors: [{ + message: "Combine this with the previous 'var' statement with uninitialized variables.", + type: "VariableDeclaration", + line: 1, + column: 19 + }] + }, + { + code: "var a = 0; var b = 1; var c; var d;", + options: [{ initialized: "consecutive", uninitialized: "always" }], + errors: [{ + message: "Combine this with the previous 'var' statement with initialized variables.", + type: "VariableDeclaration", + line: 1, + column: 12 + }, + { + message: "Combine this with the previous 'var' statement with uninitialized variables.", + type: "VariableDeclaration", + line: 1, + column: 30 + }] + }, + { + code: "let a = 0; let b; let c; let d = 1;", + options: [{ initialized: "consecutive", uninitialized: "always" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement with uninitialized variables.", + type: "VariableDeclaration", + line: 1, + column: 19 + }] + }, + { + code: "let a = 0; let b = 1; let c; let d;", + options: [{ initialized: "consecutive", uninitialized: "always" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement with initialized variables.", + type: "VariableDeclaration", + line: 1, + column: 12 + }, + { + message: "Combine this with the previous 'let' statement with uninitialized variables.", + type: "VariableDeclaration", + line: 1, + column: 30 + }] + }, + { + code: "const a = 0; let b; let c; const d = 1;", + options: [{ initialized: "consecutive", uninitialized: "always" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement with uninitialized variables.", + type: "VariableDeclaration", + line: 1, + column: 21 + }] + }, + { + code: "const a = 0; const b = 1; let c; let d;", + options: [{ initialized: "consecutive", uninitialized: "always" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'const' statement with initialized variables.", + type: "VariableDeclaration", + line: 1, + column: 14 + }, + { + message: "Combine this with the previous 'let' statement with uninitialized variables.", + type: "VariableDeclaration", + line: 1, + column: 34 + }] + }, + { + code: "var a = 0; var b = 1; var c, d;", + options: [{ initialized: "consecutive", uninitialized: "never" }], + errors: [{ + message: "Combine this with the previous 'var' statement with initialized variables.", + type: "VariableDeclaration", + line: 1, + column: 12 + }, + { + message: "Split uninitialized 'var' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 23 + }] + }, + { + code: "var a = 0; var b, c; var d = 1;", + options: [{ initialized: "consecutive", uninitialized: "never" }], + errors: [{ + message: "Split uninitialized 'var' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 12 + }] + }, + { + code: "let a = 0; let b = 1; let c, d;", + options: [{ initialized: "consecutive", uninitialized: "never" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement with initialized variables.", + type: "VariableDeclaration", + line: 1, + column: 12 + }, + { + message: "Split uninitialized 'let' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 23 + }] + }, + { + code: "let a = 0; let b, c; let d = 1;", + options: [{ initialized: "consecutive", uninitialized: "never" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Split uninitialized 'let' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 12 + }] + }, + { + code: "const a = 0; const b = 1; let c, d;", + options: [{ initialized: "consecutive", uninitialized: "never" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'const' statement with initialized variables.", + type: "VariableDeclaration", + line: 1, + column: 14 + }, + { + message: "Split uninitialized 'let' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 27 + }] + }, + { + code: "const a = 0; let b, c; const d = 1;", + options: [{ initialized: "consecutive", uninitialized: "never" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Split uninitialized 'let' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 14 + }] + }, + { + code: "var a; var b; var c = 0; var d = 1;", + options: [{ uninitialized: "consecutive", initialized: "always" }], + errors: [{ + message: "Combine this with the previous 'var' statement with uninitialized variables.", + type: "VariableDeclaration", + line: 1, + column: 8 + }, + { + message: "Combine this with the previous 'var' statement with initialized variables.", + type: "VariableDeclaration", + line: 1, + column: 26 + }] + }, + { + code: "var a; var b = 0; var c = 1; var d;", + options: [{ uninitialized: "consecutive", initialized: "always" }], + errors: [{ + message: "Combine this with the previous 'var' statement with initialized variables.", + type: "VariableDeclaration", + line: 1, + column: 19 + }] + }, + { + code: "let a; let b; let c = 0; let d = 1;", + options: [{ uninitialized: "consecutive", initialized: "always" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement with uninitialized variables.", + type: "VariableDeclaration", + line: 1, + column: 8 + }, + { + message: "Combine this with the previous 'let' statement with initialized variables.", + type: "VariableDeclaration", + line: 1, + column: 26 + }] + }, + { + code: "let a; let b = 0; let c = 1; let d;", + options: [{ uninitialized: "consecutive", initialized: "always" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement with initialized variables.", + type: "VariableDeclaration", + line: 1, + column: 19 + }] + }, + { + code: "let a; let b; const c = 0; const d = 1;", + options: [{ uninitialized: "consecutive", initialized: "always" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement with uninitialized variables.", + type: "VariableDeclaration", + line: 1, + column: 8 + }, + { + message: "Combine this with the previous 'const' statement with initialized variables.", + type: "VariableDeclaration", + line: 1, + column: 28 + }] + }, + { + code: "let a; const b = 0; const c = 1; let d;", + options: [{ uninitialized: "consecutive", initialized: "always" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'const' statement with initialized variables.", + type: "VariableDeclaration", + line: 1, + column: 21 + }] + }, + { + code: "var a; var b; var c = 0, d = 1;", + options: [{ uninitialized: "consecutive", initialized: "never" }], + errors: [{ + message: "Combine this with the previous 'var' statement with uninitialized variables.", + type: "VariableDeclaration", + line: 1, + column: 8 + }, + { + message: "Split initialized 'var' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 15 + }] + }, + { + code: "var a; var b = 0, c = 1; var d;", + options: [{ uninitialized: "consecutive", initialized: "never" }], + errors: [{ + message: "Split initialized 'var' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 8 + }] + }, + { + code: "let a; let b; let c = 0, d = 1;", + options: [{ uninitialized: "consecutive", initialized: "never" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement with uninitialized variables.", + type: "VariableDeclaration", + line: 1, + column: 8 + }, + { + message: "Split initialized 'let' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 15 + }] + }, + { + code: "let a; let b = 0, c = 1; let d;", + options: [{ uninitialized: "consecutive", initialized: "never" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Split initialized 'let' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 8 + }] + }, + { + code: "let a; let b; const c = 0, d = 1;", + options: [{ uninitialized: "consecutive", initialized: "never" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement with uninitialized variables.", + type: "VariableDeclaration", + line: 1, + column: 8 + }, + { + message: "Split initialized 'const' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 15 + }] + }, + { + code: "let a; const b = 0, c = 1; let d;", + options: [{ uninitialized: "consecutive", initialized: "never" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Split initialized 'const' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 8 + }] + }, + { + code: "var a = 0; var b = 1;", + options: [{ var: "consecutive" }], + errors: [{ + message: "Combine this with the previous 'var' statement.", + type: "VariableDeclaration", + line: 1, + column: 12 + }] + }, + { + code: "let a = 0; let b = 1;", + options: [{ let: "consecutive" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement.", + type: "VariableDeclaration", + line: 1, + column: 12 + }] + }, + { + code: "const a = 0; const b = 1;", + options: [{ const: "consecutive" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'const' statement.", + type: "VariableDeclaration", + line: 1, + column: 14 + }] + }, + { + code: "let a; let b; const c = 0; const d = 1;", + options: [{ let: "consecutive", const: "always" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement.", + type: "VariableDeclaration", + line: 1, + column: 8 + }, + { + message: "Combine this with the previous 'const' statement.", + type: "VariableDeclaration", + line: 1, + column: 28 + }] + }, + { + code: "let a; const b = 0; const c = 1; let d;", + options: [{ let: "consecutive", const: "always" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'const' statement.", + type: "VariableDeclaration", + line: 1, + column: 21 + }] + }, + { + code: "let a; let b; const c = 0, d = 1;", + options: [{ let: "consecutive", const: "never" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement.", + type: "VariableDeclaration", + line: 1, + column: 8 + }, + { + message: "Split 'const' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 15 + }] + }, + { + code: "let a; const b = 0, c = 1; let d;", + options: [{ let: "consecutive", const: "never" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Split 'const' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 8 + }] + }, + { + code: "const a = 0; const b = 1; let c; let d;", + options: [{ const: "consecutive", let: "always" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'const' statement.", + type: "VariableDeclaration", + line: 1, + column: 14 + }, + { + message: "Combine this with the previous 'let' statement.", + type: "VariableDeclaration", + line: 1, + column: 34 + }] + }, + { + code: "const a = 0; let b; let c; const d = 1;", + options: [{ const: "consecutive", let: "always" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement.", + type: "VariableDeclaration", + line: 1, + column: 21 + }] + }, + { + code: "const a = 0; const b = 1; let c, d;", + options: [{ const: "consecutive", let: "never" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'const' statement.", + type: "VariableDeclaration", + line: 1, + column: 14 + }, + { + message: "Split 'let' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 27 + }] + }, + { + code: "const a = 0; let b, c; const d = 1;", + options: [{ const: "consecutive", let: "never" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Split 'let' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 14 + }] + }, + { + code: "var bar; var baz;", + options: ["consecutive"], + errors: [{ + message: "Combine this with the previous 'var' statement.", + type: "VariableDeclaration", + line: 1, + column: 10 + }] + }, + { + code: "var bar = 1; var baz = 2; qux(); var qux = 3; var quux;", + options: ["consecutive"], + errors: [{ + message: "Combine this with the previous 'var' statement.", + type: "VariableDeclaration", + line: 1, + column: 14 + }, + { + message: "Combine this with the previous 'var' statement.", + type: "VariableDeclaration", + line: 1, + column: 47 + }] + }, + { + code: "let a, b; let c; var d, e;", + options: [{ var: "never", let: "consecutive", const: "consecutive" }], + parserOptions: { ecmaVersion: 6 }, + errors: [{ + message: "Combine this with the previous 'let' statement.", + type: "VariableDeclaration", + line: 1, + column: 11 + }, + { + message: "Split 'var' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 18 + }] + }, + { + code: "var a; var b;", + options: [{ var: "consecutive" }], + errors: [{ + message: "Combine this with the previous 'var' statement.", + type: "VariableDeclaration", + line: 1, + column: 8 + }] + }, + { + code: "var a = 1; var b = 2; var c, d; var e = 3; var f = 4;", + options: [{ initialized: "consecutive", uninitialized: "never" }], + errors: [{ + message: "Combine this with the previous 'var' statement with initialized variables.", + type: "VariableDeclaration", + line: 1, + column: 12 + }, + { + message: "Split uninitialized 'var' declarations into multiple statements.", + type: "VariableDeclaration", + line: 1, + column: 23 + }, + { + message: "Combine this with the previous 'var' statement with initialized variables.", + type: "VariableDeclaration", + line: 1, + column: 44 + }] + }, + { + code: "var a = 1; var b = 2; foo(); var c = 3; var d = 4;", + options: [{ initialized: "consecutive" }], + errors: [{ + message: "Combine this with the previous 'var' statement with initialized variables.", + type: "VariableDeclaration", + line: 1, + column: 12 + }, + { + message: "Combine this with the previous 'var' statement with initialized variables.", + type: "VariableDeclaration", + line: 1, + column: 41 + }] } ] });