Add regex eslint plugin, fix lints (#59371)
This commit is contained in:
Родитель
a5e0385edf
Коммит
195203e971
|
@ -1,5 +1,6 @@
|
|||
// @ts-check
|
||||
import eslint from "@eslint/js";
|
||||
import * as regexpPlugin from "eslint-plugin-regexp";
|
||||
import fs from "fs";
|
||||
import globals from "globals";
|
||||
import { createRequire } from "module";
|
||||
|
@ -36,6 +37,7 @@ export default tseslint.config(
|
|||
eslint.configs.recommended,
|
||||
...tseslint.configs.recommended,
|
||||
...tseslint.configs.stylistic,
|
||||
regexpPlugin.configs["flat/recommended"],
|
||||
{
|
||||
plugins: {
|
||||
local: {
|
||||
|
@ -208,6 +210,7 @@ export default tseslint.config(
|
|||
files: ["src/harness/**", "src/testRunner/**"],
|
||||
rules: {
|
||||
"no-restricted-globals": "off",
|
||||
"regexp/no-super-linear-backtracking": "off",
|
||||
"local/no-direct-import": "off",
|
||||
},
|
||||
},
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
"esbuild": "^0.23.0",
|
||||
"eslint": "^9.9.0",
|
||||
"eslint-formatter-autolinkable-stylish": "^1.4.0",
|
||||
"eslint-plugin-regexp": "^2.6.0",
|
||||
"fast-xml-parser": "^4.4.1",
|
||||
"glob": "^10.4.5",
|
||||
"globals": "^15.9.0",
|
||||
|
@ -1844,6 +1845,15 @@
|
|||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/comment-parser": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
|
||||
"integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
|
@ -2239,6 +2249,27 @@
|
|||
"eslint": "^8.3.0 || ^9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-regexp": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.6.0.tgz",
|
||||
"integrity": "sha512-FCL851+kislsTEQEMioAlpDuK5+E5vs0hi1bF8cFlPlHcEjeRhuAzEsGikXRreE+0j4WhW2uO54MqTjXtYOi3A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.9.1",
|
||||
"comment-parser": "^1.4.0",
|
||||
"jsdoc-type-pratt-parser": "^4.0.0",
|
||||
"refa": "^0.12.1",
|
||||
"regexp-ast-analysis": "^0.7.1",
|
||||
"scslre": "^0.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18 || >=20"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": ">=8.44.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-scope": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz",
|
||||
|
@ -3058,6 +3089,15 @@
|
|||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/jsdoc-type-pratt-parser": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz",
|
||||
"integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/json-buffer": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||
|
@ -3945,6 +3985,31 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/refa": {
|
||||
"version": "0.12.1",
|
||||
"resolved": "https://registry.npmjs.org/refa/-/refa-0.12.1.tgz",
|
||||
"integrity": "sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/regexpp": "^4.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/regexp-ast-analysis": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.7.1.tgz",
|
||||
"integrity": "sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/regexpp": "^4.8.0",
|
||||
"refa": "^0.12.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
|
@ -4016,6 +4081,20 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"node_modules/scslre": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/scslre/-/scslre-0.3.0.tgz",
|
||||
"integrity": "sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/regexpp": "^4.8.0",
|
||||
"refa": "^0.12.0",
|
||||
"regexp-ast-analysis": "^0.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.0.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
|
||||
|
@ -5926,6 +6005,12 @@
|
|||
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
|
||||
"dev": true
|
||||
},
|
||||
"comment-parser": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
|
||||
"integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==",
|
||||
"dev": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
|
@ -6244,6 +6329,21 @@
|
|||
"plur": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"eslint-plugin-regexp": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.6.0.tgz",
|
||||
"integrity": "sha512-FCL851+kislsTEQEMioAlpDuK5+E5vs0hi1bF8cFlPlHcEjeRhuAzEsGikXRreE+0j4WhW2uO54MqTjXtYOi3A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.9.1",
|
||||
"comment-parser": "^1.4.0",
|
||||
"jsdoc-type-pratt-parser": "^4.0.0",
|
||||
"refa": "^0.12.1",
|
||||
"regexp-ast-analysis": "^0.7.1",
|
||||
"scslre": "^0.3.0"
|
||||
}
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz",
|
||||
|
@ -6800,6 +6900,12 @@
|
|||
"argparse": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"jsdoc-type-pratt-parser": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz",
|
||||
"integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==",
|
||||
"dev": true
|
||||
},
|
||||
"json-buffer": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||
|
@ -7418,6 +7524,25 @@
|
|||
"integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==",
|
||||
"dev": true
|
||||
},
|
||||
"refa": {
|
||||
"version": "0.12.1",
|
||||
"resolved": "https://registry.npmjs.org/refa/-/refa-0.12.1.tgz",
|
||||
"integrity": "sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@eslint-community/regexpp": "^4.8.0"
|
||||
}
|
||||
},
|
||||
"regexp-ast-analysis": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.7.1.tgz",
|
||||
"integrity": "sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@eslint-community/regexpp": "^4.8.0",
|
||||
"refa": "^0.12.1"
|
||||
}
|
||||
},
|
||||
"require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
|
@ -7451,6 +7576,17 @@
|
|||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"dev": true
|
||||
},
|
||||
"scslre": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/scslre/-/scslre-0.3.0.tgz",
|
||||
"integrity": "sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@eslint-community/regexpp": "^4.8.0",
|
||||
"refa": "^0.12.0",
|
||||
"regexp-ast-analysis": "^0.7.0"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
"esbuild": "^0.23.0",
|
||||
"eslint": "^9.9.0",
|
||||
"eslint-formatter-autolinkable-stylish": "^1.4.0",
|
||||
"eslint-plugin-regexp": "^2.6.0",
|
||||
"fast-xml-parser": "^4.4.1",
|
||||
"glob": "^10.4.5",
|
||||
"globals": "^15.9.0",
|
||||
|
|
|
@ -105,7 +105,7 @@ export async function runConsoleTests(runJs, defaultReporter, runInParallel, opt
|
|||
}
|
||||
if (failed) {
|
||||
const grep = fs.readFileSync(".failed-tests", "utf8")
|
||||
.split(/\r?\n/g)
|
||||
.split(/\r?\n/)
|
||||
.map(test => test.trim())
|
||||
.filter(test => test.length > 0)
|
||||
.map(regExpEscape)
|
||||
|
|
|
@ -112,7 +112,7 @@ function getPrereleasePatch(tag, plainPatch) {
|
|||
// but we'd prefer to just remove separators and limit ourselves to YYYYMMDD.
|
||||
// UTC time will always be implicit here.
|
||||
const now = new Date();
|
||||
const timeStr = now.toISOString().replace(/:|T|\.|-/g, "").slice(0, 8);
|
||||
const timeStr = now.toISOString().replace(/[:T.-]/g, "").slice(0, 8);
|
||||
|
||||
return `${plainPatch}-${tag}.${timeStr}`;
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ class FailedTestsReporter extends Mocha.reporters.Base {
|
|||
|
||||
function readTests() {
|
||||
return fs.readFileSync(file, "utf8")
|
||||
.split(/\r?\n/g)
|
||||
.split(/\r?\n/)
|
||||
.map(line => line.trim())
|
||||
.filter(line => line.length > 0);
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ async function main() {
|
|||
ItemId = ItemId.slice(1); // remove leading semicolon
|
||||
}
|
||||
|
||||
val = val.replace(/]5D;/, "]"); // unescape `]`
|
||||
val = val.replace(/\]5D;/, "]"); // unescape `]`
|
||||
out[ItemId] = val;
|
||||
}
|
||||
return JSON.stringify(out, undefined, 2);
|
||||
|
@ -146,7 +146,7 @@ async function main() {
|
|||
*/
|
||||
function getItemXML(key, value) {
|
||||
// escape entrt value
|
||||
value = value.replace(/]/g, "]5D;");
|
||||
value = value.replace(/\]/g, "]5D;");
|
||||
|
||||
return `
|
||||
<Item ItemId=";${key}" ItemType="0" PsrId="306" Leaf="true">
|
||||
|
|
|
@ -150,7 +150,7 @@ function convertPropertyName(origName) {
|
|||
result = result.replace(/_+/g, "_");
|
||||
|
||||
// remove any leading underscore, unless it is followed by a number.
|
||||
result = result.replace(/^_([^\d])/, "$1");
|
||||
result = result.replace(/^_(\D)/, "$1");
|
||||
|
||||
// get rid of all trailing underscores.
|
||||
result = result.replace(/_$/, "");
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
const MAX_UNICODE_CODEPOINT = 0x10FFFF;
|
||||
/** @type {(c: string) => boolean} */
|
||||
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
|
||||
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
|
||||
/** @type {(c: string) => boolean} */
|
||||
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
|
||||
const isPart = c => /\p{ID_Continue}/u.test(c) || isStart(c); // Likewise for Other_ID_Continue
|
||||
const parts = [];
|
||||
let partsActive = false;
|
||||
let startsActive = false;
|
||||
|
|
|
@ -10678,7 +10678,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
|||
else if (localName === InternalSymbolName.ExportEquals) {
|
||||
localName = "_exports";
|
||||
}
|
||||
localName = isIdentifierText(localName, languageVersion) && !isStringANonContextualKeyword(localName) ? localName : "_" + localName.replace(/[^a-zA-Z0-9]/g, "_");
|
||||
localName = isIdentifierText(localName, languageVersion) && !isStringANonContextualKeyword(localName) ? localName : "_" + localName.replace(/[^a-z0-9]/gi, "_");
|
||||
return localName;
|
||||
}
|
||||
|
||||
|
@ -34355,7 +34355,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
|||
|
||||
function containerSeemsToBeEmptyDomElement(containingType: Type) {
|
||||
return (compilerOptions.lib && !compilerOptions.lib.includes("dom")) &&
|
||||
everyContainedType(containingType, type => type.symbol && /^(EventTarget|Node|((HTML[a-zA-Z]*)?Element))$/.test(unescapeLeadingUnderscores(type.symbol.escapedName))) &&
|
||||
everyContainedType(containingType, type => type.symbol && /^(?:EventTarget|Node|(?:HTML[a-zA-Z]*)?Element)$/.test(unescapeLeadingUnderscores(type.symbol.escapedName))) &&
|
||||
isEmptyObjectType(containingType);
|
||||
}
|
||||
|
||||
|
|
|
@ -3762,7 +3762,7 @@ function convertJsonOptionOfListType(
|
|||
* \*\* # matches the recursive directory wildcard "**".
|
||||
* \/?$ # matches an optional trailing directory separator at the end of the string.
|
||||
*/
|
||||
const invalidTrailingRecursionPattern = /(^|\/)\*\*\/?$/;
|
||||
const invalidTrailingRecursionPattern = /(?:^|\/)\*\*\/?$/;
|
||||
|
||||
/**
|
||||
* Matches the portion of a wildcard path that does not contain wildcards.
|
||||
|
|
|
@ -581,7 +581,7 @@ export namespace Debug {
|
|||
// This regex can trigger slow backtracking because of overlapping potential captures.
|
||||
// We don't care, this is debug code that's only enabled with a debugger attached -
|
||||
// we're just taking note of it for anyone checking regex performance in the future.
|
||||
defaultValue = String(defaultValue).replace(/(?:,[\s\w\d_]+:[^,]+)+\]$/, "]");
|
||||
defaultValue = String(defaultValue).replace(/(?:,[\s\w]+:[^,]+)+\]$/, "]");
|
||||
return `NodeArray ${defaultValue}`;
|
||||
},
|
||||
},
|
||||
|
|
|
@ -4005,7 +4005,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
|
|||
if (node.comment) {
|
||||
const text = getTextOfJSDocComment(node.comment);
|
||||
if (text) {
|
||||
const lines = text.split(/\r\n?|\n/g);
|
||||
const lines = text.split(/\r\n?|\n/);
|
||||
for (const line of lines) {
|
||||
writeLine();
|
||||
writeSpace();
|
||||
|
@ -4880,7 +4880,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
|
|||
}
|
||||
|
||||
function writeLines(text: string): void {
|
||||
const lines = text.split(/\r\n?|\n/g);
|
||||
const lines = text.split(/\r\n?|\n/);
|
||||
const indentation = guessIndentation(lines);
|
||||
for (const lineText of lines) {
|
||||
const line = indentation ? lineText.slice(indentation) : lineText;
|
||||
|
|
|
@ -10653,8 +10653,8 @@ function getNamedArgRegEx(name: string): RegExp {
|
|||
return result;
|
||||
}
|
||||
|
||||
const tripleSlashXMLCommentStartRegEx = /^\/\/\/\s*<(\S+)\s.*?\/>/im;
|
||||
const singleLinePragmaRegEx = /^\/\/\/?\s*@([^\s:]+)(.*)\s*$/im;
|
||||
const tripleSlashXMLCommentStartRegEx = /^\/\/\/\s*<(\S+)\s.*?\/>/m;
|
||||
const singleLinePragmaRegEx = /^\/\/\/?\s*@([^\s:]+)((?:[^\S\r\n]|:).*)?$/m;
|
||||
function extractPragmas(pragmas: PragmaPseudoMapEntry[], range: CommentRange, text: string) {
|
||||
const tripleSlash = range.kind === SyntaxKind.SingleLineCommentTrivia && tripleSlashXMLCommentStartRegEx.exec(text);
|
||||
if (tripleSlash) {
|
||||
|
@ -10700,7 +10700,7 @@ function extractPragmas(pragmas: PragmaPseudoMapEntry[], range: CommentRange, te
|
|||
}
|
||||
|
||||
if (range.kind === SyntaxKind.MultiLineCommentTrivia) {
|
||||
const multiLinePragmaRegEx = /@(\S+)(\s+.*)?$/gim; // Defined inline since it uses the "g" flag, which keeps a persistent index (for iterating)
|
||||
const multiLinePragmaRegEx = /@(\S+)(\s+(?:\S.*)?)?$/gm; // Defined inline since it uses the "g" flag, which keeps a persistent index (for iterating)
|
||||
let multiLineMatch: RegExpExecArray | null; // eslint-disable-line no-restricted-syntax
|
||||
while (multiLineMatch = multiLinePragmaRegEx.exec(text)) {
|
||||
addPragmaForMatch(pragmas, range, PragmaKindFlags.MultiLine, multiLineMatch);
|
||||
|
|
|
@ -98,7 +98,7 @@ export function pathIsAbsolute(path: string): boolean {
|
|||
* @internal
|
||||
*/
|
||||
export function pathIsRelative(path: string): boolean {
|
||||
return /^\.\.?($|[\\/])/.test(path);
|
||||
return /^\.\.?(?:$|[\\/])/.test(path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -779,7 +779,7 @@ export function changeFullExtension(path: string, newExtension: string) {
|
|||
//// Path Comparisons
|
||||
|
||||
// check path for these segments: '', '.'. '..'
|
||||
const relativePathSegmentRegExp = /(?:\/\/)|(?:^|\/)\.\.?(?:$|\/)/;
|
||||
const relativePathSegmentRegExp = /\/\/|(?:^|\/)\.\.?(?:$|\/)/;
|
||||
|
||||
function comparePathsWorker(a: string, b: string, componentComparer: (a: string, b: string) => Comparison) {
|
||||
if (a === b) return Comparison.EqualTo;
|
||||
|
|
|
@ -3109,7 +3109,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
|||
|
||||
// Stop searching if the line is not empty and not a comment
|
||||
const lineText = file.text.slice(lineStarts[line], lineStarts[line + 1]).trim();
|
||||
if (lineText !== "" && !/^(\s*)\/\/(.*)$/.test(lineText)) {
|
||||
if (lineText !== "" && !/^\s*\/\/.*$/.test(lineText)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -267,11 +267,11 @@ function perceivedOsRootLengthForWatching(pathComponents: Readonly<PathPathCompo
|
|||
// Ignore "/", "c:/"
|
||||
if (length <= 1) return 1;
|
||||
let indexAfterOsRoot = 1;
|
||||
let isDosStyle = pathComponents[0].search(/[a-zA-Z]:/) === 0;
|
||||
let isDosStyle = pathComponents[0].search(/[a-z]:/i) === 0;
|
||||
if (
|
||||
pathComponents[0] !== directorySeparator &&
|
||||
!isDosStyle && // Non dos style paths
|
||||
pathComponents[1].search(/[a-zA-Z]\$$/) === 0 // Dos style nextPart
|
||||
pathComponents[1].search(/[a-z]\$$/i) === 0 // Dos style nextPart
|
||||
) {
|
||||
// ignore "//vda1cs4850/c$/folderAtRoot"
|
||||
if (length === 2) return 2;
|
||||
|
|
|
@ -36,7 +36,7 @@ const buildPartRegExp = /^[a-z0-9-]+$/i;
|
|||
|
||||
// https://semver.org/#spec-item-9
|
||||
// > Numeric identifiers MUST NOT include leading zeroes.
|
||||
const numericIdentifierRegExp = /^(0|[1-9]\d*)$/;
|
||||
const numericIdentifierRegExp = /^(?:0|[1-9]\d*)$/;
|
||||
|
||||
/**
|
||||
* Describes a precise semantic version number, https://semver.org
|
||||
|
@ -244,8 +244,8 @@ interface Comparator {
|
|||
// range-set ::= range ( logical-or range ) *
|
||||
// range ::= hyphen | simple ( ' ' simple ) * | ''
|
||||
// logical-or ::= ( ' ' ) * '||' ( ' ' ) *
|
||||
const logicalOrRegExp = /\|\|/g;
|
||||
const whitespaceRegExp = /\s+/g;
|
||||
const logicalOrRegExp = /\|\|/;
|
||||
const whitespaceRegExp = /\s+/;
|
||||
|
||||
// https://github.com/npm/node-semver#range-grammar
|
||||
//
|
||||
|
@ -257,7 +257,7 @@ const whitespaceRegExp = /\s+/g;
|
|||
// build ::= parts
|
||||
// parts ::= part ( '.' part ) *
|
||||
// part ::= nr | [-0-9A-Za-z]+
|
||||
const partialRegExp = /^([xX*0]|[1-9]\d*)(?:\.([xX*0]|[1-9]\d*)(?:\.([xX*0]|[1-9]\d*)(?:-([a-z0-9-.]+))?(?:\+([a-z0-9-.]+))?)?)?$/i;
|
||||
const partialRegExp = /^([x*0]|[1-9]\d*)(?:\.([x*0]|[1-9]\d*)(?:\.([x*0]|[1-9]\d*)(?:-([a-z0-9-.]+))?(?:\+([a-z0-9-.]+))?)?)?$/i;
|
||||
|
||||
// https://github.com/npm/node-semver#range-grammar
|
||||
//
|
||||
|
@ -270,7 +270,7 @@ const hyphenRegExp = /^\s*([a-z0-9-+.*]+)\s+-\s+([a-z0-9-+.*]+)\s*$/i;
|
|||
// primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
|
||||
// tilde ::= '~' partial
|
||||
// caret ::= '^' partial
|
||||
const rangeRegExp = /^(~|\^|<|<=|>|>=|=)?\s*([a-z0-9-+.*]+)$/i;
|
||||
const rangeRegExp = /^([~^<>=]|<=|>=)?\s*([a-z0-9-+.*]+)$/i;
|
||||
|
||||
function parseRange(text: string) {
|
||||
const alternatives: Comparator[][] = [];
|
||||
|
|
|
@ -360,9 +360,9 @@ export function createSourceMapGenerator(host: EmitHost, file: string, sourceRoo
|
|||
|
||||
// Sometimes tools can see the following line as a source mapping url comment, so we mangle it a bit (the [M])
|
||||
/** @internal */
|
||||
export const sourceMapCommentRegExpDontCareLineStart = /\/\/[@#] source[M]appingURL=(.+)\r?\n?$/;
|
||||
export const sourceMapCommentRegExpDontCareLineStart = /\/\/[@#] source[M]appingURL=(.+)\r?\n?$/; // eslint-disable-line regexp/no-useless-character-class
|
||||
/** @internal */
|
||||
export const sourceMapCommentRegExp = /^\/\/[@#] source[M]appingURL=(.+)\r?\n?$/;
|
||||
export const sourceMapCommentRegExp = /^\/\/[@#] source[M]appingURL=(.+)\r?\n?$/; // eslint-disable-line regexp/no-useless-character-class
|
||||
|
||||
/** @internal */
|
||||
export const whitespaceOrMapCommentRegExp = /^\s*(\/\/[@#] .*)?$/;
|
||||
|
|
|
@ -1466,7 +1466,7 @@ export let sys: System = (() => {
|
|||
const byteOrderMarkIndicator = "\uFEFF";
|
||||
|
||||
function getNodeSystem(): System {
|
||||
const nativePattern = /^native |^\([^)]+\)$|^(internal[\\/]|[a-zA-Z0-9_\s]+(\.js)?$)/;
|
||||
const nativePattern = /^native |^\([^)]+\)$|^(?:internal[\\/]|[\w\s]+(?:\.js)?$)/;
|
||||
const _fs: typeof import("fs") = require("fs");
|
||||
const _path: typeof import("path") = require("path");
|
||||
const _os = require("os");
|
||||
|
@ -1592,7 +1592,7 @@ export let sys: System = (() => {
|
|||
disableCPUProfiler,
|
||||
cpuProfilingEnabled: () => !!activeSession || contains(process.execArgv, "--cpu-prof") || contains(process.execArgv, "--prof"),
|
||||
realpath,
|
||||
debugMode: !!process.env.NODE_INSPECTOR_IPC || !!process.env.VSCODE_INSPECTOR_OPTIONS || some(process.execArgv, arg => /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg)) || !!(process as any).recordreplay,
|
||||
debugMode: !!process.env.NODE_INSPECTOR_IPC || !!process.env.VSCODE_INSPECTOR_OPTIONS || some(process.execArgv, arg => /^--(?:inspect|debug)(?:-brk)?(?:=\d+)?$/i.test(arg)) || !!(process as any).recordreplay,
|
||||
tryEnableSourceMapsForHost() {
|
||||
try {
|
||||
(require("source-map-support") as typeof import("source-map-support")).install();
|
||||
|
|
|
@ -667,7 +667,7 @@ export function transformJsx(context: TransformationContext): (x: SourceFile | B
|
|||
const name = node.name;
|
||||
if (isIdentifier(name)) {
|
||||
const text = idText(name);
|
||||
return (/^[A-Za-z_]\w*$/.test(text)) ? name : factory.createStringLiteral(text);
|
||||
return (/^[A-Z_]\w*$/i.test(text)) ? name : factory.createStringLiteral(text);
|
||||
}
|
||||
return factory.createStringLiteral(idText(name.namespace) + ":" + idText(name.name));
|
||||
}
|
||||
|
|
|
@ -2622,12 +2622,12 @@ export function getJSDocCommentRanges(node: Node, text: string) {
|
|||
text.charCodeAt(comment.pos + 3) !== CharacterCodes.slash);
|
||||
}
|
||||
|
||||
const fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*<reference\s+path\s*=\s*)(('[^']*')|("[^"]*")).*?\/>/;
|
||||
const fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*<reference\s+types\s*=\s*)(('[^']*')|("[^"]*")).*?\/>/;
|
||||
const fullTripleSlashLibReferenceRegEx = /^(\/\/\/\s*<reference\s+lib\s*=\s*)(('[^']*')|("[^"]*")).*?\/>/;
|
||||
const fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*<amd-dependency\s+path\s*=\s*)(('[^']*')|("[^"]*")).*?\/>/;
|
||||
const fullTripleSlashAMDModuleRegEx = /^\/\/\/\s*<amd-module\s+.*?\/>/;
|
||||
const defaultLibReferenceRegEx = /^(\/\/\/\s*<reference\s+no-default-lib\s*=\s*)(('[^']*')|("[^"]*"))\s*\/>/;
|
||||
const fullTripleSlashReferencePathRegEx = /^\/\/\/\s*<reference\s+path\s*=\s*(?:'[^']*'|"[^"]*").*?\/>/;
|
||||
const fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^\/\/\/\s*<reference\s+types\s*=\s*(?:'[^']*'|"[^"]*").*?\/>/;
|
||||
const fullTripleSlashLibReferenceRegEx = /^\/\/\/\s*<reference\s+lib\s*=\s*(?:'[^']*'|"[^"]*").*?\/>/;
|
||||
const fullTripleSlashAMDReferencePathRegEx = /^\/\/\/\s*<amd-dependency\s+path\s*=\s*(?:'[^']*'|"[^"]*").*?\/>/;
|
||||
const fullTripleSlashAMDModuleRegEx = /^\/\/\/\s*<amd-module\s+(?:\S.*?)??\/>/;
|
||||
const defaultLibReferenceRegEx = /^\/\/\/\s*<reference\s+no-default-lib\s*=\s*(?:'[^']*'|"[^"]*")\s*\/>/;
|
||||
|
||||
export function isPartOfTypeNode(node: Node): boolean {
|
||||
if (SyntaxKind.FirstTypeNode <= node.kind && node.kind <= SyntaxKind.LastTypeNode) {
|
||||
|
@ -5988,10 +5988,10 @@ export function hasInvalidEscape(template: TemplateLiteral): boolean {
|
|||
// the language service. These characters should be escaped when printing, and if any characters are added,
|
||||
// the map below must be updated. Note that this regexp *does not* include the 'delete' character.
|
||||
// There is no reason for this other than that JSON.stringify does not handle it either.
|
||||
const doubleQuoteEscapedCharsRegExp = /[\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
|
||||
const singleQuoteEscapedCharsRegExp = /[\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
|
||||
const doubleQuoteEscapedCharsRegExp = /[\\"\u0000-\u001f\u2028\u2029\u0085]/g;
|
||||
const singleQuoteEscapedCharsRegExp = /[\\'\u0000-\u001f\u2028\u2029\u0085]/g;
|
||||
// Template strings preserve simple LF newlines, still encode CRLF (or CR)
|
||||
const backtickQuoteEscapedCharsRegExp = /\r\n|[\\`\u0000-\u001f\t\v\f\b\r\u2028\u2029\u0085]/g;
|
||||
const backtickQuoteEscapedCharsRegExp = /\r\n|[\\`\u0000-\u001f\u2028\u2029\u0085]/g;
|
||||
const escapedCharsMap = new Map(Object.entries({
|
||||
"\t": "\\t",
|
||||
"\v": "\\v",
|
||||
|
@ -8365,7 +8365,7 @@ export function setObjectAllocator(alloc: ObjectAllocator) {
|
|||
|
||||
/** @internal */
|
||||
export function formatStringFromArgs(text: string, args: DiagnosticArguments): string {
|
||||
return text.replace(/{(\d+)}/g, (_match, index: string) => "" + Debug.checkDefined(args[+index]));
|
||||
return text.replace(/\{(\d+)\}/g, (_match, index: string) => "" + Debug.checkDefined(args[+index]));
|
||||
}
|
||||
|
||||
let localizedDiagnosticMessages: MapLike<string> | undefined;
|
||||
|
@ -10623,7 +10623,7 @@ export function isFunctionExpressionOrArrowFunction(node: Node): node is Functio
|
|||
|
||||
/** @internal */
|
||||
export function escapeSnippetText(text: string): string {
|
||||
return text.replace(/\$/gm, () => "\\$");
|
||||
return text.replace(/\$/g, () => "\\$");
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
|
|
@ -681,7 +681,7 @@ export function validateLocaleAndSetLanguage(
|
|||
errors?: Diagnostic[],
|
||||
) {
|
||||
const lowerCaseLocale = locale.toLowerCase();
|
||||
const matchResult = /^([a-z]+)([_-]([a-z]+))?$/.exec(lowerCaseLocale);
|
||||
const matchResult = /^([a-z]+)(?:[_-]([a-z]+))?$/.exec(lowerCaseLocale);
|
||||
|
||||
if (!matchResult) {
|
||||
if (errors) {
|
||||
|
@ -691,7 +691,7 @@ export function validateLocaleAndSetLanguage(
|
|||
}
|
||||
|
||||
const language = matchResult[1];
|
||||
const territory = matchResult[3];
|
||||
const territory = matchResult[2];
|
||||
|
||||
// First try the entire locale, then fall back to just language if that's all we have.
|
||||
// Either ways do not fail, and fallback to the English diagnostic strings.
|
||||
|
|
|
@ -72,8 +72,8 @@ export class SourceMap {
|
|||
public readonly mappings: readonly Mapping[] = [];
|
||||
public readonly names: readonly string[] | undefined;
|
||||
|
||||
private static readonly _mappingRegExp = /([A-Za-z0-9+/]+),?|(;)|./g;
|
||||
private static readonly _sourceMappingURLRegExp = /^\/\/[#@]\s*sourceMappingURL\s*=\s*(.*?)\s*$/mig;
|
||||
private static readonly _mappingRegExp = /([A-Z0-9+/]+),?|(;)|./gi;
|
||||
private static readonly _sourceMappingURLRegExp = /^\/\/[#@]\s*sourceMappingURL\s*=\s*(.*?)\s*$/gim;
|
||||
private static readonly _dataURLRegExp = /^data:application\/json;base64,([a-z0-9+/=]+)$/i;
|
||||
private static readonly _base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
|
|
|
@ -966,7 +966,7 @@ export class TestState {
|
|||
const annotations = ts.map(hints.sort(sortHints), hint => {
|
||||
if (hint.displayParts) {
|
||||
hint.displayParts = ts.map(hint.displayParts, part => {
|
||||
if (part.file && /lib(?:.*)\.d\.ts$/.test(part.file)) {
|
||||
if (part.file && /lib.*\.d\.ts$/.test(part.file)) {
|
||||
part.span!.start = -1;
|
||||
}
|
||||
return part;
|
||||
|
@ -1547,7 +1547,7 @@ export class TestState {
|
|||
}: BaselineDocumentSpansWithFileContentsOptions<T>,
|
||||
spanToContextId: Map<T, number>,
|
||||
) {
|
||||
const isLibFile = /lib(?:.*)\.d\.ts$/.test(fileName);
|
||||
const isLibFile = /lib.*\.d\.ts$/.test(fileName);
|
||||
let readableContents = `// === ${fileName} ===`;
|
||||
let newContent = "";
|
||||
interface Detail {
|
||||
|
@ -2514,7 +2514,7 @@ export class TestState {
|
|||
for (const part of tag.text ?? ts.emptyArray) {
|
||||
if (part.kind === "linkName") {
|
||||
const link = part as ts.JSDocLinkDisplayPart;
|
||||
if (/lib(?:.*)\.d\.ts$/.test(link.target.fileName)) {
|
||||
if (/lib.*\.d\.ts$/.test(link.target.fileName)) {
|
||||
// The object literal isn't a complete TextSpan, but we're only going to
|
||||
// use these results in the baseline for diffing, so just overwrite.
|
||||
(link.target.textSpan as any) = { start: "--", length: "--" };
|
||||
|
|
|
@ -582,7 +582,7 @@ export namespace Compiler {
|
|||
let location = info.file ? " " + ts.formatLocation(info.file, info.start!, formatDiagnsoticHost, ts.identity) : "";
|
||||
location = Utils.removeTestPathPrefixes(location);
|
||||
if (location && isDefaultLibraryFile(info.file!.fileName)) {
|
||||
location = location.replace(/(lib(?:.*)\.d\.ts):\d+:\d+/i, "$1:--:--");
|
||||
location = location.replace(/(lib.*\.d\.ts):\d+:\d+/i, "$1:--:--");
|
||||
}
|
||||
errLines.push(`!!! related TS${info.code}${location}: ${ts.flattenDiagnosticMessageText(info.messageText, IO.newLine())}`);
|
||||
}
|
||||
|
@ -603,7 +603,7 @@ export namespace Compiler {
|
|||
|
||||
let topDiagnostics = minimalDiagnosticsToString(diagnostics, options && options.pretty);
|
||||
topDiagnostics = Utils.removeTestPathPrefixes(topDiagnostics);
|
||||
topDiagnostics = topDiagnostics.replace(/^(lib(?:.*)\.d\.ts)\(\d+,\d+\)/igm, "$1(--,--)");
|
||||
topDiagnostics = topDiagnostics.replace(/^(lib.*\.d\.ts)\(\d+,\d+\)/gim, "$1(--,--)");
|
||||
|
||||
yield [diagnosticSummaryMarker, topDiagnostics + IO.newLine() + IO.newLine(), diagnostics.length];
|
||||
|
||||
|
@ -666,7 +666,7 @@ export namespace Compiler {
|
|||
// Calculate the start of the squiggle
|
||||
const squiggleStart = Math.max(0, relativeOffset);
|
||||
// TODO/REVIEW: this doesn't work quite right in the browser if a multi file test has files whose names are just the right length relative to one another
|
||||
outputLines += newLine() + " " + line.substr(0, squiggleStart).replace(/[^\s]/g, " ") + new Array(Math.min(length, line.length - squiggleStart) + 1).join("~");
|
||||
outputLines += newLine() + " " + line.substr(0, squiggleStart).replace(/\S/g, " ") + new Array(Math.min(length, line.length - squiggleStart) + 1).join("~");
|
||||
|
||||
// If the error ended here, or we're at the end of the file, emit its message
|
||||
if ((lineIndex === lines.length - 1) || nextLineStart > end) {
|
||||
|
@ -862,7 +862,7 @@ export namespace Compiler {
|
|||
for (const file of allFiles) {
|
||||
const { unitName } = file;
|
||||
let typeLines = "=== " + unitName + " ===\r\n";
|
||||
const codeLines = ts.flatMap(file.content.split(/\r?\n/g), e => e.split(/[\r\u2028\u2029]/g));
|
||||
const codeLines = ts.flatMap(file.content.split(/\r?\n/), e => e.split(/[\r\u2028\u2029]/));
|
||||
const gen: IterableIterator<TypeWriterResult> = isSymbolBaseline ? fullWalker.getSymbols(unitName) : fullWalker.getTypes(unitName);
|
||||
let lastIndexWritten: number | undefined;
|
||||
for (const result of gen) {
|
||||
|
@ -1103,7 +1103,7 @@ function splitVaryBySettingValue(text: string, varyBy: string): string[] | undef
|
|||
let star = false;
|
||||
const includes: string[] = [];
|
||||
const excludes: string[] = [];
|
||||
for (let s of text.split(/,/g)) {
|
||||
for (let s of text.split(/,/)) {
|
||||
s = s.trim().toLowerCase();
|
||||
if (s.length === 0) continue;
|
||||
if (s === "*") {
|
||||
|
@ -1247,8 +1247,8 @@ export namespace TestCaseParser {
|
|||
}
|
||||
|
||||
// Regex for parsing options in the format "@Alpha: Value of any sort"
|
||||
const optionRegex = /^[/]{2}\s*@(\w+)\s*:\s*([^\r\n]*)/gm; // multiple matches on multiple lines
|
||||
const linkRegex = /^[/]{2}\s*@link\s*:\s*([^\r\n]*)\s*->\s*([^\r\n]*)/gm; // multiple matches on multiple lines
|
||||
const optionRegex = /^\/{2}\s*@(\w+)\s*:\s*([^\r\n]*)/gm; // multiple matches on multiple lines
|
||||
const linkRegex = /^\/{2}\s*@link\s*:\s*([^\r\n]*)\s*->\s*([^\r\n]*)/gm; // multiple matches on multiple lines
|
||||
|
||||
export function parseSymlinkFromTest(line: string, symlinks: vfs.FileSet | undefined, absoluteRootDir?: string) {
|
||||
const linkMetaData = linkRegex.exec(line);
|
||||
|
|
|
@ -333,7 +333,7 @@ const maxHarnessFrames = 1;
|
|||
export function filterStack(error: Error, stackTraceLimit = Infinity) {
|
||||
const stack = (error as any).stack as string;
|
||||
if (stack) {
|
||||
const lines = stack.split(/\r\n?|\n/g);
|
||||
const lines = stack.split(/\r\n?|\n/);
|
||||
const filtered: string[] = [];
|
||||
let frameCount = 0;
|
||||
let harnessFrameCount = 0;
|
||||
|
@ -355,7 +355,7 @@ export function filterStack(error: Error, stackTraceLimit = Infinity) {
|
|||
harnessFrameCount++;
|
||||
}
|
||||
|
||||
line = line.replace(/\bfile:\/\/\/(.*?)(?=(:\d+)*($|\)))/, (_, path) => ts.sys.resolvePath(path));
|
||||
line = line.replace(/\bfile:\/\/\/(.*?)(?=(?::\d+)*(?:$|\)))/, (_, path) => ts.sys.resolvePath(path));
|
||||
frameCount++;
|
||||
}
|
||||
|
||||
|
@ -373,11 +373,11 @@ function isStackFrame(line: string) {
|
|||
}
|
||||
|
||||
function isMocha(line: string) {
|
||||
return /[\\/](node_modules|components)[\\/]mocha(js)?[\\/]|[\\/]mocha\.js/.test(line);
|
||||
return /[\\/](?:node_modules|components)[\\/]mocha(?:js)?[\\/]|[\\/]mocha\.js/.test(line);
|
||||
}
|
||||
|
||||
function isNode(line: string) {
|
||||
return /\((timers|events|node|module)\.js:/.test(line);
|
||||
return /\((?:timers|events|node|module)\.js:/.test(line);
|
||||
}
|
||||
|
||||
function isHarness(line: string) {
|
||||
|
|
|
@ -159,7 +159,7 @@ function getProgramStructure(program: ts.Program | undefined) {
|
|||
const baseline: string[] = [];
|
||||
program?.getSourceFiles().slice().sort((f1, f2) => ts.comparePathsCaseSensitive(f1.path, f2.path)).forEach(f => {
|
||||
baseline.push(` File: ${f.fileName} Path: ${f.path} ResolvedPath: ${f.resolvedPath} impliedNodeFormat: ${f.impliedNodeFormat}`);
|
||||
baseline.push(f.text.split(/\r?\n/g).map(l => l ? " " + l : "").join("\n"));
|
||||
baseline.push(f.text.split(/\r?\n/).map(l => l ? " " + l : "").join("\n"));
|
||||
getResolutionCacheDetails(
|
||||
baseline,
|
||||
"Modules",
|
||||
|
|
|
@ -55,7 +55,7 @@ export abstract class RunnerBase {
|
|||
/** Replaces instances of full paths with fileNames only */
|
||||
static removeFullPaths(path: string) {
|
||||
// If its a full path (starts with "C:" or "/") replace with just the filename
|
||||
let fixedPath = /^(\w:|\/)/.test(path) ? ts.getBaseFileName(path) : path;
|
||||
let fixedPath = /^(?:\w:|\/)/.test(path) ? ts.getBaseFileName(path) : path;
|
||||
|
||||
// when running in the browser the 'full path' is the host name, shows up in error baselines
|
||||
const localHost = /http:\/localhost:\d+/g;
|
||||
|
|
|
@ -321,7 +321,7 @@ export class TypeWriterWalker {
|
|||
const declSourceFile = declaration.getSourceFile();
|
||||
const declLineAndCharacter = declSourceFile.getLineAndCharacterOfPosition(declaration.pos);
|
||||
const fileName = ts.getBaseFileName(declSourceFile.fileName);
|
||||
const isLibFile = /lib(.*)\.d\.ts/i.test(fileName);
|
||||
const isLibFile = /lib.*\.d\.ts/i.test(fileName);
|
||||
const declText = `Decl(${fileName}, ${isLibFile ? "--" : declLineAndCharacter.line}, ${isLibFile ? "--" : declLineAndCharacter.character})`;
|
||||
symbolString += declText;
|
||||
(declaration as any).__symbolTestOutputCache = declText;
|
||||
|
|
|
@ -4,13 +4,13 @@ import * as ts from "./_namespaces/ts.js";
|
|||
* Common utilities
|
||||
*/
|
||||
|
||||
const testPathPrefixRegExp = /(?:(file:\/{3})|\/)\.(ts|lib|src)\//g;
|
||||
const testPathPrefixRegExp = /(?:(file:\/{3})|\/)\.(?:ts|lib|src)\//g;
|
||||
export function removeTestPathPrefixes(text: string, retainTrailingDirectorySeparator?: boolean): string {
|
||||
return text !== undefined ? text.replace(testPathPrefixRegExp, (_, scheme) => scheme || (retainTrailingDirectorySeparator ? "/" : "")) : undefined!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
function createDiagnosticMessageReplacer<R extends (messageArgs: string[], ...args: string[]) => string[]>(diagnosticMessage: ts.DiagnosticMessage, replacer: R) {
|
||||
const messageParts = diagnosticMessage.message.split(/{\d+}/g);
|
||||
const messageParts = diagnosticMessage.message.split(/\{\d+\}/);
|
||||
const regExp = new RegExp(`^(?:${messageParts.map(ts.regExpEscape).join("(.*?)")})$`);
|
||||
type Args<R> = R extends (messageArgs: string[], ...args: infer A) => string[] ? A : [];
|
||||
return (text: string, ...args: Args<R>) => text.replace(regExp, (_, ...fixedArgs) => ts.formatStringFromArgs(diagnosticMessage.message, replacer(fixedArgs, ...args)));
|
||||
|
|
|
@ -26,7 +26,7 @@ export import changeExtension = ts.changeAnyExtension;
|
|||
export import isTypeScript = ts.hasTSFileExtension;
|
||||
export import isJavaScript = ts.hasJSFileExtension;
|
||||
|
||||
const invalidRootComponentRegExp = /^(?!(\/|\/\/\w+\/|[a-zA-Z]:\/?|)$)/;
|
||||
const invalidRootComponentRegExp = /^(?!(?:\/|\/\/\w+\/|[a-z]:\/?)?$)/i;
|
||||
const invalidNavigableComponentRegExp = /[:*?"<>|]/;
|
||||
const invalidNavigableComponentWithWildcardsRegExp = /[:"<>|]/;
|
||||
const invalidNonNavigableComponentRegExp = /^\.{1,2}$|[:*?"<>|]/;
|
||||
|
|
|
@ -5041,7 +5041,7 @@ export class ProjectService {
|
|||
if (
|
||||
!pluginConfigEntry.name ||
|
||||
isExternalModuleNameRelative(pluginConfigEntry.name) ||
|
||||
/[\\/]\.\.?($|[\\/])/.test(pluginConfigEntry.name)
|
||||
/[\\/]\.\.?(?:$|[\\/])/.test(pluginConfigEntry.name)
|
||||
) {
|
||||
this.logger.info(`Skipped loading plugin ${pluginConfigEntry.name || JSON.stringify(pluginConfigEntry)} because only package name is allowed plugin name`);
|
||||
return;
|
||||
|
|
|
@ -927,9 +927,9 @@ export function getEncodedSyntacticClassifications(cancellationToken: Cancellati
|
|||
}
|
||||
|
||||
function tryClassifyTripleSlashComment(start: number, width: number): boolean {
|
||||
const tripleSlashXMLCommentRegEx = /^(\/\/\/\s*)(<)(?:(\S+)((?:[^/]|\/[^>])*)(\/>)?)?/im;
|
||||
const tripleSlashXMLCommentRegEx = /^(\/\/\/\s*)(<)(?:(\S+)((?:[^/]|\/[^>])*)(\/>)?)?/m;
|
||||
// Require a leading whitespace character (the parser already does) to prevent terrible backtracking performance
|
||||
const attributeRegex = /(\s)(\S+)(\s*)(=)(\s*)('[^']+'|"[^"]+")/img;
|
||||
const attributeRegex = /(\s)(\S+)(\s*)(=)(\s*)('[^']+'|"[^"]+")/g;
|
||||
|
||||
const text = sourceFile.text.substr(start, width);
|
||||
const match = tripleSlashXMLCommentRegEx.exec(text);
|
||||
|
|
|
@ -147,7 +147,7 @@ function findEndOfTextBetween(jsDocComment: JSDoc, from: number, to: number): nu
|
|||
const comment = jsDocComment.getText().substring(from - jsDocComment.getStart(), to - jsDocComment.getStart());
|
||||
|
||||
for (let i = comment.length; i > 0; i--) {
|
||||
if (!/[*/\s]/g.test(comment.substring(i - 1, i))) {
|
||||
if (!/[*/\s]/.test(comment.substring(i - 1, i))) {
|
||||
return from + i;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1100,5 +1100,5 @@ function cleanText(text: string): string {
|
|||
// \r - Carriage Return
|
||||
// \u2028 - Line separator
|
||||
// \u2029 - Paragraph separator
|
||||
return text.replace(/\\?(\r?\n|\r|\u2028|\u2029)/g, "");
|
||||
return text.replace(/\\?(?:\r?\n|[\r\u2028\u2029])/g, "");
|
||||
}
|
||||
|
|
|
@ -138,14 +138,14 @@ function addRegionOutliningSpans(sourceFile: SourceFile, out: OutliningSpan[]):
|
|||
for (const currentLineStart of lineStarts) {
|
||||
const lineEnd = sourceFile.getLineEndOfPosition(currentLineStart);
|
||||
const lineText = sourceFile.text.substring(currentLineStart, lineEnd);
|
||||
const result = isRegionDelimiter(lineText);
|
||||
const result = parseRegionDelimiter(lineText);
|
||||
if (!result || isInComment(sourceFile, currentLineStart)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!result[1]) {
|
||||
if (result.isStart) {
|
||||
const span = createTextSpanFromBounds(sourceFile.text.indexOf("//", currentLineStart), lineEnd);
|
||||
regions.push(createOutliningSpan(span, OutliningSpanKind.Region, span, /*autoCollapse*/ false, result[2] || "#region"));
|
||||
regions.push(createOutliningSpan(span, OutliningSpanKind.Region, span, /*autoCollapse*/ false, result.name || "#region"));
|
||||
}
|
||||
else {
|
||||
const region = regions.pop();
|
||||
|
@ -158,8 +158,8 @@ function addRegionOutliningSpans(sourceFile: SourceFile, out: OutliningSpan[]):
|
|||
}
|
||||
}
|
||||
|
||||
const regionDelimiterRegExp = /^#(end)?region(?:\s+(.*))?(?:\r)?$/;
|
||||
function isRegionDelimiter(lineText: string) {
|
||||
const regionDelimiterRegExp = /^#(end)?region(.*)\r?$/;
|
||||
function parseRegionDelimiter(lineText: string) {
|
||||
// We trim the leading whitespace and // without the regex since the
|
||||
// multiple potential whitespace matches can make for some gnarly backtracking behavior
|
||||
lineText = lineText.trimStart();
|
||||
|
@ -167,7 +167,11 @@ function isRegionDelimiter(lineText: string) {
|
|||
return null; // eslint-disable-line no-restricted-syntax
|
||||
}
|
||||
lineText = lineText.slice(2).trim();
|
||||
return regionDelimiterRegExp.exec(lineText);
|
||||
const result = regionDelimiterRegExp.exec(lineText);
|
||||
if (result) {
|
||||
return { isStart: !result[1], name: result[2].trim() };
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function addOutliningForLeadingCommentsForPos(pos: number, sourceFile: SourceFile, cancellationToken: CancellationToken, out: OutliningSpan[]): void {
|
||||
|
@ -184,7 +188,7 @@ function addOutliningForLeadingCommentsForPos(pos: number, sourceFile: SourceFil
|
|||
case SyntaxKind.SingleLineCommentTrivia:
|
||||
// never fold region delimiters into single-line comment regions
|
||||
const commentText = sourceText.slice(pos, end);
|
||||
if (isRegionDelimiter(commentText)) {
|
||||
if (parseRegionDelimiter(commentText)) {
|
||||
combineAndAddMultipleSingleLineComments();
|
||||
singleLineCommentCount = 0;
|
||||
break;
|
||||
|
|
|
@ -3166,7 +3166,7 @@ export function createLanguageService(
|
|||
//
|
||||
// The following three regexps are used to match the start of the text up to the TODO
|
||||
// comment portion.
|
||||
const singleLineCommentStart = /(?:\/\/+\s*)/.source;
|
||||
const singleLineCommentStart = /(?:\/{2,}\s*)/.source;
|
||||
const multiLineCommentStart = /(?:\/\*+\s*)/.source;
|
||||
const anyNumberOfSpacesAndAsterisksAtStartOfLine = /(?:^(?:\s|\*)*)/.source;
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ import {
|
|||
tryParseRawSourceMap,
|
||||
} from "./_namespaces/ts.js";
|
||||
|
||||
const base64UrlRegExp = /^data:(?:application\/json(?:;charset=[uU][tT][fF]-8);base64,([A-Za-z0-9+/=]+)$)?/;
|
||||
const base64UrlRegExp = /^data:(?:application\/json;charset=[uU][tT][fF]-8;base64,([A-Za-z0-9+/=]+)$)?/;
|
||||
|
||||
/** @internal */
|
||||
export interface SourceMapper {
|
||||
|
|
|
@ -31,7 +31,7 @@ function runTests(runners: RunnerBase[]) {
|
|||
for (const full of runner.enumerateTestFiles()) {
|
||||
const base = vpath.basename(full).toLowerCase();
|
||||
// allow existing dupes in fourslash/shims and fourslash/server
|
||||
if (seen.has(base) && !/fourslash\/(shim|server)/.test(full)) {
|
||||
if (seen.has(base) && !/fourslash\/(?:shim|server)/.test(full)) {
|
||||
dupes.push([seen.get(base)!, full]);
|
||||
}
|
||||
else {
|
||||
|
@ -52,7 +52,7 @@ function tryGetConfig(args: string[]) {
|
|||
const prefix = "--config=";
|
||||
const configPath = ts.forEach(args, arg => arg.lastIndexOf(prefix, 0) === 0 && arg.substr(prefix.length));
|
||||
// strip leading and trailing quotes from the path (necessary on Windows since shell does not do it automatically)
|
||||
return configPath && configPath.replace(/(^["'])|(["']$)/g, "");
|
||||
return configPath && configPath.replace(/^["']|["']$/g, "");
|
||||
}
|
||||
|
||||
export function createRunner(kind: TestRunnerKind): RunnerBase {
|
||||
|
|
|
@ -6,7 +6,7 @@ describe("unittests:: config:: initTSConfig", () => {
|
|||
describe(name, () => {
|
||||
const commandLine = ts.parseCommandLine(commandLinesArgs);
|
||||
const initResult = ts.generateTSConfig(commandLine.options, commandLine.fileNames, "\n");
|
||||
const outputFileName = `config/initTSConfig/${name.replace(/[^a-z0-9\-. ]/ig, "")}/tsconfig.json`;
|
||||
const outputFileName = `config/initTSConfig/${name.replace(/[^a-z0-9\-. ]/gi, "")}/tsconfig.json`;
|
||||
|
||||
it(`Correct output for ${outputFileName}`, () => {
|
||||
Harness.Baseline.runBaseline(outputFileName, initResult, { PrintDiff: true });
|
||||
|
|
|
@ -4,7 +4,7 @@ import * as ts from "../../_namespaces/ts.js";
|
|||
describe("unittests:: config:: showConfig", () => {
|
||||
function showTSConfigCorrectly(name: string, commandLinesArgs: string[], configJson?: object) {
|
||||
describe(name, () => {
|
||||
const outputFileName = `config/showConfig/${name.replace(/[^a-z0-9\-./ ]/ig, "")}/tsconfig.json`;
|
||||
const outputFileName = `config/showConfig/${name.replace(/[^a-z0-9\-./ ]/gi, "")}/tsconfig.json`;
|
||||
|
||||
it(`Correct output for ${outputFileName}`, () => {
|
||||
const cwd = `/${name}`;
|
||||
|
|
|
@ -7,8 +7,8 @@ import { TestServerHost } from "./virtualFileSystemWithWatch.js";
|
|||
|
||||
export function sanitizeSysOutput(output: string) {
|
||||
return output
|
||||
.replace(/Elapsed::\s[0-9]+(?:\.\d+)?ms/g, "Elapsed:: *ms")
|
||||
.replace(/[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\s(A|P)M/g, "HH:MM:SS AM");
|
||||
.replace(/Elapsed::\s\d+(?:\.\d+)?ms/g, "Elapsed:: *ms")
|
||||
.replace(/\d\d:\d\d:\d\d\s(?:A|P)M/g, "HH:MM:SS AM");
|
||||
}
|
||||
|
||||
export type CommandLineProgram = [ts.Program, ts.BuilderProgram?];
|
||||
|
|
|
@ -7,7 +7,7 @@ describe("unittests:: jsonParserRecovery", () => {
|
|||
const file = ts.parseJsonText(name, text);
|
||||
assert(file.parseDiagnostics.length, "Should have parse errors");
|
||||
Harness.Baseline.runBaseline(
|
||||
`jsonParserRecovery/${name.replace(/[^a-z0-9_-]/ig, "_")}.errors.txt`,
|
||||
`jsonParserRecovery/${name.replace(/[^\w-]/g, "_")}.errors.txt`,
|
||||
Harness.Compiler.getErrorBaseline([{
|
||||
content: text,
|
||||
unitName: name,
|
||||
|
|
|
@ -126,7 +126,7 @@ describe("unittests:: PrinterAPI", () => {
|
|||
const file = program.getSourceFile("/test.d.ts")!;
|
||||
const printer = ts.createPrinter({ newLine: ts.NewLineKind.CarriageReturnLineFeed });
|
||||
const output = printer.printFile(file);
|
||||
assert.equal(output.split(/\r?\n/g).length, 3);
|
||||
assert.equal(output.split(/\r?\n/).length, 3);
|
||||
});
|
||||
it("with statements", () => {
|
||||
const host = new fakes.CompilerHost(
|
||||
|
@ -140,7 +140,7 @@ describe("unittests:: PrinterAPI", () => {
|
|||
const file = program.getSourceFile("/test.d.ts")!;
|
||||
const printer = ts.createPrinter({ newLine: ts.NewLineKind.CarriageReturnLineFeed });
|
||||
const output = printer.printFile(file);
|
||||
assert.equal(output.split(/\r?\n/g).length, 4);
|
||||
assert.equal(output.split(/\r?\n/).length, 4);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ describe("unittests:: services:: Transpile", () => {
|
|||
|
||||
transpileOptions.reportDiagnostics = true;
|
||||
|
||||
const justName = "transpile/" + name.replace(/[^a-z0-9\-. ()=]/ig, "") + (transpileOptions.compilerOptions.jsx ? ts.Extension.Tsx : ts.Extension.Ts);
|
||||
const justName = "transpile/" + name.replace(/[^a-z0-9\-. ()=]/gi, "") + (transpileOptions.compilerOptions.jsx ? ts.Extension.Tsx : ts.Extension.Ts);
|
||||
const toBeCompiled = [{
|
||||
unitName,
|
||||
content: input,
|
||||
|
|
|
@ -526,7 +526,7 @@ describe("unittests:: tsserver:: CachingFileSystemInformation:: tsserverProjectS
|
|||
ts.forEach(filesAndFoldersToAdd, f => {
|
||||
f.path = f.path
|
||||
.replace("/a/b/node_modules/.staging", "/a/b/node_modules")
|
||||
.replace(/[-.][\d\w][\d\w][\d\w][\d\w][\d\w][\d\w][\d\w][\d\w]/g, "");
|
||||
.replace(/[-.]\w\w\w\w\w\w\w\w/g, "");
|
||||
});
|
||||
|
||||
host.deleteFolder(root + "/a/b/node_modules/.staging", /*recursive*/ true);
|
||||
|
|
Загрузка…
Ссылка в новой задаче