Files

Return to Package Diff Home.
Brought to you by Intrinsic.

Package Diff: eslint @ 5.14.1 .. 5.15.3

CHANGELOG.md

@@ -1,3 +1,54 @@
+v5.15.3 - March 18, 2019
+
+* [`71adc66`](https://github.com/eslint/eslint/commit/71adc665b9649b173adc76f80723b8de20664ae1) Fix: avoid moving comments in implicit-arrow-linebreak (fixes #11521) (#11522) (Teddy Katz)
+* [`1f715a2`](https://github.com/eslint/eslint/commit/1f715a20c145d8ccc38f3310afccd838495d09d4) Chore: make test-case-property-ordering reasonable (#11511) (Toru Nagashima)
+
+v5.15.2 - March 15, 2019
+
+* [`29dbca7`](https://github.com/eslint/eslint/commit/29dbca73d762a809adb2f457b527e144426d54a7) Fix: implicit-arrow-linebreak adds extra characters (fixes #11268) (#11407) (Mark de Dios)
+* [`5d2083f`](https://github.com/eslint/eslint/commit/5d2083fa3e14c024197f6c386ff72237a145e258) Upgrade: eslint-scope@4.0.3 (#11513) (Teddy Katz)
+* [`a5dae7c`](https://github.com/eslint/eslint/commit/a5dae7c3d30231c2f5f075d98c2c8825899bab16) Fix: Empty glob pattern incorrectly expands to "/**" (#11476) (Ben Chauvette)
+* [`448e8da`](https://github.com/eslint/eslint/commit/448e8da94d09b397e98ffcb6f22b55a578ef79c1) Chore: improve crash reporting (fixes #11304) (#11463) (Alex Zherdev)
+* [`0f56dc6`](https://github.com/eslint/eslint/commit/0f56dc6d9eadad05dc3d5c9d1d9ddef94e10c5d3) Chore: make config validator params more consistent (#11435) (薛定谔的猫)
+* [`d6c1122`](https://github.com/eslint/eslint/commit/d6c112289f0f16ade070865c8786831b7940ca79) Docs: Add working groups to maintainer guide (#11400) (Nicholas C. Zakas)
+* [`5fdb4d3`](https://github.com/eslint/eslint/commit/5fdb4d3fb01b9d8a4c2dff71ed9cddb2f8feefb0) Build: compile deps to ES5 when generating browser file (fixes #11504) (#11505) (Teddy Katz)
+* [`06fa165`](https://github.com/eslint/eslint/commit/06fa1655c3da8394ed9144d727115fc434b0416f) Build: update CI testing configuration (#11500) (Reece Dunham)
+* [`956e883`](https://github.com/eslint/eslint/commit/956e883c21fd9f393bf6718d032a4e2e53b33f22) Docs: Fix example in no-restricted-modules docs (#11454) (Paul O’Shannessy)
+* [`2c7431d`](https://github.com/eslint/eslint/commit/2c7431d6b32063f74e3837ee727f26af215eada7) Docs: fix json schema example dead link (#11498) (kazuya kawaguchi)
+* [`e7266c2`](https://github.com/eslint/eslint/commit/e7266c2478aff5d66e7859313feb49e3a129f85e) Docs: Fix invalid JSON in "Specifying Parser Options" (#11492) (Mihira Jayasekera)
+* [`6693161`](https://github.com/eslint/eslint/commit/6693161978a83e0730d5ea0fecdb627c5a2acdfd) Sponsors: Sync README with website (ESLint Jenkins)
+* [`62fee4a`](https://github.com/eslint/eslint/commit/62fee4a976897d158c8c137339728cd280333286) Chore: eslint-config-eslint enable comma-dangle functions: "never" (#11434) (薛定谔的猫)
+* [`34a5382`](https://github.com/eslint/eslint/commit/34a53829e7a63ff2f6b371d77ce283bbdd373b91) Build: copy bundled espree to website directory (#11478) (Pig Fang)
+* [`f078f9a`](https://github.com/eslint/eslint/commit/f078f9a9e094ec00c61a6ef1c9550d017631e69a) Chore: use "file:" dependencies for internal rules/config (#11465) (Teddy Katz)
+* [`0756128`](https://github.com/eslint/eslint/commit/075612871f85aa04cef8137bd32247e128ad600b) Docs: Add `visualstudio` to formatter list (#11480) (Patrick Eriksson)
+* [`44de9d7`](https://github.com/eslint/eslint/commit/44de9d7e1aa2fcae475a97b8f597b7d8094566b2) Docs: Fix typo in func-name-matching rule docs (#11484) (Iulian Onofrei)
+
+v5.15.1 - March 4, 2019
+
+* [`fe1a892`](https://github.com/eslint/eslint/commit/fe1a892f85b09c3d2fea05bef011530a678a6af5) Build: bundle espree (fixes eslint/eslint.github.io#546) (#11467) (薛定谔的猫)
+* [`458053b`](https://github.com/eslint/eslint/commit/458053b0b541f857bf233dacbde5ba80681820f8) Fix: avoid creating invalid regex in no-warning-comments (fixes #11471) (#11472) (Teddy Katz)
+
+v5.15.0 - March 1, 2019
+
+* [`4088c6c`](https://github.com/eslint/eslint/commit/4088c6c9d4578cd581ce8ff4385d90b58a75b755) Build: Remove path.resolve in webpack build (#11462) (Kevin Partington)
+* [`ec59ec0`](https://github.com/eslint/eslint/commit/ec59ec09c8d001b8c04f9edc09994e2b0d0af0f9) New: add rule "prefer-named-capture-group" (fixes #11381) (#11392) (Pig Fang)
+* [`a44f750`](https://github.com/eslint/eslint/commit/a44f75073306e5ea4e6722654009a99884fbca4f) Upgrade: eslint-scope@4.0.2 (#11461) (Teddy Katz)
+* [`d3ce611`](https://github.com/eslint/eslint/commit/d3ce611e1c705440ccbcae357f2194134d026541) Sponsors: Sync README with website (ESLint Jenkins)
+* [`ee88475`](https://github.com/eslint/eslint/commit/ee884754e4111e11994ff0df3f0c29e43e1dc3f2) Chore: add utils for rule tests (#11453) (薛定谔的猫)
+* [`d4824e4`](https://github.com/eslint/eslint/commit/d4824e46d7a6ca1618454d3c6198403382108123) Sponsors: Sync README with website (ESLint Jenkins)
+* [`6489518`](https://github.com/eslint/eslint/commit/64895185bde5233223648bcaf46f8deb72c9fb55) Fix: no-extra-parens crash when code is "((let))" (#11444) (Teddy Katz)
+* [`9d20de2`](https://github.com/eslint/eslint/commit/9d20de2b0ac756bd62888119b8e08c7441d8a5aa) Sponsors: Sync README with website (ESLint Jenkins)
+* [`3f14de4`](https://github.com/eslint/eslint/commit/3f14de458ba120e9c013f5fc7c6fe3e9b40c1460) Sponsors: Sync README with website (ESLint Jenkins)
+* [`3d6c770`](https://github.com/eslint/eslint/commit/3d6c7709d47e047b25d91ca1a77d6dab92313061) Sponsors: Sync README with website (ESLint Jenkins)
+* [`de5cbc5`](https://github.com/eslint/eslint/commit/de5cbc526b30405e742b35d85d04361529d49ed4) Update: remove invalid defaults from core rules (fixes #11415) (#11427) (Teddy Katz)
+* [`eb0650b`](https://github.com/eslint/eslint/commit/eb0650ba20cf9f9ad78dbaccfeb7e0e7ab56e31d) Build: fix linting errors on master (#11428) (Teddy Katz)
+* [`5018378`](https://github.com/eslint/eslint/commit/5018378131fd5190bbccca902c0cf4276ee1581a) Chore: enable require-unicode-regexp on ESLint codebase (#11422) (Teddy Katz)
+* [`f6ba633`](https://github.com/eslint/eslint/commit/f6ba633f56eca6be20fc4b0d9496a78b9498d578) Chore: lint all files in the repo at the same time (#11425) (Teddy Katz)
+* [`8f3d717`](https://github.com/eslint/eslint/commit/8f3d71754932669332ad7623bcc4c1aef3897125) Docs: Add non-attending TSC member info (#11411) (Nicholas C. Zakas)
+* [`ce0777d`](https://github.com/eslint/eslint/commit/ce0777da5bc167fe0c529158fd8216d3eaf11565) Docs: use more common spelling (#11417) (薛定谔的猫)
+* [`b9aabe3`](https://github.com/eslint/eslint/commit/b9aabe34311f6189b87c9d8a1aa40f3513fed773) Chore: run fuzzer along with unit tests (#11404) (Teddy Katz)
+* [`db0c5e2`](https://github.com/eslint/eslint/commit/db0c5e2a7f894b7cda71007b0ba43d7814b3fb2e) Build: switch from browserify to webpack (fixes #11366) (#11398) (Pig Fang)
+
v5.14.1 - February 18, 2019
* [`1d6e639`](https://github.com/eslint/eslint/commit/1d6e63930073e79e52890f552cc6e9a0646b7fb4) Fix: sort-keys throws Error at SpreadElement (fixes #11402) (#11403) (Krist Wongsuphasawat)

lib/built-in-rules-index.js

@@ -232,6 +232,7 @@
"prefer-arrow-callback": require("./rules/prefer-arrow-callback"),
"prefer-const": require("./rules/prefer-const"),
"prefer-destructuring": require("./rules/prefer-destructuring"),
+ "prefer-named-capture-group": require("./rules/prefer-named-capture-group"),
"prefer-numeric-literals": require("./rules/prefer-numeric-literals"),
"prefer-object-spread": require("./rules/prefer-object-spread"),
"prefer-promise-reject-errors": require("./rules/prefer-promise-reject-errors"),

lib/cli-engine.js

@@ -258,7 +258,7 @@
*/
function createIgnoreResult(filePath, baseDir) {
let message;
- const isHidden = /^\./.test(path.basename(filePath));
+ const isHidden = /^\./u.test(path.basename(filePath));
const isInNodeModules = baseDir && path.relative(baseDir, filePath).startsWith("node_modules");
const isInBowerComponents = baseDir && path.relative(baseDir, filePath).startsWith("bower_components");
@@ -757,7 +757,7 @@
if (typeof resolvedFormatName === "string") {
// replace \ with / for Windows compatibility
- const normalizedFormatName = resolvedFormatName.replace(/\\/g, "/");
+ const normalizedFormatName = resolvedFormatName.replace(/\\/gu, "/");
const cwd = this.options ? this.options.cwd : process.cwd();
const namespace = naming.getNamespaceFromTerm(normalizedFormatName);

lib/config/config-file.js

@@ -61,7 +61,7 @@
* @private
*/
function readFile(filePath) {
- return fs.readFileSync(filePath, "utf8").replace(/^\ufeff/, "");
+ return fs.readFileSync(filePath, "utf8").replace(/^\ufeff/u, "");
}
/**
@@ -73,7 +73,7 @@
* @private
*/
function isFilePath(filePath) {
- return path.isAbsolute(filePath) || !/\w|@/.test(filePath.charAt(0));
+ return path.isAbsolute(filePath) || !/\w|@/u.test(filePath.charAt(0));
}
/**
@@ -541,7 +541,7 @@
const ruleMap = configContext.linterContext.getRules();
// validate the configuration before continuing
- validator.validate(config, resolvedPath.configFullName, ruleMap.get.bind(ruleMap), configContext.linterContext.environments);
+ validator.validate(config, ruleMap.get.bind(ruleMap), configContext.linterContext.environments, resolvedPath.configFullName);
/*
* If an `extends` property is defined, it represents a configuration file to use as

lib/config/config-initializer.js

@@ -152,7 +152,7 @@
bar.tick(0); // Shows the progress bar
// Get the SourceCode of all chosen files
- const patterns = answers.patterns.split(/[\s]+/);
+ const patterns = answers.patterns.split(/[\s]+/u);
try {
sourceCodes = getSourceCodeOfFiles(patterns, { baseConfig: newConfig, useEslintrc: false }, total => {

lib/config/config-validator.js

@@ -76,7 +76,7 @@
return normSeverity;
}
- throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util.inspect(severity).replace(/'/g, "\"").replace(/\n/g, "")}').\n`);
+ throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util.inspect(severity).replace(/'/gu, "\"").replace(/\n/gu, "")}').\n`);
}
@@ -116,7 +116,7 @@
* no source is prepended to the message.
* @returns {void}
*/
-function validateRuleOptions(rule, ruleId, options, source) {
+function validateRuleOptions(rule, ruleId, options, source = null) {
if (!rule) {
return;
}
@@ -140,11 +140,11 @@
/**
* Validates an environment object
* @param {Object} environment The environment config object to validate.
- * @param {string} source The name of the configuration source to report in any errors.
* @param {Environments} envContext Env context
+ * @param {string} source The name of the configuration source to report in any errors.
* @returns {void}
*/
-function validateEnvironment(environment, source, envContext) {
+function validateEnvironment(environment, envContext, source = null) {
// not having an environment is ok
if (!environment) {
@@ -163,11 +163,11 @@
/**
* Validates a rules config object
* @param {Object} rulesConfig The rules config object to validate.
- * @param {string} source The name of the configuration source to report in any errors.
* @param {function(string): {create: Function}} ruleMapper A mapper function from strings to loaded rules
+ * @param {string} source The name of the configuration source to report in any errors.
* @returns {void}
*/
-function validateRules(rulesConfig, source, ruleMapper) {
+function validateRules(rulesConfig, ruleMapper, source = null) {
if (!rulesConfig) {
return;
}
@@ -228,7 +228,7 @@
* @param {string} source The name of the configuration source to report in any errors.
* @returns {void}
*/
-function validateConfigSchema(config, source) {
+function validateConfigSchema(config, source = null) {
validateSchema = validateSchema || ajv.compile(configSchema);
if (!validateSchema(config)) {
@@ -252,19 +252,19 @@
/**
* Validates an entire config object.
* @param {Object} config The config object to validate.
- * @param {string} source The name of the configuration source to report in any errors.
* @param {function(string): {create: Function}} ruleMapper A mapper function from rule IDs to defined rules
* @param {Environments} envContext The env context
+ * @param {string} source The name of the configuration source to report in any errors.
* @returns {void}
*/
-function validate(config, source, ruleMapper, envContext) {
+function validate(config, ruleMapper, envContext, source = null) {
validateConfigSchema(config, source);
- validateRules(config.rules, source, ruleMapper);
- validateEnvironment(config.env, source, envContext);
+ validateRules(config.rules, ruleMapper, source);
+ validateEnvironment(config.env, envContext, source);
for (const override of config.overrides || []) {
- validateRules(override.rules, source, ruleMapper);
- validateEnvironment(override.env, source, envContext);
+ validateRules(override.rules, ruleMapper, source);
+ validateEnvironment(override.env, envContext, source);
}
}

lib/config/plugins.js

@@ -84,7 +84,7 @@
const shortName = naming.getShorthandName(longName, "eslint-plugin");
let plugin = null;
- if (pluginName.match(/\s+/)) {
+ if (pluginName.match(/\s+/u)) {
const whitespaceError = new Error(`Whitespace found in plugin name '${pluginName}'`);
whitespaceError.messageTemplate = "whitespace-found";

lib/formatters/codeframe.js

@@ -47,7 +47,7 @@
*/
function formatMessage(message, parentResult) {
const type = (message.fatal || message.severity === 2) ? chalk.red("error") : chalk.yellow("warning");
- const msg = `${chalk.bold(message.message.replace(/([^ ])\.$/, "$1"))}`;
+ const msg = `${chalk.bold(message.message.replace(/([^ ])\.$/u, "$1"))}`;
const ruleId = message.fatal ? "" : chalk.dim(`(${message.ruleId})`);
const filePath = formatFilePath(parentResult.filePath, message.line, message.column);
const sourceCode = parentResult.output ? parentResult.output : parentResult.source;

lib/formatters/stylish.js

@@ -65,7 +65,7 @@
message.line || 0,
message.column || 0,
messageType,
- message.message.replace(/([^ ])\.$/, "$1"),
+ message.message.replace(/([^ ])\.$/u, "$1"),
chalk.dim(message.ruleId || "")
];
}),
@@ -75,7 +75,7 @@
return stripAnsi(str).length;
}
}
- ).split("\n").map(el => el.replace(/(\d+)\s+(\d+)/, (m, p1, p2) => chalk.dim(`${p1}:${p2}`))).join("\n")}\n\n`;
+ ).split("\n").map(el => el.replace(/(\d+)\s+(\d+)/u, (m, p1, p2) => chalk.dim(`${p1}:${p2}`))).join("\n")}\n\n`;
});
const total = errorCount + warningCount;

lib/linter.js

@@ -11,6 +11,7 @@
const eslintScope = require("eslint-scope"),
evk = require("eslint-visitor-keys"),
+ espree = require("espree"),
lodash = require("lodash"),
CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer"),
ConfigOps = require("./config/config-ops"),
@@ -163,7 +164,7 @@
ast.comments.filter(token => token.type !== "Shebang").forEach(comment => {
const trimmedCommentText = comment.value.trim();
- const match = /^(eslint(-\w+){0,3}|exported|globals?)(\s|$)/.exec(trimmedCommentText);
+ const match = /^(eslint(-\w+){0,3}|exported|globals?)(\s|$)/u.exec(trimmedCommentText);
if (!match) {
return;
@@ -171,7 +172,7 @@
const directiveValue = trimmedCommentText.slice(match.index + match[1].length);
- if (/^eslint-disable-(next-)?line$/.test(match[1])) {
+ if (/^eslint-disable-(next-)?line$/u.test(match[1])) {
if (comment.loc.start.line === comment.loc.end.line) {
const directiveType = match[1].slice("eslint-".length);
@@ -275,7 +276,7 @@
return ecmaVersion;
}
-const eslintEnvPattern = /\/\*\s*eslint-env\s(.+?)\*\//g;
+const eslintEnvPattern = /\/\*\s*eslint-env\s(.+?)\*\//gu;
/**
* Checks whether or not there is a comment which has "eslint-env *" in a given text.
@@ -497,7 +498,7 @@
} catch (ex) {
// If the message includes a leading line number, strip it:
- const message = `Parsing error: ${ex.message.replace(/^line \d+:/i, "").trim()}`;
+ const message = `Parsing error: ${ex.message.replace(/^line \d+:/iu, "").trim()}`;
return {
success: false,
@@ -746,11 +747,16 @@
nodeQueue.forEach(traversalInfo => {
currentNode = traversalInfo.node;
+ try {
if (traversalInfo.isEntering) {
eventGenerator.enterNode(currentNode);
} else {
eventGenerator.leaveNode(currentNode);
}
+ } catch (err) {
+ err.currentNode = currentNode;
+ throw err;
+ }
});
return lintingProblems;
@@ -776,6 +782,8 @@
ruleMaps.set(this, new Rules());
this.version = pkg.version;
this.environments = new Environments();
+
+ this.defineParser("espree", espree);
}
/**
@@ -898,8 +906,15 @@
options.filename
);
} catch (err) {
+ err.message += `\nOccurred while linting ${options.filename}`;
debug("An error occurred while traversing");
debug("Filename:", options.filename);
+ if (err.currentNode) {
+ const { line } = err.currentNode.loc.start;
+
+ debug("Line:", line);
+ err.message += `:${line}`;
+ }
debug("Parser Options:", parserOptions);
debug("Parser Path:", parserName);
debug("Settings:", settings);

lib/rules/array-bracket-newline.js

@@ -34,13 +34,11 @@
type: "object",
properties: {
multiline: {
- type: "boolean",
- default: true
+ type: "boolean"
},
minItems: {
type: ["integer", "null"],
- minimum: 0,
- default: null
+ minimum: 0
}
},
additionalProperties: false

lib/rules/array-callback-return.js

@@ -17,8 +17,8 @@
// Helpers
//------------------------------------------------------------------------------
-const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/;
-const TARGET_METHODS = /^(?:every|filter|find(?:Index)?|map|reduce(?:Right)?|some|sort)$/;
+const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u;
+const TARGET_METHODS = /^(?:every|filter|find(?:Index)?|map|reduce(?:Right)?|some|sort)$/u;
/**
* Checks a given code path segment is reachable.

lib/rules/array-element-newline.js

@@ -34,13 +34,11 @@
type: "object",
properties: {
multiline: {
- type: "boolean",
- default: false
+ type: "boolean"
},
minItems: {
type: ["integer", "null"],
- minimum: 0,
- default: null
+ minimum: 0
}
},
additionalProperties: false

lib/rules/arrow-body-style.js

@@ -46,7 +46,7 @@
{
type: "object",
properties: {
- requireReturnForObjectLiteral: { type: "boolean", default: false }
+ requireReturnForObjectLiteral: { type: "boolean" }
},
additionalProperties: false
}
@@ -82,7 +82,7 @@
* @returns {boolean} `true` if it changes semantics if `;` or `}` followed by the token are removed.
*/
function hasASIProblem(token) {
- return token && token.type === "Punctuator" && /^[([/`+-]/.test(token.value);
+ return token && token.type === "Punctuator" && /^[([/`+-]/u.test(token.value);
}
/**

lib/rules/camelcase.js

@@ -90,7 +90,7 @@
*/
function isAllowed(name) {
return allow.findIndex(
- entry => name === entry || name.match(new RegExp(entry))
+ entry => name === entry || name.match(new RegExp(entry)) // eslint-disable-line require-unicode-regexp
) !== -1;
}
@@ -142,7 +142,7 @@
* private/protected identifiers, strip them before checking if underscored
*/
const name = node.name,
- nameIsUnderscored = isUnderscored(name.replace(/^_+|_+$/g, "")),
+ nameIsUnderscored = isUnderscored(name.replace(/^_+|_+$/gu, "")),
effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent;
// First, we ignore the node if it match the ignore list

lib/rules/capitalized-comments.js

@@ -16,8 +16,8 @@
//------------------------------------------------------------------------------
const DEFAULT_IGNORE_PATTERN = astUtils.COMMENTS_IGNORE_PATTERN,
- WHITESPACE = /\s/g,
- MAYBE_URL = /^\s*[^:/?#\s]+:\/\/[^?#]/; // TODO: Combine w/ max-len pattern?
+ WHITESPACE = /\s/gu,
+ MAYBE_URL = /^\s*[^:/?#\s]+:\/\/[^?#]/u; // TODO: Combine w/ max-len pattern?
/*
* Base schema body for defining the basic capitalization rule, ignorePattern,
@@ -28,27 +28,22 @@
type: "object",
properties: {
ignorePattern: {
- type: "string",
- default: ""
+ type: "string"
},
ignoreInlineComments: {
- type: "boolean",
- default: false
+ type: "boolean"
},
ignoreConsecutiveComments: {
- type: "boolean",
- default: false
+ type: "boolean"
}
},
additionalProperties: false
};
-const DEFAULTS = Object.keys(SCHEMA_BODY.properties).reduce(
- (obj, current) => {
- obj[current] = SCHEMA_BODY.properties[current].default;
- return obj;
- },
- {}
-);
+const DEFAULTS = {
+ ignorePattern: "",
+ ignoreInlineComments: false,
+ ignoreConsecutiveComments: false
+};
/**
* Get normalized options for either block or line comments from the given
@@ -96,7 +91,7 @@
const ignorePatternStr = normalizedOptions[key].ignorePattern;
if (ignorePatternStr) {
- const regExp = RegExp(`^\\s*(?:${ignorePatternStr})`);
+ const regExp = RegExp(`^\\s*(?:${ignorePatternStr})`); // eslint-disable-line require-unicode-regexp
normalizedOptions[key].ignorePatternRegExp = regExp;
}
@@ -215,7 +210,7 @@
// 2. Check for custom ignore pattern.
const commentWithoutAsterisks = comment.value
- .replace(/\*/g, "");
+ .replace(/\*/gu, "");
if (options.ignorePatternRegExp && options.ignorePatternRegExp.test(commentWithoutAsterisks)) {
return true;

lib/rules/complexity.js

@@ -41,13 +41,11 @@
properties: {
maximum: {
type: "integer",
- minimum: 0,
- default: 20
+ minimum: 0
},
max: {
type: "integer",
- minimum: 0,
- default: 20
+ minimum: 0
}
},
additionalProperties: false
@@ -65,7 +63,10 @@
const option = context.options[0];
let THRESHOLD = 20;
- if (typeof option === "object") {
+ if (
+ typeof option === "object" &&
+ (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
+ ) {
THRESHOLD = option.maximum || option.max;
} else if (typeof option === "number") {
THRESHOLD = option;

lib/rules/curly.js

@@ -191,7 +191,7 @@
return true;
}
- if (/^[([/`+-]/.test(tokenAfter.value)) {
+ if (/^[([/`+-]/u.test(tokenAfter.value)) {
// If the next token starts with a character that would disrupt ASI, insert a semicolon.
return true;

lib/rules/default-case.js

@@ -4,7 +4,7 @@
*/
"use strict";
-const DEFAULT_COMMENT_PATTERN = /^no default$/i;
+const DEFAULT_COMMENT_PATTERN = /^no default$/iu;
//------------------------------------------------------------------------------
// Rule Definition
@@ -39,7 +39,7 @@
create(context) {
const options = context.options[0] || {};
const commentPattern = options.commentPattern
- ? new RegExp(options.commentPattern)
+ ? new RegExp(options.commentPattern) // eslint-disable-line require-unicode-regexp
: DEFAULT_COMMENT_PATTERN;
const sourceCode = context.getSourceCode();

lib/rules/dot-notation.js

@@ -14,7 +14,7 @@
// Rule Definition
//------------------------------------------------------------------------------
-const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
+const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/u;
const keywords = require("../util/keywords");
module.exports = {
@@ -61,7 +61,7 @@
let allowPattern;
if (options.allowPattern) {
- allowPattern = new RegExp(options.allowPattern);
+ allowPattern = new RegExp(options.allowPattern); // eslint-disable-line require-unicode-regexp
}
/**

lib/rules/eol-last.js

@@ -97,7 +97,7 @@
loc: location,
messageId: "unexpected",
fix(fixer) {
- const finalEOLs = /(?:\r?\n)+$/,
+ const finalEOLs = /(?:\r?\n)+$/u,
match = finalEOLs.exec(sourceCode.text),
start = match.index,
end = sourceCode.text.length;

lib/rules/eqeqeq.js

@@ -38,8 +38,7 @@
type: "object",
properties: {
null: {
- enum: ["always", "never", "ignore"],
- default: "always"
+ enum: ["always", "never", "ignore"]
}
},
additionalProperties: false

lib/rules/func-call-spacing.js

@@ -50,8 +50,7 @@
type: "object",
properties: {
allowNewlines: {
- type: "boolean",
- default: false
+ type: "boolean"
}
},
additionalProperties: false
@@ -93,8 +92,8 @@
return;
}
- const textBetweenTokens = text.slice(prevToken.range[1], parenToken.range[0]).replace(/\/\*.*?\*\//g, "");
- const hasWhitespace = /\s/.test(textBetweenTokens);
+ const textBetweenTokens = text.slice(prevToken.range[1], parenToken.range[0]).replace(/\/\*.*?\*\//gu, "");
+ const hasWhitespace = /\s/u.test(textBetweenTokens);
const hasNewline = hasWhitespace && astUtils.LINEBREAK_MATCHER.test(textBetweenTokens);
/*

lib/rules/getter-return.js

@@ -14,7 +14,7 @@
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
-const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/;
+const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u;
/**
* Checks a given code path segment is reachable.

lib/rules/handle-callback-err.js

@@ -52,7 +52,7 @@
*/
function matchesConfiguredErrorName(name) {
if (isPattern(errorArgument)) {
- const regexp = new RegExp(errorArgument);
+ const regexp = new RegExp(errorArgument); // eslint-disable-line require-unicode-regexp
return regexp.test(name);
}

lib/rules/id-match.js

@@ -53,7 +53,7 @@
// Options
//--------------------------------------------------------------------------
const pattern = context.options[0] || "^.+$",
- regexp = new RegExp(pattern);
+ regexp = new RegExp(pattern); // eslint-disable-line require-unicode-regexp
const options = context.options[1] || {},
properties = !!options.properties,

lib/rules/implicit-arrow-linebreak.js

@@ -4,11 +4,7 @@
*/
"use strict";
-const {
- isArrowToken,
- isParenthesised,
- isOpeningParenToken
-} = require("../util/ast-utils");
+const { isCommentToken, isNotOpeningParenToken } = require("../util/ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
@@ -39,153 +35,7 @@
create(context) {
const sourceCode = context.getSourceCode();
-
- //----------------------------------------------------------------------
- // Helpers
- //----------------------------------------------------------------------
- /**
- * Gets the applicable preference for a particular keyword
- * @returns {string} The applicable option for the keyword, e.g. 'beside'
- */
- function getOption() {
- return context.options[0] || "beside";
- }
-
- /**
- * Formats the comments depending on whether it's a line or block comment.
- * @param {Comment[]} comments The array of comments between the arrow and body
- * @param {Integer} column The column number of the first token
- * @returns {string} A string of comment text joined by line breaks
- */
- function formatComments(comments, column) {
- const whiteSpaces = " ".repeat(column);
-
- return `${comments.map(comment => {
-
- if (comment.type === "Line") {
- return `//${comment.value}`;
- }
-
- return `/*${comment.value}*/`;
- }).join(`\n${whiteSpaces}`)}\n${whiteSpaces}`;
- }
-
- /**
- * Finds the first token to prepend comments to depending on the parent type
- * @param {Node} node The validated node
- * @returns {Token|Node} The node to prepend comments to
- */
- function findFirstToken(node) {
- switch (node.parent.type) {
- case "VariableDeclarator":
-
- // If the parent is first or only declarator, return the declaration, else, declarator
- return sourceCode.getFirstToken(
- node.parent.parent.declarations.length === 1 ||
- node.parent.parent.declarations[0].id.name === node.parent.id.name
- ? node.parent.parent : node.parent
- );
- case "CallExpression":
- case "Property":
-
- // find the object key
- return sourceCode.getFirstToken(node.parent);
- default:
- return node;
- }
- }
-
- /**
- * Helper function for adding parentheses fixes for nodes containing nested arrow functions
- * @param {Fixer} fixer Fixer
- * @param {Token} arrow - The arrow token
- * @param {ASTNode} arrowBody - The arrow function body
- * @returns {Function[]} autofixer -- wraps function bodies with parentheses
- */
- function addParentheses(fixer, arrow, arrowBody) {
- const parenthesesFixes = [];
- let closingParentheses = "";
-
- let followingBody = arrowBody;
- let currentArrow = arrow;
-
- while (currentArrow) {
- if (!isParenthesised(sourceCode, followingBody)) {
- parenthesesFixes.push(
- fixer.insertTextAfter(currentArrow, " (")
- );
-
- const paramsToken = sourceCode.getTokenBefore(currentArrow, token =>
- isOpeningParenToken(token) || token.type === "Identifier");
-
- const whiteSpaces = " ".repeat(paramsToken.loc.start.column);
-
- closingParentheses = `\n${whiteSpaces})${closingParentheses}`;
- }
-
- currentArrow = sourceCode.getTokenAfter(currentArrow, isArrowToken);
-
- if (currentArrow) {
- followingBody = sourceCode.getTokenAfter(currentArrow, token => !isOpeningParenToken(token));
- }
- }
-
- return [...parenthesesFixes,
- fixer.insertTextAfter(arrowBody, closingParentheses)
- ];
- }
-
- /**
- * Autofixes the function body to collapse onto the same line as the arrow.
- * If comments exist, prepends the comments before the arrow function.
- * If the function body contains arrow functions, appends the function bodies with parentheses.
- * @param {Token} arrowToken The arrow token.
- * @param {ASTNode} arrowBody the function body
- * @param {ASTNode} node The evaluated node
- * @returns {Function} autofixer -- validates the node to adhere to besides
- */
- function autoFixBesides(arrowToken, arrowBody, node) {
- return fixer => {
- const placeBesides = fixer.replaceTextRange([arrowToken.range[1], arrowBody.range[0]], " ");
-
- const comments = sourceCode.getCommentsInside(node).filter(comment =>
- comment.loc.start.line < arrowBody.loc.start.line);
-
- if (comments.length) {
-
- // If the grandparent is not a variable declarator
- if (
- arrowBody.parent &&
- arrowBody.parent.parent &&
- arrowBody.parent.parent.type !== "VariableDeclarator"
- ) {
-
- // If any arrow functions follow, return the necessary parens fixes.
- if (sourceCode.getTokenAfter(arrowToken, isArrowToken) && arrowBody.parent.parent.type !== "VariableDeclarator") {
- return addParentheses(fixer, arrowToken, arrowBody);
- }
-
- // If any arrow functions precede, the necessary fixes have already been returned, so return null.
- if (sourceCode.getTokenBefore(arrowToken, isArrowToken) && arrowBody.parent.parent.type !== "VariableDeclarator") {
- return null;
- }
- }
-
- const firstToken = findFirstToken(node);
-
- const commentText = formatComments(comments, firstToken.loc.start.column);
-
- const commentBeforeExpression = fixer.insertTextBeforeRange(
- firstToken.range,
- commentText
- );
-
- return [placeBesides, commentBeforeExpression];
- }
-
- return placeBesides;
- };
- }
+ const option = context.options[0] || "beside";
/**
* Validates the location of an arrow function body
@@ -193,35 +43,30 @@
* @returns {void}
*/
function validateExpression(node) {
- const option = getOption();
-
- let tokenBefore = sourceCode.getTokenBefore(node.body);
- const hasParens = tokenBefore.value === "(";
-
- if (node.type === "BlockStatement") {
+ if (node.body.type === "BlockStatement") {
return;
}
- let fixerTarget = node.body;
+ const arrowToken = sourceCode.getTokenBefore(node.body, isNotOpeningParenToken);
+ const firstTokenOfBody = sourceCode.getTokenAfter(arrowToken);
- if (hasParens) {
-
- // Gets the first token before the function body that is not an open paren
- tokenBefore = sourceCode.getTokenBefore(node.body, token => token.value !== "(");
- fixerTarget = sourceCode.getTokenAfter(tokenBefore);
- }
-
- if (tokenBefore.loc.end.line === fixerTarget.loc.start.line && option === "below") {
+ if (arrowToken.loc.end.line === firstTokenOfBody.loc.start.line && option === "below") {
context.report({
- node: fixerTarget,
+ node: firstTokenOfBody,
messageId: "expected",
- fix: fixer => fixer.insertTextBefore(fixerTarget, "\n")
+ fix: fixer => fixer.insertTextBefore(firstTokenOfBody, "\n")
});
- } else if (tokenBefore.loc.end.line !== fixerTarget.loc.start.line && option === "beside") {
+ } else if (arrowToken.loc.end.line !== firstTokenOfBody.loc.start.line && option === "beside") {
context.report({
- node: fixerTarget,
+ node: firstTokenOfBody,
messageId: "unexpected",
- fix: autoFixBesides(tokenBefore, fixerTarget, node)
+ fix(fixer) {
+ if (sourceCode.getFirstTokenBetween(arrowToken, firstTokenOfBody, { includeComments: true, filter: isCommentToken })) {
+ return null;
+ }
+
+ return fixer.replaceTextRange([arrowToken.range[1], firstTokenOfBody.range[0]], " ");
+ }
});
}
}

lib/rules/indent.js

@@ -442,7 +442,7 @@
const offset = (
offsetInfo.from &&
offsetInfo.from.loc.start.line === token.loc.start.line &&
- !/^\s*?\n/.test(token.value) &&
+ !/^\s*?\n/u.test(token.value) &&
!offsetInfo.force
) ? 0 : offsetInfo.offset * this._indentSize;
@@ -785,7 +785,7 @@
* or the total number of linebreaks if the string is all whitespace.
*/
function countTrailingLinebreaks(string) {
- const trailingWhitespace = string.match(/\s*$/)[0];
+ const trailingWhitespace = string.match(/\s*$/u)[0];
const linebreakMatches = trailingWhitespace.match(astUtils.createGlobalLinebreakMatcher());
return linebreakMatches === null ? 0 : linebreakMatches.length;

lib/rules/indent-legacy.js

@@ -975,7 +975,7 @@
* @returns {boolean} the result
*/
function isWrappedInParenthesis(node) {
- const regex = /^return\s*?\(\s*?\);*?/;
+ const regex = /^return\s*?\(\s*?\);*?/u;
const statementWithoutArgument = sourceCode.getText(node).replace(
sourceCode.getText(node.argument), ""

lib/rules/init-declarations.js

@@ -75,8 +75,7 @@
type: "object",
properties: {
ignoreForLoopInit: {
- type: "boolean",
- default: false
+ type: "boolean"
}
},
additionalProperties: false

lib/rules/jsx-quotes.js

@@ -20,14 +20,14 @@
quote: "\"",
description: "singlequote",
convert(str) {
- return str.replace(/'/g, "\"");
+ return str.replace(/'/gu, "\"");
}
},
"prefer-single": {
quote: "'",
description: "doublequote",
convert(str) {
- return str.replace(/"/g, "'");
+ return str.replace(/"/gu, "'");
}
}
};

lib/rules/key-spacing.js

@@ -148,20 +148,16 @@
type: "object",
properties: {
mode: {
- enum: ["strict", "minimum"],
- default: "strict"
+ enum: ["strict", "minimum"]
},
on: {
- enum: ["colon", "value"],
- default: "colon"
+ enum: ["colon", "value"]
},
beforeColon: {
- type: "boolean",
- default: false
+ type: "boolean"
},
afterColon: {
- type: "boolean",
- default: true
+ type: "boolean"
}
},
additionalProperties: false
@@ -169,16 +165,13 @@
]
},
mode: {
- enum: ["strict", "minimum"],
- default: "strict"
+ enum: ["strict", "minimum"]
},
beforeColon: {
- type: "boolean",
- default: false
+ type: "boolean"
},
afterColon: {
- type: "boolean",
- default: true
+ type: "boolean"
}
},
additionalProperties: false
@@ -190,16 +183,13 @@
type: "object",
properties: {
mode: {
- enum: ["strict", "minimum"],
- default: "strict"
+ enum: ["strict", "minimum"]
},
beforeColon: {
- type: "boolean",
- default: false
+ type: "boolean"
},
afterColon: {
- type: "boolean",
- default: true
+ type: "boolean"
}
},
additionalProperties: false
@@ -216,20 +206,16 @@
type: "object",
properties: {
mode: {
- enum: ["strict", "minimum"],
- default: "strict"
+ enum: ["strict", "minimum"]
},
on: {
- enum: ["colon", "value"],
- default: "colon"
+ enum: ["colon", "value"]
},
beforeColon: {
- type: "boolean",
- default: false
+ type: "boolean"
},
afterColon: {
- type: "boolean",
- default: true
+ type: "boolean"
}
},
additionalProperties: false
@@ -237,16 +223,13 @@
]
},
mode: {
- enum: ["strict", "minimum"],
- default: "strict"
+ enum: ["strict", "minimum"]
},
beforeColon: {
- type: "boolean",
- default: false
+ type: "boolean"
},
afterColon: {
- type: "boolean",
- default: true
+ type: "boolean"
}
},
additionalProperties: false
@@ -261,16 +244,13 @@
type: "object",
properties: {
mode: {
- enum: ["strict", "minimum"],
- default: "strict"
+ enum: ["strict", "minimum"]
},
beforeColon: {
- type: "boolean",
- default: false
+ type: "boolean"
},
afterColon: {
- type: "boolean",
- default: true
+ type: "boolean"
}
},
additionalProperties: false
@@ -279,16 +259,13 @@
type: "object",
properties: {
mode: {
- enum: ["strict", "minimum"],
- default: "strict"
+ enum: ["strict", "minimum"]
},
beforeColon: {
- type: "boolean",
- default: false
+ type: "boolean"
},
afterColon: {
- type: "boolean",
- default: true
+ type: "boolean"
}
},
additionalProperties: false
@@ -297,20 +274,16 @@
type: "object",
properties: {
mode: {
- enum: ["strict", "minimum"],
- default: "strict"
+ enum: ["strict", "minimum"]
},
on: {
- enum: ["colon", "value"],
- default: "colon"
+ enum: ["colon", "value"]
},
beforeColon: {
- type: "boolean",
- default: false
+ type: "boolean"
},
afterColon: {
- type: "boolean",
- default: true
+ type: "boolean"
}
},
additionalProperties: false
@@ -528,7 +501,7 @@
* @returns {Object} Whitespace before and after the property's colon.
*/
function getPropertyWhitespace(property) {
- const whitespace = /(\s*):(\s*)/.exec(sourceCode.getText().slice(
+ const whitespace = /(\s*):(\s*)/u.exec(sourceCode.getText().slice(
property.key.range[1], property.value.range[0]
));

lib/rules/keyword-spacing.js

@@ -16,13 +16,13 @@
// Constants
//------------------------------------------------------------------------------
-const PREV_TOKEN = /^[)\]}>]$/;
-const NEXT_TOKEN = /^(?:[([{<~!]|\+\+?|--?)$/;
-const PREV_TOKEN_M = /^[)\]}>*]$/;
-const NEXT_TOKEN_M = /^[{*]$/;
-const TEMPLATE_OPEN_PAREN = /\$\{$/;
-const TEMPLATE_CLOSE_PAREN = /^\}/;
-const CHECK_TYPE = /^(?:JSXElement|RegularExpression|String|Template)$/;
+const PREV_TOKEN = /^[)\]}>]$/u;
+const NEXT_TOKEN = /^(?:[([{<~!]|\+\+?|--?)$/u;
+const PREV_TOKEN_M = /^[)\]}>*]$/u;
+const NEXT_TOKEN_M = /^[{*]$/u;
+const TEMPLATE_OPEN_PAREN = /\$\{$/u;
+const TEMPLATE_CLOSE_PAREN = /^\}/u;
+const CHECK_TYPE = /^(?:JSXElement|RegularExpression|String|Template)$/u;
const KEYS = keywords.concat(["as", "async", "await", "from", "get", "let", "of", "set", "yield"]);
// check duplications.

lib/rules/line-comment-position.js

@@ -38,12 +38,10 @@
type: "string"
},
applyDefaultPatterns: {
- type: "boolean",
- default: true
+ type: "boolean"
},
applyDefaultIgnorePatterns: {
- type: "boolean",
- default: true
+ type: "boolean"
}
},
additionalProperties: false
@@ -74,13 +72,13 @@
if (Object.prototype.hasOwnProperty.call(options, "applyDefaultIgnorePatterns")) {
applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns;
} else {
- applyDefaultIgnorePatterns = options.applyDefaultPatterns;
+ applyDefaultIgnorePatterns = options.applyDefaultPatterns !== false;
}
}
const defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN;
- const fallThroughRegExp = /^\s*falls?\s?through/;
- const customIgnoreRegExp = new RegExp(ignorePattern);
+ const fallThroughRegExp = /^\s*falls?\s?through/u;
+ const customIgnoreRegExp = new RegExp(ignorePattern); // eslint-disable-line require-unicode-regexp
const sourceCode = context.getSourceCode();
//--------------------------------------------------------------------------

lib/rules/lines-around-comment.js

@@ -130,7 +130,7 @@
const options = Object.assign({}, context.options[0]);
const ignorePattern = options.ignorePattern;
const defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN;
- const customIgnoreRegExp = new RegExp(ignorePattern);
+ const customIgnoreRegExp = new RegExp(ignorePattern); // eslint-disable-line require-unicode-regexp
const applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns !== false;
options.beforeBlockComment = typeof options.beforeBlockComment !== "undefined" ? options.beforeBlockComment : true;

lib/rules/max-depth.js

@@ -32,13 +32,11 @@
properties: {
maximum: {
type: "integer",
- minimum: 0,
- default: 4
+ minimum: 0
},
max: {
type: "integer",
- minimum: 0,
- default: 4
+ minimum: 0
}
},
additionalProperties: false
@@ -61,7 +59,10 @@
option = context.options[0];
let maxDepth = 4;
- if (typeof option === "object") {
+ if (
+ typeof option === "object" &&
+ (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
+ ) {
maxDepth = option.maximum || option.max;
}
if (typeof option === "number") {

lib/rules/max-len.js

@@ -103,7 +103,7 @@
* too many false positives
* - We don't care about matching the entire URL, any small segment is fine
*/
- const URL_REGEXP = /[^:/?#]:\/\/[^?#]/;
+ const URL_REGEXP = /[^:/?#]:\/\/[^?#]/u;
const sourceCode = context.getSourceCode();
@@ -118,7 +118,7 @@
function computeLineLength(line, tabWidth) {
let extraCharacterCount = 0;
- line.replace(/\t/g, (match, offset) => {
+ line.replace(/\t/gu, (match, offset) => {
const totalOffset = offset + extraCharacterCount,
previousTabStopOffset = tabWidth ? totalOffset % tabWidth : 0,
spaceCount = tabWidth - previousTabStopOffset;
@@ -153,7 +153,7 @@
let ignorePattern = options.ignorePattern || null;
if (ignorePattern) {
- ignorePattern = new RegExp(ignorePattern);
+ ignorePattern = new RegExp(ignorePattern); // eslint-disable-line require-unicode-regexp
}
//--------------------------------------------------------------------------
@@ -201,7 +201,7 @@
function stripTrailingComment(line, comment) {
// loc.column is zero-indexed
- return line.slice(0, comment.loc.start.column).replace(/\s+$/, "");
+ return line.slice(0, comment.loc.start.column).replace(/\s+$/u, "");
}
/**

lib/rules/max-lines.js

@@ -38,16 +38,13 @@
properties: {
max: {
type: "integer",
- minimum: 0,
- default: 300
+ minimum: 0
},
skipComments: {
- type: "boolean",
- default: false
+ type: "boolean"
},
skipBlankLines: {
- type: "boolean",
- default: false
+ type: "boolean"
}
},
additionalProperties: false
@@ -64,7 +61,7 @@
const option = context.options[0];
let max = 300;
- if (typeof option === "object") {
+ if (typeof option === "object" && Object.prototype.hasOwnProperty.call(option, "max")) {
max = option.max;
} else if (typeof option === "number") {
max = option;

lib/rules/max-lines-per-function.js

@@ -187,7 +187,7 @@
}
if (skipBlankLines) {
- if (line.match(/^\s*$/)) {
+ if (line.match(/^\s*$/u)) {
continue;
}
}

lib/rules/max-nested-callbacks.js

@@ -32,13 +32,11 @@
properties: {
maximum: {
type: "integer",
- minimum: 0,
- default: 10
+ minimum: 0
},
max: {
type: "integer",
- minimum: 0,
- default: 10
+ minimum: 0
}
},
additionalProperties: false
@@ -59,7 +57,10 @@
const option = context.options[0];
let THRESHOLD = 10;
- if (typeof option === "object") {
+ if (
+ typeof option === "object" &&
+ (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
+ ) {
THRESHOLD = option.maximum || option.max;
} else if (typeof option === "number") {
THRESHOLD = option;

lib/rules/max-params.js

@@ -40,13 +40,11 @@
properties: {
maximum: {
type: "integer",
- minimum: 0,
- default: 3
+ minimum: 0
},
max: {
type: "integer",
- minimum: 0,
- default: 3
+ minimum: 0
}
},
additionalProperties: false
@@ -64,7 +62,10 @@
const option = context.options[0];
let numParams = 3;
- if (typeof option === "object") {
+ if (
+ typeof option === "object" &&
+ (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
+ ) {
numParams = option.maximum || option.max;
}
if (typeof option === "number") {

lib/rules/max-statements.js

@@ -40,13 +40,11 @@
properties: {
maximum: {
type: "integer",
- minimum: 0,
- default: 10
+ minimum: 0
},
max: {
type: "integer",
- minimum: 0,
- default: 10
+ minimum: 0
}
},
additionalProperties: false
@@ -80,7 +78,10 @@
topLevelFunctions = [];
let maxStatements = 10;
- if (typeof option === "object") {
+ if (
+ typeof option === "object" &&
+ (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
+ ) {
maxStatements = option.maximum || option.max;
} else if (typeof option === "number") {
maxStatements = option;

lib/rules/max-statements-per-line.js

@@ -57,7 +57,7 @@
// Helpers
//--------------------------------------------------------------------------
- const SINGLE_CHILD_ALLOWED = /^(?:(?:DoWhile|For|ForIn|ForOf|If|Labeled|While)Statement|Export(?:Default|Named)Declaration)$/;
+ const SINGLE_CHILD_ALLOWED = /^(?:(?:DoWhile|For|ForIn|ForOf|If|Labeled|While)Statement|Export(?:Default|Named)Declaration)$/u;
/**
* Reports with the first extra statement, and clears it.

lib/rules/multiline-comment-style.js

@@ -52,7 +52,7 @@
}
return commentGroup[0].value
.split(astUtils.LINEBREAK_MATCHER)
- .map(line => line.replace(/^\s*\*?/, ""));
+ .map(line => line.replace(/^\s*\*?/u, ""));
}
/**
@@ -103,9 +103,9 @@
const lines = commentGroup[0].value.split(astUtils.LINEBREAK_MATCHER);
return commentGroup[0].type === "Block" &&
- /^\*\s*$/.test(lines[0]) &&
- lines.slice(1, -1).every(line => /^\s* /.test(line)) &&
- /^\s*$/.test(lines[lines.length - 1]);
+ /^\*\s*$/u.test(lines[0]) &&
+ lines.slice(1, -1).every(line => /^\s* /u.test(line)) &&
+ /^\s*$/u.test(lines[lines.length - 1]);
}
/**
@@ -143,7 +143,7 @@
const lines = block.value.split(astUtils.LINEBREAK_MATCHER);
const expectedLinePrefix = `${sourceCode.text.slice(block.range[0] - block.loc.start.column, block.range[0])} *`;
- if (!/^\*?\s*$/.test(lines[0])) {
+ if (!/^\*?\s*$/u.test(lines[0])) {
const start = block.value.startsWith("*") ? block.range[0] + 1 : block.range[0];
context.report({
@@ -156,7 +156,7 @@
});
}
- if (!/^\s*$/.test(lines[lines.length - 1])) {
+ if (!/^\s*$/u.test(lines[lines.length - 1])) {
context.report({
loc: {
start: { line: block.loc.end.line, column: block.loc.end.column - 2 },
@@ -176,12 +176,12 @@
start: { line: lineNumber, column: 0 },
end: { line: lineNumber, column: sourceCode.lines[lineNumber - 1].length }
},
- messageId: /^\s*\*/.test(lineText)
+ messageId: /^\s*\*/u.test(lineText)
? "alignment"
: "missingStar",
fix(fixer) {
const lineStartIndex = sourceCode.getIndexFromLoc({ line: lineNumber, column: 0 });
- const linePrefixLength = lineText.match(/^\s*\*? ?/)[0].length;
+ const linePrefixLength = lineText.match(/^\s*\*? ?/u)[0].length;
const commentStartIndex = lineStartIndex + linePrefixLength;
const replacementText = lineNumber === block.loc.end.line || lineText.length === linePrefixLength
@@ -244,7 +244,7 @@
const block = commentGroup[0];
const lines = block.value.split(astUtils.LINEBREAK_MATCHER).filter(line => line.trim());
- if (lines.length > 0 && lines.every(line => /^\s*\*/.test(line))) {
+ if (lines.length > 0 && lines.every(line => /^\s*\*/u.test(line))) {
context.report({
loc: {
start: block.loc.start,

lib/rules/new-cap.js

@@ -136,10 +136,10 @@
const skipProperties = config.properties === false;
const newIsCapExceptions = checkArray(config, "newIsCapExceptions", []).reduce(invert, {});
- const newIsCapExceptionPattern = config.newIsCapExceptionPattern ? new RegExp(config.newIsCapExceptionPattern) : null;
+ const newIsCapExceptionPattern = config.newIsCapExceptionPattern ? new RegExp(config.newIsCapExceptionPattern) : null; // eslint-disable-line require-unicode-regexp
const capIsNewExceptions = calculateCapIsNewExceptions(config);
- const capIsNewExceptionPattern = config.capIsNewExceptionPattern ? new RegExp(config.capIsNewExceptionPattern) : null;
+ const capIsNewExceptionPattern = config.capIsNewExceptionPattern ? new RegExp(config.capIsNewExceptionPattern) : null; // eslint-disable-line require-unicode-regexp
const listeners = {};

lib/rules/no-alert.js

@@ -20,7 +20,7 @@
* @returns {boolean} Whether or not the name is prohibited.
*/
function isProhibitedIdentifier(name) {
- return /^(alert|confirm|prompt)$/.test(name);
+ return /^(alert|confirm|prompt)$/u.test(name);
}
/**

lib/rules/no-caller.js

@@ -35,7 +35,7 @@
const objectName = node.object.name,
propertyName = node.property.name;
- if (objectName === "arguments" && !node.computed && propertyName && propertyName.match(/^calle[er]$/)) {
+ if (objectName === "arguments" && !node.computed && propertyName && propertyName.match(/^calle[er]$/u)) {
context.report({ node, messageId: "unexpected", data: { prop: propertyName } });
}

lib/rules/no-dupe-keys.js

@@ -15,8 +15,8 @@
// Helpers
//------------------------------------------------------------------------------
-const GET_KIND = /^(?:init|get)$/;
-const SET_KIND = /^(?:init|set)$/;
+const GET_KIND = /^(?:init|get)$/u;
+const SET_KIND = /^(?:init|set)$/u;
/**
* The class which stores properties' information of an object.

lib/rules/no-else-return.js

@@ -82,7 +82,7 @@
* after the if block
*/
const ifBlockMaybeUnsafe = node.parent.consequent.type !== "BlockStatement" && lastIfToken.value !== ";";
- const elseBlockUnsafe = /^[([/+`-]/.test(firstTokenOfElseBlock.value);
+ const elseBlockUnsafe = /^[([/+`-]/u.test(firstTokenOfElseBlock.value);
if (ifBlockMaybeUnsafe && elseBlockUnsafe) {
return null;
@@ -94,7 +94,7 @@
if (lastTokenOfElseBlock.value !== ";") {
const nextToken = sourceCode.getTokenAfter(endToken);
- const nextTokenUnsafe = nextToken && /^[([/+`-]/.test(nextToken.value);
+ const nextTokenUnsafe = nextToken && /^[([/+`-]/u.test(nextToken.value);
const nextTokenOnSameLine = nextToken && nextToken.loc.start.line === lastTokenOfElseBlock.loc.start.line;
/*

lib/rules/no-empty-character-class.js

@@ -21,7 +21,7 @@
* 4. `[gimuy]*`: optional regexp flags
* 5. `$`: fix the match at the end of the string
*/
-const regex = /^\/([^\\[]|\\.|\[([^\\\]]|\\.)+])*\/[gimuys]*$/;
+const regex = /^\/([^\\[]|\\.|\[([^\\\]]|\\.)+\])*\/[gimuys]*$/u;
//------------------------------------------------------------------------------
// Rule Definition

lib/rules/no-extra-parens.js

@@ -44,11 +44,11 @@
{
type: "object",
properties: {
- conditionalAssign: { type: "boolean", default: true },
- nestedBinaryExpressions: { type: "boolean", default: true },
- returnAssign: { type: "boolean", default: true },
+ conditionalAssign: { type: "boolean" },
+ nestedBinaryExpressions: { type: "boolean" },
+ returnAssign: { type: "boolean" },
ignoreJSX: { enum: ["none", "all", "single-line", "multi-line"] },
- enforceForArrowConditionals: { type: "boolean", default: true }
+ enforceForArrowConditionals: { type: "boolean" }
},
additionalProperties: false
}
@@ -471,6 +471,7 @@
const firstToken = isParenthesised(node) ? sourceCode.getTokenBefore(node) : sourceCode.getFirstToken(node);
const secondToken = sourceCode.getTokenAfter(firstToken, astUtils.isNotOpeningParenToken);
const thirdToken = secondToken ? sourceCode.getTokenAfter(secondToken) : null;
+ const tokenAfterClosingParens = secondToken ? sourceCode.getTokenAfter(secondToken, astUtils.isNotClosingParenToken) : null;
if (
astUtils.isOpeningParenToken(firstToken) &&
@@ -479,7 +480,12 @@
secondToken.type === "Keyword" && (
secondToken.value === "function" ||
secondToken.value === "class" ||
- secondToken.value === "let" && astUtils.isOpeningBracketToken(sourceCode.getTokenAfter(secondToken, astUtils.isNotClosingParenToken))
+ secondToken.value === "let" &&
+ tokenAfterClosingParens &&
+ (
+ astUtils.isOpeningBracketToken(tokenAfterClosingParens) ||
+ tokenAfterClosingParens.type === "Identifier"
+ )
) ||
secondToken && secondToken.type === "Identifier" && secondToken.value === "async" && thirdToken && thirdToken.type === "Keyword" && thirdToken.value === "function"
)

lib/rules/no-fallthrough.js

@@ -14,7 +14,7 @@
// Helpers
//------------------------------------------------------------------------------
-const DEFAULT_FALLTHROUGH_COMMENT = /falls?\s?through/i;
+const DEFAULT_FALLTHROUGH_COMMENT = /falls?\s?through/iu;
/**
* Checks whether or not a given node has a fallthrough comment.
@@ -95,7 +95,7 @@
let fallthroughCommentPattern = null;
if (options.commentPattern) {
- fallthroughCommentPattern = new RegExp(options.commentPattern);
+ fallthroughCommentPattern = new RegExp(options.commentPattern); // eslint-disable-line require-unicode-regexp
} else {
fallthroughCommentPattern = DEFAULT_FALLTHROUGH_COMMENT;
}

lib/rules/no-implicit-coercion.js

@@ -11,7 +11,7 @@
// Helpers
//------------------------------------------------------------------------------
-const INDEX_OF_PATTERN = /^(?:i|lastI)ndexOf$/;
+const INDEX_OF_PATTERN = /^(?:i|lastI)ndexOf$/u;
const ALLOWABLE_OPERATORS = ["~", "!!", "+", "*"];
/**

lib/rules/no-implied-eval.js

@@ -24,7 +24,7 @@
},
create(context) {
- const CALLEE_RE = /^(setTimeout|setInterval|execScript)$/;
+ const CALLEE_RE = /^(setTimeout|setInterval|execScript)$/u;
/*
* Figures out if we should inspect a given binary expression. Is a stack

lib/rules/no-invalid-regexp.js

@@ -10,7 +10,7 @@
const RegExpValidator = require("regexpp").RegExpValidator;
const validator = new RegExpValidator({ ecmaVersion: 2018 });
-const validFlags = /[gimuys]/g;
+const validFlags = /[gimuys]/gu;
const undefined1 = void 0;
//------------------------------------------------------------------------------
@@ -51,7 +51,7 @@
const temp = options.allowConstructorFlags.join("").replace(validFlags, "");
if (temp) {
- allowedFlags = new RegExp(`[${temp}]`, "gi");
+ allowedFlags = new RegExp(`[${temp}]`, "giu");
}
}

lib/rules/no-irregular-whitespace.js

@@ -16,9 +16,9 @@
// Constants
//------------------------------------------------------------------------------
-const ALL_IRREGULARS = /[\f\v\u0085\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000\u2028\u2029]/;
-const IRREGULAR_WHITESPACE = /[\f\v\u0085\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000]+/mg;
-const IRREGULAR_LINE_TERMINATORS = /[\u2028\u2029]/mg;
+const ALL_IRREGULARS = /[\f\v\u0085\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000\u2028\u2029]/u;
+const IRREGULAR_WHITESPACE = /[\f\v\u0085\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000]+/mgu;
+const IRREGULAR_LINE_TERMINATORS = /[\u2028\u2029]/mgu;
const LINE_BREAK = astUtils.createGlobalLinebreakMatcher();
//------------------------------------------------------------------------------

lib/rules/no-lonely-if.js

@@ -58,7 +58,7 @@
node.consequent.type !== "BlockStatement" && lastIfToken.value !== ";" && tokenAfterElseBlock &&
(
node.consequent.loc.end.line === tokenAfterElseBlock.loc.start.line ||
- /^[([/+`-]/.test(tokenAfterElseBlock.value) ||
+ /^[([/+`-]/u.test(tokenAfterElseBlock.value) ||
lastIfToken.value === "++" ||
lastIfToken.value === "--"
)

lib/rules/no-mixed-operators.js

@@ -34,7 +34,7 @@
LOGICAL_OPERATORS,
RELATIONAL_OPERATORS
];
-const TARGET_NODE_TYPE = /^(?:Binary|Logical)Expression$/;
+const TARGET_NODE_TYPE = /^(?:Binary|Logical)Expression$/u;
/**
* Normalizes options.

lib/rules/no-mixed-requires.js

@@ -30,12 +30,10 @@
type: "object",
properties: {
grouping: {
- type: "boolean",
- default: false
+ type: "boolean"
},
allowCall: {
- type: "boolean",
- default: false
+ type: "boolean"
}
},
additionalProperties: false
@@ -158,7 +156,7 @@
// "var fs = require('fs');"
return REQ_CORE;
}
- if (/^\.{0,2}\//.test(arg.value)) {
+ if (/^\.{0,2}\//u.test(arg.value)) {
// "var utils = require('./utils');"
return REQ_FILE;

lib/rules/no-mixed-spaces-and-tabs.js

@@ -88,7 +88,7 @@
* or the reverse before non-tab/-space
* characters begin.
*/
- let regex = /^(?=[\t ]*(\t | \t))/;
+ let regex = /^(?=[\t ]*(\t | \t))/u;
const lines = sourceCode.lines,
comments = sourceCode.getAllComments();
@@ -114,7 +114,7 @@
* At least one space followed by a tab
* before non-tab/-space characters begin.
*/
- regex = /^(?=[\t ]* \t)/;
+ regex = /^(?=[\t ]* \t)/u;
}
lines.forEach((line, i) => {

lib/rules/no-octal-escape.js

@@ -32,7 +32,7 @@
return;
}
- const match = node.raw.match(/^([^\\]|\\[^0-7])*\\([0-3][0-7]{1,2}|[4-7][0-7]|[0-7])/);
+ const match = node.raw.match(/^([^\\]|\\[^0-7])*\\([0-3][0-7]{1,2}|[4-7][0-7]|[0-7])/u);
if (match) {
const octalDigit = match[2];

lib/rules/no-octal.js

@@ -28,7 +28,7 @@
return {
Literal(node) {
- if (typeof node.value === "number" && /^0[0-7]/.test(node.raw)) {
+ if (typeof node.value === "number" && /^0[0-7]/u.test(node.raw)) {
context.report({ node, message: "Octal literals should not be used." });
}
}

lib/rules/no-param-reassign.js

@@ -8,7 +8,7 @@
// Rule Definition
//------------------------------------------------------------------------------
-const stopNodePattern = /(?:Statement|Declaration|Function(?:Expression)?|Program)$/;
+const stopNodePattern = /(?:Statement|Declaration|Function(?:Expression)?|Program)$/u;
module.exports = {
meta: {

lib/rules/no-path-concat.js

@@ -24,7 +24,7 @@
create(context) {
- const MATCHER = /^__(?:dir|file)name$/;
+ const MATCHER = /^__(?:dir|file)name$/u;
//--------------------------------------------------------------------------
// Public

lib/rules/no-regex-spaces.js

@@ -39,7 +39,7 @@
* @private
*/
function checkRegex(node, value, valueStart) {
- const multipleSpacesRegex = /( {2,})( [+*{?]|[^+*{?]|$)/,
+ const multipleSpacesRegex = /( {2,})( [+*{?]|[^+*{?]|$)/u,
regexResults = multipleSpacesRegex.exec(value);
if (regexResults !== null) {

lib/rules/no-return-assign.js

@@ -14,7 +14,7 @@
// Helpers
//------------------------------------------------------------------------------
-const SENTINEL_TYPE = /^(?:[a-zA-Z]+?Statement|ArrowFunctionExpression|FunctionExpression|ClassExpression)$/;
+const SENTINEL_TYPE = /^(?:[a-zA-Z]+?Statement|ArrowFunctionExpression|FunctionExpression|ClassExpression)$/u;
//------------------------------------------------------------------------------
// Rule Definition

lib/rules/no-self-assign.js

@@ -15,7 +15,7 @@
// Helpers
//------------------------------------------------------------------------------
-const SPACES = /\s+/g;
+const SPACES = /\s+/gu;
/**
* Checks whether the property of 2 given member expression nodes are the same

lib/rules/no-tabs.js

@@ -9,8 +9,8 @@
// Helpers
//------------------------------------------------------------------------------
-const tabRegex = /\t+/g;
-const anyNonWhitespaceRegex = /\S/;
+const tabRegex = /\t+/gu;
+const anyNonWhitespaceRegex = /\S/u;
//------------------------------------------------------------------------------
// Public Interface

lib/rules/no-template-curly-in-string.js

@@ -23,7 +23,7 @@
},
create(context) {
- const regex = /\$\{[^}]+\}/;
+ const regex = /\$\{[^}]+\}/u;
return {
Literal(node) {

lib/rules/no-trailing-spaces.js

@@ -111,8 +111,8 @@
* fetch the source code and do matching via regexps.
*/
- const re = new RegExp(NONBLANK),
- skipMatch = new RegExp(SKIP_BLANK),
+ const re = new RegExp(NONBLANK, "u"),
+ skipMatch = new RegExp(SKIP_BLANK, "u"),
lines = sourceCode.lines,
linebreaks = sourceCode.getText().match(astUtils.createGlobalLinebreakMatcher()),
comments = sourceCode.getAllComments(),

lib/rules/no-unexpected-multiline.js

@@ -36,7 +36,7 @@
create(context) {
- const REGEX_FLAG_MATCHER = /^[gimsuy]+$/;
+ const REGEX_FLAG_MATCHER = /^[gimsuy]+$/u;
const sourceCode = context.getSourceCode();

lib/rules/no-unmodified-loop-condition.js

@@ -16,11 +16,11 @@
// Helpers
//------------------------------------------------------------------------------
-const SENTINEL_PATTERN = /(?:(?:Call|Class|Function|Member|New|Yield)Expression|Statement|Declaration)$/;
-const LOOP_PATTERN = /^(?:DoWhile|For|While)Statement$/; // for-in/of statements don't have `test` property.
-const GROUP_PATTERN = /^(?:BinaryExpression|ConditionalExpression)$/;
-const SKIP_PATTERN = /^(?:ArrowFunction|Class|Function)Expression$/;
-const DYNAMIC_PATTERN = /^(?:Call|Member|New|TaggedTemplate|Yield)Expression$/;
+const SENTINEL_PATTERN = /(?:(?:Call|Class|Function|Member|New|Yield)Expression|Statement|Declaration)$/u;
+const LOOP_PATTERN = /^(?:DoWhile|For|While)Statement$/u; // for-in/of statements don't have `test` property.
+const GROUP_PATTERN = /^(?:BinaryExpression|ConditionalExpression)$/u;
+const SKIP_PATTERN = /^(?:ArrowFunction|Class|Function)Expression$/u;
+const DYNAMIC_PATTERN = /^(?:Call|Member|New|TaggedTemplate|Yield)Expression$/u;
/**
* @typedef {Object} LoopConditionInfo

lib/rules/no-unsafe-finally.js

@@ -9,9 +9,9 @@
// Helpers
//------------------------------------------------------------------------------
-const SENTINEL_NODE_TYPE_RETURN_THROW = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression)$/;
-const SENTINEL_NODE_TYPE_BREAK = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement|SwitchStatement)$/;
-const SENTINEL_NODE_TYPE_CONTINUE = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement)$/;
+const SENTINEL_NODE_TYPE_RETURN_THROW = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression)$/u;
+const SENTINEL_NODE_TYPE_BREAK = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement|SwitchStatement)$/u;
+const SENTINEL_NODE_TYPE_CONTINUE = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement)$/u;
//------------------------------------------------------------------------------

lib/rules/no-unused-expressions.js

@@ -88,7 +88,7 @@
grandparent = ancestors[ancestors.length - 2];
return (parent.type === "Program" || parent.type === "BlockStatement" &&
- (/Function/.test(grandparent.type))) &&
+ (/Function/u.test(grandparent.type))) &&
directives(parent).indexOf(node) >= 0;
}
@@ -116,7 +116,7 @@
return true;
}
- return /^(?:Assignment|Call|New|Update|Yield|Await)Expression$/.test(node.type) ||
+ return /^(?:Assignment|Call|New|Update|Yield|Await)Expression$/u.test(node.type) ||
(node.type === "UnaryExpression" && ["delete", "void"].indexOf(node.operator) >= 0);
}

lib/rules/no-unused-vars.js

@@ -37,26 +37,22 @@
type: "object",
properties: {
vars: {
- enum: ["all", "local"],
- default: "all"
+ enum: ["all", "local"]
},
varsIgnorePattern: {
type: "string"
},
args: {
- enum: ["all", "after-used", "none"],
- default: "after-used"
+ enum: ["all", "after-used", "none"]
},
ignoreRestSiblings: {
- type: "boolean",
- default: false
+ type: "boolean"
},
argsIgnorePattern: {
type: "string"
},
caughtErrors: {
- enum: ["all", "none"],
- default: "none"
+ enum: ["all", "none"]
},
caughtErrorsIgnorePattern: {
type: "string"
@@ -71,7 +67,7 @@
create(context) {
const sourceCode = context.getSourceCode();
- const REST_PROPERTY_TYPE = /^(?:RestElement|(?:Experimental)?RestProperty)$/;
+ const REST_PROPERTY_TYPE = /^(?:RestElement|(?:Experimental)?RestProperty)$/u;
const config = {
vars: "all",
@@ -92,15 +88,15 @@
config.caughtErrors = firstOption.caughtErrors || config.caughtErrors;
if (firstOption.varsIgnorePattern) {
- config.varsIgnorePattern = new RegExp(firstOption.varsIgnorePattern);
+ config.varsIgnorePattern = new RegExp(firstOption.varsIgnorePattern); // eslint-disable-line require-unicode-regexp
}
if (firstOption.argsIgnorePattern) {
- config.argsIgnorePattern = new RegExp(firstOption.argsIgnorePattern);
+ config.argsIgnorePattern = new RegExp(firstOption.argsIgnorePattern); // eslint-disable-line require-unicode-regexp
}
if (firstOption.caughtErrorsIgnorePattern) {
- config.caughtErrorsIgnorePattern = new RegExp(firstOption.caughtErrorsIgnorePattern);
+ config.caughtErrorsIgnorePattern = new RegExp(firstOption.caughtErrorsIgnorePattern); // eslint-disable-line require-unicode-regexp
}
}
}
@@ -147,7 +143,7 @@
// Helpers
//--------------------------------------------------------------------------
- const STATEMENT_TYPE = /(?:Statement|Declaration)$/;
+ const STATEMENT_TYPE = /(?:Statement|Declaration)$/u;
/**
* Determines if a given variable is being exported from a module.
@@ -600,7 +596,7 @@
* @private
*/
function getColumnInComment(variable, comment) {
- const namePattern = new RegExp(`[\\s,]${lodash.escapeRegExp(variable.name)}(?:$|[\\s,:])`, "g");
+ const namePattern = new RegExp(`[\\s,]${lodash.escapeRegExp(variable.name)}(?:$|[\\s,:])`, "gu");
// To ignore the first text "global".
namePattern.lastIndex = comment.value.indexOf("global") + 6;

lib/rules/no-use-before-define.js

@@ -9,8 +9,8 @@
// Helpers
//------------------------------------------------------------------------------
-const SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/;
-const FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/;
+const SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/u;
+const FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/u;
/**
* Parses a given value as options.
@@ -154,9 +154,9 @@
{
type: "object",
properties: {
- functions: { type: "boolean", default: true },
- classes: { type: "boolean", default: true },
- variables: { type: "boolean", default: true }
+ functions: { type: "boolean" },
+ classes: { type: "boolean" },
+ variables: { type: "boolean" }
},
additionalProperties: false
}

lib/rules/no-useless-escape.js

@@ -181,7 +181,7 @@
}
const value = isTemplateElement ? node.value.raw : node.raw.slice(1, -1);
- const pattern = /\\[^\d]/g;
+ const pattern = /\\[^\d]/gu;
let match;
while ((match = pattern.exec(value))) {

lib/rules/no-var.js

@@ -77,7 +77,7 @@
return node.declarations.every(declarator => declarator.init !== null);
}
-const SCOPE_NODE_TYPE = /^(?:Program|BlockStatement|SwitchStatement|ForStatement|ForInStatement|ForOfStatement)$/;
+const SCOPE_NODE_TYPE = /^(?:Program|BlockStatement|SwitchStatement|ForStatement|ForInStatement|ForOfStatement)$/u;
/**
* Gets the scope node which directly contains a given node.

lib/rules/no-warning-comments.js

@@ -47,7 +47,7 @@
configuration = context.options[0] || {},
warningTerms = configuration.terms || ["todo", "fixme", "xxx"],
location = configuration.location || "start",
- selfConfigRegEx = /\bno-warning-comments\b/;
+ selfConfigRegEx = /\bno-warning-comments\b/u;
/**
* Convert a warning term into a RegExp which will match a comment containing that whole word in the specified
@@ -58,7 +58,7 @@
* @returns {RegExp} The term converted to a RegExp
*/
function convertToRegExp(term) {
- const escaped = term.replace(/[-/\\$^*+?.()|[\]{}]/g, "\\$&");
+ const escaped = term.replace(/[-/\\$^*+?.()|[\]{}]/gu, "\\$&");
const wordBoundary = "\\b";
const eitherOrWordBoundary = `|${wordBoundary}`;
let prefix;
@@ -73,7 +73,7 @@
* In these cases, use no bounding match. Same applies for the
* prefix, handled below.
*/
- const suffix = /\w$/.test(term) ? "\\b" : "";
+ const suffix = /\w$/u.test(term) ? "\\b" : "";
if (location === "start") {
@@ -82,7 +82,7 @@
* there's no need to worry about word boundaries.
*/
prefix = "^\\s*";
- } else if (/^\w/.test(term)) {
+ } else if (/^\w/u.test(term)) {
prefix = wordBoundary;
} else {
prefix = "";
@@ -95,7 +95,7 @@
* ^\s*TERM\b. This checks the word boundary
* at the beginning of the comment.
*/
- return new RegExp(prefix + escaped + suffix, "i");
+ return new RegExp(prefix + escaped + suffix, "i"); // eslint-disable-line require-unicode-regexp
}
/*
@@ -103,7 +103,7 @@
* \bTERM\b|\bTERM\b, this checks the entire comment
* for the term.
*/
- return new RegExp(prefix + escaped + suffix + eitherOrWordBoundary + term + wordBoundary, "i");
+ return new RegExp(prefix + escaped + suffix + eitherOrWordBoundary + term + wordBoundary, "i"); // eslint-disable-line require-unicode-regexp
}
const warningRegExps = warningTerms.map(convertToRegExp);

lib/rules/object-curly-newline.js

@@ -26,16 +26,14 @@
type: "object",
properties: {
multiline: {
- type: "boolean",
- default: false
+ type: "boolean"
},
minProperties: {
type: "integer",
minimum: 0
},
consistent: {
- type: "boolean",
- default: false
+ type: "boolean"
}
},
additionalProperties: false,
@@ -61,9 +59,9 @@
} else if (value === "never") {
minProperties = Number.POSITIVE_INFINITY;
} else {
- multiline = value.multiline;
+ multiline = Boolean(value.multiline);
minProperties = value.minProperties || Number.POSITIVE_INFINITY;
- consistent = value.consistent;
+ consistent = Boolean(value.consistent);
}
} else {
consistent = true;

lib/rules/object-shorthand.js

@@ -57,8 +57,7 @@
type: "object",
properties: {
avoidQuotes: {
- type: "boolean",
- default: false
+ type: "boolean"
}
},
additionalProperties: false
@@ -77,16 +76,13 @@
type: "object",
properties: {
ignoreConstructors: {
- type: "boolean",
- default: false
+ type: "boolean"
},
avoidQuotes: {
- type: "boolean",
- default: false
+ type: "boolean"
},
avoidExplicitReturnArrows: {
- type: "boolean",
- default: false
+ type: "boolean"
}
},
additionalProperties: false

lib/rules/one-var.js

@@ -36,16 +36,13 @@
default: false
},
var: {
- enum: ["always", "never", "consecutive"],
- default: "always"
+ enum: ["always", "never", "consecutive"]
},
let: {
- enum: ["always", "never", "consecutive"],
- default: "always"
+ enum: ["always", "never", "consecutive"]
},
const: {
- enum: ["always", "never", "consecutive"],
- default: "always"
+ enum: ["always", "never", "consecutive"]
}
},
additionalProperties: false

lib/rules/padding-line-between-statements.js

@@ -17,10 +17,11 @@
const LT = `[${Array.from(astUtils.LINEBREAKS).join("")}]`;
const PADDING_LINE_SEQUENCE = new RegExp(
- String.raw`^(\s*?${LT})\s*${LT}(\s*;?)$`
+ String.raw`^(\s*?${LT})\s*${LT}(\s*;?)$`,
+ "u"
);
-const CJS_EXPORT = /^(?:module\s*\.\s*)?exports(?:\s*\.|\s*\[|$)/;
-const CJS_IMPORT = /^require\(/;
+const CJS_EXPORT = /^(?:module\s*\.\s*)?exports(?:\s*\.|\s*\[|$)/u;
+const CJS_IMPORT = /^require\(/u;
/**
* Creates tester which check if a node starts with specific keyword.

lib/rules/prefer-const.js

@@ -11,9 +11,9 @@
// Helpers
//------------------------------------------------------------------------------
-const PATTERN_TYPE = /^(?:.+?Pattern|RestElement|SpreadProperty|ExperimentalRestProperty|Property)$/;
-const DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|SwitchCase)$/;
-const DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)$/;
+const PATTERN_TYPE = /^(?:.+?Pattern|RestElement|SpreadProperty|ExperimentalRestProperty|Property)$/u;
+const DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|SwitchCase)$/u;
+const DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)$/u;
/**
* Checks whether a given node is located at `ForStatement.init` or not.

lib/rules/prefer-destructuring.js

@@ -36,12 +36,10 @@
type: "object",
properties: {
array: {
- type: "boolean",
- default: true
+ type: "boolean"
},
object: {
- type: "boolean",
- default: true
+ type: "boolean"
}
},
additionalProperties: false
@@ -50,12 +48,10 @@
type: "object",
properties: {
array: {
- type: "boolean",
- default: true
+ type: "boolean"
},
object: {
- type: "boolean",
- default: true
+ type: "boolean"
}
},
additionalProperties: false
@@ -67,12 +63,10 @@
type: "object",
properties: {
array: {
- type: "boolean",
- default: true
+ type: "boolean"
},
object: {
- type: "boolean",
- default: true
+ type: "boolean"
}
},
additionalProperties: false
@@ -83,8 +77,7 @@
type: "object",
properties: {
enforceForRenamedProperties: {
- type: "boolean",
- default: false
+ type: "boolean"
}
},
additionalProperties: false

lib/rules/prefer-named-capture-group.js

@@ -0,0 +1,123 @@
+/**
+ * @fileoverview Rule to enforce requiring named capture groups in regular expression.
+ * @author Pig Fang <https://github.com/g-plane>
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const {
+ CALL,
+ CONSTRUCT,
+ ReferenceTracker,
+ getStringIfConstant
+} = require("eslint-utils");
+const regexpp = require("regexpp");
+
+//------------------------------------------------------------------------------
+// Helpers
+//------------------------------------------------------------------------------
+
+const parser = new regexpp.RegExpParser();
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = {
+ meta: {
+ type: "suggestion",
+
+ docs: {
+ description: "enforce using named capture group in regular expression",
+ category: "Best Practices",
+ recommended: false,
+ url: "https://eslint.org/docs/rules/prefer-named-capture-group"
+ },
+
+ schema: [],
+
+ messages: {
+ required: "Capture group '{{group}}' should be converted to a named or non-capturing group."
+ }
+ },
+
+ create(context) {
+
+ /**
+ * Function to check regular expression.
+ *
+ * @param {string} regex The regular expression to be check.
+ * @param {ASTNode} node AST node which contains regular expression.
+ * @param {boolean} uFlag Flag indicates whether unicode mode is enabled or not.
+ * @returns {void}
+ */
+ function checkRegex(regex, node, uFlag) {
+ let ast;
+
+ try {
+ ast = parser.parsePattern(regex, 0, regex.length, uFlag);
+ } catch (_) {
+
+ // ignore regex syntax errors
+ return;
+ }
+
+ regexpp.visitRegExpAST(ast, {
+ onCapturingGroupEnter(group) {
+ if (!group.name) {
+ const locNode = node.type === "Literal" ? node : node.arguments[0];
+
+ context.report({
+ node,
+ messageId: "required",
+ loc: {
+ start: {
+ line: locNode.loc.start.line,
+ column: locNode.loc.start.column + group.start + 1
+ },
+ end: {
+ line: locNode.loc.start.line,
+ column: locNode.loc.start.column + group.end + 1
+ }
+ },
+ data: {
+ group: group.raw
+ }
+ });
+ }
+ }
+ });
+ }
+
+ return {
+ Literal(node) {
+ if (node.regex) {
+ checkRegex(node.regex.pattern, node, node.regex.flags.includes("u"));
+ }
+ },
+ Program() {
+ const scope = context.getScope();
+ const tracker = new ReferenceTracker(scope);
+ const traceMap = {
+ RegExp: {
+ [CALL]: true,
+ [CONSTRUCT]: true
+ }
+ };
+
+ for (const { node } of tracker.iterateGlobalReferences(traceMap)) {
+ const regex = getStringIfConstant(node.arguments[0]);
+ const flags = getStringIfConstant(node.arguments[1]);
+
+ if (regex) {
+ checkRegex(regex, node, flags && flags.includes("u"));
+ }
+ }
+ }
+ };
+ }
+};

lib/rules/prefer-object-spread.js

@@ -14,7 +14,7 @@
isParenthesised
} = require("../util/ast-utils");
-const ANY_SPACE = /\s/;
+const ANY_SPACE = /\s/u;
/**
* Helper that checks if the Object.assign call has array spread

lib/rules/prefer-template.js

@@ -52,7 +52,7 @@
return false;
}
- const match = node.raw.match(/^([^\\]|\\[^0-7])*\\([0-7]{1,3})/);
+ const match = node.raw.match(/^([^\\]|\\[^0-7])*\\([0-7]{1,3})/u);
if (match) {
@@ -187,14 +187,14 @@
* for some reason, don't add another backslash, because that would change the meaning of the code (it would cause
* an actual backslash character to appear before the dollar sign).
*/
- return `\`${currentNode.raw.slice(1, -1).replace(/\\*(\${|`)/g, matched => {
+ return `\`${currentNode.raw.slice(1, -1).replace(/\\*(\$\{|`)/gu, matched => {
if (matched.lastIndexOf("\\") % 2) {
return `\\${matched}`;
}
return matched;
// Unescape any quotes that appear in the original Literal that no longer need to be escaped.
- }).replace(new RegExp(`\\\\${currentNode.raw[0]}`, "g"), currentNode.raw[0])}\``;
+ }).replace(new RegExp(`\\\\${currentNode.raw[0]}`, "gu"), currentNode.raw[0])}\``;
}
if (currentNode.type === "TemplateLiteral") {

lib/rules/quote-props.js

@@ -32,8 +32,7 @@
type: "array",
items: [
{
- enum: ["always", "as-needed", "consistent", "consistent-as-needed"],
- default: "always"
+ enum: ["always", "as-needed", "consistent", "consistent-as-needed"]
}
],
minItems: 0,
@@ -43,23 +42,19 @@
type: "array",
items: [
{
- enum: ["always", "as-needed", "consistent", "consistent-as-needed"],
- default: "always"
+ enum: ["always", "as-needed", "consistent", "consistent-as-needed"]
},
{
type: "object",
properties: {
keywords: {
- type: "boolean",
- default: false
+ type: "boolean"
},
unnecessary: {
- type: "boolean",
- default: true
+ type: "boolean"
},
numbers: {
- type: "boolean",
- default: false
+ type: "boolean"
}
},
additionalProperties: false

lib/rules/quotes.js

@@ -34,7 +34,7 @@
};
// An unescaped newline is a newline preceded by an even number of backslashes.
-const UNESCAPED_LINEBREAK_PATTERN = new RegExp(String.raw`(^|[^\\])(\\\\)*[${Array.from(astUtils.LINEBREAKS).join("")}]`);
+const UNESCAPED_LINEBREAK_PATTERN = new RegExp(String.raw`(^|[^\\])(\\\\)*[${Array.from(astUtils.LINEBREAKS).join("")}]`, "u");
/**
* Switches quoting of javascript string between ' " and `
@@ -54,7 +54,7 @@
if (newQuote === oldQuote) {
return str;
}
- return newQuote + str.slice(1, -1).replace(/\\(\${|\r\n?|\n|.)|["'`]|\${|(\r\n?|\n)/g, (match, escaped, newline) => {
+ return newQuote + str.slice(1, -1).replace(/\\(\$\{|\r\n?|\n|.)|["'`]|\$\{|(\r\n?|\n)/gu, (match, escaped, newline) => {
if (escaped === oldQuote || oldQuote === "`" && escaped === "${") {
return escaped; // unescape
}
@@ -100,12 +100,10 @@
type: "object",
properties: {
avoidEscape: {
- type: "boolean",
- default: false
+ type: "boolean"
},
allowTemplateLiterals: {
- type: "boolean",
- default: false
+ type: "boolean"
}
},
additionalProperties: false

lib/rules/semi.js

@@ -40,8 +40,7 @@
type: "object",
properties: {
beforeStatementContinuationChars: {
- enum: ["always", "any", "never"],
- default: "any"
+ enum: ["always", "any", "never"]
}
},
additionalProperties: false
@@ -59,7 +58,7 @@
{
type: "object",
properties: {
- omitLastInOneLineBlock: { type: "boolean", default: false }
+ omitLastInOneLineBlock: { type: "boolean" }
},
additionalProperties: false
}
@@ -73,11 +72,11 @@
create(context) {
- const OPT_OUT_PATTERN = /^[-[(/+`]/; // One of [(/+-`
+ const OPT_OUT_PATTERN = /^[-[(/+`]/u; // One of [(/+-`
const options = context.options[1];
const never = context.options[0] === "never";
- const exceptOneLine = options && options.omitLastInOneLineBlock;
- const beforeStatementContinuationChars = options && options.beforeStatementContinuationChars;
+ const exceptOneLine = Boolean(options && options.omitLastInOneLineBlock);
+ const beforeStatementContinuationChars = options && options.beforeStatementContinuationChars || "any";
const sourceCode = context.getSourceCode();
//--------------------------------------------------------------------------
@@ -292,7 +291,7 @@
const parent = node.parent;
if ((parent.type !== "ForStatement" || parent.init !== node) &&
- (!/^For(?:In|Of)Statement/.test(parent.type) || parent.left !== node)
+ (!/^For(?:In|Of)Statement/u.test(parent.type) || parent.left !== node)
) {
checkForSemicolon(node);
}
@@ -319,7 +318,7 @@
}
},
ExportDefaultDeclaration(node) {
- if (!/(?:Class|Function)Declaration/.test(node.declaration.type)) {
+ if (!/(?:Class|Function)Declaration/u.test(node.declaration.type)) {
checkForSemicolon(node);
}
}

lib/rules/space-before-function-paren.js

@@ -37,16 +37,13 @@
type: "object",
properties: {
anonymous: {
- enum: ["always", "never", "ignore"],
- default: "always"
+ enum: ["always", "never", "ignore"]
},
named: {
- enum: ["always", "never", "ignore"],
- default: "always"
+ enum: ["always", "never", "ignore"]
},
asyncArrow: {
- enum: ["always", "never", "ignore"],
- default: "always"
+ enum: ["always", "never", "ignore"]
}
},
additionalProperties: false

lib/rules/spaced-comment.js

@@ -126,7 +126,7 @@
pattern += "?"; // or nothing.
pattern += createExceptionsPattern(exceptions);
- return new RegExp(pattern);
+ return new RegExp(pattern); // eslint-disable-line require-unicode-regexp
}
/**
@@ -142,7 +142,7 @@
function createNeverStylePattern(markers) {
const pattern = `^(${markers.map(escape).join("|")})?[ \t]+`;
- return new RegExp(pattern);
+ return new RegExp(pattern); // eslint-disable-line require-unicode-regexp
}
//------------------------------------------------------------------------------
@@ -250,9 +250,9 @@
// Create RegExp object for valid patterns.
rule[type] = {
beginRegex: requireSpace ? createAlwaysStylePattern(markers, exceptions) : createNeverStylePattern(markers),
- endRegex: balanced && requireSpace ? new RegExp(`${createExceptionsPattern(exceptions)}$`) : new RegExp(endNeverPattern),
+ endRegex: balanced && requireSpace ? new RegExp(`${createExceptionsPattern(exceptions)}$`) : new RegExp(endNeverPattern), // eslint-disable-line require-unicode-regexp
hasExceptions: exceptions.length > 0,
- markers: new RegExp(`^(${markers.map(escape).join("|")})`)
+ markers: new RegExp(`^(${markers.map(escape).join("|")})`) // eslint-disable-line require-unicode-regexp
};
return rule;

lib/rules/template-curly-spacing.js

@@ -15,8 +15,8 @@
// Helpers
//------------------------------------------------------------------------------
-const OPEN_PAREN = /\$\{$/;
-const CLOSE_PAREN = /^\}/;
+const OPEN_PAREN = /\$\{$/u;
+const CLOSE_PAREN = /^\}/u;
//------------------------------------------------------------------------------
// Rule Definition

lib/rules/use-isnan.js

@@ -30,7 +30,7 @@
return {
BinaryExpression(node) {
- if (/^(?:[<>]|[!=]=)=?$/.test(node.operator) && (node.left.name === "NaN" || node.right.name === "NaN")) {
+ if (/^(?:[<>]|[!=]=)=?$/u.test(node.operator) && (node.left.name === "NaN" || node.right.name === "NaN")) {
context.report({ node, messageId: "useIsNaN" });
}
}

lib/rules/valid-jsdoc.js

@@ -300,7 +300,7 @@
});
} catch (ex) {
- if (/braces/i.test(ex.message)) {
+ if (/braces/iu.test(ex.message)) {
context.report({ node: jsdocNode, messageId: "missingBrace" });
} else {
context.report({ node: jsdocNode, messageId: "syntaxError" });
@@ -482,7 +482,7 @@
}
if (options.matchDescription) {
- const regex = new RegExp(options.matchDescription);
+ const regex = new RegExp(options.matchDescription); // eslint-disable-line require-unicode-regexp
if (!regex.test(jsdoc.description)) {
context.report({ node: jsdocNode, messageId: "unsatisfiedDesc" });

lib/rules/vars-on-top.js

@@ -117,7 +117,7 @@
* @returns {void}
*/
function blockScopeVarCheck(node, parent, grandParent) {
- if (!(/Function/.test(grandParent.type) &&
+ if (!(/Function/u.test(grandParent.type) &&
parent.type === "BlockStatement" &&
isVarOnTop(node, parent.body))) {
context.report({ node, messageId: "top" });

lib/rules/yield-star-spacing.js

@@ -31,8 +31,8 @@
{
type: "object",
properties: {
- before: { type: "boolean", default: false },
- after: { type: "boolean", default: true }
+ before: { type: "boolean" },
+ after: { type: "boolean" }
},
additionalProperties: false
}

lib/rules/yoda.js

@@ -20,7 +20,7 @@
* @returns {boolean} Whether or not it is a comparison operator.
*/
function isComparisonOperator(operator) {
- return (/^(==|===|!=|!==|<|>|<=|>=)$/).test(operator);
+ return (/^(==|===|!=|!==|<|>|<=|>=)$/u).test(operator);
}
/**
@@ -29,7 +29,7 @@
* @returns {boolean} Whether or not it is an equality operator.
*/
function isEqualityOperator(operator) {
- return (/^(==|===)$/).test(operator);
+ return (/^(==|===)$/u).test(operator);
}
/**

lib/testers/rule-tester.js

@@ -379,7 +379,7 @@
}
}
- validator.validate(config, "rule-tester", ruleMap.get.bind(ruleMap), new Environments());
+ validator.validate(config, ruleMap.get.bind(ruleMap), new Environments(), "rule-tester");
return {
messages: linter.verify(code, config, filename, true),

lib/util/ast-utils.js

@@ -16,19 +16,19 @@
// Helpers
//------------------------------------------------------------------------------
-const anyFunctionPattern = /^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression)$/;
-const anyLoopPattern = /^(?:DoWhile|For|ForIn|ForOf|While)Statement$/;
-const arrayOrTypedArrayPattern = /Array$/;
-const arrayMethodPattern = /^(?:every|filter|find|findIndex|forEach|map|some)$/;
-const bindOrCallOrApplyPattern = /^(?:bind|call|apply)$/;
-const breakableTypePattern = /^(?:(?:Do)?While|For(?:In|Of)?|Switch)Statement$/;
-const thisTagPattern = /^[\s*]*@this/m;
+const anyFunctionPattern = /^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression)$/u;
+const anyLoopPattern = /^(?:DoWhile|For|ForIn|ForOf|While)Statement$/u;
+const arrayOrTypedArrayPattern = /Array$/u;
+const arrayMethodPattern = /^(?:every|filter|find|findIndex|forEach|map|some)$/u;
+const bindOrCallOrApplyPattern = /^(?:bind|call|apply)$/u;
+const breakableTypePattern = /^(?:(?:Do)?While|For(?:In|Of)?|Switch)Statement$/u;
+const thisTagPattern = /^[\s*]*@this/mu;
-const COMMENTS_IGNORE_PATTERN = /^\s*(?:eslint|jshint\s+|jslint\s+|istanbul\s+|globals?\s+|exported\s+|jscs)/;
+const COMMENTS_IGNORE_PATTERN = /^\s*(?:eslint|jshint\s+|jslint\s+|istanbul\s+|globals?\s+|exported\s+|jscs)/u;
const LINEBREAKS = new Set(["\r\n", "\r", "\n", "\u2028", "\u2029"]);
-const LINEBREAK_MATCHER = /\r\n|[\r\n\u2028\u2029]/;
-const SHEBANG_MATCHER = /^#!([^\r\n]+)/;
+const LINEBREAK_MATCHER = /\r\n|[\r\n\u2028\u2029]/u;
+const SHEBANG_MATCHER = /^#!([^\r\n]+)/u;
// A set of node types that can contain a list of statements
const STATEMENT_LIST_PARENTS = new Set(["Program", "BlockStatement", "SwitchCase"]);
@@ -398,7 +398,7 @@
* @returns {RegExp} A global regular expression that matches line terminators
*/
function createGlobalLinebreakMatcher() {
- return new RegExp(LINEBREAK_MATCHER.source, "g");
+ return new RegExp(LINEBREAK_MATCHER.source, "gu");
}
/**
@@ -1006,7 +1006,7 @@
* '5' // false
*/
isDecimalInteger(node) {
- return node.type === "Literal" && typeof node.value === "number" && /^(0|[1-9]\d*)$/.test(node.raw);
+ return node.type === "Literal" && typeof node.value === "number" && /^(0|[1-9]\d*)$/u.test(node.raw);
},
/**

lib/util/config-comment-parser.js

@@ -38,9 +38,9 @@
const items = {};
// Collapse whitespace around `:` and `,` to make parsing easier
- const trimmedString = string.replace(/\s*([:,])\s*/g, "$1");
+ const trimmedString = string.replace(/\s*([:,])\s*/gu, "$1");
- trimmedString.split(/\s|,+/).forEach(name => {
+ trimmedString.split(/\s|,+/u).forEach(name => {
if (!name) {
return;
}
@@ -90,7 +90,7 @@
* But we are supporting that. So this is a fallback for that.
*/
items = {};
- const normalizedString = string.replace(/([a-zA-Z0-9\-/]+):/g, "\"$1\":").replace(/(]|[0-9])\s+(?=")/, "$1,");
+ const normalizedString = string.replace(/([a-zA-Z0-9\-/]+):/gu, "\"$1\":").replace(/(\]|[0-9])\s+(?=")/u, "$1,");
try {
items = JSON.parse(`{${normalizedString}}`);
@@ -128,7 +128,7 @@
const items = {};
// Collapse whitespace around commas
- string.replace(/\s*,\s*/g, ",").split(/,+/).forEach(name => {
+ string.replace(/\s*,\s*/gu, ",").split(/,+/u).forEach(name => {
const trimmedName = name.trim();
if (trimmedName) {

lib/util/glob-utils.js

@@ -52,7 +52,7 @@
const cwd = (options && options.cwd) || process.cwd();
let extensions = (options && options.extensions) || [".js"];
- extensions = extensions.map(ext => ext.replace(/^\./, ""));
+ extensions = extensions.map(ext => ext.replace(/^\./u, ""));
let suffix = "/**";
@@ -70,11 +70,15 @@
* @private
*/
return function(pathname) {
+ if (pathname === "") {
+ return "";
+ }
+
let newPath = pathname;
const resolvedPath = path.resolve(cwd, pathname);
if (directoryExists(resolvedPath)) {
- newPath = pathname.replace(/[/\\]$/, "") + suffix;
+ newPath = pathname.replace(/[/\\]$/u, "") + suffix;
}
return pathUtils.convertPathToPosix(newPath);
@@ -169,7 +173,7 @@
return patterns.map(processPathExtensions);
}
-const dotfilesPattern = /(?:(?:^\.)|(?:[/\\]\.))[^/\\.].*/;
+const dotfilesPattern = /(?:(?:^\.)|(?:[/\\]\.))[^/\\.].*/u;
/**
* Build a list of absolute filesnames on which ESLint will act.
@@ -201,6 +205,13 @@
debug("Creating list of files to process.");
const resolvedPathsByGlobPattern = resolvedGlobPatterns.map(pattern => {
+ if (pattern === "") {
+ return [{
+ filename: "",
+ behavior: SILENTLY_IGNORE
+ }];
+ }
+
const file = path.resolve(cwd, pattern);
if (options.globInputPaths === false || (fs.existsSync(file) && fs.statSync(file).isFile())) {
@@ -240,7 +251,7 @@
});
const allPathDescriptors = resolvedPathsByGlobPattern.reduce((pathsForAllGlobs, pathsForCurrentGlob, index) => {
- if (pathsForCurrentGlob.every(pathDescriptor => pathDescriptor.behavior === SILENTLY_IGNORE)) {
+ if (pathsForCurrentGlob.every(pathDescriptor => pathDescriptor.behavior === SILENTLY_IGNORE && pathDescriptor.filename !== "")) {
throw new (pathsForCurrentGlob.length ? AllFilesIgnoredError : NoFilesFoundError)(globPatterns[index]);
}

lib/util/ignored-paths.js

@@ -89,7 +89,7 @@
*/
const normalizePathSeps = path.sep === "/"
? (str => str)
- : ((seps, str) => str.replace(seps, "/")).bind(null, new RegExp(`\\${path.sep}`, "g"));
+ : ((seps, str) => str.replace(seps, "/")).bind(null, new RegExp(`\\${path.sep}`, "gu"));
/* eslint-enable valid-jsdoc */
/**
@@ -104,7 +104,7 @@
}
const prefix = globPattern.startsWith("!") ? "!" : "";
- const globWithoutPrefix = globPattern.replace(/^!/, "");
+ const globWithoutPrefix = globPattern.replace(/^!/u, "");
if (globWithoutPrefix.startsWith("/")) {
return `${prefix}/${normalizePathSeps(relativePathToOldBaseDir)}${globWithoutPrefix}`;
@@ -284,7 +284,7 @@
}
// If it's only Windows drive letter, it needs \
- if (/^[A-Z]:$/.test(this._baseDir)) {
+ if (/^[A-Z]:$/u.test(this._baseDir)) {
this._baseDir += "\\";
}
@@ -300,7 +300,7 @@
*/
readIgnoreFile(filePath) {
if (typeof this.cache[filePath] === "undefined") {
- this.cache[filePath] = fs.readFileSync(filePath, "utf8").split(/\r?\n/g).filter(Boolean);
+ this.cache[filePath] = fs.readFileSync(filePath, "utf8").split(/\r?\n/gu).filter(Boolean);
}
return this.cache[filePath];
}

lib/util/interpolate.js

@@ -15,7 +15,7 @@
}
// Substitution content for any {{ }} markers.
- return text.replace(/\{\{([^{}]+?)\}\}/g, (fullMatch, termWithWhitespace) => {
+ return text.replace(/\{\{([^{}]+?)\}\}/gu, (fullMatch, termWithWhitespace) => {
const term = termWithWhitespace.trim();
if (term in data) {

lib/util/naming.js

@@ -13,7 +13,7 @@
// Private
//------------------------------------------------------------------------------
-const NAMESPACE_REGEX = /^@.*\//i;
+const NAMESPACE_REGEX = /^@.*\//iu;
/**
* Brings package name to correct format based on prefix
@@ -40,8 +40,8 @@
* it's a scoped package
* package name is the prefix, or just a username
*/
- const scopedPackageShortcutRegex = new RegExp(`^(@[^/]+)(?:/(?:${prefix})?)?$`),
- scopedPackageNameRegex = new RegExp(`^${prefix}(-|$)`);
+ const scopedPackageShortcutRegex = new RegExp(`^(@[^/]+)(?:/(?:${prefix})?)?$`, "u"),
+ scopedPackageNameRegex = new RegExp(`^${prefix}(-|$)`, "u");
if (scopedPackageShortcutRegex.test(normalizedName)) {
normalizedName = normalizedName.replace(scopedPackageShortcutRegex, `$1/${prefix}`);
@@ -51,7 +51,7 @@
* for scoped packages, insert the prefix after the first / unless
* the path is already @scope/eslint or @scope/eslint-xxx-yyy
*/
- normalizedName = normalizedName.replace(/^@([^/]+)\/(.*)$/, `@$1/${prefix}-$2`);
+ normalizedName = normalizedName.replace(/^@([^/]+)\/(.*)$/u, `@$1/${prefix}-$2`);
}
} else if (normalizedName.indexOf(`${prefix}-`) !== 0) {
normalizedName = `${prefix}-${normalizedName}`;
@@ -68,13 +68,13 @@
*/
function getShorthandName(fullname, prefix) {
if (fullname[0] === "@") {
- let matchResult = new RegExp(`^(@[^/]+)/${prefix}$`).exec(fullname);
+ let matchResult = new RegExp(`^(@[^/]+)/${prefix}$`, "u").exec(fullname);
if (matchResult) {
return matchResult[1];
}
- matchResult = new RegExp(`^(@[^/]+)/${prefix}-(.+)$`).exec(fullname);
+ matchResult = new RegExp(`^(@[^/]+)/${prefix}-(.+)$`, "u").exec(fullname);
if (matchResult) {
return `${matchResult[1]}/${matchResult[2]}`;
}

lib/util/node-event-generator.js

@@ -157,7 +157,7 @@
*/
function tryParseSelector(rawSelector) {
try {
- return esquery.parse(rawSelector.replace(/:exit$/, ""));
+ return esquery.parse(rawSelector.replace(/:exit$/u, ""));
} catch (err) {
if (typeof err.offset === "number") {
throw new SyntaxError(`Syntax error in selector "${rawSelector}" at position ${err.offset}: ${err.message}`);

lib/util/path-utils.js

@@ -22,7 +22,7 @@
*/
function convertPathToPosix(filepath) {
const normalizedFilepath = path.normalize(filepath);
- const posixFilepath = normalizedFilepath.replace(/\\/g, "/");
+ const posixFilepath = normalizedFilepath.replace(/\\/gu, "/");
return posixFilepath;
}
@@ -58,7 +58,7 @@
}
return path.relative(baseDir, absolutePath);
}
- return absolutePath.replace(/^\//, "");
+ return absolutePath.replace(/^\//u, "");
}

lib/util/patterns/letters.js

@@ -33,4 +33,4 @@
"use strict";
-module.exports = /[A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDE00-\uDE11\uDE13-\uDE2B\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDE00-\uDE2F\uDE44\uDE80-\uDEAA]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]/;
+module.exports = /[A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDE00-\uDE11\uDE13-\uDE2B\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDE00-\uDE2F\uDE44\uDE80-\uDEAA]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]/u;

lib/util/source-code.js

@@ -357,7 +357,7 @@
if (parent.type !== "CallExpression" && parent.type !== "NewExpression") {
while (
!this.getCommentsBefore(parent).length &&
- !/Function/.test(parent.type) &&
+ !/Function/u.test(parent.type) &&
parent.type !== "MethodDefinition" &&
parent.type !== "Property"
) {
@@ -422,7 +422,7 @@
isSpaceBetweenTokens(first, second) {
const text = this.text.slice(first.range[1], second.range[0]);
- return /\s/.test(text.replace(/\/\*.*?\*\//g, ""));
+ return /\s/u.test(text.replace(/\/\*.*?\*\//gu, ""));
}
/**

lib/util/xml-escape.js

@@ -15,7 +15,7 @@
* @private
*/
module.exports = function(s) {
- return (`${s}`).replace(/[<>&"'\x00-\x1F\x7F\u0080-\uFFFF]/g, c => { // eslint-disable-line no-control-regex
+ return (`${s}`).replace(/[<>&"'\x00-\x1F\x7F\u0080-\uFFFF]/gu, c => { // eslint-disable-line no-control-regex
switch (c) {
case "<":
return "&lt;";

package.json

@@ -1,6 +1,6 @@
{
"name": "eslint",
- "version": "5.14.1",
+ "version": "5.15.3",
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
"description": "An AST-based pattern checker for JavaScript.",
"bin": {
@@ -18,7 +18,7 @@
"publish-release": "node Makefile.js publishRelease",
"docs": "node Makefile.js docs",
"gensite": "node Makefile.js gensite",
- "browserify": "node Makefile.js browserify",
+ "webpack": "node Makefile.js webpack",
"perf": "node Makefile.js perf",
"profile": "beefy tests/bench/bench.js --open -- -t brfs -t ./tests/bench/xform-rules.js -r espree",
"coveralls": "cat ./coverage/lcov.info | coveralls"
@@ -41,7 +41,7 @@
"cross-spawn": "^6.0.5",
"debug": "^4.0.1",
"doctrine": "^3.0.0",
- "eslint-scope": "^4.0.0",
+ "eslint-scope": "^4.0.3",
"eslint-utils": "^1.3.1",
"eslint-visitor-keys": "^1.0.0",
"espree": "^5.0.1",
@@ -76,30 +76,29 @@
"@babel/core": "^7.2.2",
"@babel/polyfill": "^7.2.5",
"@babel/preset-env": "^7.3.1",
- "babelify": "^10.0.0",
+ "babel-loader": "^8.0.5",
"beefy": "^2.1.8",
"brfs": "^2.0.0",
- "browserify": "^16.2.2",
"chai": "^4.0.1",
"cheerio": "^0.22.0",
"common-tags": "^1.8.0",
"coveralls": "^3.0.1",
"dateformat": "^3.0.3",
"ejs": "^2.6.1",
+ "eslint-config-eslint": "file:packages/eslint-config-eslint",
"eslint-plugin-eslint-plugin": "^2.0.1",
+ "eslint-plugin-internal-rules": "file:tools/internal-rules",
"eslint-plugin-node": "^8.0.0",
- "eslint-plugin-rulesdir": "^0.1.0",
"eslint-release": "^1.2.0",
- "eslint-rule-composer": "^0.3.0",
"eslump": "^2.0.0",
"esprima": "^4.0.1",
"istanbul": "^0.4.5",
"jsdoc": "^3.5.5",
"karma": "^3.1.4",
- "karma-babel-preprocessor": "^8.0.0",
"karma-chrome-launcher": "^2.2.0",
"karma-mocha": "^1.3.0",
"karma-mocha-reporter": "^2.2.3",
+ "karma-webpack": "^4.0.0-rc.6",
"leche": "^2.2.3",
"load-perf": "^0.2.0",
"markdownlint": "^0.12.0",
@@ -111,7 +110,9 @@
"shelljs": "^0.8.2",
"sinon": "^3.3.0",
"temp": "^0.9.0",
- "through": "^2.3.8"
+ "through": "^2.3.8",
+ "webpack": "^4.29.3",
+ "webpack-cli": "^3.2.3"
},
"keywords": [
"ast",

README.md

@@ -266,9 +266,9 @@
<!-- NOTE: This section is autogenerated. Do not manually edit.-->
<!--sponsorsstart-->
<h3>Gold Sponsors</h3>
-<p><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://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></p><h3>Silver 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.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></p>
+<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-->
## Technology Sponsors