From 33dcf0517589341664e4f0dfe1ed78744d6c91f7 Mon Sep 17 00:00:00 2001 From: Toru Nagashima Date: Sun, 5 Jun 2016 02:56:43 +0900 Subject: [PATCH] Breaking: drop support ESLint v1 - Revive support Node 0.10 and 0.12. - Upgrade dependencies. --- .eslintrc | 11 +- .travis.yml | 6 +- lib/rules/arrow-parens.js | 32 ++- lib/rules/block-scoped-var.js | 347 +++++++++++++--------------- package.json | 38 ++- scripts/generate-index.js | 73 +++--- tests/lib/rules/arrow-parens.js | 50 ++-- tests/lib/rules/block-scoped-var.js | 26 +-- 8 files changed, 272 insertions(+), 311 deletions(-) diff --git a/.eslintrc b/.eslintrc index 83389b6..a77ff9a 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,14 +1,5 @@ { - "extends": "mysticatea/nodejs", - "plugins": ["node"], - "ecmaFeatures": { - "modules": false - }, + "extends": ["mysticatea/es5", "mysticatea/node"], "rules": { - "func-names": 0, - "node/no-missing-require": 2, - "node/no-unpublished-require": 2, - "node/no-unsupported-features": [2, {"version": 4}], - "node/shebang": 2 } } diff --git a/.travis.yml b/.travis.yml index ebce07d..9874843 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,9 @@ sudo: false language: node_js node_js: + - "0.10" + - "0.12" - "4" - - "5" -before_install: - - npm install -g npm + - "6" after_success: - npm run coveralls diff --git a/lib/rules/arrow-parens.js b/lib/rules/arrow-parens.js index 20b19c5..4b3510d 100644 --- a/lib/rules/arrow-parens.js +++ b/lib/rules/arrow-parens.js @@ -4,7 +4,7 @@ * See LICENSE file in root directory for full license. */ -"use strict"; +"use strict" //------------------------------------------------------------------------------ // Helpers @@ -16,7 +16,7 @@ * @returns {boolean} `true` when the token is `(`. */ function isOpenParen(token) { - return token.type === "Punctuator" && token.value === "("; + return token.type === "Punctuator" && token.value === "(" } /** @@ -26,7 +26,7 @@ function isOpenParen(token) { * @returns {boolean} `true` when the tokens are at a same line. */ function isSameLine(a, b) { - return a.loc.end.line === b.loc.start.line; + return a.loc.end.line === b.loc.start.line } //------------------------------------------------------------------------------ @@ -35,9 +35,9 @@ function isSameLine(a, b) { module.exports = function(context) { return { - ArrowFunctionExpression(node) { - const first = context.getFirstToken(node); - const before = context.getTokenBefore(first); + ArrowFunctionExpression: function(node) { + var first = context.getFirstToken(node) + var before = context.getTokenBefore(first) if (isOpenParen(first)) { if (node.params.length === 1 && @@ -47,18 +47,16 @@ module.exports = function(context) { ) { context.report( node, - "remove redundant parens of the argument list."); + "remove redundant parens of the argument list.") } } - else { - if (!isOpenParen(before) || !isSameLine(before, first)) { - context.report( - node, - "enclose the argument with parens."); - } + else if (!isOpenParen(before) || !isSameLine(before, first)) { + context.report( + node, + "enclose the argument with parens.") } - } - }; -}; + }, + } +} -module.exports.schema = []; +module.exports.schema = [] diff --git a/lib/rules/block-scoped-var.js b/lib/rules/block-scoped-var.js index a6d19c0..c1f9f10 100644 --- a/lib/rules/block-scoped-var.js +++ b/lib/rules/block-scoped-var.js @@ -3,37 +3,14 @@ * @copyright 2015 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ - -"use strict"; +"use strict" //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -const scopeNodeType = /^(?:(?:Block|Switch|For(?:In|Of)?)Statement|CatchClause|Program)$/; -const containerNodeType = /^(?:For(?:In|Of)?Statement|(?:Arrow)?Function(?:Declaration|Expression))$/; - -/** - * Collects unresolved references from the global scope, then creates a map to references from its name. - * @param {RuleContext} context - The current context. - * @returns {object} A map object. Its key is the variable names. Its value is the references of each variable. - */ -function collectUnresolvedReferences(context) { - const unresolved = Object.create(null); - const references = context.getScope().through; - - for (let i = 0; i < references.length; ++i) { - const reference = references[i]; - const name = reference.identifier.name; - - if (name in unresolved === false) { - unresolved[name] = []; - } - unresolved[name].push(reference); - } - - return unresolved; -} +var scopeNodeType = /^(?:(?:Block|Switch|For(?:In|Of)?)Statement|CatchClause|Program)$/ +var containerNodeType = /^(?:For(?:In|Of)?Statement|(?:Arrow)?Function(?:Declaration|Expression))$/ /** * Checks whether or not a given definition should be skipped. @@ -45,171 +22,170 @@ function collectUnresolvedReferences(context) { function shouldSkip(def, defs, variable) { // To check re-declarations. if (defs.length >= 2 && def.type !== "TDZ") { - return false; + return false } switch (def.type) { case "ClassName": case "FunctionName": - return variable.scope.block === def.node; + return variable.scope.block === def.node case "Parameter": case "TDZ": - return true; + return true case "Variable": - return def.parent.kind !== "var"; + return def.parent.kind !== "var" default: - return false; + return false } } /** * Pseudo scope information for `var`. + * + * Finds and creates information of a containing scope of a given declaration. + * + * @constructor + * @param {escope.Variable.DefineEntry} def - A declaration. */ -class PseudoScope { - /** - * Finds and creates information of a containing scope of a given declaration. - * @param {escope.Variable.DefineEntry} def - A declaration. - */ - constructor(def) { - let node = null; +function PseudoScope(def) { + var node = null - if (def.type === "Parameter") { - node = def.node; - } - else { - node = (def.parent || def.node).parent; + if (def.type === "Parameter") { + node = def.node + } + else { + node = (def.parent || def.node).parent - while (!scopeNodeType.test(node.type)) { - node = node.parent; - } - if (node.parent != null && containerNodeType.test(node.parent.type)) { - node = node.parent; - } + while (!scopeNodeType.test(node.type)) { + node = node.parent + } + if (node.parent != null && containerNodeType.test(node.parent.type)) { + node = node.parent } - - /** - * The `Identifier` node of the declaration. - * @type {ASTNode} - */ - this.identifier = def.name; - - /** - * The start position of the scope. - * @type {number} - */ - this.start = node.range[0]; - - /** - * The end position of the scope. - * @type {number} - */ - this.end = node.range[1]; - - /** - * The `Identifier` nodes of re-declarations. - * @type {ASTNode[]} - */ - this.redeclarations = []; - - /** - * The `PseudoScope` instances which are nested. - * @type {PseudoScope[]} - */ - this.children = []; - - /** - * The flag of shadowing. - * @type {boolean} - */ - this.shadowing = false; - - /** - * The flag of used. - * @type {boolean} - */ - this.used = false; } /** - * Creates pseudo scopes of a given variable. - * @param {escope.Variable} variable - A variable to create. - * @returns {PseudoScope[]} the created scopes. + * The `Identifier` node of the declaration. + * @type {ASTNode} */ - static createScopesFrom(variable) { - const defs = variable.defs; - const scopes = []; - for (let j = 0; j < defs.length; ++j) { - const def = defs[j]; - if (!shouldSkip(def, defs, variable)) { - PseudoScope.push(scopes, new PseudoScope(def)); - } - } - return scopes; - } + this.identifier = def.name /** - * Adds a given scope into a given scope list. - * This considers re-declarations and shadowing. - * @param {PseudoScope[]} scopes - Scopes to be added. - * @param {PseudoScope} newScope - A scope to add. - * @returns {void} + * The start position of the scope. + * @type {number} */ - static push(scopes, newScope) { - for (let i = 0; i < scopes.length; ++i) { - const scope = scopes[i]; + this.start = node.range[0] - if (scope.start === newScope.start && scope.end === newScope.end) { - scope.redeclarations.push(newScope.identifier); - return; - } - if (scope.start <= newScope.start && newScope.end <= scope.end) { - newScope.markAsShadowing(); - PseudoScope.push(scope.children, newScope); - return; - } - } + /** + * The end position of the scope. + * @type {number} + */ + this.end = node.range[1] - scopes.push(newScope); - } + /** + * The `Identifier` nodes of re-declarations. + * @type {ASTNode[]} + */ + this.redeclarations = [] /** - * Finds a containing scope of a given reference. - * @param {PseudoScope[]} scopes - Scopes to be domain. - * @param {escope.Reference} reference - A reference to find. - * @returns {PseudoScope|null} A containing scope of the reference. + * The `PseudoScope` instances which are nested. + * @type {PseudoScope[]} */ - static findScope(scopes, reference) { - const range = reference.identifier.range; + this.children = [] - for (let i = 0; i < scopes.length; ++i) { - const scope = scopes[i]; + /** + * The flag of shadowing. + * @type {boolean} + */ + this.shadowing = false - if (scope.start < range[0] && range[1] < scope.end) { - return PseudoScope.findScope(scope.children, reference) || scope; - } - } + /** + * The flag of used. + * @type {boolean} + */ + this.used = false +} - return null; +/** + * Creates pseudo scopes of a given variable. + * @param {escope.Variable} variable - A variable to create. + * @returns {PseudoScope[]} the created scopes. + */ +PseudoScope.createScopesFrom = function(variable) { + var defs = variable.defs + var scopes = [] + for (var j = 0; j < defs.length; ++j) { + var def = defs[j] + if (!shouldSkip(def, defs, variable)) { + PseudoScope.push(scopes, new PseudoScope(def)) + } } + return scopes +} - /** - * Turns a shadowing flag on. - * @returns {void} - */ - markAsShadowing() { - this.shadowing = true; +/** + * Adds a given scope into a given scope list. + * This considers re-declarations and shadowing. + * @param {PseudoScope[]} scopes - Scopes to be added. + * @param {PseudoScope} newScope - A scope to add. + * @returns {void} + */ +PseudoScope.push = function(scopes, newScope) { + for (var i = 0; i < scopes.length; ++i) { + var scope = scopes[i] + + if (scope.start === newScope.start && scope.end === newScope.end) { + scope.redeclarations.push(newScope.identifier) + return + } + if (scope.start <= newScope.start && newScope.end <= scope.end) { + newScope.markAsShadowing() + PseudoScope.push(scope.children, newScope) + return + } } - /** - * Turns an used flag on. - * @returns {void} - */ - markAsUsed() { - this.used = true; + scopes.push(newScope) +} + +/** + * Finds a containing scope of a given reference. + * @param {PseudoScope[]} scopes - Scopes to be domain. + * @param {escope.Reference} reference - A reference to find. + * @returns {PseudoScope|null} A containing scope of the reference. + */ +PseudoScope.findScope = function(scopes, reference) { + var range = reference.identifier.range + + for (var i = 0; i < scopes.length; ++i) { + var scope = scopes[i] + + if (scope.start < range[0] && range[1] < scope.end) { + return PseudoScope.findScope(scope.children, reference) || scope + } } + + return null +} + +/** + * Turns a shadowing flag on. + * @returns {void} + */ +PseudoScope.prototype.markAsShadowing = function() { + this.shadowing = true +} + +/** + * Turns an used flag on. + * @returns {void} + */ +PseudoScope.prototype.markAsUsed = function() { + this.used = true } //------------------------------------------------------------------------------ @@ -217,51 +193,42 @@ class PseudoScope { //------------------------------------------------------------------------------ module.exports = function(context) { - let unresolvedReferences = Object.create(null); - /** * Finds and reports references which are outside of valid scopes. * @param {ASTNode} node - A node to get variables. * @returns {void} */ function checkForVariables(node) { - const isGlobal = context.getScope().type === "global"; - const variables = context.getDeclaredVariables(node); - for (let i = 0; i < variables.length; ++i) { - const variable = variables[i]; - const defs = variable.defs; - const lastDef = defs[defs.length - 1]; + var variables = context.getDeclaredVariables(node) + for (var i = 0; i < variables.length; ++i) { + var variable = variables[i] + var defs = variable.defs + var lastDef = defs[defs.length - 1] // Skip except the last declaration. // Because `node.parent` is possibly not defined. if ((lastDef.parent || lastDef.node) !== node) { - continue; + continue } // Collect the containing scopes. - const scopes = PseudoScope.createScopesFrom(variable); + var scopes = PseudoScope.createScopesFrom(variable) if (scopes.length === 0) { - continue; - } - - // Some global variables are possibly unresolved. - // In this case, use unresolved references. - let references = variable.references; - if (isGlobal && variable.name in unresolvedReferences) { - references = unresolvedReferences[variable.name]; + continue } // Check whether or not any reading reference exists. - // And while it does, warn references which does not belong to any scope. - let hasReadRef = false; - for (let j = 0; j < references.length; ++j) { - const reference = references[j]; - const scope = PseudoScope.findScope(scopes, reference); + // And while it does, warn references which does not belong to any + // scope. + var hasReadRef = false + for (var j = 0; j < variable.references.length; ++j) { + var reference = variable.references[j] + var scope = PseudoScope.findScope(scopes, reference) if (reference.isRead()) { - hasReadRef = true; + hasReadRef = true if (scope != null) { - scope.markAsUsed(); + scope.markAsUsed() } } @@ -269,49 +236,45 @@ module.exports = function(context) { context.report( reference.identifier, "\"{{name}}\" is not defined.", - {name: reference.identifier.name}); + {name: reference.identifier.name}) } } // Warn re-declarations, shadowing, and unused. - scopes.forEach(function walk(scope) { // eslint-disable-line no-loop-func - for (let j = 0; j < scope.redeclarations.length; ++j) { - const identifier = scope.redeclarations[j]; + scopes.forEach(function walk(scope) { //eslint-disable-line no-loop-func, no-shadow + for (var j = 0; j < scope.redeclarations.length; ++j) { //eslint-disable-line no-shadow + var identifier = scope.redeclarations[j] context.report( identifier, "\"{{name}}\" is already defined.", - {name: identifier.name}); + {name: identifier.name}) } if (scope.shadowing) { context.report( scope.identifier, "\"{{name}}\" is already defined in the upper scope.", - {name: scope.identifier.name}); + {name: scope.identifier.name}) } if (hasReadRef && !scope.used) { context.report( scope.identifier, "\"{{name}}\" is defined but never used.", - {name: scope.identifier.name}); + {name: scope.identifier.name}) } - scope.children.forEach(walk); - }); + scope.children.forEach(walk) + }) } } return { - Program() { - unresolvedReferences = collectUnresolvedReferences(context); - }, - VariableDeclaration: checkForVariables, FunctionDeclaration: checkForVariables, ClassDeclaration: checkForVariables, - ImportDeclaration: checkForVariables - }; -}; + ImportDeclaration: checkForVariables, + } +} -module.exports.schema = []; +module.exports.schema = [] diff --git a/package.json b/package.json index 2fa9d4f..8b2c809 100644 --- a/package.json +++ b/package.json @@ -2,39 +2,37 @@ "name": "eslint-plugin-mysticatea", "version": "2.0.1", "description": "ESLint rules for me.", + "engines": { + "node": "^0.10.0 || ^0.12.0 || >=4.0.0" + }, "main": "index.js", "files": [ "lib" ], "scripts": { - "preversion": "npm run build", + "preversion": "run-s test build", "postversion": "git push && git push --tags", "clean": "rimraf coverage index.js", "lint": "eslint src tests scripts", - "build": "npm-run-all clean test build:index", - "build:index": "node scripts/generate-index.js", - "test": "npm-run-all lint test:mocha", - "test:mocha": "istanbul cover node_modules/mocha/bin/_mocha -- tests/lib/**/*.js", - "testing": "mocha tests/**/*.js --watch --growl", + "prebuild": "npm run clean", + "build": "node scripts/generate-index.js", + "pretest": "npm run lint", + "test": "istanbul cover node_modules/mocha/bin/_mocha -- tests/lib/**/*.js", + "watch": "mocha \"tests/**/*.js\" --watch --growl", "coveralls": "cat coverage/lcov.info | coveralls" }, - "dependencies": {}, "peerDependencies": { - "eslint": ">=1.10.3 || 2.0.0-beta.1" + "eslint": "^2.0.0" }, + "dependencies": {}, "devDependencies": { - "coveralls": "^2.11.6", - "eslint": "^1.10.3", - "eslint-config-mysticatea": "^1.9.0", - "eslint-plugin-mysticatea": "^1.0.3", - "eslint-plugin-node": "^0.4.1", - "istanbul": "^0.4.2", - "mocha": "^2.3.4", - "npm-run-all": "^1.4.0", - "rimraf": "^2.5.0" - }, - "engines": { - "node": ">=4" + "coveralls": "^2.11.9", + "eslint": "^2.11.1", + "eslint-config-mysticatea": "^4.0.0", + "istanbul": "^0.4.3", + "mocha": "^2.5.3", + "npm-run-all": "^2.1.1", + "rimraf": "^2.5.2" }, "repository": { "type": "git", diff --git a/scripts/generate-index.js b/scripts/generate-index.js index fa73963..ba4b921 100644 --- a/scripts/generate-index.js +++ b/scripts/generate-index.js @@ -3,38 +3,49 @@ * @copyright 2015 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ +"use strict" -"use strict"; +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ -const fs = require("fs"); -const path = require("path"); +var fs = require("fs") +var path = require("path") -const ruleNames = fs - .readdirSync(path.join(__dirname, "../lib/rules")) - .map(name => path.basename(name, ".js")); - -const rules = ruleNames - .map(name => ` "${name}": require("./lib/rules/${name}")`) - .join(",\n"); - -const rulesConfig = ruleNames - .map(name => ` "${name}": 0`) - .join(",\n"); - -fs.writeFileSync(path.join(__dirname, "../index.js"), `/** - * @author Toru Nagashima - * @copyright 2015 Toru Nagashima. All rights reserved. - * See LICENSE file in root directory for full license. - */ +//------------------------------------------------------------------------------ +// Main +//------------------------------------------------------------------------------ -"use strict\"; - -module.exports = { - rules: { -${rules} - }, - rulesConfig: { -${rulesConfig} - } -}; -`); +var ruleNames = fs + .readdirSync(path.join(__dirname, "../lib/rules")) + .map(function(name) { + return path.basename(name, ".js") + }) + +var rules = ruleNames + .map(function(name) { + return "\"" + name + "\": require(\"./lib/rules/" + name + "\")," + }) + .join("\n ") + +var rulesConfig = ruleNames + .map(function(name) { + return "\"" + name + "\": 0," + }) + .join("\n ") + +fs.writeFileSync(path.join(__dirname, "../index.js"), "/**\n\ + * @author Toru Nagashima\n\ + * @copyright 2015 Toru Nagashima. All rights reserved.\n\ + * See LICENSE file in root directory for full license.\n\ + */\n\ +\"use strict\"\n\ +\n\ +module.exports = {\n\ + rules: {\n\ + " + rules + "\n\ + },\n\ + rulesConfig: {\n\ + " + rulesConfig + "\n\ + },\n\ +}\n") diff --git a/tests/lib/rules/arrow-parens.js b/tests/lib/rules/arrow-parens.js index d1ee132..e8b92e0 100644 --- a/tests/lib/rules/arrow-parens.js +++ b/tests/lib/rules/arrow-parens.js @@ -4,47 +4,47 @@ * See LICENSE file in root directory for full license. */ -"use strict"; +"use strict" -const RuleTester = require("eslint").RuleTester; -const rule = require("../../../lib/rules/arrow-parens"); +var RuleTester = require("eslint").RuleTester +var rule = require("../../../lib/rules/arrow-parens"); (new RuleTester()).run("arrow-parens", rule, { valid: [ - {code: "var foo = (x) => x;", ecmaFeatures: {arrowFunctions: true}}, - {code: "var foo = (x => x);", ecmaFeatures: {arrowFunctions: true}}, - {code: "foo(x => x);", ecmaFeatures: {arrowFunctions: true}}, - {code: "foo(() => 0);", ecmaFeatures: {arrowFunctions: true}}, - {code: "foo((x, y) => x);", ecmaFeatures: {arrowFunctions: true}}, - {code: "foo((x = 0) => x);", ecmaFeatures: {arrowFunctions: true, defaultParams: true}}, - {code: "foo(([x]) => x);", ecmaFeatures: {arrowFunctions: true, destructuring: true}}, - {code: "foo(({x}) => x);", ecmaFeatures: {arrowFunctions: true, destructuring: true}}, - {code: "foo(x => x, (x) => x);", ecmaFeatures: {arrowFunctions: true}}, - {code: "foo(\n (x) => x,\n (x) => x\n);", ecmaFeatures: {arrowFunctions: true}} + {code: "var foo = (x) => x;", env: {es6: true}}, + {code: "var foo = (x => x);", env: {es6: true}}, + {code: "foo(x => x);", env: {es6: true}}, + {code: "foo(() => 0);", env: {es6: true}}, + {code: "foo((x, y) => x);", env: {es6: true}}, + {code: "foo((x = 0) => x);", env: {es6: true}}, + {code: "foo(([x]) => x);", env: {es6: true}}, + {code: "foo(({x}) => x);", env: {es6: true}}, + {code: "foo(x => x, (x) => x);", env: {es6: true}}, + {code: "foo(\n (x) => x,\n (x) => x\n);", env: {es6: true}}, ], invalid: [ { code: "var foo = x => x;", - ecmaFeatures: {arrowFunctions: true}, - errors: [{type: "ArrowFunctionExpression", message: "enclose the argument with parens."}] + env: {es6: true}, + errors: [{type: "ArrowFunctionExpression", message: "enclose the argument with parens."}], }, { code: "foo(x => x, x => x);", - ecmaFeatures: {arrowFunctions: true}, - errors: [{type: "ArrowFunctionExpression", message: "enclose the argument with parens."}] + env: {es6: true}, + errors: [{type: "ArrowFunctionExpression", message: "enclose the argument with parens."}], }, { code: "foo(\n x => x,\n x => x\n);", - ecmaFeatures: {arrowFunctions: true}, + env: {es6: true}, errors: [ {type: "ArrowFunctionExpression", message: "enclose the argument with parens."}, - {type: "ArrowFunctionExpression", message: "enclose the argument with parens."} - ] + {type: "ArrowFunctionExpression", message: "enclose the argument with parens."}, + ], }, { code: "foo((x) => x);", - ecmaFeatures: {arrowFunctions: true}, - errors: [{type: "ArrowFunctionExpression", message: "remove redundant parens of the argument list."}] - } - ] -}); + env: {es6: true}, + errors: [{type: "ArrowFunctionExpression", message: "remove redundant parens of the argument list."}], + }, + ], +}) diff --git a/tests/lib/rules/block-scoped-var.js b/tests/lib/rules/block-scoped-var.js index 547ee85..2907dbe 100644 --- a/tests/lib/rules/block-scoped-var.js +++ b/tests/lib/rules/block-scoped-var.js @@ -4,10 +4,10 @@ * See LICENSE file in root directory for full license. */ -"use strict"; +"use strict" -const RuleTester = require("eslint").RuleTester; -const rule = require("../../../lib/rules/block-scoped-var"); +var RuleTester = require("eslint").RuleTester +var rule = require("../../../lib/rules/block-scoped-var"); (new RuleTester()).run("block-scoped-var", rule, { valid: [ @@ -15,9 +15,8 @@ const rule = require("../../../lib/rules/block-scoped-var"); {code: "{ var a; a; } { { var a; a; } { var a; { a; } } }"}, {code: "if (true) { var a; a; } else if (true) { var a; a; } else { var a; a; }"}, {code: "while (true) { var a; a; } do { var a; a; } while (true);"}, - {code: "for (var a = 0; a; a) { a; var b; b; } for (var a in []) { a; var b; b; } for (var a of []) { a; var b; b; }", ecmaFeatures: {forOf: true}}, + {code: "for (var a = 0; a; a) { a; var b; b; } for (var a in []) { a; var b; b; } for (var a of []) { a; var b; b; }", env: {es6: true}}, {code: "switch (0) { case 0: var a; a; case 1: a; default: a; } { var a; a; }"}, - {code: "{ var {x: [a = 0]} = {x: [1]}; a; } { var a; ({x: [a = 0]}) = {x: [1]}; }", ecmaFeatures: {destructuring: true}}, // below should be warned by no-shadow rule. // this rule ignores those merely. @@ -25,8 +24,8 @@ const rule = require("../../../lib/rules/block-scoped-var"); {code: "var a; function foo(a) { }"}, {code: "function a() { var a; }"}, {code: "(function a() { var a; })();"}, - {code: "class a { foo() { var a; } }", ecmaFeatures: {classes: true}}, - {code: "(class a { foo() { var a; } })();", ecmaFeatures: {classes: true}} + {code: "class a { foo() { var a; } }", env: {es6: true}}, + {code: "(class a { foo() { var a; } })();", env: {es6: true}}, ], invalid: [ {code: "{ var a; a; } a;", errors: [{type: "Identifier", message: "\"a\" is not defined."}]}, @@ -37,10 +36,11 @@ const rule = require("../../../lib/rules/block-scoped-var"); {code: "for (var a; a; a) { var a; }", errors: [{type: "Identifier", message: "\"a\" is already defined."}]}, {code: "{ var a; function a() {} }", errors: [{type: "Identifier", message: "\"a\" is already defined."}]}, {code: "function foo(a) { var a; } var a;", errors: [{type: "Identifier", message: "\"a\" is already defined."}]}, - {code: "import a from \"a\"; var a;", ecmaFeatures: {modules: true}, errors: [{type: "Identifier", message: "\"a\" is already defined."}]}, - {code: "import a from \"a\"; import a from \"b/a\";", ecmaFeatures: {modules: true}, errors: [{type: "Identifier", message: "\"a\" is already defined."}]}, + {code: "import a from \"a\"; var a;", parserOptions: {sourceType: "module"}, errors: [{type: "Identifier", message: "\"a\" is already defined."}]}, + {code: "import a from \"a\"; import a from \"b/a\";", parserOptions: {sourceType: "module"}, errors: [{type: "Identifier", message: "\"a\" is already defined."}]}, {code: "{ var a; { var a; } }", errors: [{type: "Identifier", message: "\"a\" is already defined in the upper scope."}]}, - {code: "import a from \"a\"; { var a; }", ecmaFeatures: {modules: true}, errors: [{type: "Identifier", message: "\"a\" is already defined in the upper scope."}]}, - {code: "{ var a; } { var a; a; }", errors: [{type: "Identifier", message: "\"a\" is defined but never used.", column: 7}]} - ] -}); + {code: "import a from \"a\"; { var a; }", parserOptions: {sourceType: "module"}, errors: [{type: "Identifier", message: "\"a\" is already defined in the upper scope."}]}, + {code: "{ var a; } { var a; a; }", errors: [{type: "Identifier", message: "\"a\" is defined but never used.", column: 7}]}, + {code: "{ var {x: [a = 0]} = {x: [1]}; a; } { var a; ({x: [a = 0]} = {x: [1]}); }", env: {es6: true}, errors: [{type: "Identifier", message: "\"a\" is defined but never used.", column: 43}]}, + ], +})