mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-11 09:24:19 -06:00
perf: improve regexp performance by using non-capturing groups (#58551)
This commit is contained in:
parent
5fd65f3189
commit
e58dde511c
@ -9542,7 +9542,7 @@ const wildcardCharCodes = [CharacterCodes.asterisk, CharacterCodes.question];
|
||||
|
||||
const commonPackageFolders: readonly string[] = ["node_modules", "bower_components", "jspm_packages"];
|
||||
|
||||
const implicitExcludePathRegexPattern = `(?!(${commonPackageFolders.join("|")})(/|$))`;
|
||||
const implicitExcludePathRegexPattern = `(?!(?:${commonPackageFolders.join("|")})(?:/|$))`;
|
||||
|
||||
/** @internal */
|
||||
export interface WildcardMatcher {
|
||||
@ -9558,12 +9558,12 @@ const filesMatcher: WildcardMatcher = {
|
||||
* [^./] # matches everything up to the first . character (excluding directory separators)
|
||||
* (\\.(?!min\\.js$))? # matches . characters but not if they are part of the .min.js file extension
|
||||
*/
|
||||
singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*",
|
||||
singleAsteriskRegexFragment: "(?:[^./]|(?:\\.(?!min\\.js$))?)*",
|
||||
/**
|
||||
* Regex for the ** wildcard. Matches any number of subdirectories. When used for including
|
||||
* files or directories, does not match subdirectories that start with a . character
|
||||
*/
|
||||
doubleAsteriskRegexFragment: `(/${implicitExcludePathRegexPattern}[^/.][^/]*)*?`,
|
||||
doubleAsteriskRegexFragment: `(?:/${implicitExcludePathRegexPattern}[^/.][^/]*)*?`,
|
||||
replaceWildcardCharacter: match => replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment),
|
||||
};
|
||||
|
||||
@ -9573,13 +9573,13 @@ const directoriesMatcher: WildcardMatcher = {
|
||||
* Regex for the ** wildcard. Matches any number of subdirectories. When used for including
|
||||
* files or directories, does not match subdirectories that start with a . character
|
||||
*/
|
||||
doubleAsteriskRegexFragment: `(/${implicitExcludePathRegexPattern}[^/.][^/]*)*?`,
|
||||
doubleAsteriskRegexFragment: `(?:/${implicitExcludePathRegexPattern}[^/.][^/]*)*?`,
|
||||
replaceWildcardCharacter: match => replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment),
|
||||
};
|
||||
|
||||
const excludeMatcher: WildcardMatcher = {
|
||||
singleAsteriskRegexFragment: "[^/]*",
|
||||
doubleAsteriskRegexFragment: "(/.+?)?",
|
||||
doubleAsteriskRegexFragment: "(?:/.+?)?",
|
||||
replaceWildcardCharacter: match => replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment),
|
||||
};
|
||||
|
||||
@ -9596,10 +9596,10 @@ export function getRegularExpressionForWildcard(specs: readonly string[] | undef
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const pattern = patterns.map(pattern => `(${pattern})`).join("|");
|
||||
const pattern = patterns.map(pattern => `(?:${pattern})`).join("|");
|
||||
// If excluding, match "foo/bar/baz...", but if including, only allow "foo".
|
||||
const terminator = usage === "exclude" ? "($|/)" : "$";
|
||||
return `^(${pattern})${terminator}`;
|
||||
const terminator = usage === "exclude" ? "(?:$|/)" : "$";
|
||||
return `^(?:${pattern})${terminator}`;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@ -9624,7 +9624,7 @@ export function isImplicitGlob(lastPathComponent: string): boolean {
|
||||
/** @internal */
|
||||
export function getPatternFromSpec(spec: string, basePath: string, usage: "files" | "directories" | "exclude"): string | undefined {
|
||||
const pattern = spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]);
|
||||
return pattern && `^(${pattern})${usage === "exclude" ? "($|/)" : "$"}`;
|
||||
return pattern && `^(?:${pattern})${usage === "exclude" ? "(?:$|/)" : "$"}`;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@ -9657,7 +9657,7 @@ export function getSubPatternFromSpec(
|
||||
}
|
||||
else {
|
||||
if (usage === "directories") {
|
||||
subpattern += "(";
|
||||
subpattern += "(?:";
|
||||
optionalCount++;
|
||||
}
|
||||
|
||||
@ -9671,7 +9671,7 @@ export function getSubPatternFromSpec(
|
||||
// appear first in a component. Dotted directories and files can be included explicitly
|
||||
// like so: **/.*/.*
|
||||
if (component.charCodeAt(0) === CharacterCodes.asterisk) {
|
||||
componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?";
|
||||
componentPattern += "(?:[^./]" + singleAsteriskRegexFragment + ")?";
|
||||
component = component.substr(1);
|
||||
}
|
||||
else if (component.charCodeAt(0) === CharacterCodes.question) {
|
||||
|
||||
@ -436,7 +436,7 @@ export function getMatchedIncludeSpec(program: Program, fileName: string): strin
|
||||
const index = findIndex(configFile?.configFileSpecs?.validatedIncludeSpecs, includeSpec => {
|
||||
if (isJsonFile && !endsWith(includeSpec, Extension.Json)) return false;
|
||||
const pattern = getPatternFromSpec(includeSpec, basePath, "files");
|
||||
return !!pattern && getRegexFromPattern(`(${pattern})$`, useCaseSensitiveFileNames).test(fileName);
|
||||
return !!pattern && getRegexFromPattern(`(?:${pattern})$`, useCaseSensitiveFileNames).test(fileName);
|
||||
});
|
||||
return index !== -1 ? configFile.configFileSpecs.validatedIncludeSpecsBeforeSubstitution![index] : undefined;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user