diff --git a/Makefile.js b/Makefile.js index 8e03784c990..c34b1c8f2f8 100644 --- a/Makefile.js +++ b/Makefile.js @@ -42,7 +42,7 @@ const { cat, cd, cp, echo, exec, exit, find, ls, mkdir, pwd, rm, test } = requir const PERF_MULTIPLIER = 13e6; const OPEN_SOURCE_LICENSES = [ - /MIT/, /BSD/, /Apache/, /ISC/, /WTF/, /Public Domain/, /LGPL/ + /MIT/u, /BSD/u, /Apache/u, /ISC/u, /WTF/u, /Public Domain/u, /LGPL/u ]; //------------------------------------------------------------------------------ @@ -135,7 +135,7 @@ function generateBlogPost(releaseInfo, prereleaseMajorVersion) { const ruleList = ls("lib/rules") // Strip the .js extension - .map(ruleFileName => ruleFileName.replace(/\.js$/, "")) + .map(ruleFileName => ruleFileName.replace(/\.js$/u, "")) /* * Sort by length descending. This ensures that rule names which are substrings of other rule names are not @@ -699,7 +699,7 @@ target.gensite = function(prereleaseVersion) { } else { // extract the title from the file itself - title = text.match(/#([^#].+)\n/); + title = text.match(/#([^#].+)\n/u); if (title) { title = title[1].trim(); } else { @@ -720,10 +720,10 @@ target.gensite = function(prereleaseVersion) { ].join("\n"); // 6. Remove .md extension for relative links and change README to empty string - text = text.replace(/\((?!https?:\/\/)([^)]*?)\.md(.*?)\)/g, "($1$2)").replace("README.html", ""); + text = text.replace(/\((?!https?:\/\/)([^)]*?)\.md(.*?)\)/gu, "($1$2)").replace("README.html", ""); // 7. Check if there's a trailing white line at the end of the file, if there isn't one, add it - if (!/\n$/.test(text)) { + if (!/\n$/u.test(text)) { text = `${text}\n`; } @@ -827,8 +827,8 @@ target.checkRuleFiles = function() { */ function hasIdInTitle(id) { const docText = cat(docFilename); - const idOldAtEndOfTitleRegExp = new RegExp(`^# (.*?) \\(${id}\\)`); // original format - const idNewAtBeginningOfTitleRegExp = new RegExp(`^# ${id}: `); // new format is same as rules index + const idOldAtEndOfTitleRegExp = new RegExp(`^# (.*?) \\(${id}\\)`, "u"); // original format + const idNewAtBeginningOfTitleRegExp = new RegExp(`^# ${id}: `, "u"); // new format is same as rules index /* * 1. Added support for new format. * 2. Will remove support for old format after all docs files have new format. diff --git a/lib/cli-engine.js b/lib/cli-engine.js index dbf1abd0043..301ffe3c788 100644 --- a/lib/cli-engine.js +++ b/lib/cli-engine.js @@ -258,7 +258,7 @@ function processFile(filename, configHelper, options, linter) { */ 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 @@ class CLIEngine { 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); diff --git a/lib/config/config-file.js b/lib/config/config-file.js index f76b92830c4..492800b7a3c 100644 --- a/lib/config/config-file.js +++ b/lib/config/config-file.js @@ -61,7 +61,7 @@ const resolver = new ModuleResolver(); * @private */ function readFile(filePath) { - return fs.readFileSync(filePath, "utf8").replace(/^\ufeff/, ""); + return fs.readFileSync(filePath, "utf8").replace(/^\ufeff/u, ""); } /** @@ -73,7 +73,7 @@ function readFile(filePath) { * @private */ function isFilePath(filePath) { - return path.isAbsolute(filePath) || !/\w|@/.test(filePath.charAt(0)); + return path.isAbsolute(filePath) || !/\w|@/u.test(filePath.charAt(0)); } /** diff --git a/lib/config/config-initializer.js b/lib/config/config-initializer.js index b8126d4735c..adaf6c15840 100644 --- a/lib/config/config-initializer.js +++ b/lib/config/config-initializer.js @@ -152,7 +152,7 @@ function configureRules(answers, config) { 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 => { diff --git a/lib/config/config-validator.js b/lib/config/config-validator.js index 0c63b68f76c..2345b28893c 100644 --- a/lib/config/config-validator.js +++ b/lib/config/config-validator.js @@ -76,7 +76,7 @@ function validateRuleSeverity(options) { 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`); } diff --git a/lib/config/plugins.js b/lib/config/plugins.js index f32cc26c33f..029e7b106db 100644 --- a/lib/config/plugins.js +++ b/lib/config/plugins.js @@ -84,7 +84,7 @@ class Plugins { 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"; diff --git a/lib/formatters/codeframe.js b/lib/formatters/codeframe.js index a42872c5a1d..41e3ab7b0af 100644 --- a/lib/formatters/codeframe.js +++ b/lib/formatters/codeframe.js @@ -47,7 +47,7 @@ function formatFilePath(filePath, line, column) { */ 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; diff --git a/lib/formatters/stylish.js b/lib/formatters/stylish.js index 48d70ecb3d2..ca132ffa8a2 100644 --- a/lib/formatters/stylish.js +++ b/lib/formatters/stylish.js @@ -65,7 +65,7 @@ module.exports = function(results) { message.line || 0, message.column || 0, messageType, - message.message.replace(/([^ ])\.$/, "$1"), + message.message.replace(/([^ ])\.$/u, "$1"), chalk.dim(message.ruleId || "") ]; }), @@ -75,7 +75,7 @@ module.exports = function(results) { 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; diff --git a/lib/linter.js b/lib/linter.js index 2abd2d3ff1b..88448d90f8a 100644 --- a/lib/linter.js +++ b/lib/linter.js @@ -164,7 +164,7 @@ function getDirectiveComments(filename, ast, ruleMapper) { 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; @@ -172,7 +172,7 @@ function getDirectiveComments(filename, ast, ruleMapper) { 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); @@ -276,7 +276,7 @@ function normalizeEcmaVersion(ecmaVersion, isModule) { 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. @@ -498,7 +498,7 @@ function parse(text, providedParserOptions, parserName, parserMap, filePath) { } 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, diff --git a/lib/rules/array-callback-return.js b/lib/rules/array-callback-return.js index f88f4b8bfae..1c2f0562904 100644 --- a/lib/rules/array-callback-return.js +++ b/lib/rules/array-callback-return.js @@ -17,8 +17,8 @@ const astUtils = require("../util/ast-utils"); // 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. diff --git a/lib/rules/arrow-body-style.js b/lib/rules/arrow-body-style.js index 83fc28aba06..28001d7f488 100644 --- a/lib/rules/arrow-body-style.js +++ b/lib/rules/arrow-body-style.js @@ -82,7 +82,7 @@ module.exports = { * @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); } /** diff --git a/lib/rules/camelcase.js b/lib/rules/camelcase.js index 6dd3793f665..4647cc17e59 100644 --- a/lib/rules/camelcase.js +++ b/lib/rules/camelcase.js @@ -90,7 +90,7 @@ module.exports = { */ 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 @@ module.exports = { * 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 diff --git a/lib/rules/capitalized-comments.js b/lib/rules/capitalized-comments.js index 285f856379d..a488eb20b0d 100644 --- a/lib/rules/capitalized-comments.js +++ b/lib/rules/capitalized-comments.js @@ -16,8 +16,8 @@ const astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ 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, @@ -96,7 +96,7 @@ function createRegExpForIgnorePatterns(normalizedOptions) { 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 +215,7 @@ module.exports = { // 2. Check for custom ignore pattern. const commentWithoutAsterisks = comment.value - .replace(/\*/g, ""); + .replace(/\*/gu, ""); if (options.ignorePatternRegExp && options.ignorePatternRegExp.test(commentWithoutAsterisks)) { return true; diff --git a/lib/rules/curly.js b/lib/rules/curly.js index ee12da71352..6803eb6cd3b 100644 --- a/lib/rules/curly.js +++ b/lib/rules/curly.js @@ -191,7 +191,7 @@ module.exports = { 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; diff --git a/lib/rules/default-case.js b/lib/rules/default-case.js index 3061265ed8e..c8d0af3926f 100644 --- a/lib/rules/default-case.js +++ b/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 @@ module.exports = { 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(); diff --git a/lib/rules/dot-notation.js b/lib/rules/dot-notation.js index a1b091da0ea..e25ab12b771 100644 --- a/lib/rules/dot-notation.js +++ b/lib/rules/dot-notation.js @@ -14,7 +14,7 @@ const astUtils = require("../util/ast-utils"); // 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 @@ module.exports = { let allowPattern; if (options.allowPattern) { - allowPattern = new RegExp(options.allowPattern); + allowPattern = new RegExp(options.allowPattern); // eslint-disable-line require-unicode-regexp } /** diff --git a/lib/rules/eol-last.js b/lib/rules/eol-last.js index 84f4d45f176..fbba6c8f5e8 100644 --- a/lib/rules/eol-last.js +++ b/lib/rules/eol-last.js @@ -97,7 +97,7 @@ module.exports = { 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; diff --git a/lib/rules/func-call-spacing.js b/lib/rules/func-call-spacing.js index 62bba144e6f..348f5a8f4cd 100644 --- a/lib/rules/func-call-spacing.js +++ b/lib/rules/func-call-spacing.js @@ -93,8 +93,8 @@ module.exports = { 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); /* diff --git a/lib/rules/getter-return.js b/lib/rules/getter-return.js index a1806c357b1..c6035eed042 100644 --- a/lib/rules/getter-return.js +++ b/lib/rules/getter-return.js @@ -14,7 +14,7 @@ const astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/; +const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u; /** * Checks a given code path segment is reachable. diff --git a/lib/rules/handle-callback-err.js b/lib/rules/handle-callback-err.js index 2966aff2e61..4d08e4fec1b 100644 --- a/lib/rules/handle-callback-err.js +++ b/lib/rules/handle-callback-err.js @@ -52,7 +52,7 @@ module.exports = { */ 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); } diff --git a/lib/rules/id-match.js b/lib/rules/id-match.js index 3978a5ef684..48c1087674d 100644 --- a/lib/rules/id-match.js +++ b/lib/rules/id-match.js @@ -53,7 +53,7 @@ module.exports = { // 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, diff --git a/lib/rules/indent-legacy.js b/lib/rules/indent-legacy.js index 2a712c520a2..93e963a1c04 100644 --- a/lib/rules/indent-legacy.js +++ b/lib/rules/indent-legacy.js @@ -975,7 +975,7 @@ module.exports = { * @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), "" diff --git a/lib/rules/indent.js b/lib/rules/indent.js index 08b9250f05c..cd018d91d66 100644 --- a/lib/rules/indent.js +++ b/lib/rules/indent.js @@ -442,7 +442,7 @@ class OffsetStorage { 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 @@ module.exports = { * 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; diff --git a/lib/rules/jsx-quotes.js b/lib/rules/jsx-quotes.js index 372dc2f42e7..6d709afe35b 100644 --- a/lib/rules/jsx-quotes.js +++ b/lib/rules/jsx-quotes.js @@ -20,14 +20,14 @@ const QUOTE_SETTINGS = { 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, "'"); } } }; diff --git a/lib/rules/key-spacing.js b/lib/rules/key-spacing.js index 31ba9522e9b..3f4d711c14e 100644 --- a/lib/rules/key-spacing.js +++ b/lib/rules/key-spacing.js @@ -528,7 +528,7 @@ module.exports = { * @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] )); diff --git a/lib/rules/keyword-spacing.js b/lib/rules/keyword-spacing.js index 83ad6282688..97df9418307 100644 --- a/lib/rules/keyword-spacing.js +++ b/lib/rules/keyword-spacing.js @@ -16,13 +16,13 @@ const astUtils = require("../util/ast-utils"), // 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. diff --git a/lib/rules/line-comment-position.js b/lib/rules/line-comment-position.js index 132a8ad875f..21f1127af91 100644 --- a/lib/rules/line-comment-position.js +++ b/lib/rules/line-comment-position.js @@ -79,8 +79,8 @@ module.exports = { } 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(); //-------------------------------------------------------------------------- diff --git a/lib/rules/lines-around-comment.js b/lib/rules/lines-around-comment.js index 0f9851f7241..f2f9e3f9d45 100644 --- a/lib/rules/lines-around-comment.js +++ b/lib/rules/lines-around-comment.js @@ -130,7 +130,7 @@ module.exports = { const options = Object.assign({}, context.options[0]); const ignorePattern = options.ignorePattern; const defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN; - const customIgnoreRegExp = new RegExp(ignorePattern); + 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; diff --git a/lib/rules/max-len.js b/lib/rules/max-len.js index f6f0b6d3ac0..6e7dd6f1ac1 100644 --- a/lib/rules/max-len.js +++ b/lib/rules/max-len.js @@ -103,7 +103,7 @@ module.exports = { * 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 @@ module.exports = { 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 @@ module.exports = { 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 @@ module.exports = { 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, ""); } /** diff --git a/lib/rules/max-lines-per-function.js b/lib/rules/max-lines-per-function.js index 2a0e1a645a3..3b2f656fb76 100644 --- a/lib/rules/max-lines-per-function.js +++ b/lib/rules/max-lines-per-function.js @@ -187,7 +187,7 @@ module.exports = { } if (skipBlankLines) { - if (line.match(/^\s*$/)) { + if (line.match(/^\s*$/u)) { continue; } } diff --git a/lib/rules/max-statements-per-line.js b/lib/rules/max-statements-per-line.js index 444bdfa21aa..597847f88f8 100644 --- a/lib/rules/max-statements-per-line.js +++ b/lib/rules/max-statements-per-line.js @@ -57,7 +57,7 @@ module.exports = { // 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. diff --git a/lib/rules/multiline-comment-style.js b/lib/rules/multiline-comment-style.js index e262c255869..ece1035eaa9 100644 --- a/lib/rules/multiline-comment-style.js +++ b/lib/rules/multiline-comment-style.js @@ -52,7 +52,7 @@ module.exports = { } return commentGroup[0].value .split(astUtils.LINEBREAK_MATCHER) - .map(line => line.replace(/^\s*\*?/, "")); + .map(line => line.replace(/^\s*\*?/u, "")); } /** @@ -103,9 +103,9 @@ module.exports = { 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 @@ module.exports = { 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 @@ module.exports = { }); } - 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 @@ module.exports = { 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 @@ module.exports = { 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, diff --git a/lib/rules/new-cap.js b/lib/rules/new-cap.js index ab70fcfadd5..9e88981ce55 100644 --- a/lib/rules/new-cap.js +++ b/lib/rules/new-cap.js @@ -136,10 +136,10 @@ module.exports = { const skipProperties = config.properties === false; const newIsCapExceptions = checkArray(config, "newIsCapExceptions", []).reduce(invert, {}); - const newIsCapExceptionPattern = config.newIsCapExceptionPattern ? new RegExp(config.newIsCapExceptionPattern) : null; + 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 = {}; diff --git a/lib/rules/no-alert.js b/lib/rules/no-alert.js index 21f10b3c399..609bb0b7729 100644 --- a/lib/rules/no-alert.js +++ b/lib/rules/no-alert.js @@ -20,7 +20,7 @@ const getPropertyName = require("../util/ast-utils").getStaticPropertyName; * @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); } /** diff --git a/lib/rules/no-caller.js b/lib/rules/no-caller.js index 1703ad867dc..5fe1bd44985 100644 --- a/lib/rules/no-caller.js +++ b/lib/rules/no-caller.js @@ -35,7 +35,7 @@ module.exports = { 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 } }); } diff --git a/lib/rules/no-dupe-keys.js b/lib/rules/no-dupe-keys.js index 9b9c02f5efc..c0ccf73b8d3 100644 --- a/lib/rules/no-dupe-keys.js +++ b/lib/rules/no-dupe-keys.js @@ -15,8 +15,8 @@ const astUtils = require("../util/ast-utils"); // 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. diff --git a/lib/rules/no-else-return.js b/lib/rules/no-else-return.js index 5c21fb1b3fc..17f355eeb0c 100644 --- a/lib/rules/no-else-return.js +++ b/lib/rules/no-else-return.js @@ -82,7 +82,7 @@ module.exports = { * 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 @@ module.exports = { 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; /* diff --git a/lib/rules/no-empty-character-class.js b/lib/rules/no-empty-character-class.js index 6d2fb3c5018..7dc219fe1a7 100644 --- a/lib/rules/no-empty-character-class.js +++ b/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 diff --git a/lib/rules/no-fallthrough.js b/lib/rules/no-fallthrough.js index dfd9d854158..241e07258e1 100644 --- a/lib/rules/no-fallthrough.js +++ b/lib/rules/no-fallthrough.js @@ -14,7 +14,7 @@ const lodash = require("lodash"); // 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 @@ module.exports = { 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; } diff --git a/lib/rules/no-implicit-coercion.js b/lib/rules/no-implicit-coercion.js index d54c578646d..6483af0229f 100644 --- a/lib/rules/no-implicit-coercion.js +++ b/lib/rules/no-implicit-coercion.js @@ -11,7 +11,7 @@ const astUtils = require("../util/ast-utils"); // Helpers //------------------------------------------------------------------------------ -const INDEX_OF_PATTERN = /^(?:i|lastI)ndexOf$/; +const INDEX_OF_PATTERN = /^(?:i|lastI)ndexOf$/u; const ALLOWABLE_OPERATORS = ["~", "!!", "+", "*"]; /** diff --git a/lib/rules/no-implied-eval.js b/lib/rules/no-implied-eval.js index afa24ab8efd..f2f6f9cea4f 100644 --- a/lib/rules/no-implied-eval.js +++ b/lib/rules/no-implied-eval.js @@ -24,7 +24,7 @@ module.exports = { }, 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 diff --git a/lib/rules/no-invalid-regexp.js b/lib/rules/no-invalid-regexp.js index 74659001fdb..852efbbb935 100644 --- a/lib/rules/no-invalid-regexp.js +++ b/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 @@ module.exports = { const temp = options.allowConstructorFlags.join("").replace(validFlags, ""); if (temp) { - allowedFlags = new RegExp(`[${temp}]`, "gi"); + allowedFlags = new RegExp(`[${temp}]`, "giu"); } } diff --git a/lib/rules/no-irregular-whitespace.js b/lib/rules/no-irregular-whitespace.js index ddbfd1c91cc..de6d518bd50 100644 --- a/lib/rules/no-irregular-whitespace.js +++ b/lib/rules/no-irregular-whitespace.js @@ -16,9 +16,9 @@ const astUtils = require("../util/ast-utils"); // 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(); //------------------------------------------------------------------------------ diff --git a/lib/rules/no-lonely-if.js b/lib/rules/no-lonely-if.js index 4bbb5399ff9..b62d176a264 100644 --- a/lib/rules/no-lonely-if.js +++ b/lib/rules/no-lonely-if.js @@ -58,7 +58,7 @@ module.exports = { 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 === "--" ) diff --git a/lib/rules/no-mixed-operators.js b/lib/rules/no-mixed-operators.js index 2b603a86df5..83f27fb0076 100644 --- a/lib/rules/no-mixed-operators.js +++ b/lib/rules/no-mixed-operators.js @@ -34,7 +34,7 @@ const DEFAULT_GROUPS = [ LOGICAL_OPERATORS, RELATIONAL_OPERATORS ]; -const TARGET_NODE_TYPE = /^(?:Binary|Logical)Expression$/; +const TARGET_NODE_TYPE = /^(?:Binary|Logical)Expression$/u; /** * Normalizes options. diff --git a/lib/rules/no-mixed-requires.js b/lib/rules/no-mixed-requires.js index 5b07a5f2938..e79dde0fedd 100644 --- a/lib/rules/no-mixed-requires.js +++ b/lib/rules/no-mixed-requires.js @@ -158,7 +158,7 @@ module.exports = { // "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; diff --git a/lib/rules/no-mixed-spaces-and-tabs.js b/lib/rules/no-mixed-spaces-and-tabs.js index 1fc0b6074b8..7b1e2c4a2a7 100644 --- a/lib/rules/no-mixed-spaces-and-tabs.js +++ b/lib/rules/no-mixed-spaces-and-tabs.js @@ -88,7 +88,7 @@ module.exports = { * 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 @@ module.exports = { * 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) => { diff --git a/lib/rules/no-octal-escape.js b/lib/rules/no-octal-escape.js index fc073b14033..a2860ca5bf8 100644 --- a/lib/rules/no-octal-escape.js +++ b/lib/rules/no-octal-escape.js @@ -32,7 +32,7 @@ module.exports = { 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]; diff --git a/lib/rules/no-octal.js b/lib/rules/no-octal.js index db1fa40aa5d..b8c2238265f 100644 --- a/lib/rules/no-octal.js +++ b/lib/rules/no-octal.js @@ -28,7 +28,7 @@ module.exports = { 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." }); } } diff --git a/lib/rules/no-param-reassign.js b/lib/rules/no-param-reassign.js index 83760edb8c2..880ff93cb53 100644 --- a/lib/rules/no-param-reassign.js +++ b/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: { diff --git a/lib/rules/no-path-concat.js b/lib/rules/no-path-concat.js index dad56a4f56a..abe0d5247db 100644 --- a/lib/rules/no-path-concat.js +++ b/lib/rules/no-path-concat.js @@ -24,7 +24,7 @@ module.exports = { create(context) { - const MATCHER = /^__(?:dir|file)name$/; + const MATCHER = /^__(?:dir|file)name$/u; //-------------------------------------------------------------------------- // Public diff --git a/lib/rules/no-regex-spaces.js b/lib/rules/no-regex-spaces.js index d0f7293d20e..75faa11191d 100644 --- a/lib/rules/no-regex-spaces.js +++ b/lib/rules/no-regex-spaces.js @@ -39,7 +39,7 @@ module.exports = { * @private */ function checkRegex(node, value, valueStart) { - const multipleSpacesRegex = /( {2,})( [+*{?]|[^+*{?]|$)/, + const multipleSpacesRegex = /( {2,})( [+*{?]|[^+*{?]|$)/u, regexResults = multipleSpacesRegex.exec(value); if (regexResults !== null) { diff --git a/lib/rules/no-return-assign.js b/lib/rules/no-return-assign.js index b3c39ea2b8c..c4a79d5fb1c 100644 --- a/lib/rules/no-return-assign.js +++ b/lib/rules/no-return-assign.js @@ -14,7 +14,7 @@ const astUtils = require("../util/ast-utils"); // Helpers //------------------------------------------------------------------------------ -const SENTINEL_TYPE = /^(?:[a-zA-Z]+?Statement|ArrowFunctionExpression|FunctionExpression|ClassExpression)$/; +const SENTINEL_TYPE = /^(?:[a-zA-Z]+?Statement|ArrowFunctionExpression|FunctionExpression|ClassExpression)$/u; //------------------------------------------------------------------------------ // Rule Definition diff --git a/lib/rules/no-self-assign.js b/lib/rules/no-self-assign.js index 8bc7afbe38e..5b74ca8fbcf 100644 --- a/lib/rules/no-self-assign.js +++ b/lib/rules/no-self-assign.js @@ -15,7 +15,7 @@ const astUtils = require("../util/ast-utils"); // Helpers //------------------------------------------------------------------------------ -const SPACES = /\s+/g; +const SPACES = /\s+/gu; /** * Checks whether the property of 2 given member expression nodes are the same diff --git a/lib/rules/no-tabs.js b/lib/rules/no-tabs.js index 91fb000796f..0c0a220110c 100644 --- a/lib/rules/no-tabs.js +++ b/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 diff --git a/lib/rules/no-template-curly-in-string.js b/lib/rules/no-template-curly-in-string.js index c286ec69000..f7822e961cc 100644 --- a/lib/rules/no-template-curly-in-string.js +++ b/lib/rules/no-template-curly-in-string.js @@ -23,7 +23,7 @@ module.exports = { }, create(context) { - const regex = /\$\{[^}]+\}/; + const regex = /\$\{[^}]+\}/u; return { Literal(node) { diff --git a/lib/rules/no-trailing-spaces.js b/lib/rules/no-trailing-spaces.js index 1f0b53aca2a..a75ef0ec4c5 100644 --- a/lib/rules/no-trailing-spaces.js +++ b/lib/rules/no-trailing-spaces.js @@ -111,8 +111,8 @@ module.exports = { * 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(), diff --git a/lib/rules/no-unexpected-multiline.js b/lib/rules/no-unexpected-multiline.js index 35c2140bae6..f4a83f0cefa 100644 --- a/lib/rules/no-unexpected-multiline.js +++ b/lib/rules/no-unexpected-multiline.js @@ -36,7 +36,7 @@ module.exports = { create(context) { - const REGEX_FLAG_MATCHER = /^[gimsuy]+$/; + const REGEX_FLAG_MATCHER = /^[gimsuy]+$/u; const sourceCode = context.getSourceCode(); diff --git a/lib/rules/no-unmodified-loop-condition.js b/lib/rules/no-unmodified-loop-condition.js index 95898c5f19d..5bb54f81d67 100644 --- a/lib/rules/no-unmodified-loop-condition.js +++ b/lib/rules/no-unmodified-loop-condition.js @@ -16,11 +16,11 @@ const Traverser = require("../util/traverser"), // 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 diff --git a/lib/rules/no-unsafe-finally.js b/lib/rules/no-unsafe-finally.js index ab612ae6526..4daa63b6929 100644 --- a/lib/rules/no-unsafe-finally.js +++ b/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; //------------------------------------------------------------------------------ diff --git a/lib/rules/no-unused-expressions.js b/lib/rules/no-unused-expressions.js index 25c21775b0d..02cce309ee9 100644 --- a/lib/rules/no-unused-expressions.js +++ b/lib/rules/no-unused-expressions.js @@ -88,7 +88,7 @@ module.exports = { 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 @@ module.exports = { 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); } diff --git a/lib/rules/no-unused-vars.js b/lib/rules/no-unused-vars.js index e56ba221bbc..de13f26ce23 100644 --- a/lib/rules/no-unused-vars.js +++ b/lib/rules/no-unused-vars.js @@ -71,7 +71,7 @@ module.exports = { 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 +92,15 @@ module.exports = { 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 +147,7 @@ module.exports = { // 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 +600,7 @@ module.exports = { * @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; diff --git a/lib/rules/no-use-before-define.js b/lib/rules/no-use-before-define.js index e0b2d23a7e6..61998c7a87c 100644 --- a/lib/rules/no-use-before-define.js +++ b/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. diff --git a/lib/rules/no-useless-escape.js b/lib/rules/no-useless-escape.js index c3c0421cc0c..82db1f2be44 100644 --- a/lib/rules/no-useless-escape.js +++ b/lib/rules/no-useless-escape.js @@ -181,7 +181,7 @@ module.exports = { } 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))) { diff --git a/lib/rules/no-var.js b/lib/rules/no-var.js index edaed98f62e..83681a7aaed 100644 --- a/lib/rules/no-var.js +++ b/lib/rules/no-var.js @@ -77,7 +77,7 @@ function isDeclarationInitialized(node) { 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. diff --git a/lib/rules/no-warning-comments.js b/lib/rules/no-warning-comments.js index 9ea39b490f8..0dd0a26c1f9 100644 --- a/lib/rules/no-warning-comments.js +++ b/lib/rules/no-warning-comments.js @@ -47,7 +47,7 @@ module.exports = { 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 @@ module.exports = { * @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 @@ module.exports = { * 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 @@ module.exports = { * 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 @@ module.exports = { * ^\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, "iu"); } /* @@ -103,7 +103,7 @@ module.exports = { * \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, "iu"); } const warningRegExps = warningTerms.map(convertToRegExp); diff --git a/lib/rules/padding-line-between-statements.js b/lib/rules/padding-line-between-statements.js index c9995885442..7d37870a481 100644 --- a/lib/rules/padding-line-between-statements.js +++ b/lib/rules/padding-line-between-statements.js @@ -17,10 +17,11 @@ const astUtils = require("../util/ast-utils"); 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. diff --git a/lib/rules/prefer-const.js b/lib/rules/prefer-const.js index 023f69cbd32..c4180faeb94 100644 --- a/lib/rules/prefer-const.js +++ b/lib/rules/prefer-const.js @@ -11,9 +11,9 @@ const astUtils = require("../util/ast-utils"); // 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. diff --git a/lib/rules/prefer-object-spread.js b/lib/rules/prefer-object-spread.js index 4d724339db0..c5fca98efeb 100644 --- a/lib/rules/prefer-object-spread.js +++ b/lib/rules/prefer-object-spread.js @@ -14,7 +14,7 @@ const { 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 diff --git a/lib/rules/prefer-template.js b/lib/rules/prefer-template.js index 386674a92ef..d8dd5dd86e0 100644 --- a/lib/rules/prefer-template.js +++ b/lib/rules/prefer-template.js @@ -52,7 +52,7 @@ function isOctalEscapeSequence(node) { 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 @@ module.exports = { * 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") { diff --git a/lib/rules/quotes.js b/lib/rules/quotes.js index e0797f9e8be..887a0b75f58 100644 --- a/lib/rules/quotes.js +++ b/lib/rules/quotes.js @@ -34,7 +34,7 @@ const QUOTE_SETTINGS = { }; // 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 @@ QUOTE_SETTINGS.backtick.convert = function(str) { 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 } diff --git a/lib/rules/semi.js b/lib/rules/semi.js index f7bc0f5fd66..740ce53f428 100644 --- a/lib/rules/semi.js +++ b/lib/rules/semi.js @@ -73,7 +73,7 @@ module.exports = { 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; @@ -292,7 +292,7 @@ module.exports = { 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 +319,7 @@ module.exports = { } }, ExportDefaultDeclaration(node) { - if (!/(?:Class|Function)Declaration/.test(node.declaration.type)) { + if (!/(?:Class|Function)Declaration/u.test(node.declaration.type)) { checkForSemicolon(node); } } diff --git a/lib/rules/spaced-comment.js b/lib/rules/spaced-comment.js index 63177eb1c7f..6e469ef9403 100644 --- a/lib/rules/spaced-comment.js +++ b/lib/rules/spaced-comment.js @@ -126,7 +126,7 @@ function createAlwaysStylePattern(markers, exceptions) { 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 createAlwaysStylePattern(markers, exceptions) { 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 @@ module.exports = { // 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; diff --git a/lib/rules/template-curly-spacing.js b/lib/rules/template-curly-spacing.js index 84957d47594..e255a890ec4 100644 --- a/lib/rules/template-curly-spacing.js +++ b/lib/rules/template-curly-spacing.js @@ -15,8 +15,8 @@ const astUtils = require("../util/ast-utils"); // Helpers //------------------------------------------------------------------------------ -const OPEN_PAREN = /\$\{$/; -const CLOSE_PAREN = /^\}/; +const OPEN_PAREN = /\$\{$/u; +const CLOSE_PAREN = /^\}/u; //------------------------------------------------------------------------------ // Rule Definition diff --git a/lib/rules/use-isnan.js b/lib/rules/use-isnan.js index c8adefd608a..877c02754ae 100644 --- a/lib/rules/use-isnan.js +++ b/lib/rules/use-isnan.js @@ -30,7 +30,7 @@ module.exports = { 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" }); } } diff --git a/lib/rules/valid-jsdoc.js b/lib/rules/valid-jsdoc.js index 46eb02211a4..3250d9233c7 100644 --- a/lib/rules/valid-jsdoc.js +++ b/lib/rules/valid-jsdoc.js @@ -300,7 +300,7 @@ module.exports = { }); } 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 @@ module.exports = { } 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" }); diff --git a/lib/rules/vars-on-top.js b/lib/rules/vars-on-top.js index 92d483b6ecc..e919d02da00 100644 --- a/lib/rules/vars-on-top.js +++ b/lib/rules/vars-on-top.js @@ -117,7 +117,7 @@ module.exports = { * @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" }); diff --git a/lib/rules/yoda.js b/lib/rules/yoda.js index 825634a79f6..048c670a645 100644 --- a/lib/rules/yoda.js +++ b/lib/rules/yoda.js @@ -20,7 +20,7 @@ const astUtils = require("../util/ast-utils"); * @returns {boolean} Whether or not it is a comparison operator. */ function isComparisonOperator(operator) { - return (/^(==|===|!=|!==|<|>|<=|>=)$/).test(operator); + return (/^(==|===|!=|!==|<|>|<=|>=)$/u).test(operator); } /** @@ -29,7 +29,7 @@ function isComparisonOperator(operator) { * @returns {boolean} Whether or not it is an equality operator. */ function isEqualityOperator(operator) { - return (/^(==|===)$/).test(operator); + return (/^(==|===)$/u).test(operator); } /** diff --git a/lib/util/ast-utils.js b/lib/util/ast-utils.js index a188c7fa1c6..85205a75d24 100644 --- a/lib/util/ast-utils.js +++ b/lib/util/ast-utils.js @@ -16,19 +16,19 @@ const espree = require("espree"); // 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 @@ function getOpeningParenOfParams(node, sourceCode) { * @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 @@ module.exports = { * '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); }, /** diff --git a/lib/util/config-comment-parser.js b/lib/util/config-comment-parser.js index 8ee0230cb26..7ac93475740 100644 --- a/lib/util/config-comment-parser.js +++ b/lib/util/config-comment-parser.js @@ -38,9 +38,9 @@ module.exports = class ConfigCommentParser { 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 @@ module.exports = class ConfigCommentParser { * 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 @@ module.exports = class ConfigCommentParser { 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) { diff --git a/lib/util/glob-utils.js b/lib/util/glob-utils.js index fd4cfa00851..b05c354439d 100644 --- a/lib/util/glob-utils.js +++ b/lib/util/glob-utils.js @@ -52,7 +52,7 @@ function processPath(options) { 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 = "/**"; @@ -74,7 +74,7 @@ function processPath(options) { const resolvedPath = path.resolve(cwd, pathname); if (directoryExists(resolvedPath)) { - newPath = pathname.replace(/[/\\]$/, "") + suffix; + newPath = pathname.replace(/[/\\]$/u, "") + suffix; } return pathUtils.convertPathToPosix(newPath); @@ -169,7 +169,7 @@ function resolveFileGlobPatterns(patterns, options) { return patterns.map(processPathExtensions); } -const dotfilesPattern = /(?:(?:^\.)|(?:[/\\]\.))[^/\\.].*/; +const dotfilesPattern = /(?:(?:^\.)|(?:[/\\]\.))[^/\\.].*/u; /** * Build a list of absolute filesnames on which ESLint will act. diff --git a/lib/util/ignored-paths.js b/lib/util/ignored-paths.js index de4a79cde33..41bc3f48c84 100644 --- a/lib/util/ignored-paths.js +++ b/lib/util/ignored-paths.js @@ -89,7 +89,7 @@ function mergeDefaultOptions(options) { */ 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 @@ function relativize(globPattern, relativePathToOldBaseDir) { } 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 @@ class IgnoredPaths { } // 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 @@ class IgnoredPaths { */ 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]; } diff --git a/lib/util/interpolate.js b/lib/util/interpolate.js index cefdcca5454..87e06a02369 100644 --- a/lib/util/interpolate.js +++ b/lib/util/interpolate.js @@ -15,7 +15,7 @@ module.exports = (text, data) => { } // 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) { diff --git a/lib/util/naming.js b/lib/util/naming.js index aaf00237820..ea1cc9518ea 100644 --- a/lib/util/naming.js +++ b/lib/util/naming.js @@ -13,7 +13,7 @@ const pathUtils = require("../util/path-utils"); // Private //------------------------------------------------------------------------------ -const NAMESPACE_REGEX = /^@.*\//i; +const NAMESPACE_REGEX = /^@.*\//iu; /** * Brings package name to correct format based on prefix @@ -40,8 +40,8 @@ function normalizePackageName(name, prefix) { * 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 @@ function normalizePackageName(name, prefix) { * 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 normalizePackageName(name, prefix) { */ 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]}`; } diff --git a/lib/util/node-event-generator.js b/lib/util/node-event-generator.js index 1ae56643196..4193cc82758 100644 --- a/lib/util/node-event-generator.js +++ b/lib/util/node-event-generator.js @@ -157,7 +157,7 @@ function compareSpecificity(selectorA, selectorB) { */ 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}`); diff --git a/lib/util/path-utils.js b/lib/util/path-utils.js index 07cf4e79066..c96254df6b8 100644 --- a/lib/util/path-utils.js +++ b/lib/util/path-utils.js @@ -22,7 +22,7 @@ const path = require("path"); */ function convertPathToPosix(filepath) { const normalizedFilepath = path.normalize(filepath); - const posixFilepath = normalizedFilepath.replace(/\\/g, "/"); + const posixFilepath = normalizedFilepath.replace(/\\/gu, "/"); return posixFilepath; } @@ -58,7 +58,7 @@ function getRelativePath(filepath, baseDir) { } return path.relative(baseDir, absolutePath); } - return absolutePath.replace(/^\//, ""); + return absolutePath.replace(/^\//u, ""); } diff --git a/lib/util/patterns/letters.js b/lib/util/patterns/letters.js index eb255d8f001..9bb2de31010 100644 --- a/lib/util/patterns/letters.js +++ b/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; diff --git a/lib/util/source-code.js b/lib/util/source-code.js index 4e90ac1aa92..93b05a87d23 100644 --- a/lib/util/source-code.js +++ b/lib/util/source-code.js @@ -357,7 +357,7 @@ class SourceCode extends TokenStore { 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 @@ class SourceCode extends TokenStore { 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, "")); } /** diff --git a/lib/util/xml-escape.js b/lib/util/xml-escape.js index 9f43c99c46a..175c2c0c2dd 100644 --- a/lib/util/xml-escape.js +++ b/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 "<"; diff --git a/packages/eslint-config-eslint/default.yml b/packages/eslint-config-eslint/default.yml index 9fdb4c767db..0cfe3506bf9 100644 --- a/packages/eslint-config-eslint/default.yml +++ b/packages/eslint-config-eslint/default.yml @@ -160,6 +160,7 @@ rules: radix: "error" require-atomic-updates: "error" require-jsdoc: "error" + require-unicode-regexp: "error" rest-spread-spacing: "error" semi: "error" semi-spacing: ["error", {before: false, after: true}] diff --git a/tests/bin/eslint.js b/tests/bin/eslint.js index 7749b12f107..b6254fa5ff1 100644 --- a/tests/bin/eslint.js +++ b/tests/bin/eslint.js @@ -128,7 +128,7 @@ describe("bin/eslint.js", () => { if ( fs.readdirSync("/").some( fileName => - /^\.eslintrc(?:\.(?:js|yaml|yml|json))?$/ + /^\.eslintrc(?:\.(?:js|yaml|yml|json))?$/u .test(fileName) ) ) { @@ -142,7 +142,7 @@ describe("bin/eslint.js", () => { const stderrPromise = getOutput(child).then(output => { assert.match( output.stderr, - /ESLint couldn't find a configuration file/ + /ESLint couldn't find a configuration file/u ); }); @@ -287,7 +287,7 @@ describe("bin/eslint.js", () => { assert.throws( () => JSON.parse(fs.readFileSync(CACHE_PATH, "utf8")), SyntaxError, - /Unexpected token/, + /Unexpected token/u, "Cache file should not contain valid JSON at the start" ); }); diff --git a/tests/lib/cli-engine.js b/tests/lib/cli-engine.js index f2cfb03187c..ee582c83a95 100644 --- a/tests/lib/cli-engine.js +++ b/tests/lib/cli-engine.js @@ -344,7 +344,7 @@ describe("CLIEngine", () => { fix: true, fixTypes: ["layou"] }); - }, /invalid fix type/i); + }, /invalid fix type/iu); }); it("should not fix any rules when fixTypes is used without fix", () => { @@ -1371,7 +1371,7 @@ describe("CLIEngine", () => { assert.throws(() => { engine.executeOnFiles([getFixturePath("rules", "test", "test-custom-rule.js")]); - }, /Error while loading rule 'custom-rule'/); + }, /Error while loading rule 'custom-rule'/u); }); it("should return one message when a custom rule matches a file", () => { @@ -1581,7 +1581,7 @@ describe("CLIEngine", () => { */ function convertCRLF(result) { if (result && result.output) { - result.output = result.output.replace(/\r\n/g, "\n"); + result.output = result.output.replace(/\r\n/gu, "\n"); } } @@ -2746,7 +2746,7 @@ describe("CLIEngine", () => { describe("autofixing with processors", () => { const HTML_PROCESSOR = Object.freeze({ preprocess(text) { - return [text.replace(/^