Enable unicorn/better-regex (#7991)

* Enable `unicorn/better-regex`

* Spellcheck ignore regex
This commit is contained in:
fisker Cheung authored and GitHub committed 2020-04-10 21:20:40 +08:00
1 parent 1221598304
commit f0207e6850
31 files changed
+60 -57

No files matched your search

+1
View File
@@ -10,6 +10,7 @@ insert_final_newline = true
[cspell.json]
indent_size = 4
insert_final_newline = false
[website/blog/*.md]
trim_trailing_whitespace = false
+1
View File
@@ -56,6 +56,7 @@ rules:
- error
- never
- exceptRange: true
unicorn/better-regex: error
unicorn/new-for-builtins: error
unicorn/prefer-includes: error
unicorn/prefer-set-has: error
+2 -1
View File
@@ -431,7 +431,8 @@
"\\[@\\w+?\\]",
"\\[`\\w+`\\]",
"ve{2,}r{2,}y",
"ve+r+y+long\\w*"
"ve+r+y+long\\w*",
"\\/.*?\\/"
],
"ignorePaths": [
"**/node_modules/**",
+2 -2
View File
@@ -67,9 +67,9 @@ for (const dir of dirs) {
highlight: title.includes("[HIGHLIGHT]"),
content: [
title
.replace(/\[(BREAKING|HIGHLIGHT)\]/g, "")
.replace(/\[(BREAKING|HIGHLIGHT)]/g, "")
.replace(/\s+/g, " ")
.replace(/^#### [a-z]/, (s) => s.toUpperCase()),
.replace(/^#{4} [a-z]/, (s) => s.toUpperCase()),
...rest,
].join("\n"),
};
+2 -2
View File
@@ -52,14 +52,14 @@ for (const file of [
}
}
const authorRegex = /by \[@(.*?)\]\(https:\/\/github\.com\/\1\)/;
const authorRegex = /by \[@(.*?)]\(https:\/\/github\.com\/\1\)/;
const titleRegex = /^#{4} (.*?)\(\[#\d{4,}]/;
const template = fs.readFileSync(
path.join(CHANGELOG_ROOT, TEMPLATE_FILE),
"utf8"
);
const [templateComment] = template.match(/<!--[\s\S]*?-->/);
const [templateComment] = template.match(/<!--[\S\s]*?-->/);
const [templateAuthorLink] = template.match(authorRegex);
for (const category of CHANGELOG_CATEGORIES) {
+1 -1
View File
@@ -21,7 +21,7 @@ async function bump({ version }) {
// Update unpkg link in docs
processFile("docs/browser.md", (content) =>
content.replace(/(\/\/unpkg\.com\/prettier@)(?:.*?)\//g, `$1${version}/`)
content.replace(/(\/\/unpkg\.com\/prettier@).*?\//g, `$1${version}/`)
);
await execa("yarn", ["update-stable-docs"], {
+4 -4
View File
@@ -73,7 +73,7 @@ const skipToLineEnd = skip(",; \t");
/**
* @type {(text: string, index: number | false, opts?: SkipOptions) => number | false}
*/
const skipEverythingButNewLine = skip(/[^\r\n]/);
const skipEverythingButNewLine = skip(/[^\n\r]/);
/**
* @param {string} text
@@ -520,7 +520,7 @@ function getIndentSize(value, tabWidth) {
return getAlignmentSize(
// All the leading whitespaces
value.slice(lastNewlineIndex + 1).match(/^[ \t]*/)[0],
value.slice(lastNewlineIndex + 1).match(/^[\t ]*/)[0],
tabWidth
);
}
@@ -624,7 +624,7 @@ function makeString(rawContent, enclosingQuote, unescapeUnnecessaryEscapes) {
const otherQuote = enclosingQuote === '"' ? "'" : '"';
// Matches _any_ escape and unescaped quotes (both single and double).
const regex = /\\([\s\S])|(['"])/g;
const regex = /\\([\S\s])|(["'])/g;
// Escape and unescape single and double quotes as needed to be able to
// enclose `rawContent` with `enclosingQuote`.
@@ -650,7 +650,7 @@ function makeString(rawContent, enclosingQuote, unescapeUnnecessaryEscapes) {
// Unescape any unnecessarily escaped character.
// Adapted from https://github.com/eslint/eslint/blob/de0b4ad7bd820ade41b1f606008bea68683dc11a/lib/rules/no-useless-escape.js#L27
return unescapeUnnecessaryEscapes &&
/^[^\\nrvtbfux\r\n\u2028\u2029"'0-7]$/.test(escaped)
/^[^\n\r"'0-7\\bfnrt-vx\u2028\u2029]$/.test(escaped)
? escaped
: "\\" + escaped;
});
+2 -2
View File
@@ -121,13 +121,13 @@ function trim(out) {
while (
out.length > 0 &&
typeof out[out.length - 1] === "string" &&
out[out.length - 1].match(/^[ \t]*$/)
out[out.length - 1].match(/^[\t ]*$/)
) {
trimCount += out.pop().length;
}
if (out.length && typeof out[out.length - 1] === "string") {
const trimmed = out[out.length - 1].replace(/[ \t]*$/, "");
const trimmed = out[out.length - 1].replace(/[\t ]*$/, "");
trimCount += out[out.length - 1].length - trimmed.length;
out[out.length - 1] = trimmed;
}
+3 -3
View File
@@ -113,7 +113,7 @@ function clean(ast, newObj, parent) {
}
if (newObj.value) {
newObj.value = newObj.value.trim().replace(/^['"]|['"]$/g, "");
newObj.value = newObj.value.trim().replace(/^["']|["']$/g, "");
delete newObj.quoted;
}
}
@@ -129,7 +129,7 @@ function clean(ast, newObj, parent) {
newObj.value
) {
newObj.value = newObj.value.replace(
/([\d.eE+-]+)([a-zA-Z]*)/g,
/([\d+.Ee-]+)([A-Za-z]*)/g,
(match, numStr, unit) => {
const num = Number(numStr);
return isNaN(num) ? match : num + unit.toLowerCase();
@@ -157,7 +157,7 @@ function clean(ast, newObj, parent) {
}
function cleanCSSStrings(value) {
return value.replace(/'/g, '"').replace(/\\([^a-fA-F\d])/g, "$1");
return value.replace(/'/g, '"').replace(/\\([^\dA-Fa-f])/g, "$1");
}
module.exports = clean;
+2 -2
View File
@@ -464,7 +464,7 @@ function parseNestedCSS(node, options) {
}
if (name === "at-root") {
if (/^\(\s*(without|with)\s*:[\s\S]+\)$/.test(params)) {
if (/^\(\s*(without|with)\s*:[\S\s]+\)$/.test(params)) {
node.params = parseValue(params);
} else {
node.selector = parseSelector(params);
@@ -500,7 +500,7 @@ function parseNestedCSS(node, options) {
].includes(name)
) {
// Remove unnecessary spaces in SCSS variable arguments
params = params.replace(/(\$\S+?)\s+?\.\.\./, "$1...");
params = params.replace(/(\$\S+?)\s+?\.{3}/, "$1...");
// Remove unnecessary spaces before SCSS control, mixin and function directives
params = params.replace(/^(?!if)(\S+)\s+\(/, "$1(");
+4 -4
View File
@@ -974,10 +974,10 @@ function printNodeSequence(path, options, print) {
return concat(parts);
}
const STRING_REGEX = /(['"])(?:(?!\1)[^\\]|\\[\s\S])*\1/g;
const NUMBER_REGEX = /(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g;
const STANDARD_UNIT_REGEX = /[a-zA-Z]+/g;
const WORD_PART_REGEX = /[$@]?[a-zA-Z_\u0080-\uFFFF][\w\-\u0080-\uFFFF]*/g;
const STRING_REGEX = /(["'])(?:(?!\1)[^\\]|\\[\S\s])*\1/g;
const NUMBER_REGEX = /(?:\d*\.\d+|\d+\.?)(?:[Ee][+-]?\d+)?/g;
const STANDARD_UNIT_REGEX = /[A-Za-z]+/g;
const WORD_PART_REGEX = /[$@]?[A-Z_a-z\u0080-\uFFFF][\w\u0080-\uFFFF-]*/g;
const ADJUST_NUMBERS_REGEX = new RegExp(
STRING_REGEX.source +
"|" +
+2 -2
View File
@@ -60,7 +60,7 @@ function getPropOfDeclNode(path) {
function isSCSS(parser, text) {
const hasExplicitParserChoice = parser === "less" || parser === "scss";
const IS_POSSIBLY_SCSS = /(\w\s*:\s*[^}:]+|#){|@import[^\n]+(?:url|,)/;
const IS_POSSIBLY_SCSS = /(\w\s*:\s*[^:}]+|#){|@import[^\n]+(?:url|,)/;
return hasExplicitParserChoice
? parser === "scss"
: IS_POSSIBLY_SCSS.test(text);
@@ -385,7 +385,7 @@ function isLessParser(options) {
}
function lastLineHasInlineComment(text) {
return /\/\//.test(text.split(/[\r\n]/).pop());
return /\/\//.test(text.split(/[\n\r]/).pop());
}
module.exports = {
+1 -1
View File
@@ -1,7 +1,7 @@
"use strict";
function hasPragma(text) {
return /^\s*#[^\n\S]*@(format|prettier)\s*(\n|$)/.test(text);
return /^\s*#[^\S\n]*@(format|prettier)\s*(\n|$)/.test(text);
}
function insertPragma(text) {
+2 -2
View File
@@ -493,14 +493,14 @@ function countNewLines(string) {
function countLeadingNewLines(string) {
/* istanbul ignore next */
string = typeof string === "string" ? string : "";
const newLines = (string.match(/^([^\S\r\n]*[\r\n])+/g) || [])[0] || "";
const newLines = (string.match(/^([^\S\n\r]*[\n\r])+/g) || [])[0] || "";
return countNewLines(newLines);
}
function countTrailingNewLines(string) {
/* istanbul ignore next */
string = typeof string === "string" ? string : "";
const newLines = (string.match(/([\r\n][^\S\r\n]*)+$/g) || [])[0] || "";
const newLines = (string.match(/([\n\r][^\S\n\r]*)+$/g) || [])[0] || "";
return countNewLines(newLines);
}
+3 -3
View File
@@ -3,11 +3,11 @@
// https://css-tricks.com/how-to-create-an-ie-only-stylesheet
// <!--[if ... ]> ... <![endif]-->
const IE_CONDITIONAL_START_END_COMMENT_REGEX = /^(\[if([^\]]*?)\]>)([\s\S]*?)<!\s*\[endif\]$/;
const IE_CONDITIONAL_START_END_COMMENT_REGEX = /^(\[if([^\]]*?)]>)([\S\s]*?)<!\s*\[endif]$/;
// <!--[if ... ]><!-->
const IE_CONDITIONAL_START_COMMENT_REGEX = /^\[if([^\]]*?)\]><!$/;
const IE_CONDITIONAL_START_COMMENT_REGEX = /^\[if([^\]]*?)]><!$/;
// <!--<![endif]-->
const IE_CONDITIONAL_END_COMMENT_REGEX = /^<!\s*\[endif\]$/;
const IE_CONDITIONAL_END_COMMENT_REGEX = /^<!\s*\[endif]$/;
const REGEX_PARSE_TUPLES = [
[IE_CONDITIONAL_START_END_COMMENT_REGEX, parseIeConditionalStartEndComment],
+1 -1
View File
@@ -13,7 +13,7 @@ const getCssStyleTags = (property) =>
htmlStyle.selectorText
.split(",")
.map((selector) => selector.trim())
.filter((selector) => /^[a-zA-Z0-9]+$/.test(selector))
.filter((selector) => /^[\dA-Za-z]+$/.test(selector))
.map((tagName) => [tagName, htmlStyle.style[property]])
)
)
+2 -2
View File
@@ -93,7 +93,7 @@ function ngHtmlParser(
attr.value = null;
} else {
attr.value = attr.valueSpan.toString();
if (/['"]/.test(attr.value[0])) {
if (/["']/.test(attr.value[0])) {
attr.value = attr.value.slice(1, -1);
}
}
@@ -204,7 +204,7 @@ function _parse(text, options, parserOptions, shouldParseFrontMatter = true) {
const parseSubHtml = (subContent, startSpan) => {
const { offset } = startSpan;
const fakeContent = text.slice(0, offset).replace(/[^\r\n]/g, " ");
const fakeContent = text.slice(0, offset).replace(/[^\n\r]/g, " ");
const realContent = subContent;
const subAst = _parse(
fakeContent + realContent,
+2 -2
View File
@@ -232,7 +232,7 @@ function extractInterpolation(ast, options) {
return ast;
}
const interpolationRegex = /\{\{([\s\S]+?)\}\}/g;
const interpolationRegex = /{{([\S\s]+?)}}/g;
return ast.map((node) => {
if (!canHaveInterpolation(node)) {
return node;
@@ -337,7 +337,7 @@ function extractWhitespaces(ast /*, options*/) {
const localChildren = [];
const [, leadingSpaces, text, trailingSpaces] = child.value.match(
/^(\s*)([\s\S]*?)(\s*)$/
/^(\s*)([\S\s]*?)(\s*)$/
);
if (leadingSpaces) {
+2 -2
View File
@@ -120,7 +120,7 @@ function embed(path, print, textToDoc, options) {
// lwc: html`<my-element data-for={value}></my-element>`
if (options.parser === "lwc") {
const interpolationRegex = /^\{[\s\S]*\}$/;
const interpolationRegex = /^{[\S\s]*}$/;
if (
interpolationRegex.test(
options.originalText.slice(
@@ -1100,7 +1100,7 @@ function printEmbeddedAttributeValue(node, originalTextToDoc, options) {
);
}
const interpolationRegex = /\{\{([\s\S]+?)\}\}/g;
const interpolationRegex = /{{([\S\s]+?)}}/g;
const value = getValue();
if (interpolationRegex.test(value)) {
const parts = [];
+3 -3
View File
@@ -29,7 +29,7 @@ function printVueFor(value, textToDoc) {
// modified from https://github.com/vuejs/vue/blob/v2.5.17/src/compiler/parser/index.js#L370-L387
function parseVueFor(value) {
const forAliasRE = /([^]*?)\s+(in|of)\s+([^]*)/;
const forIteratorRE = /,([^,}\]]*)(?:,([^,}\]]*))?$/;
const forIteratorRE = /,([^,\]}]*)(?:,([^,\]}]*))?$/;
const stripParensRE = /^\(|\)$/g;
const inMatch = value.match(forAliasRE);
@@ -69,9 +69,9 @@ function printVueSlotScope(value, textToDoc) {
function isVueEventBindingExpression(eventBindingValue) {
// https://github.com/vuejs/vue/blob/v2.5.17/src/compiler/codegen/events.js#L3-L4
// arrow function or anonymous function
const fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/;
const fnExpRE = /^([\w$]+|\([^)]*?\))\s*=>|^function\s*\(/;
// simple member expression chain (a, a.b, a['b'], a["b"], a[0], a[b])
const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/;
const simplePathRE = /^[$A-Z_a-z][\w$]*(?:\.[$A-Z_a-z][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[$A-Z_a-z][\w$]*])*$/;
// https://github.com/vuejs/vue/blob/v2.5.17/src/compiler/helpers.js#L104
const value = eventBindingValue.trim();
+1 -1
View File
@@ -951,7 +951,7 @@ function getGapRegex(enclosingNode) {
) {
// Support degenerate single-element unions and intersections.
// E.g.: `type A = /* 1 */ & B`
return /^[\s(&|]*$/;
return /^[\s&(|]*$/;
}
}
+4 -4
View File
@@ -94,11 +94,11 @@ function embed(path, print, textToDoc, options) {
lines[numLines - 2].trim() === "";
const commentsAndWhitespaceOnly = lines.every((line) =>
/^\s*(?:#[^\r\n]*)?$/.test(line)
/^\s*(?:#[^\n\r]*)?$/.test(line)
);
// Bail out if an interpolation occurs within a comment.
if (!isLast && /#[^\r\n]*$/.test(lines[numLines - 1])) {
if (!isLast && /#[^\n\r]*$/.test(lines[numLines - 1])) {
return null;
}
@@ -204,7 +204,7 @@ function getIndentation(str) {
}
function uncook(cookedValue) {
return cookedValue.replace(/([\\`]|\$\{)/g, "\\$1");
return cookedValue.replace(/([\\`]|\${)/g, "\\$1");
}
function escapeTemplateCharacters(doc, raw) {
@@ -292,7 +292,7 @@ function replacePlaceholders(quasisDoc, expressionDocs) {
const placeholder = parts[atPlaceholderIndex];
const rest = parts.slice(atPlaceholderIndex + 1);
const placeholderMatch = placeholder.match(
/@prettier-placeholder-(.+)-id([\s\S]*)/
/@prettier-placeholder-(.+)-id([\S\s]*)/
);
const placeholderID = placeholderMatch[1];
// When the expression has a suffix appended, like:
+2 -2
View File
@@ -3641,7 +3641,7 @@ function printPathNoParens(path, options, print, args) {
)
);
case "NGMicrosyntaxKey":
return /^[a-z_$][a-z0-9_$]*(-[a-z_$][a-z0-9_$])*$/i.test(n.name)
return /^[$_a-z][\w$]*(-[$_a-z][\w$])*$/i.test(n.name)
? n.name
: JSON.stringify(n.name);
case "NGMicrosyntaxExpression":
@@ -5114,7 +5114,7 @@ function printMemberChain(path, options, print) {
// letter or just a sequence of _$. The rationale is that they are
// likely to be factories.
function isFactory(name) {
return /^[A-Z]|^[_$]+$/.test(name);
return /^[A-Z]|^[$_]+$/.test(name);
}
// In case the Identifier is shorter than tab width, we can keep the
+1 -1
View File
@@ -731,7 +731,7 @@ function isJestEachTemplateLiteral(node, parentNode) {
*
* Ref: https://github.com/facebook/jest/pull/6102
*/
const jestEachTriggerRegex = /^[xf]?(describe|it|test)$/;
const jestEachTriggerRegex = /^[fx]?(describe|it|test)$/;
return (
parentNode.type === "TaggedTemplateExpression" &&
parentNode.quasi === node &&
+1 -1
View File
@@ -13,7 +13,7 @@ function embed(path, print, textToDoc, options) {
if (node.type === "code" && node.lang !== null) {
// only look for the first string so as to support [markdown-preview-enhanced](https://shd101wyy.github.io/markdown-preview-enhanced/#/code-chunk)
const langMatch = node.lang.match(/^[A-Za-z0-9_-]+/);
const langMatch = node.lang.match(/^[\w-]+/);
const lang = langMatch ? langMatch[0] : "";
const parser = getParserName(lang);
if (parser) {
+1 -1
View File
@@ -80,7 +80,7 @@ function liquid() {
proto.inlineTokenizers.liquid = tokenizer;
function tokenizer(eat, value) {
const match = value.match(/^({%[\s\S]*?%}|{{[\s\S]*?}})/);
const match = value.match(/^({%[\S\s]*?%}|{{[\S\s]*?}})/);
if (match) {
return eat(match[0])({
+4 -4
View File
@@ -81,7 +81,7 @@ function genericPrint(path, options, print) {
return printChildren(path, options, print);
case "word":
return node.value
.replace(/[*$]/g, "\\$&") // escape all `*` and `$` (math)
.replace(/[$*]/g, "\\$&") // escape all `*` and `$` (math)
.replace(
new RegExp(
[
@@ -103,7 +103,7 @@ function genericPrint(path, options, print) {
const proseWrap =
// leading char that may cause different syntax
nextNode && /^>|^([-+*]|#{1,6}|[0-9]+[.)])$/.test(nextNode.value)
nextNode && /^>|^([*+-]|#{1,6}|\d+[).])$/.test(nextNode.value)
? "never"
: options.proseWrap;
@@ -236,7 +236,7 @@ function genericPrint(path, options, print) {
privateUtil.getLast(parentNode.children) === node
? node.value.trimEnd()
: node.value;
const isHtmlComment = /^<!--[\s\S]*-->$/.test(value);
const isHtmlComment = /^<!--[\S\s]*-->$/.test(value);
return concat(
replaceEndOfLineWith(
value,
@@ -951,7 +951,7 @@ function clean(ast, newObj, parent) {
}
if (ast.type === "inlineCode") {
newObj.value = ast.value.replace(/[ \t\n]+/g, " ");
newObj.value = ast.value.replace(/[\t\n ]+/g, " ");
}
// for insert pragma
+1 -1
View File
@@ -52,7 +52,7 @@ function splitText(text, options) {
? text
: text.replace(new RegExp(`(${cjkPattern})\n(${cjkPattern})`, "g"), "$1$2")
)
.split(/([ \t\n]+)/)
.split(/([\t\n ]+)/)
.forEach((token, index, tokens) => {
// whitespace
if (index % 2 === 1) {
+1 -1
View File
@@ -5,7 +5,7 @@ function isPragma(text) {
}
function hasPragma(text) {
return /^\s*#[^\n\S]*@(prettier|format)\s*?(\n|$)/.test(text);
return /^\s*#[^\S\n]*@(prettier|format)\s*?(\n|$)/.test(text);
}
function insertPragma(text) {
+1 -1
View File
@@ -246,7 +246,7 @@ function getBlockValueLineContents(
: options.originalText
.slice(node.position.start.offset, node.position.end.offset)
// exclude open line `>` or `|`
.match(/^[^\n]*?\n([\s\S]*)$/)[1];
.match(/^[^\n]*?\n([\S\s]*)$/)[1];
const leadingSpaceCount =
node.indent === null
+1 -1
View File
@@ -95,7 +95,7 @@ function testPatterns(namePrefix, cliArgs, expected = {}) {
(namePrefix ? namePrefix + ": " : "") +
"prettier " +
cliArgs
.map((arg) => (/^[\w.=/-]+$/.test(arg) ? arg : `'${arg}'`))
.map((arg) => (/^[\w./=-]+$/.test(arg) ? arg : `'${arg}'`))
.join(" ");
describe(testName, () => {