tools: update ESLint to 6.3.0

Update ESLint to 6.3.0

PR-URL: https://github.com/nodejs/node/pull/29382
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com>
This commit is contained in:
cjihrig 2019-08-30 16:56:49 -04:00 committed by Daniel Bevenius
parent d18b6a7e40
commit d62d2b4560
20 changed files with 143 additions and 30 deletions

View File

@ -1,5 +1,6 @@
[![NPM version][npm-image]][npm-url]
[![Build Status](https://dev.azure.com/eslint/eslint/_apis/build/status/eslint.eslint?branchName=master)](https://dev.azure.com/eslint/eslint/_build/latest?definitionId=1&branchName=master)
[![Build Status](https://github.com/eslint/eslint/workflows/CI/badge.svg)](https://github.com/eslint/eslint/actions)
[![Downloads][downloads-image]][downloads-url]
[![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=282608)](https://www.bountysource.com/trackers/282608-eslint?utm_source=282608&utm_medium=shield&utm_campaign=TRACKER_BADGE)
[![Join the chat at https://gitter.im/eslint/eslint](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/eslint/eslint?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

View File

@ -21,6 +21,7 @@ const baseConfigProperties = {
rules: { type: "object" },
settings: { type: "object" },
noInlineConfig: { type: "boolean" },
reportUnusedDisableDirectives: { type: "boolean" },
ecmaFeatures: { type: "object" } // deprecated; logs a warning when used
};

View File

@ -26,6 +26,6 @@ module.exports = {
cacheFile: ".eslintcache",
fix: false,
allowInlineConfig: true,
reportUnusedDisableDirectives: false,
reportUnusedDisableDirectives: void 0,
globInputPaths: true
};

View File

@ -531,6 +531,7 @@ class ConfigArrayFactory {
parserOptions,
plugins: pluginList,
processor,
reportUnusedDisableDirectives,
root,
rules,
settings,
@ -573,6 +574,7 @@ class ConfigArrayFactory {
parserOptions,
plugins,
processor,
reportUnusedDisableDirectives,
root,
rules,
settings

View File

@ -59,6 +59,7 @@ const { ExtractedConfig } = require("./extracted-config");
* @property {Object|undefined} parserOptions The parser options.
* @property {Record<string, DependentPlugin>|undefined} plugins The plugin loaders.
* @property {string|undefined} processor The processor name to refer plugin's processor.
* @property {boolean|undefined} reportUnusedDisableDirectives The flag to report unused `eslint-disable` comments.
* @property {boolean|undefined} root The flag to express root.
* @property {Record<string, RuleConf>|undefined} rules The rule settings
* @property {Object|undefined} settings The shared settings.
@ -257,6 +258,11 @@ function createConfig(instance, indices) {
config.configNameOfNoInlineConfig = element.name;
}
// Adopt the reportUnusedDisableDirectives which was found at first.
if (config.reportUnusedDisableDirectives === void 0 && element.reportUnusedDisableDirectives !== void 0) {
config.reportUnusedDisableDirectives = element.reportUnusedDisableDirectives;
}
// Merge others.
mergeWithoutOverwrite(config.env, element.env);
mergeWithoutOverwrite(config.globals, element.globals);

View File

@ -77,6 +77,12 @@ class ExtractedConfig {
*/
this.processor = null;
/**
* The flag that reports unused `eslint-disable` directive comments.
* @type {boolean|undefined}
*/
this.reportUnusedDisableDirectives = void 0;
/**
* Rule settings.
* @type {Record<string, [SeverityConf, ...any[]]>}

View File

@ -96,5 +96,6 @@ module.exports = function(results) {
}
}
return total > 0 ? output : "";
// Resets output color, for prevent change on top level
return total > 0 ? chalk.reset(output) : "";
};

View File

@ -120,6 +120,12 @@ function getModulesList(config, installESLint) {
}
}
const parser = config.parser || (config.parserOptions && config.parserOptions.parser);
if (parser) {
modules[parser] = "latest";
}
if (installESLint === false) {
delete modules.eslint;
} else {
@ -291,6 +297,20 @@ function processAnswers(answers) {
config.extends.push("plugin:vue/essential");
}
if (answers.typescript) {
if (answers.framework === "vue") {
config.parserOptions.parser = "@typescript-eslint/parser";
} else {
config.parser = "@typescript-eslint/parser";
}
if (Array.isArray(config.plugins)) {
config.plugins.push("@typescript-eslint");
} else {
config.plugins = ["@typescript-eslint"];
}
}
// setup rules based on problems/style enforcement preferences
if (answers.purpose === "problems") {
config.extends.unshift("eslint:recommended");
@ -306,6 +326,9 @@ function processAnswers(answers) {
config = autoconfig.extendFromRecommended(config);
}
}
if (answers.typescript && config.extends.includes("eslint:recommended")) {
config.extends.push("plugin:@typescript-eslint/eslint-recommended");
}
// normalize extends
if (config.extends.length === 0) {
@ -465,6 +488,12 @@ function promptUser() {
{ name: "None of these", value: "none" }
]
},
{
type: "confirm",
name: "typescript",
message: "Does your project use TypeScript?",
default: false
},
{
type: "checkbox",
name: "env",

View File

@ -98,7 +98,7 @@ function fetchPeerDependencies(packageName) {
* and values are booleans indicating installation.
*/
function check(packages, opt) {
let deps = [];
const deps = new Set();
const pkgJson = (opt) ? findPackageJson(opt.startDir) : findPackageJson();
let fileJson;
@ -119,14 +119,14 @@ function check(packages, opt) {
throw error;
}
if (opt.devDependencies && typeof fileJson.devDependencies === "object") {
deps = deps.concat(Object.keys(fileJson.devDependencies));
}
if (opt.dependencies && typeof fileJson.dependencies === "object") {
deps = deps.concat(Object.keys(fileJson.dependencies));
}
["dependencies", "devDependencies"].forEach(key => {
if (opt[key] && typeof fileJson[key] === "object") {
Object.keys(fileJson[key]).forEach(dep => deps.add(dep));
}
});
return packages.reduce((status, pkg) => {
status[pkg] = deps.indexOf(pkg) !== -1;
status[pkg] = deps.has(pkg);
return status;
}, {});
}

View File

@ -93,7 +93,7 @@ function applyDirectives(options) {
: "Unused eslint-disable directive (no problems were reported).",
line: directive.unprocessedDirective.line,
column: directive.unprocessedDirective.column,
severity: 2,
severity: options.reportUnusedDisableDirectives === "warn" ? 1 : 2,
nodeType: null
}));
@ -114,17 +114,17 @@ function applyDirectives(options) {
* comment for two different rules is represented as two directives).
* @param {{ruleId: (string|null), line: number, column: number}[]} options.problems
* A list of problems reported by rules, sorted by increasing location in the file, with one-based columns.
* @param {boolean} options.reportUnusedDisableDirectives If `true`, adds additional problems for unused directives
* @param {"off" | "warn" | "error"} options.reportUnusedDisableDirectives If `"warn"` or `"error"`, adds additional problems for unused directives
* @returns {{ruleId: (string|null), line: number, column: number}[]}
* A list of reported problems that were not disabled by the directive comments.
*/
module.exports = options => {
const blockDirectives = options.directives
module.exports = ({ directives, problems, reportUnusedDisableDirectives = "off" }) => {
const blockDirectives = directives
.filter(directive => directive.type === "disable" || directive.type === "enable")
.map(directive => Object.assign({}, directive, { unprocessedDirective: directive }))
.sort(compareLocations);
const lineDirectives = lodash.flatMap(options.directives, directive => {
const lineDirectives = lodash.flatMap(directives, directive => {
switch (directive.type) {
case "disable":
case "enable":
@ -147,10 +147,18 @@ module.exports = options => {
}
}).sort(compareLocations);
const blockDirectivesResult = applyDirectives({ problems: options.problems, directives: blockDirectives });
const lineDirectivesResult = applyDirectives({ problems: blockDirectivesResult.problems, directives: lineDirectives });
const blockDirectivesResult = applyDirectives({
problems,
directives: blockDirectives,
reportUnusedDisableDirectives
});
const lineDirectivesResult = applyDirectives({
problems: blockDirectivesResult.problems,
directives: lineDirectives,
reportUnusedDisableDirectives
});
return options.reportUnusedDisableDirectives
return reportUnusedDisableDirectives !== "off"
? lineDirectivesResult.problems
.concat(blockDirectivesResult.unusedDisableDirectives)
.concat(lineDirectivesResult.unusedDisableDirectives)

View File

@ -54,6 +54,11 @@ const DEFAULT_ERROR_LOC = { start: { line: 1, column: 0 }, end: { line: 1, colum
/** @typedef {import("../shared/types").Processor} Processor */
/** @typedef {import("../shared/types").Rule} Rule */
/**
* @template T
* @typedef {{ [P in keyof T]-?: T[P] }} Required
*/
/**
* @typedef {Object} DisableDirective
* @property {("disable"|"enable"|"disable-line"|"disable-next-line")} type
@ -79,7 +84,7 @@ const DEFAULT_ERROR_LOC = { start: { line: 1, column: 0 }, end: { line: 1, colum
* @property {boolean} [disableFixes] if `true` then the linter doesn't make `fix`
* properties into the lint result.
* @property {string} [filename] the filename of the source code.
* @property {boolean} [reportUnusedDisableDirectives] Adds reported errors for
* @property {boolean | "off" | "warn" | "error"} [reportUnusedDisableDirectives] Adds reported errors for
* unused `eslint-disable` directives.
*/
@ -103,6 +108,12 @@ const DEFAULT_ERROR_LOC = { start: { line: 1, column: 0 }, end: { line: 1, colum
* whether fixes should be applied.
*/
/**
* @typedef {Object} InternalOptions
* @property {string | null} warnInlineConfig The config name what `noInlineConfig` setting came from. If `noInlineConfig` setting didn't exist, this is null. If this is a config name, then the linter warns directive comments.
* @property {"off" | "warn" | "error"} reportUnusedDisableDirectives (boolean values were normalized)
*/
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
@ -467,7 +478,7 @@ function normalizeFilename(filename) {
* consistent shape.
* @param {VerifyOptions} providedOptions Options
* @param {ConfigData} config Config.
* @returns {Required<VerifyOptions> & { warnInlineConfig: string|null }} Normalized options
* @returns {Required<VerifyOptions> & InternalOptions} Normalized options
*/
function normalizeVerifyOptions(providedOptions, config) {
const disableInlineConfig = config.noInlineConfig === true;
@ -476,13 +487,22 @@ function normalizeVerifyOptions(providedOptions, config) {
? ` (${config.configNameOfNoInlineConfig})`
: "";
let reportUnusedDisableDirectives = providedOptions.reportUnusedDisableDirectives;
if (typeof reportUnusedDisableDirectives === "boolean") {
reportUnusedDisableDirectives = reportUnusedDisableDirectives ? "error" : "off";
}
if (typeof reportUnusedDisableDirectives !== "string") {
reportUnusedDisableDirectives = config.reportUnusedDisableDirectives ? "warn" : "off";
}
return {
filename: normalizeFilename(providedOptions.filename || "<input>"),
allowInlineConfig: !ignoreInlineConfig,
warnInlineConfig: disableInlineConfig && !ignoreInlineConfig
? `your config${configNameOfNoInlineConfig}`
: null,
reportUnusedDisableDirectives: Boolean(providedOptions.reportUnusedDisableDirectives),
reportUnusedDisableDirectives,
disableFixes: Boolean(providedOptions.disableFixes)
};
}

View File

@ -192,7 +192,7 @@ module.exports = optionator({
{
option: "report-unused-disable-directives",
type: "Boolean",
default: false,
default: void 0,
description: "Adds reported errors for unused eslint-disable directives"
},
{

View File

@ -118,6 +118,7 @@ module.exports = {
return false;
}
return node.type === "CallExpression" &&
node.callee.type === "MemberExpression" &&
node.callee.object.name === objName &&
node.callee.property.name === funcName;
}

View File

@ -51,8 +51,8 @@ module.exports = {
expectedBefore: "Expected newline before ')'.",
expectedAfter: "Expected newline after '('.",
expectedBetween: "Expected newline between arguments/params.",
unexpectedBefore: "Unexpected newline before '('.",
unexpectedAfter: "Unexpected newline after ')'."
unexpectedBefore: "Unexpected newline before ')'.",
unexpectedAfter: "Unexpected newline after '('."
}
},

View File

@ -102,7 +102,17 @@ module.exports = {
if (hasCommentsInside(parent)) {
return null;
}
return fixer.replaceText(parent, sourceCode.getText(node.argument));
let prefix = "";
const tokenBefore = sourceCode.getTokenBefore(parent);
const firstReplacementToken = sourceCode.getFirstToken(node.argument);
if (tokenBefore && tokenBefore.range[1] === parent.range[0] &&
!astUtils.canTokensBeAdjacent(tokenBefore, firstReplacementToken)) {
prefix = " ";
}
return fixer.replaceText(parent, prefix + sourceCode.getText(node.argument));
}
});
}

View File

@ -49,7 +49,8 @@ module.exports = {
nestedBinaryExpressions: { type: "boolean" },
returnAssign: { type: "boolean" },
ignoreJSX: { enum: ["none", "all", "single-line", "multi-line"] },
enforceForArrowConditionals: { type: "boolean" }
enforceForArrowConditionals: { type: "boolean" },
enforceForSequenceExpressions: { type: "boolean" }
},
additionalProperties: false
}
@ -77,6 +78,8 @@ module.exports = {
const IGNORE_JSX = ALL_NODES && context.options[1] && context.options[1].ignoreJSX;
const IGNORE_ARROW_CONDITIONALS = ALL_NODES && context.options[1] &&
context.options[1].enforceForArrowConditionals === false;
const IGNORE_SEQUENCE_EXPRESSIONS = ALL_NODES && context.options[1] &&
context.options[1].enforceForSequenceExpressions === false;
const PRECEDENCE_OF_ASSIGNMENT_EXPR = precedence({ type: "AssignmentExpression" });
const PRECEDENCE_OF_UPDATE_EXPR = precedence({ type: "UpdateExpression" });
@ -115,6 +118,10 @@ module.exports = {
}
}
if (node.type === "SequenceExpression" && IGNORE_SEQUENCE_EXPRESSIONS) {
return false;
}
return ALL_NODES || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
}

View File

@ -94,9 +94,19 @@ function eachSelfAssignment(left, right, props, report) {
const end = Math.min(left.elements.length, right.elements.length);
for (let i = 0; i < end; ++i) {
const leftElement = left.elements[i];
const rightElement = right.elements[i];
eachSelfAssignment(left.elements[i], rightElement, props, report);
// Avoid cases such as [...a] = [...a, 1]
if (
leftElement &&
leftElement.type === "RestElement" &&
i < right.elements.length - 1
) {
break;
}
eachSelfAssignment(leftElement, rightElement, props, report);
// After a spread element, those indices are unknown.
if (rightElement && rightElement.type === "SpreadElement") {

View File

@ -274,13 +274,22 @@ module.exports = {
* @returns {string} A string representation of the node with the sides and operator flipped
*/
function getFlippedString(node) {
const tokenBefore = sourceCode.getTokenBefore(node);
const operatorToken = sourceCode.getFirstTokenBetween(node.left, node.right, token => token.value === node.operator);
const textBeforeOperator = sourceCode.getText().slice(sourceCode.getTokenBefore(operatorToken).range[1], operatorToken.range[0]);
const textAfterOperator = sourceCode.getText().slice(operatorToken.range[1], sourceCode.getTokenAfter(operatorToken).range[0]);
const leftText = sourceCode.getText().slice(node.range[0], sourceCode.getTokenBefore(operatorToken).range[1]);
const rightText = sourceCode.getText().slice(sourceCode.getTokenAfter(operatorToken).range[0], node.range[1]);
const firstRightToken = sourceCode.getTokenAfter(operatorToken);
const rightText = sourceCode.getText().slice(firstRightToken.range[0], node.range[1]);
return rightText + textBeforeOperator + OPERATOR_FLIP_MAP[operatorToken.value] + textAfterOperator + leftText;
let prefix = "";
if (tokenBefore && tokenBefore.range[1] === node.range[0] &&
!astUtils.canTokensBeAdjacent(tokenBefore, firstRightToken)) {
prefix = " ";
}
return prefix + rightText + textBeforeOperator + OPERATOR_FLIP_MAP[operatorToken.value] + textAfterOperator + leftText;
}
//--------------------------------------------------------------------------

View File

@ -36,6 +36,7 @@ module.exports = {};
* @property {ParserOptions} [parserOptions] The parser options.
* @property {string[]} [plugins] The plugin specifiers.
* @property {string} [processor] The processor specifier.
* @property {boolean|undefined} reportUnusedDisableDirectives The flag to report unused `eslint-disable` comments.
* @property {boolean} [root] The root flag.
* @property {Record<string, RuleConf>} [rules] The rule settings.
* @property {Object} [settings] The shared settings.
@ -54,6 +55,7 @@ module.exports = {};
* @property {ParserOptions} [parserOptions] The parser options.
* @property {string[]} [plugins] The plugin specifiers.
* @property {string} [processor] The processor specifier.
* @property {boolean|undefined} reportUnusedDisableDirectives The flag to report unused `eslint-disable` comments.
* @property {Record<string, RuleConf>} [rules] The rule settings.
* @property {Object} [settings] The shared settings.
*/

View File

@ -149,5 +149,5 @@
"test": "node Makefile.js test",
"webpack": "node Makefile.js webpack"
},
"version": "6.2.2"
"version": "6.3.0"
}