Skip to content

Commit 145f0b2

Browse files
author
Andy Hanson
committed
Add createMultiMap to replace multiMapAdd and multiMapRemove
1 parent 932eaa3 commit 145f0b2

6 files changed

Lines changed: 53 additions & 41 deletions

File tree

src/compiler/core.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -989,43 +989,43 @@ namespace ts {
989989
return result;
990990
}
991991

992-
/**
993-
* Adds the value to an array of values associated with the key, and returns the array.
994-
* Creates the array if it does not already exist.
995-
*/
996-
export function multiMapAdd<V>(map: Map<V[]>, key: string, value: V): V[] {
997-
let values = map.get(key);
998-
if (values) {
999-
values.push(value);
1000-
}
1001-
else {
1002-
map.set(key, values = [value]);
1003-
}
1004-
return values;
992+
export interface MultiMap<T> extends Map<T[]> {
993+
/**
994+
* Adds the value to an array of values associated with the key, and returns the array.
995+
* Creates the array if it does not already exist.
996+
*/
997+
add(key: string, value: T): T[];
998+
/**
999+
* Removes a value from an array of values associated with the key.
1000+
* Does not preserve the order of those values.
1001+
* Does nothing if `key` is not in `map`, or `value` is not in `map[key]`.
1002+
*/
1003+
remove(key: string, value: T): void;
10051004
}
10061005

1007-
export function multiMapSparseArrayAdd<V>(map: SparseArray<V[]>, key: number, value: V): V[] {
1008-
let values = map[key];
1006+
export function createMultiMap<T>(): MultiMap<T> {
1007+
const map = createMap<T[]>() as MultiMap<T>;
1008+
map.add = multiMapAdd;
1009+
map.remove = multiMapRemove;
1010+
return map;
1011+
}
1012+
function multiMapAdd<T>(this: MultiMap<T>, key: string, value: T) {
1013+
let values = this.get(key);
10091014
if (values) {
10101015
values.push(value);
10111016
}
10121017
else {
1013-
map[key] = values = [value];
1018+
this.set(key, values = [value]);
10141019
}
10151020
return values;
1016-
}
10171021

1018-
/**
1019-
* Removes a value from an array of values associated with the key.
1020-
* Does not preserve the order of those values.
1021-
* Does nothing if `key` is not in `map`, or `value` is not in `map[key]`.
1022-
*/
1023-
export function multiMapRemove<V>(map: Map<V[]>, key: string, value: V): void {
1024-
const values = map.get(key);
1022+
}
1023+
function multiMapRemove<T>(this: MultiMap<T>, key: string, value: T) {
1024+
const values = this.get(key);
10251025
if (values) {
10261026
unorderedRemoveItem(values, value);
10271027
if (!values.length) {
1028-
map.delete(key);
1028+
this.delete(key);
10291029
}
10301030
}
10311031
}

src/compiler/factory.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3298,7 +3298,7 @@ namespace ts {
32983298

32993299
export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver, compilerOptions: CompilerOptions): ExternalModuleInfo {
33003300
const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = [];
3301-
const exportSpecifiers = createMap<ExportSpecifier[]>();
3301+
const exportSpecifiers = createMultiMap<ExportSpecifier>();
33023302
const exportedBindings: SparseArray<Identifier[]> = [];
33033303
const uniqueExports = createMap<boolean>();
33043304
let exportedNames: Identifier[];
@@ -3352,7 +3352,7 @@ namespace ts {
33523352
for (const specifier of (<ExportDeclaration>node).exportClause.elements) {
33533353
if (!uniqueExports.get(specifier.name.text)) {
33543354
const name = specifier.propertyName || specifier.name;
3355-
multiMapAdd(exportSpecifiers, name.text, specifier);
3355+
exportSpecifiers.add(name.text, specifier);
33563356

33573357
const decl = resolver.getReferencedImportDeclaration(name)
33583358
|| resolver.getReferencedValueDeclaration(name);
@@ -3446,4 +3446,16 @@ namespace ts {
34463446
}
34473447
return exportedNames;
34483448
}
3449+
3450+
/** Use a sparse array as a multi-map. */
3451+
function multiMapSparseArrayAdd<V>(map: SparseArray<V[]>, key: number, value: V): V[] {
3452+
let values = map[key];
3453+
if (values) {
3454+
values.push(value);
3455+
}
3456+
else {
3457+
map[key] = values = [value];
3458+
}
3459+
return values;
3460+
}
34493461
}

src/compiler/sys.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/// <reference path="core.ts"/>
1+
/// <reference path="core.ts"/>
22

33
namespace ts {
44
export type FileWatcherCallback = (fileName: string, removed?: boolean) => void;
@@ -243,7 +243,7 @@ namespace ts {
243243
function createWatchedFileSet() {
244244
const dirWatchers = createMap<DirectoryWatcher>();
245245
// One file can have multiple watchers
246-
const fileWatcherCallbacks = createMap<FileWatcherCallback[]>();
246+
const fileWatcherCallbacks = createMultiMap<FileWatcherCallback>();
247247
return { addFile, removeFile };
248248

249249
function reduceDirWatcherRefCountForFile(fileName: string) {
@@ -275,7 +275,7 @@ namespace ts {
275275
}
276276

277277
function addFileWatcherCallback(filePath: string, callback: FileWatcherCallback): void {
278-
multiMapAdd(fileWatcherCallbacks, filePath, callback);
278+
fileWatcherCallbacks.add(filePath, callback);
279279
}
280280

281281
function addFile(fileName: string, callback: FileWatcherCallback): WatchedFile {
@@ -291,7 +291,7 @@ namespace ts {
291291
}
292292

293293
function removeFileWatcherCallback(filePath: string, callback: FileWatcherCallback) {
294-
multiMapRemove(fileWatcherCallbacks, filePath, callback);
294+
fileWatcherCallbacks.remove(filePath, callback);
295295
}
296296

297297
function fileEventHandler(eventName: string, relativeFileName: string, baseDirPath: string) {

src/harness/fourslash.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,10 +1760,10 @@ namespace FourSlash {
17601760
}
17611761

17621762
public rangesByText(): ts.Map<Range[]> {
1763-
const result = ts.createMap<Range[]>();
1763+
const result = ts.createMultiMap<Range>();
17641764
for (const range of this.getRanges()) {
17651765
const text = this.rangeText(range);
1766-
ts.multiMapAdd(result, text, range);
1766+
result.add(text, range);
17671767
}
17681768
return result;
17691769
}

src/harness/unittests/tsserverProjectSystem.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,8 @@ namespace ts.projectSystem {
334334
private timeoutCallbacks = new Callbacks();
335335
private immediateCallbacks = new Callbacks();
336336

337-
readonly watchedDirectories = createMap<{ cb: DirectoryWatcherCallback, recursive: boolean }[]>();
338-
readonly watchedFiles = createMap<FileWatcherCallback[]>();
337+
readonly watchedDirectories = createMultiMap<{ cb: DirectoryWatcherCallback, recursive: boolean }>();
338+
readonly watchedFiles = createMultiMap<FileWatcherCallback>();
339339

340340
private filesOrFolders: FileOrFolder[];
341341

@@ -421,11 +421,11 @@ namespace ts.projectSystem {
421421
watchDirectory(directoryName: string, callback: DirectoryWatcherCallback, recursive: boolean): DirectoryWatcher {
422422
const path = this.toPath(directoryName);
423423
const cbWithRecursive = { cb: callback, recursive };
424-
multiMapAdd(this.watchedDirectories, path, cbWithRecursive);
424+
this.watchedDirectories.add(path, cbWithRecursive);
425425
return {
426426
referenceCount: 0,
427427
directoryName,
428-
close: () => multiMapRemove(this.watchedDirectories, path, cbWithRecursive)
428+
close: () => this.watchedDirectories.remove(path, cbWithRecursive)
429429
};
430430
}
431431

@@ -455,8 +455,8 @@ namespace ts.projectSystem {
455455

456456
watchFile(fileName: string, callback: FileWatcherCallback) {
457457
const path = this.toPath(fileName);
458-
multiMapAdd(this.watchedFiles, path, callback);
459-
return { close: () => multiMapRemove(this.watchedFiles, path, callback) };
458+
this.watchedFiles.add(path, callback);
459+
return { close: () => this.watchedFiles.remove(path, callback) };
460460
}
461461

462462
// TOOD: record and invoke callbacks to simulate timer events

src/services/services.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ namespace ts {
518518
}
519519

520520
private computeNamedDeclarations(): Map<Declaration[]> {
521-
const result = createMap<Declaration[]>();
521+
const result = createMultiMap<Declaration>();
522522

523523
forEachChild(this, visit);
524524

@@ -527,7 +527,7 @@ namespace ts {
527527
function addDeclaration(declaration: Declaration) {
528528
const name = getDeclarationName(declaration);
529529
if (name) {
530-
multiMapAdd(result, name, declaration);
530+
result.add(name, declaration);
531531
}
532532
}
533533

0 commit comments

Comments
 (0)