Skip to content

Commit e0e5afc

Browse files
author
Andy Hanson
committed
Add getOrUpdate helper
1 parent d2d5d42 commit e0e5afc

File tree

6 files changed

+23
-10
lines changed

6 files changed

+23
-10
lines changed

src/compiler/binder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ namespace ts {
326326
// Otherwise, we'll be merging into a compatible existing symbol (for example when
327327
// you have multiple 'vars' with the same name in the same container). In this case
328328
// just add this node into the declarations list of the symbol.
329-
symbol = symbolTable[name] || (symbolTable[name] = createSymbol(SymbolFlags.None, name));
329+
symbol = getOrUpdate(symbolTable, name, () => createSymbol(SymbolFlags.None, name));
330330

331331
if (name && (includes & SymbolFlags.Classifiable)) {
332332
classifiableNames[name] = name;

src/compiler/checker.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -518,12 +518,12 @@ namespace ts {
518518
function getSymbolLinks(symbol: Symbol): SymbolLinks {
519519
if (symbol.flags & SymbolFlags.Transient) return <TransientSymbol>symbol;
520520
const id = getSymbolId(symbol);
521-
return symbolLinks[id] || (symbolLinks[id] = {});
521+
return getOrUpdateArray(symbolLinks, id, () => ({}));
522522
}
523523

524524
function getNodeLinks(node: Node): NodeLinks {
525525
const nodeId = getNodeId(node);
526-
return nodeLinks[nodeId] || (nodeLinks[nodeId] = { flags: 0 });
526+
return getOrUpdateArray<NodeLinks>(nodeLinks, nodeId, () => ({ flags: 0 }));
527527
}
528528

529529
function isGlobalSourceFile(node: Node) {
@@ -5027,7 +5027,7 @@ namespace ts {
50275027
}
50285028
const typeArguments = map(node.typeArguments, getTypeFromTypeNode);
50295029
const id = getTypeListId(typeArguments);
5030-
return links.instantiations[id] || (links.instantiations[id] = instantiateType(type, createTypeMapper(typeParameters, typeArguments)));
5030+
return getOrUpdate(links.instantiations, id, () => instantiateType(type, createTypeMapper(typeParameters, typeArguments)));
50315031
}
50325032
if (node.typeArguments) {
50335033
error(node, Diagnostics.Type_0_is_not_generic, symbolToString(symbol));
@@ -5236,7 +5236,7 @@ namespace ts {
52365236

52375237
function createTupleType(elementTypes: Type[], thisType?: Type) {
52385238
const id = getTypeListId(elementTypes) + "," + (thisType ? thisType.id : 0);
5239-
return tupleTypes[id] || (tupleTypes[id] = createNewTupleType(elementTypes, thisType));
5239+
return getOrUpdate(tupleTypes, id, () => createNewTupleType(elementTypes, thisType));
52405240
}
52415241

52425242
function createNewTupleType(elementTypes: Type[], thisType?: Type) {
@@ -5480,7 +5480,7 @@ namespace ts {
54805480

54815481
function getLiteralTypeForText(flags: TypeFlags, text: string) {
54825482
const map = flags & TypeFlags.StringLiteral ? stringLiteralTypes : numericLiteralTypes;
5483-
return map[text] || (map[text] = createLiteralType(flags, text));
5483+
return getOrUpdate(map, text, () => createLiteralType(flags, text));
54845484
}
54855485

54865486
function getTypeFromLiteralTypeNode(node: LiteralTypeNode): Type {
@@ -8351,7 +8351,7 @@ namespace ts {
83518351
// If we have previously computed the control flow type for the reference at
83528352
// this flow loop junction, return the cached type.
83538353
const id = getFlowNodeId(flow);
8354-
const cache = flowLoopCaches[id] || (flowLoopCaches[id] = createMap<Type>());
8354+
const cache = getOrUpdateArray<Map<Type>>(flowLoopCaches, id, createMap);
83558355
if (!key) {
83568356
key = getFlowCacheKey(reference);
83578357
}

src/compiler/core.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,19 @@ namespace ts {
409409
return hasOwnProperty.call(map, key) ? map[key] : undefined;
410410
}
411411

412+
/** Gets a property in a Map, or if it doesn't exist, creates and returns it. */
413+
export function getOrUpdate<T>(map: Map<T>, key: string, makeValue: () => T) {
414+
return map[key] || (map[key] = makeValue());
415+
}
416+
417+
/**
418+
* Gets a value in an array, or if it doesn't exist, creates and returns it.
419+
* It is the caller's responsibility to ensure that `key` is within the bounds of the array.
420+
*/
421+
export function getOrUpdateArray<T>(arr: T[], key: number, makeValue: () => T) {
422+
return arr[key] || (arr[key] = makeValue());
423+
}
424+
412425
/**
413426
* Gets the owned, enumerable property keys of a map-like.
414427
*

src/compiler/emitter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
760760

761761
function getGeneratedNameForNode(node: Node) {
762762
const id = getNodeId(node);
763-
return nodeToGeneratedName[id] || (nodeToGeneratedName[id] = unescapeIdentifier(generateNameForNode(node)));
763+
return getOrUpdateArray(nodeToGeneratedName, id, () => unescapeIdentifier(generateNameForNode(node)));
764764
}
765765

766766
/** Write emitted output to disk */

src/compiler/parser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,7 @@ namespace ts {
10861086

10871087
function internIdentifier(text: string): string {
10881088
text = escapeIdentifier(text);
1089-
return identifiers[text] || (identifiers[text] = text);
1089+
return getOrUpdate(identifiers, text, () => text);
10901090
}
10911091

10921092
// An identifier that starts with two underscores has an extra underscore character prepended to it to avoid issues

src/services/services.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,7 @@ namespace ts {
990990
}
991991

992992
function getDeclarations(name: string) {
993-
return result[name] || (result[name] = []);
993+
return getOrUpdate(result, name, () => []);
994994
}
995995

996996
function getDeclarationName(declaration: Declaration) {

0 commit comments

Comments
 (0)