Remove useless u flags in regular expressions (#18509)

This commit is contained in:
fisker Cheung authored and GitHub committed 2025-12-21 23:44:08 +08:00
1 parent 97f2e81d06
commit c9eb4bcd9e
131 files changed
+388 -405

No files matched your search

+2 -3
View File
@@ -13,12 +13,11 @@ for (const size of [1, 1e1, 1e2]) {
},
{
loop: () => trimIndentation(text).text,
"RegExp (inline)": () => text.replace(/[ \t]*$/u, ""),
"RegExp (inline)": () => text.replace(/[ \t]*$/, ""),
"RegExp (stored)": (
(regexp) => () =>
text.replace(regexp, "")
)(/[ \t]*$/gu),
"RegExp (no `u` flag)": () => text.replace(/[ \t]*$/, ""),
)(/[ \t]*$/g),
},
);
}
+6
View File
@@ -140,6 +140,12 @@ const configs = [
exceptRange: true,
},
],
"no-restricted-syntax": [
"error",
// Forbid `u` flag in regexp, kept for refactoring
// "Literal[regex.flags=/u/]",
// 'NewExpression[callee.name="RegExp"] > Literal.arguments:nth-child(2)[value=/u/]',
],
// Internal rules
"prettier-internal-rules/jsx-identifier-case": "error",
+2 -2
View File
@@ -49,7 +49,7 @@ function getEsbuildOptions({ packageConfig, file, cliOptions, buildOptions }) {
process(text) {
const exports = [
...text.matchAll(
/(?<=\n)exports\.(?<specifier>\w+) = \k<specifier>;/gu,
/(?<=\n)exports\.(?<specifier>\w+) = \k<specifier>;/g,
),
].map((match) => match.groups.specifier);
@@ -93,7 +93,7 @@ function getEsbuildOptions({ packageConfig, file, cliOptions, buildOptions }) {
// #12493, not sure what the problem is, but replace the cjs version with esm version seems fix it
{
module: require.resolve("tslib"),
path: require.resolve("tslib").replace(/tslib\.js$/u, "tslib.es6.js"),
path: require.resolve("tslib").replace(/tslib\.js$/, "tslib.es6.js"),
},
// https://github.com/evanw/esbuild/issues/2103
{
+1 -1
View File
@@ -61,7 +61,7 @@ async function inlineWasmBinary(directory) {
`;
text = text.replaceAll(
/new URL\((?<url>".*?"), import\.meta\.url\)/gu,
/new URL\((?<url>".*?"), import\.meta\.url\)/g,
"{/* $<url> */}",
);
@@ -17,7 +17,7 @@ function esmifyTypescriptEslint(text) {
*/
text = text.replaceAll(
// TODO: Use duplicate capture group name when eslint supports
/(?<=\n)(?:const|let|var) (?<variable>\w+) = (?:__importStar\(require\(["'](?<moduleName1>.*?)["']\)\)|require\(["'](?<moduleName2>.*?)["']\));/gu,
/(?<=\n)(?:const|let|var) (?<variable>\w+) = (?:__importStar\(require\(["'](?<moduleName1>.*?)["']\)\)|require\(["'](?<moduleName2>.*?)["']\));/g,
(...args) => {
const groups = args.at(-1);
return `import * as ${groups.variable} from "${groups.moduleName1 || groups.moduleName2}";`;
@@ -35,7 +35,7 @@ function esmifyTypescriptEslint(text) {
````
*/
text = text.replaceAll(
/(?<=\n)(?:const|let|var) (?<variable>\w+) = __importDefault\(require\(["'](?<moduleName>.*?)["']\)\);/gu,
/(?<=\n)(?:const|let|var) (?<variable>\w+) = __importDefault\(require\(["'](?<moduleName>.*?)["']\)\);/g,
outdent`
import $<variable>_default_export from "$<moduleName>";
const $<variable> = {default: $<variable>_default_export};
@@ -57,9 +57,9 @@ function esmifyTypescriptEslint(text) {
"",
);
text = text.replaceAll(/(?<=\n)(?:exports\.\w+ = )+void 0;/gu, "");
text = text.replaceAll(/(?<=\n)(?:exports\.\w+ = )+void 0;/g, "");
text = text.replaceAll(
/(?<=\n)exports\.(?<specifier>\w+) = (?<variable>\w+);/gu,
/(?<=\n)exports\.(?<specifier>\w+) = (?<variable>\w+);/g,
(...args) => {
const { variable, specifier } = args.at(-1);
if (specifier === variable) {
@@ -71,7 +71,7 @@ function esmifyTypescriptEslint(text) {
);
text = text.replaceAll(
/(?<=\n)exports\.(?<specifier>\w+)(?= = `)/gu,
/(?<=\n)exports\.(?<specifier>\w+)(?= = `)/g,
"export const $<specifier>",
);
@@ -85,7 +85,7 @@ function esmifyTypescriptEslint(text) {
````
*/
text = text.replaceAll(
/(?<=\n)__exportStar\(require\(["'](?<moduleName>.*?)["']\), exports\);/gu,
/(?<=\n)__exportStar\(require\(["'](?<moduleName>.*?)["']\), exports\);/g,
'export * from "$<moduleName>";',
);
@@ -99,7 +99,7 @@ function esmifyTypescriptEslint(text) {
````
*/
text = text.replaceAll(
/(?<=\n)Object\.defineProperty\(exports, "(?<specifier>\w+)", \{ enumerable: true, get: function \(\) \{ return (?<value>.*?); \} \}\);/gu,
/(?<=\n)Object\.defineProperty\(exports, "(?<specifier>\w+)", \{ enumerable: true, get: function \(\) \{ return (?<value>.*?); \} \}\);/g,
"export const $<specifier> = $<value>;",
);
@@ -114,7 +114,7 @@ function esmifyTypescriptEslint(text) {
````
*/
text = text.replaceAll(
/(?<=\n)exports\.(?<specifier>\w+) = __importStar\(require\(["'](?<moduleName>.*?)["']\)\);/gu,
/(?<=\n)exports\.(?<specifier>\w+) = __importStar\(require\(["'](?<moduleName>.*?)["']\)\);/g,
outdent`
import * as $<specifier>_namespace_export from "$<moduleName>";
export {$<specifier>_namespace_export as $<specifier>};
@@ -136,7 +136,7 @@ function esmifyTypescriptEslint(text) {
```
*/
text = text.replaceAll(
/(?<=\n\}\))\((?<name>\S+) \|\| \(exports\.\k<name> = \k<name> = \{\}\)\);/gu,
/(?<=\n\}\))\((?<name>\S+) \|\| \(exports\.\k<name> = \k<name> = \{\}\)\);/g,
outdent`
($<name> ??= {});
export {$<name>};
@@ -6,7 +6,7 @@ import { PROJECT_ROOT, writeFile } from "../../utilities/index.js";
import UNUSED_SPECIFIERS from "./typescript-unused-specifiers.js";
function* getModules(text) {
const parts = text.split(/(?<=\n)(\/\/ src\/\S+\n)/u);
const parts = text.split(/(?<=\n)(\/\/ src\/\S+\n)/);
let start = parts[0].length;
@@ -73,7 +73,7 @@ class TypeScriptModuleSource {
escapeStringRegexp(end),
"(?=\n)",
].join(""),
"gsu",
"gs",
);
this.#source.replaceAll(regexp, replacement);
@@ -150,7 +150,7 @@ function getExports(entry) {
const exports = lines
.map((line) => {
const match = line.match(
/^\s*(?<specifier>.*?): \(\) => (?<variable>.*?),?$/u,
/^\s*(?<specifier>.*?): \(\) => (?<variable>.*?),?$/,
);
if (!match) {
@@ -26,11 +26,11 @@ function generatePackageJson(packageJson, { packageConfig }) {
return [
isPlugin ? `./plugins/${basename}` : `./${basename}`,
{
types: `./${file.output.replace(/\.js$/u, ".d.ts")}`,
types: `./${file.output.replace(/\.js$/, ".d.ts")}`,
// `module-sync` condition can prevent CJS plugins from working: https://github.com/prettier/prettier/issues/17139
// Perform a test before re-adding it.
require: `./${file.output}`,
default: `./${file.output.replace(/\.js$/u, ".mjs")}`,
default: `./${file.output.replace(/\.js$/, ".mjs")}`,
},
];
}),
@@ -56,7 +56,7 @@ function generatePackageJson(packageJson, { packageConfig }) {
[`./parser-${basename}.js`, `./${file.output}`],
[
`./esm/parser-${basename}.mjs`,
`./${file.output.replace(/\.js$/u, ".mjs")}`,
`./${file.output.replace(/\.js$/, ".mjs")}`,
],
];
}),
+28 -28
View File
@@ -99,17 +99,17 @@ const mainModule = {
);
text = text.replaceAll(
/(?<=\n)let tokenize;\n\{\n.*?\n\}(?=\n)/gsu,
/(?<=\n)let tokenize;\n\{\n.*?\n\}(?=\n)/gs,
"",
);
text = text.replaceAll(
/(?<=\n)function highlight\(text\) \{\n.*?\n\}(?=\n)/gsu,
/(?<=\n)function highlight\(text\) \{\n.*?\n\}(?=\n)/gs,
"function highlight(text) {return text}",
);
text = text.replaceAll(
/(?<=\n)function getDefs\(enabled\) \{\n.*?\n\}(?=\n)/gsu,
/(?<=\n)function getDefs\(enabled\) \{\n.*?\n\}(?=\n)/gs,
outdent`
function getDefs() {
return new Proxy({}, {get: () => (text) => text})
@@ -269,7 +269,7 @@ const pluginFiles = [
module: require.resolve("@babel/parser"),
process: (text) =>
text.replaceAll(
/const entity\s?=\s?entities\[desc\];/gu,
/const entity\s?=\s?entities\[desc\];/g,
"const entity = undefined;",
),
},
@@ -360,7 +360,7 @@ const pluginFiles = [
{
module: "*",
process(text, file) {
if (/require\(["'](?:typescript|ts-api-utils)["']\)/u.test(text)) {
if (/require\(["'](?:typescript|ts-api-utils)["']\)/.test(text)) {
throw new Error(`Unexpected \`require("typescript")\` in ${file}.`);
}
@@ -476,7 +476,7 @@ const pluginFiles = [
process(text) {
const typescriptVariables = [
...text.matchAll(
/import (?<variable>\w+) from ["']typescript["']/gu,
/import (?<variable>\w+) from ["']typescript["']/g,
),
].map((match) => match.groups.variable);
@@ -484,13 +484,13 @@ const pluginFiles = [
text = text.replaceAll(
new RegExp(
String.raw`".*?" in (?:${typescriptVariables.join("|")})(?=\W)`,
"gu",
"g",
),
"true",
);
text = text.replaceAll(
/(?<=import )(?=\w+ from ["']typescript["'])/gu,
/(?<=import )(?=\w+ from ["']typescript["'])/g,
"* as ",
);
@@ -601,10 +601,10 @@ const pluginFiles = [
);
text = text.replace("const _visitor = new _Visitor$2()", "");
text = text.replaceAll(
/const (.*?) = new BuiltinType\(BuiltinTypeName\..*?\);/gu,
/const (.*?) = new BuiltinType\(BuiltinTypeName\..*?\);/g,
"const $1 = undefined;",
);
text = text.replaceAll(/var output_ast =.*?;\n/gsu, "var output_ast");
text = text.replaceAll(/var output_ast =.*?;\n/gs, "var output_ast");
text = text.replace(
"const serializer = new IcuSerializerVisitor();",
@@ -616,62 +616,62 @@ const pluginFiles = [
);
text = text.replaceAll(
/function transformExpressionsInExpression\(.*?\n.*?\n\}\n/gsu,
/function transformExpressionsInExpression\(.*?\n.*?\n\}\n/gs,
"function transformExpressionsInExpression(){}",
);
text = text.replaceAll(
/const deferTriggerToR3TriggerInstructionsMap = new Map\(\[\n.*?\n\]\);\n/gsu,
/const deferTriggerToR3TriggerInstructionsMap = new Map\(\[\n.*?\n\]\);\n/gs,
"const deferTriggerToR3TriggerInstructionsMap = undefined;",
);
text = text.replaceAll(
/const BINARY_OPERATORS = new Map\(\[\n.*?\n\]\);\n/gsu,
/const BINARY_OPERATORS = new Map\(\[\n.*?\n\]\);\n/gs,
"const BINARY_OPERATORS = undefined;",
);
text = text.replaceAll(
/const PIPE_BINDINGS = \[\n.*?\n\];\n/gsu,
/const PIPE_BINDINGS = \[\n.*?\n\];\n/gs,
"const PIPE_BINDINGS = undefined;",
);
text = text.replaceAll(
/const TEXT_INTERPOLATE_CONFIG = \{\n.*?\n\};\n/gsu,
/const TEXT_INTERPOLATE_CONFIG = \{\n.*?\n\};\n/gs,
"const TEXT_INTERPOLATE_CONFIG = undefined;",
);
text = text.replaceAll(
/const CHAINABLE = new Set\(\[\n.*?\n\]\);\n/gsu,
/const CHAINABLE = new Set\(\[\n.*?\n\]\);\n/gs,
"const CHAINABLE = undefined;",
);
text = text.replaceAll(
/const PROPERTY_INTERPOLATE_CONFIG = \{\n.*?\n\};\n/gsu,
/const PROPERTY_INTERPOLATE_CONFIG = \{\n.*?\n\};\n/gs,
"const PROPERTY_INTERPOLATE_CONFIG = undefined;",
);
text = text.replaceAll(
/const STYLE_PROP_INTERPOLATE_CONFIG = \{\n.*?\n\};\n/gsu,
/const STYLE_PROP_INTERPOLATE_CONFIG = \{\n.*?\n\};\n/gs,
"const STYLE_PROP_INTERPOLATE_CONFIG = undefined;",
);
text = text.replaceAll(
/const ATTRIBUTE_INTERPOLATE_CONFIG = \{\n.*?\n\};\n/gsu,
/const ATTRIBUTE_INTERPOLATE_CONFIG = \{\n.*?\n\};\n/gs,
"const ATTRIBUTE_INTERPOLATE_CONFIG = undefined;",
);
text = text.replaceAll(
/const STYLE_MAP_INTERPOLATE_CONFIG = \{\n.*?\n\};\n/gsu,
/const STYLE_MAP_INTERPOLATE_CONFIG = \{\n.*?\n\};\n/gs,
"const STYLE_MAP_INTERPOLATE_CONFIG = undefined;",
);
text = text.replaceAll(
/const CLASS_MAP_INTERPOLATE_CONFIG = \{\n.*?\n\};\n/gsu,
/const CLASS_MAP_INTERPOLATE_CONFIG = \{\n.*?\n\};\n/gs,
"const CLASS_MAP_INTERPOLATE_CONFIG = undefined;",
);
text = text.replaceAll(
/const PURE_FUNCTION_CONFIG = \{\n.*?\n\};\n/gsu,
/const PURE_FUNCTION_CONFIG = \{\n.*?\n\};\n/gs,
"const PURE_FUNCTION_CONFIG = undefined;",
);
text = text.replaceAll(
/const NAMED_ENTITIES = \{\n.*?\n\};\n/gsu,
/const NAMED_ENTITIES = \{\n.*?\n\};\n/gs,
"const NAMED_ENTITIES = {};",
);
@@ -749,15 +749,15 @@ const pluginFiles = [
);
// This passed to plugins, our plugin don't need access to the options
text = text.replace(/(?<=\sconst syntax = )\{.*?\n\}(?=;\n)/su, "{}");
text = text.replace(/(?<=\sconst syntax = )\{.*?\n\}(?=;\n)/s, "{}");
text = text.replaceAll(
/\sclass \S+ extends[(\s]+node\(.*?\).*?\{(?:\n.*?\n)?\}\n/gsu,
/\sclass \S+ extends[(\s]+node\(.*?\).*?\{(?:\n.*?\n)?\}\n/gs,
"\n",
);
text = text.replaceAll(
/\nvar api\S* = \s*(?:\/\*#__PURE__\*\/)?\s*Object\.freeze\(\{.*?\n\}\);/gsu,
/\nvar api\S* = \s*(?:\/\*#__PURE__\*\/)?\s*Object\.freeze\(\{.*?\n\}\);/gs,
"",
);
@@ -777,7 +777,7 @@ const pluginFiles = [
);
text = text.replace(
/(?<=\n)export .*?;/u,
/(?<=\n)export .*?;/,
"export { preprocess, getVoidTags, visitorKeys };",
);
@@ -801,7 +801,7 @@ function createPluginModule(file) {
const { input, ...buildOptions } = file;
const { pluginName } = input.match(
/\/plugins\/(?<pluginName>.*?)\.js$/u,
/\/plugins\/(?<pluginName>.*?)\.js$/,
).groups;
const umdVariableName = `prettierPlugins.${pluginName}`;
@@ -66,7 +66,7 @@ function transformMethodCallToFunctionCall(node, functionName) {
function createMethodCallTransform({ methodName, argumentsLength }) {
const functionName = `__${methodName}`;
const fileName = `method-${methodName.replaceAll(
/[A-Z]/gu,
/[A-Z]/g,
(character) => `-${character.toLowerCase()}`,
)}.js`;
const functionImplementationUrl = new URL(
+1 -1
View File
@@ -34,7 +34,7 @@ const nextVersion = `${semver.major(version)}.${semver.minor(
const postGlob = path.join(blogDir, `????-??-??-${nextVersion}.md`);
const postFile = path.join(
blogDir,
`${new Date().toISOString().replace(/T.+/u, "")}-${nextVersion}.md`,
`${new Date().toISOString().replace(/T.+/, "")}-${nextVersion}.md`,
);
const categoriesByDir = new Map(
@@ -66,20 +66,20 @@ function toDts(text) {
text = text.replaceAll("'use strict';", " ");
// `{+foo: string}` -> `{foo: string}`
text = text.replaceAll(/(?<=\n)(?<indention>[ {2}]+)\+/gu, "$<indention>");
text = text.replaceAll(/(?<=\n)(?<indention>[ {2}]+)\+/g, "$<indention>");
// `{foo: interface {}}` -> `{foo: {}}`
text = text.replaceAll(": interface {", ": {");
// `{foo: interface extends T {}}` -> `{foo: T & {}}`
text = text.replaceAll(
/(?<=: )interface extends (?<type>\w+)(?= \{)/gu,
/(?<=: )interface extends (?<type>\w+)(?= \{)/g,
"$<type> & ",
);
// `$ReadOnlyArray<?T>` -> `ReadonlyArray<T | null>`
text = text.replaceAll(
/\$ReadOnlyArray<\?(\w+)>/gu,
/\$ReadOnlyArray<\?(\w+)>/g,
"ReadonlyArray<$1 | null>",
);
@@ -91,7 +91,7 @@ function toDts(text) {
// `{[string]: T}` -> `{[key: string]: T}`
text = text.replaceAll(
/(?<=\n)(?<indention>[ {2}]+)\[(?<type>string)\](?=: )/gu,
/(?<=\n)(?<indention>[ {2}]+)\[(?<type>string)\](?=: )/g,
"$<indention>[key: $<type>]",
);
@@ -19,7 +19,7 @@ async function getRemovedSpecifiers(code, exports) {
const specifiers = [];
for (const { text } of errors) {
const match = text.match(
/^"(?<variable>.*?)" is not declared in this file$/u,
/^"(?<variable>.*?)" is not declared in this file$/,
);
if (match) {
+5 -5
View File
@@ -39,14 +39,14 @@ for (const file of [
}
}
const authorRegex = /by @[\w-]+|by \[@([\w-]+)\]\(https:\/\/github\.com\/\1\)/u;
const titleRegex = /^#{4} (.*?)\((#\d{4,}|\[#\d{4,}\])/u;
const authorRegex = /by @[\w-]+|by \[@([\w-]+)\]\(https:\/\/github\.com\/\1\)/;
const titleRegex = /^#{4} (.*?)\((#\d{4,}|\[#\d{4,}\])/;
const template = fs.readFileSync(
new URL(TEMPLATE_FILE, CHANGELOG_ROOT),
"utf8",
);
const templateComments = template.match(/<!--.*?-->/gsu);
const templateComments = template.match(/<!--.*?-->/gs);
const [templateAuthorLink] = template.match(authorRegex);
const checkedFiles = new Map();
@@ -63,7 +63,7 @@ for (const category of CHANGELOG_CATEGORIES) {
continue;
}
const match = prFile.match(/^(\d{4,})(-\d+)?\.md$/u);
const match = prFile.match(/^(\d{4,})(-\d+)?\.md$/);
const displayPath = `${CHANGELOG_DIR}/${category}/${prFile}`;
if (!match) {
@@ -137,7 +137,7 @@ for (const category of CHANGELOG_CATEGORIES) {
);
}
if (/prettier master/iu.test(content)) {
if (/prettier master/i.test(content)) {
showErrorMessage(
`[${displayPath}]: Please use "main" instead of "master".`,
);
+1 -1
View File
@@ -9,7 +9,7 @@ import esbuild from "esbuild";
export async function getSource(url, context, defaultGetSource) {
if (
!/node_modules\/@babel\/(?:code-frame|highlight)/u.test(url) ||
!/node_modules\/@babel\/(?:code-frame|highlight)/.test(url) ||
context.format !== "module"
) {
return defaultGetSource(url, context, defaultGetSource);
+1 -1
View File
@@ -13,7 +13,7 @@ const jsFiles = packageBuildConfigs
.flatMap((packageConfig) =>
packageConfig.modules.flatMap((module) =>
module.files
.filter((file) => /\.[cm]?js$/u.test(file.output))
.filter((file) => /\.[cm]?js$/.test(file.output))
.map((file) => path.join(packageConfig.distDirectory, file.output)),
),
)
@@ -7,7 +7,7 @@ async function getNpmDependentsCount() {
fetchText("https://www.npmjs.com/package/prettier"),
);
const dependentsCountNpm = Number(
npmPage.match(/"dependentsCount":"(?<dependentsCount>\d+)",/u).groups
npmPage.match(/"dependentsCount":"(?<dependentsCount>\d+)",/).groups
.dependentsCount,
);
if (Number.isNaN(dependentsCountNpm)) {
@@ -28,7 +28,7 @@ async function getGithubDependentsCount() {
githubPage
.replaceAll("\n", "")
.match(
/<svg.*?octicon-code-square.*?>.*?<\/svg>\s*(?<dependentsCount>[\d,]+)\s*Repositories\s*<\/a>/u,
/<svg.*?octicon-code-square.*?>.*?<\/svg>\s*(?<dependentsCount>[\d,]+)\s*Repositories\s*<\/a>/,
)
.groups.dependentsCount.replaceAll(",", ""),
);
@@ -54,14 +54,14 @@ async function update({ repo }) {
processFile("website/src/pages/index.jsx", (content) => {
if (dependentsCountNpm) {
content = content.replace(
/(<strong data-placeholder="dependent-npm">)(.*?)(<\/strong>)/u,
/(<strong data-placeholder="dependent-npm">)(.*?)(<\/strong>)/,
`$1${formatNumber(dependentsCountNpm)}$3`,
);
}
if (dependentsCountGithub) {
content = content.replace(
/(<strong data-placeholder="dependent-github">)(.*?)(<\/strong>)/u,
/(<strong data-placeholder="dependent-github">)(.*?)(<\/strong>)/,
`$1${formatNumber(dependentsCountGithub)}$3`,
);
}
+3 -5
View File
@@ -12,16 +12,14 @@ export default async function updateVersion({ version, next }) {
// Update github issue templates
processFile(".github/ISSUE_TEMPLATE/formatting.md", (content) =>
content.replace(/^(\*\*Prettier ).*?(\*\*)$/mu, `$1${version}$2`),
content.replace(/^(\*\*Prettier ).*?(\*\*)$/m, `$1${version}$2`),
);
processFile(".github/ISSUE_TEMPLATE/integration.md", (content) =>
content.replace(/^(- Prettier Version: ).*$/mu, `$1${version}`),
content.replace(/^(- Prettier Version: ).*$/m, `$1${version}`),
);
await runYarn(["install"], { cwd: "./website" });
process.env.PRETTIER_VERSION = version;
await runYarn(["update-stable-docs"], {
cwd: "./website",
});
await runYarn(["update-stable-docs"], { cwd: "./website" });
}
+1 -1
View File
@@ -50,7 +50,7 @@ for (const packageConfig of packageBuildConfigs) {
/* `require` in `parser-typescript.js`, #12338 */
for (const module of modules) {
for (const file of module.files) {
if (!/\.m?js$/u.test(file.output) || excludedFiles.has(file.output)) {
if (!/\.m?js$/.test(file.output) || excludedFiles.has(file.output)) {
continue;
}
console.log(`${file.output}: `);
+8 -8
View File
@@ -48,7 +48,7 @@ export function getEntries(dirPath, options) {
const filePath = path.join(dirPath, fileName);
let [title, ...rest] = fs.readFileSync(filePath, "utf8").trim().split("\n");
const improvement = title.match(/\[IMPROVEMENT(:(\d+))?\]/u);
const improvement = title.match(/\[IMPROVEMENT(:(\d+))?\]/);
const section = title.includes("[HIGHLIGHT]")
? "highlight"
@@ -100,11 +100,11 @@ export function replaceVersions(data, prevVer, newVer, isPatch = false) {
return data
.replaceAll(
/prettier stable/giu,
/prettier stable/gi,
`Prettier ${isPatch ? prevVer : formatVersion(prevVer)}`,
)
.replaceAll(
/prettier main/giu,
/prettier main/gi,
`Prettier ${isPatch ? newVer : formatVersion(newVer)}`,
);
}
@@ -115,12 +115,12 @@ function formatVersion(version) {
function processTitle(title) {
return title
.replaceAll(/\[(BREAKING|HIGHLIGHT|IMPROVEMENT(:\d+)?)\]/gu, "")
.replaceAll(/\s+/gu, " ")
.replace(/^#{4} [a-z]/u, (s) => s.toUpperCase())
.replaceAll(/(?<![[`])@([\w-]+)/gu, "[@$1](https://github.com/$1)")
.replaceAll(/\[(BREAKING|HIGHLIGHT|IMPROVEMENT(:\d+)?)\]/g, "")
.replaceAll(/\s+/g, " ")
.replace(/^#{4} [a-z]/, (s) => s.toUpperCase())
.replaceAll(/(?<![[`])@([\w-]+)/g, "[@$1](https://github.com/$1)")
.replaceAll(
/(?<![[`])#(\d{4,})/gu,
/(?<![[`])#(\d{4,})/g,
"[#$1](https://github.com/prettier/prettier/pull/$1)",
);
}
+1 -1
View File
@@ -75,7 +75,7 @@ class Context {
/* c8 ignore start */
const { PRETTIER_PERF_REPEAT } = process.env;
if (PRETTIER_PERF_REPEAT && /^\d+$/u.test(PRETTIER_PERF_REPEAT)) {
if (PRETTIER_PERF_REPEAT && /^\d+$/.test(PRETTIER_PERF_REPEAT)) {
return {
name: "PRETTIER_PERF_REPEAT (environment variable)",
debugRepeat: Number(PRETTIER_PERF_REPEAT),
+1 -1
View File
@@ -48,7 +48,7 @@ function handleError(context, filename, error, printedFilename, ignoreUnknown) {
}
const isParseError = Boolean(error?.loc);
const isValidationError = /^Invalid \S+ value\./u.test(error?.message);
const isValidationError = /^Invalid \S+ value\./.test(error?.message);
if (isParseError) {
// `invalid.js: SyntaxError: Unexpected token (1:1)`.
+1 -1
View File
@@ -43,7 +43,7 @@ function createLogger(logLevel = "log") {
...options,
};
message =
message.replaceAll(/^/gmu, prefix) + (options.newline ? "\n" : "");
message.replaceAll(/^/gm, prefix) + (options.newline ? "\n" : "");
stream.write(message);
if (options.clearable) {
+1 -1
View File
@@ -8,7 +8,7 @@ const CHOICE_USAGE_MARGIN = 3;
const CHOICE_USAGE_INDENTATION = 2;
function indent(str, spaces) {
return str.replaceAll(/^/gmu, " ".repeat(spaces));
return str.replaceAll(/^/gm, " ".repeat(spaces));
}
function createDefaultValueDisplay(value) {
+4 -4
View File
@@ -40,9 +40,9 @@ function convertEndOfLineOptionToCharacter(endOfLineOption) {
}
const regexps = new Map([
[CHARACTER_LF, /\n/gu],
[CHARACTER_CR, /\r/gu],
[CHARACTER_CRLF, /\r\n/gu],
[CHARACTER_LF, /\n/g],
[CHARACTER_CR, /\r/g],
[CHARACTER_CRLF, /\r\n/g],
]);
/**
@param {string} text
@@ -63,7 +63,7 @@ function countEndOfLineCharacters(text, endOfLineCharacter) {
return text.match(regex)?.length ?? 0;
}
const END_OF_LINE_REGEXP = /\r\n?/gu;
const END_OF_LINE_REGEXP = /\r\n?/g;
/**
@param {string} text
@returns {string}
+7 -7
View File
@@ -31,7 +31,7 @@ function clean(original, cloned, parent) {
delete cloned.text;
// standalone pragma
if (/^\*\s*@(?:format|prettier)\s*$/u.test(original.text)) {
if (/^\*\s*@(?:format|prettier)\s*$/.test(original.text)) {
return null;
}
}
@@ -76,7 +76,7 @@ function clean(original, cloned, parent) {
}
if (original.type === "selector-combinator") {
cloned.value = cloned.value.replaceAll(/\s+/gu, " ");
cloned.value = cloned.value.replaceAll(/\s+/g, " ");
}
if (original.type === "media-feature") {
@@ -105,7 +105,7 @@ function clean(original, cloned, parent) {
cloned.unit = original.unit.toLowerCase();
}
if (original.type === "value-unknown") {
cloned.value = cloned.value.replaceAll(/;$/gu, "");
cloned.value = cloned.value.replaceAll(/;$/g, "");
}
if (original.type === "selector-attribute") {
@@ -118,7 +118,7 @@ function clean(original, cloned, parent) {
if (original.value) {
let { value } = cloned;
// Parser only understands the `i` flag
if (/\s[a-zA-Z]$/u.test(value)) {
if (/\s[a-z]$/i.test(value)) {
// Add an extra property to make sure flag is preserved
cloned.__prettier_attribute_selector_flag = value.at(-1);
value = value.slice(0, -1);
@@ -127,7 +127,7 @@ function clean(original, cloned, parent) {
value = value.trim();
value = value.replace(
/^(?<quote>["'])(?<value>.*?)\k<quote>$/u,
/^(?<quote>["'])(?<value>.*?)\k<quote>$/,
"$<value>",
);
@@ -147,7 +147,7 @@ function clean(original, cloned, parent) {
original.value
) {
cloned.value = cloned.value.replaceAll(
/([\d+.e-]+)([a-z]*)/giu,
/([\d+.e-]+)([a-z]*)/gi,
(match, numStr, unit) => {
const num = Number(numStr);
return Number.isNaN(num) ? match : num + unit.toLowerCase();
@@ -220,7 +220,7 @@ function clean(original, cloned, parent) {
clean.ignoredProperties = ignoredProperties;
function cleanCSSStrings(value) {
return value.replaceAll("'", '"').replaceAll(/\\([^\da-f])/giu, "$1");
return value.replaceAll("'", '"').replaceAll(/\\([^\da-f])/gi, "$1");
}
export default clean;
+2 -2
View File
@@ -109,7 +109,7 @@ function getValueRootOffset(node) {
if (node.type === "css-atrule" && typeof node.name === "string") {
result +=
1 + node.name.length + node.raws.afterName.match(/^\s*:?\s*/u)[0].length;
1 + node.name.length + node.raws.afterName.match(/^\s*:?\s*/)[0].length;
}
if (node.type !== "css-atrule" && typeof node.raws?.between === "string") {
@@ -238,7 +238,7 @@ function replaceQuotesInInlineComments(text) {
for (const [start, end] of inlineCommentsToReplace) {
text =
text.slice(0, start) +
text.slice(start, end).replaceAll(/["'*]/gu, " ") +
text.slice(start, end).replaceAll(/["'*]/g, " ") +
text.slice(end);
}
+1 -1
View File
@@ -6,7 +6,7 @@ function parseSelector(selector) {
// the content of the comment as selectors which turns it into complete
// garbage. Better to print the whole selector as-is and not try to parse
// and reformat it.
if (/\/[/*]/u.test(selector.replaceAll(/"[^"]+"|'[^']+'/gu, ""))) {
if (/\/[/*]/.test(selector.replaceAll(/"[^"]+"|'[^']+'/g, ""))) {
return {
type: "selector-unknown",
value: selector.trim(),
+1 -1
View File
@@ -192,7 +192,7 @@ function parseValue(value, options) {
const parsedResult = parseNestedValue(result, options);
return addTypePrefix(parsedResult, "value-", /^selector-/u);
return addTypePrefix(parsedResult, "value-", /^selector-/);
}
export default parseValue;
+6 -6
View File
@@ -19,8 +19,8 @@ import { hasIgnorePragma, hasPragma } from "./pragma.js";
import isModuleRuleName from "./utilities/is-module-rule-name.js";
import isSCSSNestedPropertyNode from "./utilities/is-scss-nested-property-node.js";
const DEFAULT_SCSS_DIRECTIVE = /(\s*)(!default).*$/u;
const GLOBAL_SCSS_DIRECTIVE = /(\s*)(!global).*$/u;
const DEFAULT_SCSS_DIRECTIVE = /(\s*)(!default).*$/;
const GLOBAL_SCSS_DIRECTIVE = /(\s*)(!global).*$/;
function parseNestedCSS(node, options) {
if (isObject(node)) {
@@ -232,7 +232,7 @@ function parseNestedCSS(node, options) {
// only css support custom-selector
if (options.parser === "css" && node.name === "custom-selector") {
const customSelector = node.params.match(/:--\S+\s+/u)[0].trim();
const customSelector = node.params.match(/:--\S+\s+/)[0].trim();
node.customSelector = customSelector;
node.selector = parseSelector(
node.params.slice(customSelector.length).trim(),
@@ -307,7 +307,7 @@ function parseNestedCSS(node, options) {
}
if (name === "at-root") {
if (/^\(\s*(?:without|with)\s*:.+\)$/su.test(params)) {
if (/^\(\s*(?:without|with)\s*:.+\)$/s.test(params)) {
node.params = parseValue(params, options);
} else {
node.selector = parseSelector(params);
@@ -344,11 +344,11 @@ function parseNestedCSS(node, options) {
) {
// Remove unnecessary spaces in SCSS variable arguments
// Move spaces after the `...`, so we can keep the range correct
params = params.replace(/(\$\S+?)(\s+)?\.{3}/u, "$1...$2");
params = params.replace(/(\$\S+?)(\s+)?\.{3}/, "$1...$2");
// Remove unnecessary spaces before SCSS control, mixin and function directives
// Move spaces after the `(`, so we can keep the range correct
// Only match the first function call at the beginning, not nested ones
params = params.replace(/^(?!if)([^"'\s(]+)(\s+)\(/u, "$1($2");
params = params.replace(/^(?!if)([^"'\s(]+)(\s+)\(/, "$1($2");
node.value = parseValue(params, options);
delete node.params;
+7 -7
View File
@@ -7,10 +7,10 @@ function printUnit(unit) {
return CSS_UNITS.has(lowercased) ? CSS_UNITS.get(lowercased) : unit;
}
const STRING_REGEX = /(["'])(?:(?!\1)[^\\]|\\.)*\1/gsu;
const NUMBER_REGEX = /(?:\d*\.\d+|\d+\.?)(?:e[+-]?\d+)?/giu;
const STANDARD_UNIT_REGEX = /[a-z]+/giu;
const WORD_PART_REGEX = /[$@]?[_a-z\u0080-\uFFFF][\w\u0080-\uFFFF-]*/giu;
const STRING_REGEX = /(["'])(?:(?!\1)[^\\]|\\.)*\1/gs;
const NUMBER_REGEX = /(?:\d*\.\d+|\d+\.?)(?:e[+-]?\d+)?/gi;
const STANDARD_UNIT_REGEX = /[a-z]+/gi;
const WORD_PART_REGEX = /[$@]?[_a-z\u0080-\uFFFF][\w\u0080-\uFFFF-]*/gi;
const ADJUST_NUMBERS_REGEX = new RegExp(
STRING_REGEX.source +
"|" +
@@ -18,7 +18,7 @@ const ADJUST_NUMBERS_REGEX = new RegExp(
`(${WORD_PART_REGEX.source})?` +
`(${NUMBER_REGEX.source})` +
`(${STANDARD_UNIT_REGEX.source})?`,
"giu",
"gi",
);
function adjustStrings(value, options) {
@@ -33,7 +33,7 @@ function quoteAttributeValue(value, options) {
// To support future flags, we simply check if it's an alphabet letter
// https://github.com/prettier/prettier/pull/17865#discussion_r2332698101
let flag = "";
const match = value.match(/^(?<value>.+?)\s+(?<flag>[a-zA-Z])$/u);
const match = value.match(/^(?<value>.+?)\s+(?<flag>[a-z])$/i);
if (match) {
({ value, flag } = match.groups);
}
@@ -72,7 +72,7 @@ function printCssNumber(rawNumber) {
return (
printNumber(rawNumber)
// Remove trailing `.0`.
.replace(/\.0(?=$|e)/u, "")
.replace(/\.0(?=$|e)/, "")
);
}
+9 -11
View File
@@ -112,7 +112,7 @@ function genericPrint(path, options, print) {
const isColon = trimmedBetween === ":";
const hasSpaceAfterColon = rawBetween.endsWith(" ") && isColon;
const isValueAllSpace =
typeof node.value === "string" && /^ *$/u.test(node.value);
typeof node.value === "string" && /^ *$/.test(node.value);
let value = typeof node.value === "string" ? node.value : print("value");
value = hasComposesNode(node) ? removeLines(value) : value;
@@ -126,7 +126,7 @@ function genericPrint(path, options, print) {
}
return [
node.raws.before.replaceAll(/[\s;]/gu, ""),
node.raws.before.replaceAll(/[\s;]/g, ""),
// Less variable
(parentNode.type === "css-atrule" && parentNode.variable) ||
insideIcssRuleNode(path)
@@ -147,17 +147,17 @@ function genericPrint(path, options, print) {
: "",
value,
node.raws.important
? node.raws.important.replace(/\s*!\s*important/iu, " !important")
? node.raws.important.replace(/\s*!\s*important/i, " !important")
: node.important
? " !important"
: "",
node.raws.scssDefault
? node.raws.scssDefault.replace(/\s*!default/iu, " !default")
? node.raws.scssDefault.replace(/\s*!default/i, " !default")
: node.scssDefault
? " !default"
: "",
node.raws.scssGlobal
? node.raws.scssGlobal.replace(/\s*!global/iu, " !global")
? node.raws.scssGlobal.replace(/\s*!global/i, " !global")
: node.scssGlobal
? " !global"
: "",
@@ -248,9 +248,9 @@ function genericPrint(path, options, print) {
? ""
: node.name.endsWith(":")
? " "
: /^\s*\n\s*\n/u.test(node.raws.afterName)
: /^\s*\n\s*\n/.test(node.raws.afterName)
? [hardline, hardline]
: /^\s*\n/u.test(node.raws.afterName)
: /^\s*\n/.test(node.raws.afterName)
? hardline
: " "
: " ",
@@ -323,7 +323,7 @@ function genericPrint(path, options, print) {
case "media-feature":
return maybeToLowerCase(
adjustStrings(node.value.replaceAll(/ +/gu, " "), options),
adjustStrings(node.value.replaceAll(/ +/g, " "), options),
);
case "media-colon":
@@ -337,9 +337,7 @@ function genericPrint(path, options, print) {
case "media-url":
return adjustStrings(
node.value
.replaceAll(/^url\(\s+/giu, "url(")
.replaceAll(/\s+\)$/gu, ")"),
node.value.replaceAll(/^url\(\s+/gi, "url(").replaceAll(/\s+\)$/g, ")"),
options,
);
+4 -4
View File
@@ -123,8 +123,8 @@ function isDetachedRulesetDeclarationNode(node) {
}
return (
(typeof selector === "string" && /^@.+:.*$/u.test(selector)) ||
(selector.value && /^@.+:.*$/u.test(selector.value))
(typeof selector === "string" && /^@.+:.*$/.test(selector)) ||
(selector.value && /^@.+:.*$/.test(selector.value))
);
}
@@ -194,7 +194,7 @@ function isSCSSControlDirectiveNode(node, options) {
}
function isDetachedRulesetCallNode(node) {
return node.raws?.params && /^\(\s*\)$/u.test(node.raws.params);
return node.raws?.params && /^\(\s*\)$/.test(node.raws.params);
}
function isTemplatePlaceholderNode(node) {
@@ -356,7 +356,7 @@ function isColorAdjusterFuncNode(node) {
}
function lastLineHasInlineComment(text) {
return /\/\//u.test(text.split(/[\n\r]/u).pop());
return /\/\//.test(text.split(/[\n\r]/).pop());
}
function isAtWordPlaceholderNode(node) {
@@ -9,8 +9,8 @@ function isSCSSNestedPropertyNode(node, options) {
}
return node.selector
.replace(/\/\*.*?\*\//u, "")
.replace(/\/\/.*\n/u, "")
.replace(/\/\*.*?\*\//, "")
.replace(/\/\/.*\n/, "")
.trim()
.endsWith(":");
}
+1 -1
View File
@@ -109,7 +109,7 @@ function genericPrint(path, options, print) {
return [
'"',
node.value
.replaceAll(/["\\]/gu, String.raw`\$&`)
.replaceAll(/["\\]/g, String.raw`\$&`)
.replaceAll("\n", String.raw`\n`),
'"',
];
+5 -5
View File
@@ -26,7 +26,7 @@ function addBackslash(node) {
childrenOrBody[i + 1].type === "MustacheStatement"
) {
childrenOrBody[i].chars = childrenOrBody[i].chars.replace(
/\\$/u,
/\\$/,
"\\\\",
);
}
@@ -126,8 +126,8 @@ function getErrorMessage(error) {
*/
if (
lines.length >= 4 &&
/^Parse error on line \d+:$/u.test(lines[0]) &&
/^-*\^$/u.test(lines.at(-2))
/^Parse error on line \d+:$/.test(lines[0]) &&
/^-*\^$/.test(lines.at(-2))
) {
return lines.at(-1);
}
@@ -147,8 +147,8 @@ function getErrorMessage(error) {
*/
if (
lines.length >= 4 &&
/:\s?$/u.test(lines[0]) &&
/^\(error occurred in '.*?' @ line \d+ : column \d+\)$/u.test(
/:\s?$/.test(lines[0]) &&
/^\(error occurred in '.*?' @ line \d+ : column \d+\)$/.test(
lines.at(-1),
) &&
lines[1] === "" &&
+8 -8
View File
@@ -173,7 +173,7 @@ function print(path, options, print) {
}
if (parent.tag === "style") {
text = text.replaceAll(/^\n+/gu, "");
text = text.replaceAll(/^\n+/g, "");
text = htmlWhitespace.trimEnd(text);
text = htmlWhitespace.dedentString(text);
@@ -191,7 +191,7 @@ function print(path, options, print) {
if (attrName) {
// TODO: format style and srcset attributes
if (attrName === "class") {
const formattedClasses = text.trim().split(/\s+/u).join(" ");
const formattedClasses = text.trim().split(/\s+/).join(" ");
let leadingSpace = false;
let trailingSpace = false;
@@ -199,13 +199,13 @@ function print(path, options, print) {
if (path.parent.type === "ConcatStatement") {
if (
path.previous?.type === "MustacheStatement" &&
/^\s/u.test(text)
/^\s/.test(text)
) {
leadingSpace = true;
}
if (
path.next?.type === "MustacheStatement" &&
/\s$/u.test(text) &&
/\s$/.test(text) &&
formattedClasses !== ""
) {
trailingSpace = true;
@@ -695,14 +695,14 @@ function countNewLines(string) {
function countLeadingNewLines(string) {
/* c8 ignore next */
string = typeof string === "string" ? string : "";
const newLines = (string.match(/^([^\S\n\r]*[\n\r])+/gu) || [])[0] || "";
const newLines = (string.match(/^([^\S\n\r]*[\n\r])+/g) || [])[0] || "";
return countNewLines(newLines);
}
function countTrailingNewLines(string) {
/* c8 ignore next */
string = typeof string === "string" ? string : "";
const newLines = (string.match(/([\n\r][^\S\n\r]*)+$/gu) || [])[0] || "";
const newLines = (string.match(/([\n\r][^\S\n\r]*)+$/g) || [])[0] || "";
return countNewLines(newLines);
}
@@ -817,8 +817,8 @@ const isPathExpressionPartNeedBrackets = (part, index) => {
return (
(index !== 0 && PATH_EXPRESSION_FORBIDDEN_IN_FIRST_PART.has(part)) ||
/\s/u.test(part) ||
/^\d/u.test(part) ||
/\s/.test(part) ||
/^\d/.test(part) ||
Array.prototype.some.call(part, (character) =>
PATH_EXPRESSION_FORBIDDEN_CHARACTERS.has(character),
)
+1 -1
View File
@@ -31,7 +31,7 @@ function isVoidElement(node) {
}
function isWhitespaceNode(node) {
return node.type === "TextNode" && !/\S/u.test(node.chars);
return node.type === "TextNode" && !/\S/.test(node.chars);
}
function isPrettierIgnoreNode(node) {
+2 -2
View File
@@ -64,12 +64,12 @@ function clean(original, cloned, parent) {
) {
delete cloned.value;
} else if (value) {
cloned.value = value.replaceAll(/'|&quot;|&apos;/gu, '"');
cloned.value = value.replaceAll(/'|&quot;|&apos;/g, '"');
}
}
if (original.kind === "docType") {
cloned.value = original.value.toLowerCase().replaceAll(/\s+/gu, " ");
cloned.value = original.value.toLowerCase().replaceAll(/\s+/g, " ");
}
if (
+2 -2
View File
@@ -5,7 +5,7 @@ function expandHeadingPseudoClassSelector(selector) {
return ["h1", "h2", "h3", "h4", "h5", "h6"];
}
const match = selector.match(/^:heading\((?<levels>\d+(?:,\s*\d+)*)\)$/u);
const match = selector.match(/^:heading\((?<levels>\d+(?:,\s*\d+)*)\)$/);
if (!match) {
return;
}
@@ -28,7 +28,7 @@ const getCssStyleTags = (property) =>
return selectors.flatMap((selector) => {
const tagNames =
expandHeadingPseudoClassSelector(selector) ??
(/^[\da-z]+$/iu.test(selector) ? [selector] : []);
(/^[\da-z]+$/i.test(selector) ? [selector] : []);
return tagNames.map((tagName) => [tagName, style.value]);
});
+2 -2
View File
@@ -51,7 +51,7 @@ function embed(path, options) {
return async (textToDoc, print) => {
const content = getNodeContent(node, options);
let isEmpty = /^\s*$/u.test(content);
let isEmpty = /^\s*$/.test(content);
let doc = "";
if (!isEmpty) {
doc = await textToDoc(htmlTrimPreserveIndentation(content), {
@@ -82,7 +82,7 @@ function embed(path, options) {
const value =
parser === "markdown"
? htmlWhitespace.dedentString(
node.value.replace(/^[^\S\n]*\n/u, ""),
node.value.replace(/^[^\S\n]*\n/, ""),
)
: node.value;
const textToDocOptions = { parser, __embeddedInHtml: true };
+3 -3
View File
@@ -52,9 +52,9 @@ const printers = [
const name = path.node.fullName;
return (
(name.startsWith("[") && name.endsWith("]")) ||
/^bind(?:on)?-/u.test(name) ||
/^bind(?:on)?-/.test(name) ||
// Unofficial rudimentary support for some of the most used directives of AngularJS 1.x
/^ng-(?:if|show|hide|class|style)$/u.test(name)
/^ng-(?:if|show|hide|class|style)$/.test(name)
);
},
print: createAngularPrinter("__ng_binding"),
@@ -71,7 +71,7 @@ const printers = [
- `i18n="longDescription"`
- `i18n-attr="longDescription"`
*/
test: (path /* , options */) => /^i18n(?:-.+)?$/u.test(path.node.fullName),
test: (path /* , options */) => /^i18n(?:-.+)?$/.test(path.node.fullName),
print: printAngularI18n,
},
{
@@ -12,7 +12,7 @@ function printAngularControlFlowBlockParameters(
node.sourceSpan.start.offset,
node.sourceSpan.end.offset,
);
const isEmpty = /^\s*$/u.test(content);
const isEmpty = /^\s*$/.test(content);
if (isEmpty) {
return "";
+1 -1
View File
@@ -2,7 +2,7 @@ import { group, indent, line, replaceEndOfLine } from "../../document/index.js";
import { getUnescapedAttributeValue } from "../utilities/index.js";
import { formatAttributeValue } from "./utilities.js";
const interpolationRegex = /\{\{(.+?)\}\}/su;
const interpolationRegex = /\{\{(.+?)\}\}/s;
const isAngularInterpolation = ({ node: { value } } /* , options*/) =>
interpolationRegex.test(value);
+1 -1
View File
@@ -12,6 +12,6 @@ const isClassNames = ({ node }, options) =>
/** @type {AttributeValuePrint} */
const printClassNames = (textToDoc, print, path /* , options*/) =>
getUnescapedAttributeValue(path.node).trim().split(/\s+/u).join(" ");
getUnescapedAttributeValue(path.node).trim().split(/\s+/).join(" ");
export { isClassNames, printClassNames };
@@ -38,9 +38,9 @@ async function printVueVForDirective(textToDoc, print, path, options) {
// modified from https://github.com/vuejs/vue/blob/v2.5.17/src/compiler/parser/index.js#L370-L387
function parseVueVForDirective(value) {
const forAliasRE = /(.*?)\s+(in|of)\s+(.*)/su;
const forIteratorRE = /,([^,\]}]*)(?:,([^,\]}]*))?$/u;
const stripParensRE = /^\(|\)$/gu;
const forAliasRE = /(.*?)\s+(in|of)\s+(.*)/s;
const forIteratorRE = /,([^,\]}]*)(?:,([^,\]}]*))?$/;
const stripParensRE = /^\(|\)$/g;
const inMatch = value.match(forAliasRE);
if (!inMatch) {
@@ -10,17 +10,17 @@ const parseFunctions = [
{
// <!--[if ... ]> ... <![endif]-->
regex:
/^(?<openingTagSuffix>\[if(?<condition>[^\]]*)\]>)(?<data>.*?)<!\s*\[endif\]$/su,
/^(?<openingTagSuffix>\[if(?<condition>[^\]]*)\]>)(?<data>.*?)<!\s*\[endif\]$/s,
parse: parseIeConditionalStartEndComment,
},
{
// <!--[if ... ]><!-->
regex: /^\[if(?<condition>[^\]]*)\]><!$/u,
regex: /^\[if(?<condition>[^\]]*)\]><!$/,
parse: parseIeConditionalStartComment,
},
{
// <!--<![endif]-->
regex: /^<!\s*\[endif\]$/u,
regex: /^<!\s*\[endif\]$/,
parse: parseIeConditionalEndComment,
},
];
@@ -64,7 +64,7 @@ function parseIeConditionalStartEndComment(node, match, parseHtml) {
kind: "ieConditionalComment",
complete,
children,
condition: condition.trim().replaceAll(/\s+/gu, " "),
condition: condition.trim().replaceAll(/\s+/g, " "),
sourceSpan: node.sourceSpan,
startSourceSpan: new ParseSourceSpan(
node.sourceSpan.start,
@@ -81,7 +81,7 @@ function parseIeConditionalStartComment(node, match /* , parseHtml */) {
const { condition } = match.groups;
return {
kind: "ieConditionalStartComment",
condition: condition.trim().replaceAll(/\s+/gu, " "),
condition: condition.trim().replaceAll(/\s+/g, " "),
sourceSpan: node.sourceSpan,
};
}
+2 -2
View File
@@ -69,7 +69,7 @@ function normalizeAngularControlFlowBlock(node) {
return;
}
node.name = node.name.toLowerCase().replaceAll(/\s+/gu, " ").trim();
node.name = node.name.toLowerCase().replaceAll(/\s+/g, " ").trim();
node.kind = "angularControlFlowBlock";
if (!isNonEmptyArray(node.parameters)) {
@@ -157,7 +157,7 @@ function restoreNameAndValue(node) {
attr.value = null;
} else {
attr.value = attr.valueSpan.toString();
if (/["']/u.test(attr.value[0])) {
if (/["']/.test(attr.value[0])) {
attr.value = attr.value.slice(1, -1);
}
}
+2 -2
View File
@@ -187,7 +187,7 @@ function extractInterpolation(ast, options) {
return;
}
const interpolationRegex = /\{\{(.+?)\}\}/su;
const interpolationRegex = /\{\{(.+?)\}\}/s;
ast.walk((node) => {
if (!canHaveInterpolation(node, options)) {
return;
@@ -348,7 +348,7 @@ function addHasHtmComponentClosingTag(ast, options) {
node.hasHtmComponentClosingTag =
node.endSourceSpan &&
/^<\s*\/\s*\/\s*>$/u.test(
/^<\s*\/\s*\/\s*>$/.test(
options.originalText.slice(
node.endSourceSpan.start.offset,
node.endSourceSpan.end.offset,
-1
View File
@@ -140,7 +140,6 @@ function printElement(path, options, print) {
node.isIndentationSensitive)) &&
new RegExp(
String.raw`\n[\t ]{${options.tabWidth * (path.ancestors.length - 1)}}$`,
"u",
).test(node.lastChild.value)
) {
return "";
+3 -3
View File
@@ -192,7 +192,7 @@ function needsToBorrowNextOpeningTagStartMarker(node) {
}
function getPrettierIgnoreAttributeCommentData(value) {
const match = value.trim().match(/^prettier-ignore-attribute(?:\s+(.+))?$/su);
const match = value.trim().match(/^prettier-ignore-attribute(?:\s+(.+))?$/s);
if (!match) {
return false;
@@ -202,7 +202,7 @@ function getPrettierIgnoreAttributeCommentData(value) {
return true;
}
return match[1].split(/\s+/u);
return match[1].split(/\s+/);
}
function needsToBorrowParentOpeningTagEndMarker(node) {
@@ -356,7 +356,7 @@ function printOpeningTagStartMarker(node, options) {
// Only lowercase HTML5 doctype in `.html` and `.htm` files
if (node.value === "html") {
const { filepath } = options;
if (filepath && /\.html?$/u.test(filepath)) {
if (filepath && /\.html?$/.test(filepath)) {
return HTML5_DOCTYPE_START_MARKER;
}
}
+2 -2
View File
@@ -90,7 +90,7 @@ function genericPrint(path, options, print) {
case "text": {
if (node.parent.kind === "interpolation") {
// replace the trailing literalline with hardline for better readability
const trailingNewlineRegex = /\n[^\S\n]*$/u;
const trailingNewlineRegex = /\n[^\S\n]*$/;
const hasTrailingNewline = trailingNewlineRegex.test(node.value);
const value = hasTrailingNewline
? node.value.replace(trailingNewlineRegex, "")
@@ -115,7 +115,7 @@ function genericPrint(path, options, print) {
group([
printOpeningTagStart(node, options),
" ",
node.value.replace(/^html\b/iu, "html").replaceAll(/\s+/gu, " "),
node.value.replace(/^html\b/i, "html").replaceAll(/\s+/g, " "),
]),
printClosingTagEnd(node, options),
];
+3 -3
View File
@@ -20,7 +20,7 @@ import {
import isUnknownNamespace from "./is-unknown-namespace.js";
const htmlTrimLeadingBlankLines = (string) =>
string.replaceAll(/^[\t\f\r ]*\n/gu, "");
string.replaceAll(/^[\t\f\r ]*\n/g, "");
const htmlTrimPreserveIndentation = (string) =>
htmlTrimLeadingBlankLines(htmlWhitespace.trimEnd(string));
const getLeadingAndTrailingHtmlWhitespace = (string) => {
@@ -482,7 +482,7 @@ function getNodeCssStyleDisplay(node, options) {
if (node.prev?.kind === "comment") {
// <!-- display: block -->
const match = node.prev.value.match(/^\s*display:\s*([a-z]+)\s*$/u);
const match = node.prev.value.match(/^\s*display:\s*([a-z]+)\s*$/);
if (match) {
return match[1];
}
@@ -614,7 +614,7 @@ function shouldUnquoteAttributeValue(node, options) {
return (
// Embedded HTML in JS: `` /* HTML */ `<my-element data-for={value}></my-element>` ``
/^PRETTIER_HTML_PLACEHOLDER_\d+_\d+_IN_JS$/u.test(value) ||
/^PRETTIER_HTML_PLACEHOLDER_\d+_\d+_IN_JS$/.test(value) ||
// LWC `<div foo={value}></div>`
(options.parser === "lwc" && value.startsWith("{") && value.endsWith("}"))
);
+2 -2
View File
@@ -118,10 +118,10 @@ function clean(original, cloned, parent) {
if (
original.type === "JSXAttribute" &&
original.value?.type === "Literal" &&
/["']|&quot;|&apos;/u.test(original.value.value)
/["']|&quot;|&apos;/.test(original.value.value)
) {
cloned.value.value = original.value.value.replaceAll(
/["']|&quot;|&apos;/gu,
/["']|&quot;|&apos;/g,
'"',
);
}
+1 -1
View File
@@ -2,7 +2,7 @@ function isGap(text, { parser }) {
if (parser === "flow" || parser === "hermes" || parser === "babel-flow") {
// Example: (a /* b */ /* : c */)
// gap ^^^^
text = text.replaceAll(/[\s(]/gu, "");
text = text.replaceAll(/[\s(]/g, "");
return text === "" || text === "/*" || text === "/*::";
}
}
+10 -12
View File
@@ -50,18 +50,16 @@ function replacePlaceholders(quasisDoc, expressionDocs) {
}
// When we have multiple placeholders in one line, like:
// ${Child}${Child2}:not(:first-child)
return doc
.split(/@prettier-placeholder-(\d+)-id/u)
.map((component, idx) => {
// The placeholder is always at odd indices
if (idx % 2 === 0) {
return replaceEndOfLine(component);
}
return doc.split(/@prettier-placeholder-(\d+)-id/).map((component, idx) => {
// The placeholder is always at odd indices
if (idx % 2 === 0) {
return replaceEndOfLine(component);
}
// The component will always be a number at odd index
replaceCounter++;
return expressionDocs[component];
});
// The component will always be a number at odd index
replaceCounter++;
return expressionDocs[component];
});
});
return expressionDocs.length === replaceCounter ? newDoc : null;
}
@@ -106,7 +104,7 @@ function isStyledIdentifier(node) {
}
function isStyledExtend(node) {
return /^[A-Z]/u.test(node.object.name) && node.property.name === "extend";
return /^[A-Z]/.test(node.object.name) && node.property.name === "extend";
}
/**
+2 -2
View File
@@ -30,11 +30,11 @@ async function printEmbedGraphQL(textToDoc, print, path, options) {
lines[numLines - 2].trim() === "";
const commentsAndWhitespaceOnly = lines.every((line) =>
/^\s*(?:#[^\n\r]*)?$/u.test(line),
/^\s*(?:#[^\n\r]*)?$/.test(line),
);
// Bail out if an interpolation occurs within a comment.
if (!isLast && /#[^\n\r]*$/u.test(lines[numLines - 1])) {
if (!isLast && /#[^\n\r]*$/.test(lines[numLines - 1])) {
return null;
}
+4 -4
View File
@@ -34,7 +34,7 @@ async function printEmbedHtmlLike(parser, textToDoc, print, path, options) {
const placeholderRegex = new RegExp(
composePlaceholder(String.raw`(\d+)`),
"gu",
"g",
);
let topLevelCount = 0;
const doc = await textToDoc(text, {
@@ -60,7 +60,7 @@ async function printEmbedHtmlLike(parser, textToDoc, print, path, options) {
component = uncookTemplateElementValue(component);
if (options.__embeddedInHtml) {
component = component.replaceAll(
/<\/(?=script\b)/giu,
/<\/(?=script\b)/gi,
String.raw`<\/`,
);
}
@@ -76,8 +76,8 @@ async function printEmbedHtmlLike(parser, textToDoc, print, path, options) {
return parts;
});
const leadingWhitespace = /^\s/u.test(text) ? " " : "";
const trailingWhitespace = /\s$/u.test(text) ? " " : "";
const leadingWhitespace = /^\s/.test(text) ? " " : "";
const trailingWhitespace = /\s$/.test(text) ? " " : "";
const linebreak =
options.htmlWhitespaceSensitivity === "ignore"
+3 -3
View File
@@ -9,13 +9,13 @@ import { escapeTemplateCharacters } from "../print/template-literal.js";
async function printEmbedMarkdown(textToDoc, print, path /* , options*/) {
const { node } = path;
let text = node.quasis[0].value.raw.replaceAll(
/((?:\\\\)*)\\`/gu,
/((?:\\\\)*)\\`/g,
(_, backslashes) => "\\".repeat(backslashes.length / 2) + "`",
);
const indentation = getIndentation(text);
const hasIndent = indentation !== "";
if (hasIndent) {
text = text.replaceAll(new RegExp(`^${indentation}`, "gmu"), "");
text = text.replaceAll(new RegExp(`^${indentation}`, "gm"), "");
}
const doc = escapeTemplateCharacters(
await textToDoc(text, { parser: "markdown", __inJsTemplate: true }),
@@ -30,7 +30,7 @@ async function printEmbedMarkdown(textToDoc, print, path /* , options*/) {
}
function getIndentation(str) {
const firstMatchedIndent = str.match(/^([^\S\n]*)\S/mu);
const firstMatchedIndent = str.match(/^([^\S\n]*)\S/m);
return firstMatchedIndent === null ? "" : firstMatchedIndent[1];
}
+1 -1
View File
@@ -18,7 +18,7 @@ function shouldAddParenthesesToIdentifier(path) {
// f((a + b) / 2) vs f(a + b / 2)
if (
node.extra?.parenthesized &&
/^PRETTIER_HTML_PLACEHOLDER_\d+_\d+_IN_JS$/u.test(node.name)
/^PRETTIER_HTML_PLACEHOLDER_\d+_\d+_IN_JS$/.test(node.name)
) {
return true;
}
+1 -1
View File
@@ -44,7 +44,7 @@ function createParseError(error) {
const { line, column } = loc;
return createError(message.replace(/ \(\d+:\d+\)$/u, ""), {
return createError(message.replace(/ \(\d+:\d+\)$/, ""), {
loc: {
start: { line, column: column + 1 },
},
+2 -2
View File
@@ -72,7 +72,7 @@ const appendPlugins = (plugins, options = parseOptions) => ({
// Similar to babel
// https://github.com/babel/babel/pull/7934/files#diff-a739835084910b0ee3ea649df5a4d223R67
const FLOW_PRAGMA_REGEX = /@(?:no)?flow\b/u;
const FLOW_PRAGMA_REGEX = /@(?:no)?flow\b/;
function isFlowFile(text, filepath) {
if (filepath?.endsWith(".js.flow")) {
return true;
@@ -135,7 +135,7 @@ function createParse({ isExpression = false, optionsCombinations }) {
}));
}
const shouldEnableV8intrinsicPlugin = /%[A-Z]/u.test(text);
const shouldEnableV8intrinsicPlugin = /%[A-Z]/.test(text);
if (text.includes("|>")) {
const conflictsPlugins = shouldEnableV8intrinsicPlugin
? [...pipelineOperatorPlugins, v8intrinsicPlugin]
+2 -2
View File
@@ -67,7 +67,7 @@ async function parseWithOptions(filepath, text, options) {
error.severity === "Error" &&
(error.message ===
"A 'return' statement can only be used within a function body." ||
/^Identifier `.*` has already been declared$/u.test(error.message))
/^Identifier `.*` has already been declared$/.test(error.message))
) {
continue;
}
@@ -103,7 +103,7 @@ function getLanguageCombinations(text, options) {
const filepath = options?.filepath;
if (typeof filepath === "string") {
if (/\.(?:jsx|tsx)$/iu.test(filepath)) {
if (/\.(?:jsx|tsx)$/i.test(filepath)) {
return ["tsx"];
}
+1 -1
View File
@@ -50,7 +50,7 @@ function createParseError(error) {
// https://typescript-eslint.io/packages/parser/#jsx
const isKnownFileType = (filepath) =>
filepath && /\.(?:js|mjs|cjs|jsx|ts|mts|cts|tsx)$/iu.test(filepath);
filepath && /\.(?:js|mjs|cjs|jsx|ts|mts|cts|tsx)$/i.test(filepath);
function getParseOptionsCombinations(text, filepath) {
let combinations = [{ ...baseParseOptions, filePath: filepath }];
@@ -8,5 +8,5 @@ export default new RegExp(
"|",
"^[^/]{2}.*/>", // Contains "/>" on line not starting with "//"
].join(""),
"mu",
"m",
);
@@ -16,11 +16,11 @@ export function getSourceType(filepath) {
filepath = filepath.toLowerCase();
if (/\.(?:mjs|mts)$/iu.test(filepath)) {
if (/\.(?:mjs|mts)$/i.test(filepath)) {
return SOURCE_TYPE_MODULE;
}
if (/\.(?:cjs|cts)$/iu.test(filepath)) {
if (/\.(?:cjs|cts)$/i.test(filepath)) {
return SOURCE_TYPE_COMMONJS;
}
}
+1 -1
View File
@@ -39,7 +39,7 @@ function printAngular(path, options, print) {
"body",
);
case "NGMicrosyntaxKey":
return /^[$_a-z][\w$]*(?:-[$_a-z][\w$])*$/iu.test(node.name)
return /^[$_a-z][\w$]*(?:-[$_a-z][\w$])*$/i.test(node.name)
? node.name
: JSON.stringify(node.name);
case "NGMicrosyntaxExpression":
+1 -1
View File
@@ -228,7 +228,7 @@ function printEstree(path, options, print, args) {
case "UnaryExpression": {
const parts = [node.operator];
if (/[a-z]$/u.test(node.operator)) {
if (/[a-z]$/.test(node.operator)) {
parts.push(" ");
}
+5 -5
View File
@@ -347,7 +347,7 @@ function printJsxChildren(
// Starts with whitespace
if (words[0] === "") {
words.shift();
if (/\n/u.test(words[0])) {
if (/\n/.test(words[0])) {
pushLine(
separatorWithWhitespace(
isFacebookTranslationTag,
@@ -383,7 +383,7 @@ function printJsxChildren(
}
if (endWhitespace !== undefined) {
if (/\n/u.test(endWhitespace)) {
if (/\n/.test(endWhitespace)) {
pushLine(
separatorWithWhitespace(
isFacebookTranslationTag,
@@ -405,10 +405,10 @@ function printJsxChildren(
),
);
}
} else if (/\n/u.test(text)) {
} else if (/\n/.test(text)) {
// Keep (up to one) blank line between tags/expressions/text.
// Note: We don't keep blank lines between text elements.
if (text.match(/\n/gu).length > 1) {
if (text.match(/\n/g).length > 1) {
pushLine(hardline);
}
} else {
@@ -864,7 +864,7 @@ function isMeaningfulJsxText(node) {
return (
node.type === "JSXText" &&
(jsxWhitespace.hasNonWhitespaceCharacter(getRaw(node)) ||
!/\n/u.test(getRaw(node)))
!/\n/.test(getRaw(node)))
);
}
+1 -1
View File
@@ -70,7 +70,7 @@ function printTypeScriptMappedType(path, options, print) {
start + 1,
locStart(node.key),
);
const nextTokenIndex = start + 1 + textAfter.search(/\S/u);
const nextTokenIndex = start + 1 + textAfter.search(/\S/);
if (hasNewlineInRange(options.originalText, start, nextTokenIndex)) {
shouldBreak = true;
}
+1 -1
View File
@@ -272,7 +272,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]|^[$_]+$/u.test(name);
return /^[A-Z]|^[$_]+$/.test(name);
}
// In case the Identifier is shorter than tab width, we can keep the
+2 -2
View File
@@ -10,7 +10,7 @@ const needsQuoteProps = new WeakMap();
// Matches “simple” numbers like `123` and `2.5` but not `1_000`, `1e+100` or `0b10`.
function isSimpleNumber(numberString) {
return /^(?:\d+|\d+\.\d+)$/u.test(numberString);
return /^(?:\d+|\d+\.\d+)$/.test(numberString);
}
// Note: Quoting/unquoting numbers in TypeScript is not safe.
@@ -169,7 +169,7 @@ function printPropertyKey(path, options, print) {
() =>
printComments(
path,
/^\d/u.test(key.value) ? printNumber(key.value) : key.value,
/^\d/.test(key.value) ? printNumber(key.value) : key.value,
options,
),
"key",
+4 -4
View File
@@ -90,7 +90,7 @@ function printJestEachTemplateLiteral(path, options, print) {
* ${2} | ${1} | ${3}
*/
const { node } = path;
const headerNames = node.quasis[0].value.raw.trim().split(/\s*\|\s*/u);
const headerNames = node.quasis[0].value.raw.trim().split(/\s*\|\s*/);
if (
headerNames.length > 1 ||
headerNames.some((headerName) => headerName.length > 0)
@@ -275,7 +275,7 @@ function escapeTemplateCharacters(doc, raw) {
return mapDoc(doc, (currentDoc) => {
if (typeof currentDoc === "string") {
return raw
? currentDoc.replaceAll(/(\\*)`/gu, "$1$1\\`")
? currentDoc.replaceAll(/(\\*)`/g, "$1$1\\`")
: uncookTemplateElementValue(currentDoc);
}
@@ -284,7 +284,7 @@ function escapeTemplateCharacters(doc, raw) {
}
function uncookTemplateElementValue(cookedValue) {
return cookedValue.replaceAll(/([\\`]|\$\{)/gu, String.raw`\$1`);
return cookedValue.replaceAll(/([\\`]|\$\{)/g, String.raw`\$1`);
}
/**
@@ -297,7 +297,7 @@ function uncookTemplateElementValue(cookedValue) {
*
* Ref: https://github.com/facebook/jest/pull/6102
*/
const jestEachTriggerRegex = /^[fx]?(?:describe|it|test)$/u;
const jestEachTriggerRegex = /^[fx]?(?:describe|it|test)$/;
function isJestEachTemplateLiteral({ node, parent }) {
return (
node.type === "TemplateLiteral" &&
+1 -1
View File
@@ -39,7 +39,7 @@ function shouldForceTrailingComma(path, options, paramsKey) {
node.type.startsWith("TS") &&
!node[paramsKey][0].constraint &&
path.parent.type === "ArrowFunctionExpression" &&
!(options.filepath && /\.ts$/u.test(options.filepath))
!(options.filepath && /\.ts$/.test(options.filepath))
);
}
@@ -19,7 +19,7 @@ function isTypeCastComment(comment) {
// TypeScript expects the type to be enclosed in curly brackets, however
// Closure Compiler accepts types in parens and even without any delimiters at all.
// That's why we just search for "@type" and "@satisfies".
/@(?:type|satisfies)\b/u.test(comment.value),
/@(?:type|satisfies)\b/.test(comment.value),
);
}
+2 -2
View File
@@ -36,7 +36,7 @@ function clean(original, cloned, parent) {
}
if (original.type === "wikiLink") {
cloned.value = original.value.trim().replaceAll(/[\t\n]+/gu, " ");
cloned.value = original.value.trim().replaceAll(/[\t\n]+/g, " ");
}
if (
@@ -66,7 +66,7 @@ function clean(original, cloned, parent) {
original.type === "image") &&
original.title
) {
cloned.title = original.title.replaceAll(/\\(?=["')])/gu, "");
cloned.title = original.title.replaceAll(/\\(?=["')])/g, "");
}
// for insert pragma
+4 -4
View File
@@ -22,11 +22,11 @@
* THE SOFTWARE.
*/
const IMPORT_REGEX = /^import\s/u;
const EXPORT_REGEX = /^export\s/u;
const IMPORT_REGEX = /^import\s/;
const EXPORT_REGEX = /^export\s/;
const BLOCKS_REGEX = String.raw`[a-z][a-z0-9]*(\.[a-z][a-z0-9]*)*|`;
const COMMENT_REGEX = /<!---->|<!---?[^>-](?:-?[^-])*-->/u;
const ES_COMMENT_REGEX = /^\{\s*\/\*(.*)\*\/\s*\}/u;
const COMMENT_REGEX = /<!---->|<!---?[^>-](?:-?[^-])*-->/;
const ES_COMMENT_REGEX = /^\{\s*\/\*(.*)\*\/\s*\}/;
const EMPTY_NEWLINE = "\n\n";
const isImport = (text) => IMPORT_REGEX.test(text);
@@ -10,7 +10,7 @@ const liquid = function () {
proto.inlineTokenizers.liquid = tokenizer;
function tokenizer(eat, value) {
const match = value.match(/^(\{%.*?%\}|\{\{.*?\}\})/su);
const match = value.match(/^(\{%.*?%\}|\{\{.*?\}\})/s);
if (match) {
return eat(match[0])({
@@ -5,7 +5,7 @@
*/
const wikiLink = function () {
const entityType = "wikiLink";
const wikiLinkRegex = /^\[\[(?<linkContents>.+?)\]\]/su;
const wikiLinkRegex = /^\[\[(?<linkContents>.+?)\]\]/s;
const proto = this.Parser.prototype;
const methods = proto.inlineMethods;
methods.splice(methods.indexOf("link"), 0, entityType);
+6 -7
View File
@@ -101,7 +101,7 @@ function printMdast(path, options, print) {
const proseWrap =
// leading char that may cause different syntax
next && /^>|^(?:[*+-]|#{1,6}|\d+[).])$/u.test(next.value)
next && /^>|^(?:[*+-]|#{1,6}|\d+[).])$/.test(next.value)
? "never"
: options.proseWrap;
@@ -140,7 +140,7 @@ function printMdast(path, options, print) {
const padding =
code.startsWith("`") ||
code.endsWith("`") ||
(/^[\n ]/u.test(code) && /[\n ]$/u.test(code) && /[^\n ]/u.test(code))
(/^[\n ]/.test(code) && /[\n ]$/.test(code) && /[^\n ]/.test(code))
? " "
: "";
return [backtickString, padding, code, padding, backtickString];
@@ -150,7 +150,7 @@ function printMdast(path, options, print) {
if (options.proseWrap === "preserve") {
contents = node.value;
} else {
contents = node.value.replaceAll(/[\t\n]+/gu, " ");
contents = node.value.replaceAll(/[\t\n]+/g, " ");
}
return ["[[", contents, "]]"];
@@ -233,7 +233,7 @@ function printMdast(path, options, print) {
const { parent, isLast } = path;
const value =
parent.type === "root" && isLast ? node.value.trimEnd() : node.value;
const isHtmlComment = /^<!--.*-->$/su.test(value);
const isHtmlComment = /^<!--.*-->$/s.test(value);
return replaceEndOfLine(
value,
@@ -327,7 +327,7 @@ function printMdast(path, options, print) {
case "tableCell":
return printChildren(path, options, print);
case "break":
return /\s/u.test(options.originalText[node.position.start.offset])
return /\s/.test(options.originalText[node.position.start.offset])
? [" ", markAsRoot(literalline)]
: ["\\", hardline];
case "liquidNode":
@@ -471,7 +471,6 @@ function printUrl(url, dangerousCharOrChars = []) {
return new RegExp(
dangerousChars.map((x) => escapeStringRegexp(x)).join("|"),
"u",
).test(url)
? `<${encodeUrl(url, "<>")}>`
: url;
@@ -486,7 +485,7 @@ function printTitle(title, options, printSpace = true) {
}
// title is escaped after `remark-parse` v7
title = title.replaceAll(/\\(?=["')])/gu, "");
title = title.replaceAll(/\\(?=["')])/g, "");
if (title.includes('"') && title.includes("'") && !title.includes(")")) {
return `(${title})`; // avoid escaped quotes
+2 -2
View File
@@ -3,7 +3,7 @@ import { getOrderedListItemInfo, mapAst, splitText } from "../utilities.js";
// 0x0 ~ 0x10ffff
const isSingleCharRegex = /^\\?.$/su;
const isNewLineBlockquoteRegex = /^\n *>[ >]*$/u;
const isNewLineBlockquoteRegex = /^\n *>[ >]*$/;
function preprocess(ast, options) {
ast = restoreUnescapedCharacter(ast, options);
@@ -116,7 +116,7 @@ function transformIndentedCodeblockAndMarkItsParentList(ast, options) {
return mapAst(ast, (node, index, parentStack) => {
if (node.type === "code") {
// the first char may point to `\n`, e.g. `\n\t\tbar`, just ignore it
const isIndented = /^\n?(?: {4,}|\t)/u.test(
const isIndented = /^\n?(?: {4,}|\t)/.test(
options.originalText.slice(
node.position.start.offset,
node.position.end.offset,
+1 -1
View File
@@ -45,7 +45,7 @@ function printWord(path) {
))
) {
// backslash is parsed as part of autolinks, so we need to remove it
escapedValue = escapedValue.replace(/^(\\?[*_])+/u, (prefix) =>
escapedValue = escapedValue.replace(/^(\\?[*_])+/, (prefix) =>
prefix.replaceAll("\\", ""),
);
}
+6 -8
View File
@@ -65,13 +65,13 @@ function splitText(text) {
/** @type {Array<TextNode>} */
const nodes = [];
const tokens = text.split(/([\t\n ]+)/u);
const tokens = text.split(/([\t\n ]+)/);
for (const [index, token] of tokens.entries()) {
// whitespace
if (index % 2 === 1) {
nodes.push({
type: "whitespace",
value: /\n/u.test(token) ? "\n" : " ",
value: /\n/.test(token) ? "\n" : " ",
});
continue;
}
@@ -165,7 +165,7 @@ function splitText(text) {
lastNode?.type === "word" &&
!isBetween(KIND_NON_CJK, KIND_CJK_PUNCTUATION) &&
// disallow leading/trailing full-width whitespace
![lastNode.value, node.value].some((value) => /\u3000/u.test(value))
![lastNode.value, node.value].some((value) => /\u3000/.test(value))
) {
nodes.push({ type: "whitespace", value: "" });
}
@@ -187,7 +187,7 @@ function getOrderedListItemInfo(orderListItem, options) {
);
const { numberText, leadingSpaces } = text.match(
/^\s*(?<numberText>\d+)(\.|\))(?<leadingSpaces>\s*)/u,
/^\s*(?<numberText>\d+)(\.|\))(?<leadingSpaces>\s*)/,
).groups;
return { number: Number(numberText), leadingSpaces };
@@ -257,9 +257,7 @@ function isPrettierIgnore(node) {
let match;
if (node.type === "html") {
match = node.value.match(
/^<!--\s*prettier-ignore(?:-(start|end))?\s*-->$/u,
);
match = node.value.match(/^<!--\s*prettier-ignore(?:-(start|end))?\s*-->$/);
} else {
let comment;
@@ -274,7 +272,7 @@ function isPrettierIgnore(node) {
}
if (comment) {
match = comment.value.match(/^prettier-ignore(?:-(start|end))?$/u);
match = comment.value.match(/^prettier-ignore(?:-(start|end))?$/);
}
}
+1 -1
View File
@@ -29,7 +29,7 @@ function clean(original, cloned /* , parent */) {
if (original.chomping === "keep") {
cloned.value = original.value
.split("\n")
.map((line) => line.replace(/[ \t]+$/u, ""))
.map((line) => line.replace(/[ \t]+$/, ""))
.join("\n");
}
break;
+1 -1
View File
@@ -7,7 +7,7 @@ function embed(path, options) {
if (
node.type === "root" &&
options.filepath &&
/(?:[/\\]|^)\.(?:prettier|stylelint|lintstaged)rc$/u.test(options.filepath)
/(?:[/\\]|^)\.(?:prettier|stylelint|lintstaged)rc$/.test(options.filepath)
) {
return async (textToDoc) => {
const doc = await textToDoc(options.originalText, { parser: "json" });
+2 -2
View File
@@ -173,7 +173,7 @@ function isAbsolutelyPrintedAsSingleLineNode(node, options) {
if (
// backslash-newline
/\\$/mu.test(
/\\$/m.test(
options.originalText.slice(
node.position.start.offset,
node.position.end.offset,
@@ -187,7 +187,7 @@ function isAbsolutelyPrintedAsSingleLineNode(node, options) {
case "never":
return !node.value.includes("\n");
case "always":
return !/[\n ]/u.test(node.value);
return !/[\n ]/.test(node.value);
default:
/* c8 ignore next */
return false;
+1 -1
View File
@@ -266,7 +266,7 @@ function printNode(path, options, print) {
if (
(node.type === "quoteSingle" && raw.includes("\\")) ||
(node.type === "quoteDouble" && /\\[^"]/u.test(raw))
(node.type === "quoteDouble" && /\\[^"]/.test(raw))
) {
// only quoteDouble can use escape chars
// and quoteSingle do not need to escape backslashes
+8 -10
View File
@@ -39,7 +39,7 @@ function isNextLineEmpty(node, text) {
newlineCount++;
}
if (newlineCount === 1 && /\S/u.test(char)) {
if (newlineCount === 1 && /\S/.test(char)) {
return false;
}
@@ -145,7 +145,7 @@ function hasEndComments(node) {
@param {string} text
*/
function splitWithSingleSpace(text) {
return text ? text.split(/(?<!^| ) (?! |$)/u) : [];
return text ? text.split(/(?<!^| ) (?! |$)/) : [];
}
/**
@@ -207,7 +207,7 @@ function getBlockValueLineContents(
: options.originalText
.slice(node.position.start.offset, node.position.end.offset)
// exclude open line `>` or `|`
.match(/^[^\n]*\n(.*)$/su)[1];
.match(/^[^\n]*\n(.*)$/s)[1];
if (content === "") {
return [];
@@ -216,7 +216,7 @@ function getBlockValueLineContents(
/** @type {number} */
let leadingSpaceCount;
if (node.indent === null) {
const matches = content.match(/^(?<leadingSpace> *)[^\n\r ]/mu);
const matches = content.match(/^(?<leadingSpace> *)[^\n\r ]/m);
leadingSpaceCount = matches
? matches.groups.leadingSpace.length
: Number.POSITIVE_INFINITY;
@@ -243,11 +243,11 @@ function getBlockValueLineContents(
index > 0 &&
words.length > 0 &&
rawLineContents[index - 1].length > 0 &&
!/^\s/u.test(words[0]) &&
!/^\s/.test(words[0]) &&
// This test against a `string[]`, should be a mistake
// originally introduced in https://github.com/prettier/prettier/pull/4742/files#diff-a4dc2e1922e1d8d5ac20818480f777c9a2d5af739eaa3a0409b08bf29a9d0f74R282
// @ts-expect-error -- see comment above
!/^\s|\s$/u.test(lines.at(-1))
!/^\s|\s$/.test(lines.at(-1))
) {
lines[lines.length - 1] = [...lines.at(-1), ...words];
} else {
@@ -259,7 +259,7 @@ function getBlockValueLineContents(
const words = [];
for (const word of originalWords) {
// disallow trailing spaces
if (words.length > 0 && /\s$/u.test(words.at(-1))) {
if (words.length > 0 && /\s$/.test(words.at(-1))) {
words[words.length - 1] += " " + word;
} else {
words.push(word);
@@ -286,9 +286,7 @@ function getBlockValueLineContents(
let trailingNewlineCount = 0;
for (let i = lineContents.length - 1; i >= 0; i--) {
if (
lineContents[i].every((line) => line.replace(/[ \t]+$/u, "") === "")
) {
if (lineContents[i].every((line) => line.replace(/[ \t]+$/, "") === "")) {
trailingNewlineCount++;
} else {
break;
+2 -2
View File
@@ -244,7 +244,7 @@ function attachComments(ast, options) {
}
}
const isAllEmptyAndNoLineBreak = (text) => !/[\S\n\u2028\u2029]/u.test(text);
const isAllEmptyAndNoLineBreak = (text) => !/[\S\n\u2028\u2029]/.test(text);
function isOwnLineComment(text, options, decoratedComments, commentIndex) {
const { comment, precedingNode } = decoratedComments[commentIndex];
const { locStart, locEnd } = options;
@@ -325,7 +325,7 @@ function breakTies(tiesToBreak, options) {
const gap = options.originalText.slice(options.locEnd(comment), gapEndPos);
if (options.printer.isGap?.(gap, options) ?? /^[\s(]*$/u.test(gap)) {
if (options.printer.isGap?.(gap, options) ?? /^[\s(]*$/.test(gap)) {
gapEndPos = options.locStart(comment);
} else {
// The gap string contained something other than whitespace or open
+1 -1
View File
@@ -192,7 +192,7 @@ async function formatRange(originalText, opts) {
rangeStart,
text.lastIndexOf("\n", rangeStart) + 1,
);
const indentString = text.slice(rangeStart2, rangeStart).match(/^\s*/u)[0];
const indentString = text.slice(rangeStart2, rangeStart).match(/^\s*/)[0];
const alignmentSize = getAlignmentSize(indentString, opts.tabWidth);
+1 -1
View File
@@ -65,7 +65,7 @@ function getFrontMatter(text) {
const frontMatterEndIndex = endDelimiterIndex + 1 + DELIMITER_LENGTH;
const nextCharacter = text.charAt(frontMatterEndIndex + 1);
if (!/\s?/u.test(nextCharacter)) {
if (!/\s?/.test(nextCharacter)) {
return;
}
+2 -2
View File
@@ -201,12 +201,12 @@ function calculateRange(text, opts, ast) {
assert.ok(end > start);
// Contract the range so that it has non-whitespace characters at its endpoints.
// This ensures we can format a range that doesn't end on a node.
const firstNonWhitespaceCharacterIndex = text.slice(start, end).search(/\S/u);
const firstNonWhitespaceCharacterIndex = text.slice(start, end).search(/\S/);
const isAllWhitespace = firstNonWhitespaceCharacterIndex === -1;
if (!isAllWhitespace) {
start += firstNonWhitespaceCharacterIndex;
for (; end > start; --end) {
if (/\S/u.test(text[end - 1])) {
if (/\S/.test(text[end - 1])) {
break;
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
@param {string | URL} file
@returns {string}
*/
const getFileBasename = (file) => String(file).split(/[/\\]/u).pop();
const getFileBasename = (file) => String(file).split(/[/\\]/).pop();
// Ideally, we should only allow `URL` with `file:` protocol and
// string starts with `file:`, but `URL` is missing in some environments
+1 -1
View File
@@ -14,7 +14,7 @@ function getIndentSize(value, tabWidth) {
return getAlignmentSize(
// All the leading whitespaces
value.slice(lastNewlineIndex + 1).match(/^[\t ]*/u)[0],
value.slice(lastNewlineIndex + 1).match(/^[\t ]*/)[0],
tabWidth,
);
}
+2 -2
View File
@@ -33,13 +33,13 @@ function getInterpreter(file) {
}
// #!/bin/env node, #!/usr/bin/env node
const m1 = firstLine.match(/^#!\/(?:usr\/)?bin\/env\s+(\S+)/u);
const m1 = firstLine.match(/^#!\/(?:usr\/)?bin\/env\s+(\S+)/);
if (m1) {
return m1[1];
}
// #!/bin/node, #!/usr/bin/node, #!/usr/local/bin/node
const m2 = firstLine.match(/^#!\/(?:usr\/(?:local\/)?)?bin\/(\S+)/u);
const m2 = firstLine.match(/^#!\/(?:usr\/(?:local\/)?)?bin\/(\S+)/);
if (m2) {
return m2[1];
}
+1 -1
View File
@@ -7,7 +7,7 @@ import escapeStringRegexp from "escape-string-regexp";
*/
function getMaxContinuousCount(text, searchString) {
let results = text.matchAll(
new RegExp(`(?:${escapeStringRegexp(searchString)})+`, "gu"),
new RegExp(`(?:${escapeStringRegexp(searchString)})+`, "g"),
);
// TODO: Use `Iterator#reduce` when we drop support for Node.js < 22
@@ -11,7 +11,7 @@ import escapeStringRegexp from "escape-string-regexp";
*/
function getMinNotPresentContinuousCount(text, searchString) {
const matches = text.match(
new RegExp(`(${escapeStringRegexp(searchString)})+`, "gu"),
new RegExp(`(${escapeStringRegexp(searchString)})+`, "g"),
);
if (matches === null) {
+1 -1
View File
@@ -7,7 +7,7 @@ import {
} from "get-east-asian-width";
import narrowEmojis from "./narrow-emojis.evaluate.js";
const notAsciiRegex = /[^\x20-\x7F]/u;
const notAsciiRegex = /[^\x20-\x7F]/;
const narrowEmojisSet = new Set(narrowEmojis);
// Similar to https://github.com/sindresorhus/string-width
+1 -1
View File
@@ -4,7 +4,7 @@ import { DOUBLE_QUOTE, SINGLE_QUOTE } from "./get-preferred-quote.js";
// Matches _any_ escape and unescaped quotes (both single and double).
// Matching `\` in first group, so we won't treat `\\"` as escaped quote.
const REGEX = /\\(["'\\])|(["'])/gu;
const REGEX = /\\(["'\\])|(["'])/g;
/**
* @param {string} rawText
+4 -11
View File
@@ -8,7 +8,6 @@ export const FORMAT_PRAGMA_TO_INSERT = FORMAT_PRAGMAS[0];
export const YAML_IS_PRAGMA_REGEXP = new RegExp(
String.raw`^\s*@(?:${FORMAT_PRAGMAS.join("|")})\s*$`,
"u",
);
export const [YAML_HAS_PRAGMA_REGEXP, YAML_HAS_IGNORE_PRAGMA_REGEXP] = [
@@ -16,10 +15,7 @@ export const [YAML_HAS_PRAGMA_REGEXP, YAML_HAS_IGNORE_PRAGMA_REGEXP] = [
FORMAT_IGNORE_PRAGMAS,
].map(
(pragmas) =>
new RegExp(
String.raw`^\s*#[^\S\n]*@(?:${pragmas.join("|")})\s*?(?:\n|$)`,
"u",
),
new RegExp(String.raw`^\s*#[^\S\n]*@(?:${pragmas.join("|")})\s*?(?:\n|$)`),
);
export const [GRAPHQL_HAS_PRAGMA_REGEXP, GRAPHQL_HAS_IGNORE_PRAGMA_REGEXP] = [
@@ -27,10 +23,7 @@ export const [GRAPHQL_HAS_PRAGMA_REGEXP, GRAPHQL_HAS_IGNORE_PRAGMA_REGEXP] = [
FORMAT_IGNORE_PRAGMAS,
].map(
(pragmas) =>
new RegExp(
String.raw`^\s*#[^\S\n]*@(?:${pragmas.join("|")})\s*(?:\n|$)`,
"u",
),
new RegExp(String.raw`^\s*#[^\S\n]*@(?:${pragmas.join("|")})\s*(?:\n|$)`),
);
export const [HTML_HAS_PRAGMA_REGEXP, HTML_HAS_IGNORE_PRAGMA_REGEXP] = [
@@ -38,7 +31,7 @@ export const [HTML_HAS_PRAGMA_REGEXP, HTML_HAS_IGNORE_PRAGMA_REGEXP] = [
FORMAT_IGNORE_PRAGMAS,
].map(
(pragmas) =>
new RegExp(String.raw`^\s*<!--\s*@(?:${pragmas.join("|")})\s*-->`, "u"),
new RegExp(String.raw`^\s*<!--\s*@(?:${pragmas.join("|")})\s*-->`),
);
export const [MARKDOWN_HAS_PRAGMA_REGEXP, MARKDOWN_HAS_IGNORE_PRAGMA_REGEXP] = [
@@ -52,6 +45,6 @@ export const [MARKDOWN_HAS_PRAGMA_REGEXP, MARKDOWN_HAS_IGNORE_PRAGMA_REGEXP] = [
String.raw`\{\s*\/\*\s*${pragma}\s*\*\/\s*\}`,
`<!--.*\r?\n[\\s\\S]*(^|\n)[^\\S\n]*${pragma}[^\\S\n]*($|\n)[\\s\\S]*\n.*-->`,
].join("|"),
"mu",
"m",
);
});
+5 -5
View File
@@ -6,15 +6,15 @@ function printNumber(rawNumber) {
rawNumber
.toLowerCase()
// Remove unnecessary plus and zeroes from scientific notation.
.replace(/^([+-]?[\d.]+e)(?:\+|(-))?0*(?=\d)/u, "$1$2")
.replace(/^([+-]?[\d.]+e)(?:\+|(-))?0*(?=\d)/, "$1$2")
// Remove unnecessary scientific notation (1e0).
.replace(/^([+-]?[\d.]+)e[+-]?0+$/u, "$1")
.replace(/^([+-]?[\d.]+)e[+-]?0+$/, "$1")
// Make sure numbers always start with a digit.
.replace(/^([+-])?\./u, "$10.")
.replace(/^([+-])?\./, "$10.")
// Remove extraneous trailing decimal zeroes.
.replace(/(\.\d+?)0+(?=e|$)/u, "$1")
.replace(/(\.\d+?)0+(?=e|$)/, "$1")
// Remove trailing dot.
.replace(/\.(?=e|$)/u, "")
.replace(/\.(?=e|$)/, "")
);
}
Loaded 100 of 131 files, more files were not shown because too many files have changed in this diff. Show more