Skip to content

Commit

Permalink
Merge branch 'master' into issue11510
Browse files Browse the repository at this point in the history
# Conflicts:
#	README.md
#	lib/config/config-ops.js
#	lib/config/config-validator.js
#	tests/lib/config.js
  • Loading branch information
mysticatea committed Apr 2, 2019
2 parents 808bdcd + fd1c91b commit 904eff8
Show file tree
Hide file tree
Showing 38 changed files with 224 additions and 170 deletions.
21 changes: 14 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ ESLint is a tool for identifying and reporting on patterns found in ECMAScript/J

## Installation and Usage

Prerequisites: [Node.js](https://nodejs.org/) (>=8.10), npm version 3+.
Prerequisites: [Node.js](https://nodejs.org/) (`^8.10.0`, `^10.13.0`, or `>=11.10.1`), npm version 3+.

There are two ways to install ESLint: globally and locally.

Expand Down Expand Up @@ -243,18 +243,25 @@ Teddy Katz
</td></tr></tbody></table>


### Reviewers


### Committers

The people who review and fix bugs and help triage issues.
The people who review and implement new features.

<table><tbody><tr><td align="center" valign="top" width="11%">
<a href="https://github.com/aladdin-add">
<img src="https://github.com/aladdin-add.png?s=75" width="75" height="75"><br />
薛定谔的猫
</a>
</td><td align="center" valign="top" width="11%">
</td></tr></tbody></table>




### Committers

The people who review and fix bugs and help triage issues.

<table><tbody><tr><td align="center" valign="top" width="11%">
<a href="https://github.com/g-plane">
<img src="https://github.com/g-plane.png?s=75" width="75" height="75"><br />
Pig Fang
Expand All @@ -271,7 +278,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
<!-- NOTE: This section is autogenerated. Do not manually edit.-->
<!--sponsorsstart-->
<h3>Gold Sponsors</h3>
<p><a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2F098e3bd0-4d57-11e8-9324-0f6cc1f92bf1.png&height=96" alt="Airbnb" height="96"></a> <a href="https://code.facebook.com/projects/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fres.cloudinary.com%2Fopencollective%2Fimage%2Fupload%2Fv1508519428%2FS9gk78AS_400x400_fulq2l.jpg&height=96" alt="Facebook Open Source" height="96"></a> <a href="https://badoo.com/team?utm_source=eslint"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2Fbbdb9cc0-3b5d-11e9-9537-ad85092287b8.png&height=96" alt="Badoo" height="96"></a></p><h3>Silver Sponsors</h3>
<p><a href="https://www.gitkraken.com/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Flogo.clearbit.com%2Fgitkraken.com&height=96" alt="GitKraken" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2F098e3bd0-4d57-11e8-9324-0f6cc1f92bf1.png&height=96" alt="Airbnb" height="96"></a> <a href="https://code.facebook.com/projects/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fres.cloudinary.com%2Fopencollective%2Fimage%2Fupload%2Fv1508519428%2FS9gk78AS_400x400_fulq2l.jpg&height=96" alt="Facebook Open Source" height="96"></a> <a href="https://badoo.com/team?utm_source=eslint"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2Fbbdb9cc0-3b5d-11e9-9537-ad85092287b8.png&height=96" alt="Badoo" height="96"></a></p><h3>Silver Sponsors</h3>
<p><a href="https://www.ampproject.org/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2F68ed8b70-ebf2-11e6-9958-cb7e79408c56.png&height=96" alt="AMP Project" height="64"></a></p><h3>Bronze Sponsors</h3>
<p><a href="http://faithlife.com/ref/about"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Flogo.clearbit.com%2Ffaithlife.com&height=96" alt="Faithlife" height="32"></a> <a href="https://jsheroes.io/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Flogo.clearbit.com%2Fjsheroes.io&height=96" alt="JSHeroes " height="32"></a></p>
<!--sponsorsend-->
Expand Down
9 changes: 6 additions & 3 deletions conf/eslint-recommended.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
const builtInRules = require("../lib/built-in-rules-index");

module.exports = {
rules: Object.assign({}, ...Object.keys(builtInRules).map(ruleId => ({
[ruleId]: builtInRules[ruleId].meta.docs.recommended ? "error" : "off"
})))
rules: Object.assign(
{},
...Object.keys(builtInRules)
.filter(ruleId => builtInRules[ruleId].meta.docs.recommended)
.map(ruleId => ({ [ruleId]: "error" }))
)
};
4 changes: 0 additions & 4 deletions docs/user-guide/configuring.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@ Here's an example `.eslintrc.json` file:

Setting parser options helps ESLint determine what is a parsing error. All language options are `false` by default.

### Deprecated

* `ecmaFeatures.experimentalObjectRestSpread` - enable support for the experimental [object rest/spread properties](https://github.com/tc39/proposal-object-rest-spread). This syntax has been supported in `ecmaVersion: 2018`. This option will be removed in the future.

## Specifying Parser

By default, ESLint uses [Espree](https://github.com/eslint/espree) as its parser. You can optionally specify that a different parser should be used in your configuration file so long as the parser meets the following requirements:
Expand Down
4 changes: 2 additions & 2 deletions lib/config/config-ops.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ module.exports = {
* @param {(boolean|string|null)} configuredValue The value given for a global in configuration or in
* a global directive comment
* @returns {("readable"|"writeable"|"off")} The value normalized as a string
* @throws Error if global value is invalid
*/
normalizeConfigGlobal(configuredValue) {
switch (configuredValue) {
Expand All @@ -122,9 +123,8 @@ module.exports = {
case "readonly":
return "readable";

// Fallback to minimize compatibility impact
default:
return "writeable";
throw new Error(`'${configuredValue}' is not a valid configuration for a global (use 'readonly', 'writable', or 'off')`);
}
}
};
35 changes: 25 additions & 10 deletions lib/config/config-validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ const
configSchema = require("../../conf/config-schema"),
BuiltInEnvironments = require("../../conf/environments"),
BuiltInRules = require("../built-in-rules-index"),
ajv = require("../util/ajv");
ajv = require("../util/ajv"),
ConfigOps = require("./config-ops");

const ruleValidators = new WeakMap();
const builtInEnvMap = new Map(Object.entries(BuiltInEnvironments));
Expand Down Expand Up @@ -190,6 +191,27 @@ function validateRules(
});
}

/**
* Validates a `globals` section of a config file
* @param {Object} globalsConfig The `glboals` section
* @param {string|null} source The name of the configuration source to report in the event of an error.
* @returns {void}
*/
function validateGlobals(globalsConfig, source = null) {
if (!globalsConfig) {
return;
}

Object.entries(globalsConfig)
.forEach(([configuredGlobal, configuredValue]) => {
try {
ConfigOps.normalizeConfigGlobal(configuredValue);
} catch (err) {
throw new Error(`ESLint configuration of global '${configuredGlobal}' in ${source} is invalid:\n${err.message}`);
}
});
}

/**
* Formats an array of schema validation errors.
* @param {Array} errors An array of error messages to format.
Expand Down Expand Up @@ -251,15 +273,6 @@ function validateConfigSchema(config, source = null) {
if (Object.hasOwnProperty.call(config, "ecmaFeatures")) {
emitDeprecationWarning(source, "ESLINT_LEGACY_ECMAFEATURES");
}

if (
(config.parser || "espree") === "espree" &&
config.parserOptions &&
config.parserOptions.ecmaFeatures &&
config.parserOptions.ecmaFeatures.experimentalObjectRestSpread
) {
emitDeprecationWarning(source, "ESLINT_LEGACY_OBJECT_REST_SPREAD");
}
}

/**
Expand All @@ -274,10 +287,12 @@ function validate(config, source, ruleMapper, envMapper) {
validateConfigSchema(config, source);
validateRules(config.rules, source, ruleMapper);
validateEnvironment(config.env, source, envMapper);
validateGlobals(config.globals, source);

for (const override of config.overrides || []) {
validateRules(override.rules, source, ruleMapper);
validateEnvironment(override.env, source, envMapper);
validateGlobals(config.globals, source);
}
}

Expand Down
46 changes: 32 additions & 14 deletions lib/linter.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,13 @@ const commentParser = new ConfigCommentParser();
function addDeclaredGlobals(globalScope, configGlobals, commentDirectives) {
const mergedGlobalsInfo = Object.assign(
{},

/*
* `ConfigOps.normalizeConfigGlobal` will throw an error if a configured global value is invalid. However, these errors would
* typically be caught when validating a config anyway (validity for inline global comments is checked separately).
*/
lodash.mapValues(configGlobals, value => ({ sourceComment: null, value: ConfigOps.normalizeConfigGlobal(value) })),
lodash.mapValues(commentDirectives.enabledGlobals, ({ comment, value }) => ({ sourceComment: comment, value: ConfigOps.normalizeConfigGlobal(value) }))
lodash.mapValues(commentDirectives.enabledGlobals, ({ comment, value }) => ({ sourceComment: comment, value }))
);

Object.keys(mergedGlobalsInfo)
Expand Down Expand Up @@ -206,10 +211,33 @@ function getDirectiveComments(filename, ast, ruleMapper) {
break;

case "globals":
case "global":
Object.assign(enabledGlobals, commentParser.parseStringConfig(directiveValue, comment));
break;
case "global": {
const updatedGlobals = commentParser.parseStringConfig(directiveValue, comment);

Object.keys(updatedGlobals).forEach(globalName => {
const { value } = updatedGlobals[globalName];
let normalizedValue;

try {
normalizedValue = ConfigOps.normalizeConfigGlobal(value);
} catch (err) {
problems.push({
ruleId: null,
severity: 2,
message: err.message,
line: comment.loc.start.line,
column: comment.loc.start.column + 1,
endLine: comment.loc.end.line,
endColumn: comment.loc.end.column + 1,
nodeType: null
});
return;
}

enabledGlobals[globalName] = { comment, value: normalizedValue };
});
break;
}
case "eslint-disable":
disableDirectives.push(...createDisableDirectives("disable", comment.loc.start, directiveValue));
break;
Expand Down Expand Up @@ -345,16 +373,6 @@ function resolveParserOptions(parserName, providedOptions, enabledEnvironments)

mergedParserOptions.ecmaVersion = normalizeEcmaVersion(mergedParserOptions.ecmaVersion, isModule);

// TODO: For backward compatibility. Will remove on v6.0.0.
if (
parserName === DEFAULT_PARSER_NAME &&
mergedParserOptions.ecmaFeatures &&
mergedParserOptions.ecmaFeatures.experimentalObjectRestSpread &&
(!mergedParserOptions.ecmaVersion || mergedParserOptions.ecmaVersion < 9)
) {
mergedParserOptions.ecmaVersion = 9;
}

return mergedParserOptions;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/rules/camelcase.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ module.exports = {
*/
function isAllowed(name) {
return allow.findIndex(
entry => name === entry || name.match(new RegExp(entry)) // eslint-disable-line require-unicode-regexp
entry => name === entry || name.match(new RegExp(entry, "u"))
) !== -1;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/rules/capitalized-comments.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function createRegExpForIgnorePatterns(normalizedOptions) {
const ignorePatternStr = normalizedOptions[key].ignorePattern;

if (ignorePatternStr) {
const regExp = RegExp(`^\\s*(?:${ignorePatternStr})`); // eslint-disable-line require-unicode-regexp
const regExp = RegExp(`^\\s*(?:${ignorePatternStr})`, "u");

normalizedOptions[key].ignorePatternRegExp = regExp;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/default-case.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ module.exports = {
create(context) {
const options = context.options[0] || {};
const commentPattern = options.commentPattern
? new RegExp(options.commentPattern) // eslint-disable-line require-unicode-regexp
? new RegExp(options.commentPattern, "u")
: DEFAULT_COMMENT_PATTERN;

const sourceCode = context.getSourceCode();
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/dot-notation.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ module.exports = {
let allowPattern;

if (options.allowPattern) {
allowPattern = new RegExp(options.allowPattern); // eslint-disable-line require-unicode-regexp
allowPattern = new RegExp(options.allowPattern, "u");
}

/**
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/handle-callback-err.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ module.exports = {
*/
function matchesConfiguredErrorName(name) {
if (isPattern(errorArgument)) {
const regexp = new RegExp(errorArgument); // eslint-disable-line require-unicode-regexp
const regexp = new RegExp(errorArgument, "u");

return regexp.test(name);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/id-match.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ module.exports = {
// Options
//--------------------------------------------------------------------------
const pattern = context.options[0] || "^.+$",
regexp = new RegExp(pattern); // eslint-disable-line require-unicode-regexp
regexp = new RegExp(pattern, "u");

const options = context.options[1] || {},
properties = !!options.properties,
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/line-comment-position.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ module.exports = {

const defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN;
const fallThroughRegExp = /^\s*falls?\s?through/u;
const customIgnoreRegExp = new RegExp(ignorePattern); // eslint-disable-line require-unicode-regexp
const customIgnoreRegExp = new RegExp(ignorePattern, "u");
const sourceCode = context.getSourceCode();

//--------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/lines-around-comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ module.exports = {
const options = Object.assign({}, context.options[0]);
const ignorePattern = options.ignorePattern;
const defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN;
const customIgnoreRegExp = new RegExp(ignorePattern); // eslint-disable-line require-unicode-regexp
const customIgnoreRegExp = new RegExp(ignorePattern, "u");
const applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns !== false;

options.beforeBlockComment = typeof options.beforeBlockComment !== "undefined" ? options.beforeBlockComment : true;
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/max-len.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ module.exports = {
let ignorePattern = options.ignorePattern || null;

if (ignorePattern) {
ignorePattern = new RegExp(ignorePattern); // eslint-disable-line require-unicode-regexp
ignorePattern = new RegExp(ignorePattern, "u");
}

//--------------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions lib/rules/new-cap.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,10 @@ module.exports = {
const skipProperties = config.properties === false;

const newIsCapExceptions = checkArray(config, "newIsCapExceptions", []).reduce(invert, {});
const newIsCapExceptionPattern = config.newIsCapExceptionPattern ? new RegExp(config.newIsCapExceptionPattern) : null; // eslint-disable-line require-unicode-regexp
const newIsCapExceptionPattern = config.newIsCapExceptionPattern ? new RegExp(config.newIsCapExceptionPattern, "u") : null;

const capIsNewExceptions = calculateCapIsNewExceptions(config);
const capIsNewExceptionPattern = config.capIsNewExceptionPattern ? new RegExp(config.capIsNewExceptionPattern) : null; // eslint-disable-line require-unicode-regexp
const capIsNewExceptionPattern = config.capIsNewExceptionPattern ? new RegExp(config.capIsNewExceptionPattern, "u") : null;

const listeners = {};

Expand Down
2 changes: 1 addition & 1 deletion lib/rules/no-fallthrough.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ module.exports = {
let fallthroughCommentPattern = null;

if (options.commentPattern) {
fallthroughCommentPattern = new RegExp(options.commentPattern); // eslint-disable-line require-unicode-regexp
fallthroughCommentPattern = new RegExp(options.commentPattern, "u");
} else {
fallthroughCommentPattern = DEFAULT_FALLTHROUGH_COMMENT;
}
Expand Down
6 changes: 3 additions & 3 deletions lib/rules/no-unused-vars.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,15 @@ module.exports = {
config.caughtErrors = firstOption.caughtErrors || config.caughtErrors;

if (firstOption.varsIgnorePattern) {
config.varsIgnorePattern = new RegExp(firstOption.varsIgnorePattern); // eslint-disable-line require-unicode-regexp
config.varsIgnorePattern = new RegExp(firstOption.varsIgnorePattern, "u");
}

if (firstOption.argsIgnorePattern) {
config.argsIgnorePattern = new RegExp(firstOption.argsIgnorePattern); // eslint-disable-line require-unicode-regexp
config.argsIgnorePattern = new RegExp(firstOption.argsIgnorePattern, "u");
}

if (firstOption.caughtErrorsIgnorePattern) {
config.caughtErrorsIgnorePattern = new RegExp(firstOption.caughtErrorsIgnorePattern); // eslint-disable-line require-unicode-regexp
config.caughtErrorsIgnorePattern = new RegExp(firstOption.caughtErrorsIgnorePattern, "u");
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions lib/rules/no-warning-comments.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

"use strict";

const { escapeRegExp } = require("lodash");
const astUtils = require("../util/ast-utils");

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -58,7 +59,7 @@ module.exports = {
* @returns {RegExp} The term converted to a RegExp
*/
function convertToRegExp(term) {
const escaped = term.replace(/[-/\\$^*+?.()|[\]{}]/gu, "\\$&");
const escaped = escapeRegExp(term);
const wordBoundary = "\\b";
const eitherOrWordBoundary = `|${wordBoundary}`;
let prefix;
Expand Down Expand Up @@ -95,15 +96,15 @@ module.exports = {
* ^\s*TERM\b. This checks the word boundary
* at the beginning of the comment.
*/
return new RegExp(prefix + escaped + suffix, "i"); // eslint-disable-line require-unicode-regexp
return new RegExp(prefix + escaped + suffix, "iu");
}

/*
* For location "anywhere" the regex should be
* \bTERM\b|\bTERM\b, this checks the entire comment
* for the term.
*/
return new RegExp(prefix + escaped + suffix + eitherOrWordBoundary + term + wordBoundary, "i"); // eslint-disable-line require-unicode-regexp
return new RegExp(prefix + escaped + suffix + eitherOrWordBoundary + term + wordBoundary, "iu");
}

const warningRegExps = warningTerms.map(convertToRegExp);
Expand Down

0 comments on commit 904eff8

Please sign in to comment.