mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-30 01:04:49 -05:00
Switch to ES Map/Set internally (#33771)
* Add full implemention of Map and Set to shims * Update default Map interface * Remove WeakMap/WeakSet * Add tests for set shim * Update most usages of Map<K, true> to Set * PR Feedback * Fix lint issues * Change key in fsWatchCallback * Simpler shim, more tests * Fix typo in collection shim
This commit is contained in:
@@ -126,7 +126,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
let outputFingerprints: Map<OutputFingerprint>;
|
||||
let outputFingerprints: Map<string, OutputFingerprint>;
|
||||
function writeFileWorker(fileName: string, data: string, writeByteOrderMark: boolean) {
|
||||
if (!isWatchSet(options) || !system.createHash || !system.getModifiedTime) {
|
||||
system.writeFile(fileName, data, writeByteOrderMark);
|
||||
@@ -533,7 +533,7 @@ namespace ts {
|
||||
export const inferredTypesContainingFile = "__inferred type names__.ts";
|
||||
|
||||
interface DiagnosticCache<T extends Diagnostic> {
|
||||
perFile?: Map<readonly T[]>;
|
||||
perFile?: Map<Path, readonly T[]>;
|
||||
allDiagnostics?: readonly T[];
|
||||
}
|
||||
|
||||
@@ -702,14 +702,14 @@ namespace ts {
|
||||
let processingDefaultLibFiles: SourceFile[] | undefined;
|
||||
let processingOtherFiles: SourceFile[] | undefined;
|
||||
let files: SourceFile[];
|
||||
let symlinks: ReadonlyMap<string> | undefined;
|
||||
let symlinks: ReadonlyMap<string, string> | undefined;
|
||||
let commonSourceDirectory: string;
|
||||
let diagnosticsProducingTypeChecker: TypeChecker;
|
||||
let noDiagnosticsTypeChecker: TypeChecker;
|
||||
let classifiableNames: UnderscoreEscapedMap<true>;
|
||||
const ambientModuleNameToUnmodifiedFileName = createMap<string>();
|
||||
// Todo:: Use this to report why file was included in --extendedDiagnostics
|
||||
let refFileMap: MultiMap<ts.RefFile> | undefined;
|
||||
let refFileMap: MultiMap<Path, ts.RefFile> | undefined;
|
||||
|
||||
const cachedBindAndCheckDiagnosticsForFile: DiagnosticCache<Diagnostic> = {};
|
||||
const cachedDeclarationDiagnosticsForFile: DiagnosticCache<DiagnosticWithLocation> = {};
|
||||
@@ -803,9 +803,9 @@ namespace ts {
|
||||
|
||||
// A parallel array to projectReferences storing the results of reading in the referenced tsconfig files
|
||||
let resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined;
|
||||
let projectReferenceRedirects: Map<ResolvedProjectReference | false> | undefined;
|
||||
let mapFromFileToProjectReferenceRedirects: Map<Path> | undefined;
|
||||
let mapFromToProjectReferenceRedirectSource: Map<SourceOfProjectReferenceRedirect> | undefined;
|
||||
let projectReferenceRedirects: Map<Path, ResolvedProjectReference | false> | undefined;
|
||||
let mapFromFileToProjectReferenceRedirects: Map<Path, Path> | undefined;
|
||||
let mapFromToProjectReferenceRedirectSource: Map<Path, SourceOfProjectReferenceRedirect> | undefined;
|
||||
|
||||
const useSourceOfProjectReferenceRedirect = !!host.useSourceOfProjectReferenceRedirect?.() &&
|
||||
!options.disableSourceOfProjectReferenceRedirect;
|
||||
@@ -2028,7 +2028,7 @@ namespace ts {
|
||||
): readonly U[] {
|
||||
|
||||
const cachedResult = sourceFile
|
||||
? cache.perFile && cache.perFile.get(sourceFile.path)
|
||||
? cache.perFile?.get(sourceFile.path)
|
||||
: cache.allDiagnostics;
|
||||
|
||||
if (cachedResult) {
|
||||
@@ -2036,10 +2036,7 @@ namespace ts {
|
||||
}
|
||||
const result = getDiagnostics(sourceFile, cancellationToken);
|
||||
if (sourceFile) {
|
||||
if (!cache.perFile) {
|
||||
cache.perFile = createMap();
|
||||
}
|
||||
cache.perFile.set(sourceFile.path, result);
|
||||
(cache.perFile || (cache.perFile = new Map())).set(sourceFile.path, result);
|
||||
}
|
||||
else {
|
||||
cache.allDiagnostics = result;
|
||||
@@ -2546,7 +2543,7 @@ namespace ts {
|
||||
*/
|
||||
function getResolvedProjectReferenceToRedirect(fileName: string) {
|
||||
if (mapFromFileToProjectReferenceRedirects === undefined) {
|
||||
mapFromFileToProjectReferenceRedirects = createMap();
|
||||
mapFromFileToProjectReferenceRedirects = new Map();
|
||||
forEachResolvedProjectReference((referencedProject, referenceProjectPath) => {
|
||||
// not input file from the referenced project, ignore
|
||||
if (referencedProject &&
|
||||
@@ -2892,13 +2889,13 @@ namespace ts {
|
||||
function checkSourceFilesBelongToPath(sourceFiles: readonly SourceFile[], rootDirectory: string): boolean {
|
||||
let allFilesBelongToPath = true;
|
||||
const absoluteRootDirectoryPath = host.getCanonicalFileName(getNormalizedAbsolutePath(rootDirectory, currentDirectory));
|
||||
let rootPaths: Map<true> | undefined;
|
||||
let rootPaths: Set<Path> | undefined;
|
||||
|
||||
for (const sourceFile of sourceFiles) {
|
||||
if (!sourceFile.isDeclarationFile) {
|
||||
const absoluteSourceFilePath = host.getCanonicalFileName(getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory));
|
||||
if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) {
|
||||
if (!rootPaths) rootPaths = arrayToSet(rootNames, toPath);
|
||||
if (!rootPaths) rootPaths = new Set(rootNames.map(toPath));
|
||||
addProgramDiagnosticAtRefPath(
|
||||
sourceFile,
|
||||
rootPaths,
|
||||
@@ -2916,7 +2913,7 @@ namespace ts {
|
||||
|
||||
function parseProjectReferenceConfigFile(ref: ProjectReference): ResolvedProjectReference | undefined {
|
||||
if (!projectReferenceRedirects) {
|
||||
projectReferenceRedirects = createMap<ResolvedProjectReference | false>();
|
||||
projectReferenceRedirects = new Map();
|
||||
}
|
||||
|
||||
// The actual filename (i.e. add "/tsconfig.json" if necessary)
|
||||
@@ -3015,7 +3012,7 @@ namespace ts {
|
||||
|
||||
// List of collected files is complete; validate exhautiveness if this is a project with a file list
|
||||
if (options.composite) {
|
||||
const rootPaths = arrayToSet(rootNames, toPath);
|
||||
const rootPaths = new Set(rootNames.map(toPath));
|
||||
for (const file of files) {
|
||||
// Ignore file that is not emitted
|
||||
if (sourceFileMayBeEmitted(file, program) && !rootPaths.has(file.path)) {
|
||||
@@ -3204,7 +3201,7 @@ namespace ts {
|
||||
// If the emit is enabled make sure that every output file is unique and not overwriting any of the input files
|
||||
if (!options.noEmit && !options.suppressOutputPathCheck) {
|
||||
const emitHost = getEmitHost();
|
||||
const emitFilesSeen = createMap<true>();
|
||||
const emitFilesSeen = new Set<string>();
|
||||
forEachEmittedFile(emitHost, (emitFileNames) => {
|
||||
if (!options.emitDeclarationOnly) {
|
||||
verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen);
|
||||
@@ -3214,7 +3211,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Verify that all the emit files are unique and don't overwrite input files
|
||||
function verifyEmitFilePath(emitFileName: string | undefined, emitFilesSeen: Map<true>) {
|
||||
function verifyEmitFilePath(emitFileName: string | undefined, emitFilesSeen: Set<string>) {
|
||||
if (emitFileName) {
|
||||
const emitFilePath = toPath(emitFileName);
|
||||
// Report error if the output overwrites input file
|
||||
@@ -3235,7 +3232,7 @@ namespace ts {
|
||||
blockEmittingOfFile(emitFileName, createCompilerDiagnostic(Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files, emitFileName));
|
||||
}
|
||||
else {
|
||||
emitFilesSeen.set(emitFileKey, true);
|
||||
emitFilesSeen.add(emitFileKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3262,8 +3259,8 @@ namespace ts {
|
||||
return createFileDiagnostic(refFile, pos, end - pos, message, ...args);
|
||||
}
|
||||
|
||||
function addProgramDiagnosticAtRefPath(file: SourceFile, rootPaths: Map<true>, message: DiagnosticMessage, ...args: (string | number | undefined)[]) {
|
||||
const refPaths = refFileMap && refFileMap.get(file.path);
|
||||
function addProgramDiagnosticAtRefPath(file: SourceFile, rootPaths: Set<Path>, message: DiagnosticMessage, ...args: (string | number | undefined)[]) {
|
||||
const refPaths = refFileMap?.get(file.path);
|
||||
const refPathToReportErrorOn = forEach(refPaths, refPath => rootPaths.has(refPath.file) ? refPath : undefined) ||
|
||||
elementAt(refPaths, 0);
|
||||
programDiagnostics.add(
|
||||
@@ -3455,7 +3452,7 @@ namespace ts {
|
||||
return comparePaths(file1, file2, currentDirectory, !host.useCaseSensitiveFileNames()) === Comparison.EqualTo;
|
||||
}
|
||||
|
||||
function getProbableSymlinks(): ReadonlyMap<string> {
|
||||
function getProbableSymlinks(): ReadonlyMap<string, string> {
|
||||
if (host.getSymlinks) {
|
||||
return host.getSymlinks();
|
||||
}
|
||||
@@ -3481,9 +3478,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
function updateHostForUseSourceOfProjectReferenceRedirect(host: HostForUseSourceOfProjectReferenceRedirect) {
|
||||
let mapOfDeclarationDirectories: Map<true> | undefined;
|
||||
let symlinkedDirectories: Map<SymlinkedDirectory | false> | undefined;
|
||||
let symlinkedFiles: Map<string> | undefined;
|
||||
let setOfDeclarationDirectories: Set<Path> | undefined;
|
||||
let symlinkedDirectories: Map<Path, SymlinkedDirectory | false> | undefined;
|
||||
let symlinkedFiles: Map<Path, string> | undefined;
|
||||
|
||||
const originalFileExists = host.compilerHost.fileExists;
|
||||
const originalDirectoryExists = host.compilerHost.directoryExists;
|
||||
@@ -3506,19 +3503,19 @@ namespace ts {
|
||||
|
||||
if (!host.getResolvedProjectReferences()) return false;
|
||||
|
||||
if (!mapOfDeclarationDirectories) {
|
||||
mapOfDeclarationDirectories = createMap();
|
||||
if (!setOfDeclarationDirectories) {
|
||||
setOfDeclarationDirectories = new Set();
|
||||
host.forEachResolvedProjectReference(ref => {
|
||||
if (!ref) return;
|
||||
const out = outFile(ref.commandLine.options);
|
||||
if (out) {
|
||||
mapOfDeclarationDirectories!.set(getDirectoryPath(host.toPath(out)), true);
|
||||
setOfDeclarationDirectories!.add(getDirectoryPath(host.toPath(out)));
|
||||
}
|
||||
else {
|
||||
// Set declaration's in different locations only, if they are next to source the directory present doesnt change
|
||||
const declarationDir = ref.commandLine.options.declarationDir || ref.commandLine.options.outDir;
|
||||
if (declarationDir) {
|
||||
mapOfDeclarationDirectories!.set(host.toPath(declarationDir), true);
|
||||
setOfDeclarationDirectories!.add(host.toPath(declarationDir));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -3576,7 +3573,7 @@ namespace ts {
|
||||
const dirPath = host.toPath(dir);
|
||||
const dirPathWithTrailingDirectorySeparator = `${dirPath}${directorySeparator}`;
|
||||
return forEachKey(
|
||||
mapOfDeclarationDirectories!,
|
||||
setOfDeclarationDirectories!,
|
||||
declDirPath => dirPath === declDirPath ||
|
||||
// Any parent directory of declaration dir
|
||||
startsWith(declDirPath, dirPathWithTrailingDirectorySeparator) ||
|
||||
@@ -3590,7 +3587,7 @@ namespace ts {
|
||||
|
||||
// Because we already watch node_modules, handle symlinks in there
|
||||
if (!originalRealpath || !stringContains(directory, nodeModulesPathPart)) return;
|
||||
if (!symlinkedDirectories) symlinkedDirectories = createMap();
|
||||
if (!symlinkedDirectories) symlinkedDirectories = new Map();
|
||||
const directoryPath = ensureTrailingDirectorySeparator(host.toPath(directory));
|
||||
if (symlinkedDirectories.has(directoryPath)) return;
|
||||
|
||||
@@ -3629,7 +3626,7 @@ namespace ts {
|
||||
if (!symlinkedDirectory || !startsWith(fileOrDirectoryPath, directoryPath)) return undefined;
|
||||
const result = fileOrDirectoryExistsUsingSource(fileOrDirectoryPath.replace(directoryPath, symlinkedDirectory.realPath));
|
||||
if (isFile && result) {
|
||||
if (!symlinkedFiles) symlinkedFiles = createMap();
|
||||
if (!symlinkedFiles) symlinkedFiles = new Map();
|
||||
// Store the real path for the file'
|
||||
const absolutePath = getNormalizedAbsolutePath(fileOrDirectory, host.compilerHost.getCurrentDirectory());
|
||||
symlinkedFiles.set(
|
||||
|
||||
Reference in New Issue
Block a user