Skip to content

Commit 195203e

Browse files
authored
Add regex eslint plugin, fix lints (microsoft#59371)
1 parent a5e0385 commit 195203e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+236
-92
lines changed

eslint.config.mjs

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// @ts-check
22
import eslint from "@eslint/js";
3+
import * as regexpPlugin from "eslint-plugin-regexp";
34
import fs from "fs";
45
import globals from "globals";
56
import { createRequire } from "module";
@@ -36,6 +37,7 @@ export default tseslint.config(
3637
eslint.configs.recommended,
3738
...tseslint.configs.recommended,
3839
...tseslint.configs.stylistic,
40+
regexpPlugin.configs["flat/recommended"],
3941
{
4042
plugins: {
4143
local: {
@@ -208,6 +210,7 @@ export default tseslint.config(
208210
files: ["src/harness/**", "src/testRunner/**"],
209211
rules: {
210212
"no-restricted-globals": "off",
213+
"regexp/no-super-linear-backtracking": "off",
211214
"local/no-direct-import": "off",
212215
},
213216
},

package-lock.json

+136
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"esbuild": "^0.23.0",
6565
"eslint": "^9.9.0",
6666
"eslint-formatter-autolinkable-stylish": "^1.4.0",
67+
"eslint-plugin-regexp": "^2.6.0",
6768
"fast-xml-parser": "^4.4.1",
6869
"glob": "^10.4.5",
6970
"globals": "^15.9.0",

scripts/build/tests.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ export async function runConsoleTests(runJs, defaultReporter, runInParallel, opt
105105
}
106106
if (failed) {
107107
const grep = fs.readFileSync(".failed-tests", "utf8")
108-
.split(/\r?\n/g)
108+
.split(/\r?\n/)
109109
.map(test => test.trim())
110110
.filter(test => test.length > 0)
111111
.map(regExpEscape)

scripts/configurePrerelease.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ function getPrereleasePatch(tag, plainPatch) {
112112
// but we'd prefer to just remove separators and limit ourselves to YYYYMMDD.
113113
// UTC time will always be implicit here.
114114
const now = new Date();
115-
const timeStr = now.toISOString().replace(/:|T|\.|-/g, "").slice(0, 8);
115+
const timeStr = now.toISOString().replace(/[:T.-]/g, "").slice(0, 8);
116116

117117
return `${plainPatch}-${tag}.${timeStr}`;
118118
}

scripts/failed-tests.cjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class FailedTestsReporter extends Mocha.reporters.Base {
124124

125125
function readTests() {
126126
return fs.readFileSync(file, "utf8")
127-
.split(/\r?\n/g)
127+
.split(/\r?\n/)
128128
.map(line => line.trim())
129129
.filter(line => line.length > 0);
130130
}

scripts/generateLocalizedDiagnosticMessages.mjs

+2-2
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ async function main() {
113113
ItemId = ItemId.slice(1); // remove leading semicolon
114114
}
115115

116-
val = val.replace(/]5D;/, "]"); // unescape `]`
116+
val = val.replace(/\]5D;/, "]"); // unescape `]`
117117
out[ItemId] = val;
118118
}
119119
return JSON.stringify(out, undefined, 2);
@@ -146,7 +146,7 @@ async function main() {
146146
*/
147147
function getItemXML(key, value) {
148148
// escape entrt value
149-
value = value.replace(/]/g, "]5D;");
149+
value = value.replace(/\]/g, "]5D;");
150150

151151
return `
152152
<Item ItemId=";${key}" ItemType="0" PsrId="306" Leaf="true">

scripts/processDiagnosticMessages.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ function convertPropertyName(origName) {
150150
result = result.replace(/_+/g, "_");
151151

152152
// remove any leading underscore, unless it is followed by a number.
153-
result = result.replace(/^_([^\d])/, "$1");
153+
result = result.replace(/^_(\D)/, "$1");
154154

155155
// get rid of all trailing underscores.
156156
result = result.replace(/_$/, "");

scripts/regenerate-unicode-identifier-parts.mjs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
const MAX_UNICODE_CODEPOINT = 0x10FFFF;
22
/** @type {(c: string) => boolean} */
3-
const isStart = c => /[\p{ID_Start}\u{2118}\u{212E}\u{309B}\u{309C}]/u.test(c); // Other_ID_Start explicitly included for back compat - see http://www.unicode.org/reports/tr31/#Introduction
3+
const isStart = c => /\p{ID_Start}/u.test(c); // Other_ID_Start explicitly included for back compat - see http://www.unicode.org/reports/tr31/#Introduction
44
/** @type {(c: string) => boolean} */
5-
const isPart = c => /[\p{ID_Continue}\u{00B7}\u{0387}\u{19DA}\u{1369}\u{136A}\u{136B}\u{136C}\u{136D}\u{136E}\u{136F}\u{1370}\u{1371}]/u.test(c) || isStart(c); // Likewise for Other_ID_Continue
5+
const isPart = c => /\p{ID_Continue}/u.test(c) || isStart(c); // Likewise for Other_ID_Continue
66
const parts = [];
77
let partsActive = false;
88
let startsActive = false;

src/compiler/checker.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -10678,7 +10678,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1067810678
else if (localName === InternalSymbolName.ExportEquals) {
1067910679
localName = "_exports";
1068010680
}
10681-
localName = isIdentifierText(localName, languageVersion) && !isStringANonContextualKeyword(localName) ? localName : "_" + localName.replace(/[^a-zA-Z0-9]/g, "_");
10681+
localName = isIdentifierText(localName, languageVersion) && !isStringANonContextualKeyword(localName) ? localName : "_" + localName.replace(/[^a-z0-9]/gi, "_");
1068210682
return localName;
1068310683
}
1068410684

@@ -34355,7 +34355,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3435534355

3435634356
function containerSeemsToBeEmptyDomElement(containingType: Type) {
3435734357
return (compilerOptions.lib && !compilerOptions.lib.includes("dom")) &&
34358-
everyContainedType(containingType, type => type.symbol && /^(EventTarget|Node|((HTML[a-zA-Z]*)?Element))$/.test(unescapeLeadingUnderscores(type.symbol.escapedName))) &&
34358+
everyContainedType(containingType, type => type.symbol && /^(?:EventTarget|Node|(?:HTML[a-zA-Z]*)?Element)$/.test(unescapeLeadingUnderscores(type.symbol.escapedName))) &&
3435934359
isEmptyObjectType(containingType);
3436034360
}
3436134361

src/compiler/commandLineParser.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3762,7 +3762,7 @@ function convertJsonOptionOfListType(
37623762
* \*\* # matches the recursive directory wildcard "**".
37633763
* \/?$ # matches an optional trailing directory separator at the end of the string.
37643764
*/
3765-
const invalidTrailingRecursionPattern = /(^|\/)\*\*\/?$/;
3765+
const invalidTrailingRecursionPattern = /(?:^|\/)\*\*\/?$/;
37663766

37673767
/**
37683768
* Matches the portion of a wildcard path that does not contain wildcards.

src/compiler/debug.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ export namespace Debug {
581581
// This regex can trigger slow backtracking because of overlapping potential captures.
582582
// We don't care, this is debug code that's only enabled with a debugger attached -
583583
// we're just taking note of it for anyone checking regex performance in the future.
584-
defaultValue = String(defaultValue).replace(/(?:,[\s\w\d_]+:[^,]+)+\]$/, "]");
584+
defaultValue = String(defaultValue).replace(/(?:,[\s\w]+:[^,]+)+\]$/, "]");
585585
return `NodeArray ${defaultValue}`;
586586
},
587587
},

src/compiler/emitter.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -4005,7 +4005,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
40054005
if (node.comment) {
40064006
const text = getTextOfJSDocComment(node.comment);
40074007
if (text) {
4008-
const lines = text.split(/\r\n?|\n/g);
4008+
const lines = text.split(/\r\n?|\n/);
40094009
for (const line of lines) {
40104010
writeLine();
40114011
writeSpace();
@@ -4880,7 +4880,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
48804880
}
48814881

48824882
function writeLines(text: string): void {
4883-
const lines = text.split(/\r\n?|\n/g);
4883+
const lines = text.split(/\r\n?|\n/);
48844884
const indentation = guessIndentation(lines);
48854885
for (const lineText of lines) {
48864886
const line = indentation ? lineText.slice(indentation) : lineText;

src/compiler/parser.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -10653,8 +10653,8 @@ function getNamedArgRegEx(name: string): RegExp {
1065310653
return result;
1065410654
}
1065510655

10656-
const tripleSlashXMLCommentStartRegEx = /^\/\/\/\s*<(\S+)\s.*?\/>/im;
10657-
const singleLinePragmaRegEx = /^\/\/\/?\s*@([^\s:]+)(.*)\s*$/im;
10656+
const tripleSlashXMLCommentStartRegEx = /^\/\/\/\s*<(\S+)\s.*?\/>/m;
10657+
const singleLinePragmaRegEx = /^\/\/\/?\s*@([^\s:]+)((?:[^\S\r\n]|:).*)?$/m;
1065810658
function extractPragmas(pragmas: PragmaPseudoMapEntry[], range: CommentRange, text: string) {
1065910659
const tripleSlash = range.kind === SyntaxKind.SingleLineCommentTrivia && tripleSlashXMLCommentStartRegEx.exec(text);
1066010660
if (tripleSlash) {
@@ -10700,7 +10700,7 @@ function extractPragmas(pragmas: PragmaPseudoMapEntry[], range: CommentRange, te
1070010700
}
1070110701

1070210702
if (range.kind === SyntaxKind.MultiLineCommentTrivia) {
10703-
const multiLinePragmaRegEx = /@(\S+)(\s+.*)?$/gim; // Defined inline since it uses the "g" flag, which keeps a persistent index (for iterating)
10703+
const multiLinePragmaRegEx = /@(\S+)(\s+(?:\S.*)?)?$/gm; // Defined inline since it uses the "g" flag, which keeps a persistent index (for iterating)
1070410704
let multiLineMatch: RegExpExecArray | null; // eslint-disable-line no-restricted-syntax
1070510705
while (multiLineMatch = multiLinePragmaRegEx.exec(text)) {
1070610706
addPragmaForMatch(pragmas, range, PragmaKindFlags.MultiLine, multiLineMatch);

0 commit comments

Comments
 (0)