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