Skip to content

Commit 1dc495a

Browse files
committed
Migrate additional MapLikes to Maps.
1 parent 7f0a02f commit 1dc495a

22 files changed

+295
-216
lines changed

src/compiler/checker.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -284,33 +284,33 @@ namespace ts {
284284
NullFacts = TypeofEQObject | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | TypeofNEHostObject | EQNull | EQUndefinedOrNull | NEUndefined | Falsy,
285285
}
286286

287-
const typeofEQFacts: MapLike<TypeFacts> = {
287+
const typeofEQFacts = createMap({
288288
"string": TypeFacts.TypeofEQString,
289289
"number": TypeFacts.TypeofEQNumber,
290290
"boolean": TypeFacts.TypeofEQBoolean,
291291
"symbol": TypeFacts.TypeofEQSymbol,
292292
"undefined": TypeFacts.EQUndefined,
293293
"object": TypeFacts.TypeofEQObject,
294294
"function": TypeFacts.TypeofEQFunction
295-
};
295+
});
296296

297-
const typeofNEFacts: MapLike<TypeFacts> = {
297+
const typeofNEFacts = createMap({
298298
"string": TypeFacts.TypeofNEString,
299299
"number": TypeFacts.TypeofNENumber,
300300
"boolean": TypeFacts.TypeofNEBoolean,
301301
"symbol": TypeFacts.TypeofNESymbol,
302302
"undefined": TypeFacts.NEUndefined,
303303
"object": TypeFacts.TypeofNEObject,
304304
"function": TypeFacts.TypeofNEFunction
305-
};
305+
});
306306

307-
const typeofTypesByName: MapLike<Type> = {
307+
const typeofTypesByName = createMap<Type>({
308308
"string": stringType,
309309
"number": numberType,
310310
"boolean": booleanType,
311311
"symbol": esSymbolType,
312312
"undefined": undefinedType
313-
};
313+
});
314314

315315
let jsxElementType: ObjectType;
316316
/** Things we lazy load from the JSX namespace */
@@ -8467,11 +8467,11 @@ namespace ts {
84678467
return type;
84688468
}
84698469
const doubleEquals = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken;
8470-
const facts = doubleEquals ?
8471-
assumeTrue ? TypeFacts.EQUndefinedOrNull : TypeFacts.NEUndefinedOrNull :
8472-
value.kind === SyntaxKind.NullKeyword ?
8473-
assumeTrue ? TypeFacts.EQNull : TypeFacts.NENull :
8474-
assumeTrue ? TypeFacts.EQUndefined : TypeFacts.NEUndefined;
8470+
const facts = doubleEquals
8471+
? assumeTrue ? TypeFacts.EQUndefinedOrNull : TypeFacts.NEUndefinedOrNull
8472+
: value.kind === SyntaxKind.NullKeyword
8473+
? assumeTrue ? TypeFacts.EQNull : TypeFacts.NENull
8474+
: assumeTrue ? TypeFacts.EQUndefined : TypeFacts.NEUndefined;
84758475
return getTypeWithFacts(type, facts);
84768476
}
84778477
if (type.flags & TypeFlags.NotUnionOrUnit) {
@@ -8502,14 +8502,14 @@ namespace ts {
85028502
// We narrow a non-union type to an exact primitive type if the non-union type
85038503
// is a supertype of that primitive type. For example, type 'any' can be narrowed
85048504
// to one of the primitive types.
8505-
const targetType = getProperty(typeofTypesByName, literal.text);
8505+
const targetType = typeofTypesByName[literal.text];
85068506
if (targetType && isTypeSubtypeOf(targetType, type)) {
85078507
return targetType;
85088508
}
85098509
}
8510-
const facts = assumeTrue ?
8511-
getProperty(typeofEQFacts, literal.text) || TypeFacts.TypeofEQHostObject :
8512-
getProperty(typeofNEFacts, literal.text) || TypeFacts.TypeofNEHostObject;
8510+
const facts = assumeTrue
8511+
? typeofEQFacts[literal.text] || TypeFacts.TypeofEQHostObject
8512+
: typeofNEFacts[literal.text] || TypeFacts.TypeofNEHostObject;
85138513
return getTypeWithFacts(type, facts);
85148514
}
85158515

src/compiler/commandLineParser.ts

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ namespace ts {
6161
},
6262
{
6363
name: "jsx",
64-
type: {
64+
type: createMap({
6565
"preserve": JsxEmit.Preserve,
6666
"react": JsxEmit.React
67-
},
67+
}),
6868
paramType: Diagnostics.KIND,
6969
description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_or_react,
7070
},
@@ -91,24 +91,24 @@ namespace ts {
9191
{
9292
name: "module",
9393
shortName: "m",
94-
type: {
94+
type: createMap({
9595
"none": ModuleKind.None,
9696
"commonjs": ModuleKind.CommonJS,
9797
"amd": ModuleKind.AMD,
9898
"system": ModuleKind.System,
9999
"umd": ModuleKind.UMD,
100100
"es6": ModuleKind.ES6,
101101
"es2015": ModuleKind.ES2015,
102-
},
102+
}),
103103
description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015,
104104
paramType: Diagnostics.KIND,
105105
},
106106
{
107107
name: "newLine",
108-
type: {
108+
type: createMap({
109109
"crlf": NewLineKind.CarriageReturnLineFeed,
110110
"lf": NewLineKind.LineFeed
111-
},
111+
}),
112112
description: Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix,
113113
paramType: Diagnostics.NEWLINE,
114114
},
@@ -250,12 +250,12 @@ namespace ts {
250250
{
251251
name: "target",
252252
shortName: "t",
253-
type: {
253+
type: createMap({
254254
"es3": ScriptTarget.ES3,
255255
"es5": ScriptTarget.ES5,
256256
"es6": ScriptTarget.ES6,
257257
"es2015": ScriptTarget.ES2015,
258-
},
258+
}),
259259
description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015,
260260
paramType: Diagnostics.VERSION,
261261
},
@@ -284,10 +284,10 @@ namespace ts {
284284
},
285285
{
286286
name: "moduleResolution",
287-
type: {
287+
type: createMap({
288288
"node": ModuleResolutionKind.NodeJs,
289289
"classic": ModuleResolutionKind.Classic,
290-
},
290+
}),
291291
description: Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6,
292292
},
293293
{
@@ -392,7 +392,7 @@ namespace ts {
392392
type: "list",
393393
element: {
394394
name: "lib",
395-
type: {
395+
type: createMap({
396396
// JavaScript only
397397
"es5": "lib.es5.d.ts",
398398
"es6": "lib.es2015.d.ts",
@@ -417,7 +417,7 @@ namespace ts {
417417
"es2016.array.include": "lib.es2016.array.include.d.ts",
418418
"es2017.object": "lib.es2017.object.d.ts",
419419
"es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts"
420-
},
420+
}),
421421
},
422422
description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon
423423
},
@@ -487,9 +487,7 @@ namespace ts {
487487
export function createCompilerDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType): Diagnostic {
488488
const namesOfType: string[] = [];
489489
for (const key in opt.type) {
490-
if (hasProperty(opt.type, key)) {
491-
namesOfType.push(` '${key}'`);
492-
}
490+
namesOfType.push(` '${key}'`);
493491
}
494492
return createCompilerDiagnostic(Diagnostics.Argument_for_0_option_must_be_Colon_1, `--${opt.name}`, namesOfType);
495493
}
@@ -498,7 +496,7 @@ namespace ts {
498496
export function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) {
499497
const key = trimString((value || "")).toLowerCase();
500498
const map = opt.type;
501-
if (hasProperty(map, key)) {
499+
if (key in map) {
502500
return map[key];
503501
}
504502
else {
@@ -849,7 +847,7 @@ namespace ts {
849847

850848
function convertJsonOptionOfCustomType(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) {
851849
const key = value.toLowerCase();
852-
if (hasProperty(opt.type, key)) {
850+
if (key in opt.type) {
853851
return opt.type[key];
854852
}
855853
else {

src/compiler/core.ts

Lines changed: 103 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,21 @@ namespace ts {
190190
return array;
191191
}
192192

193+
export function removeWhere<T>(array: T[], f: (x: T) => boolean): boolean {
194+
let outIndex = 0;
195+
for (const item of array) {
196+
if (!f(item)) {
197+
array[outIndex] = item;
198+
outIndex++;
199+
}
200+
}
201+
if (outIndex !== array.length) {
202+
array.length = outIndex;
203+
return true;
204+
}
205+
return false;
206+
}
207+
193208
export function filterMutate<T>(array: T[], f: (x: T) => boolean): void {
194209
let outIndex = 0;
195210
for (const item of array) {
@@ -381,6 +396,9 @@ namespace ts {
381396
/**
382397
* Gets the owned, enumerable property keys of a map-like.
383398
*
399+
* NOTE: This is intended for use with MapLike<T> objects. For Map<T> objects, use
400+
* Object.keys instead as it offers better performance.
401+
*
384402
* @param map A map-like.
385403
*/
386404
export function getOwnKeys<T>(map: MapLike<T>): string[] {
@@ -425,6 +443,36 @@ namespace ts {
425443
return result;
426444
}
427445

446+
/**
447+
* Maps key-value pairs of a map into a new map.
448+
*
449+
* NOTE: The key-value pair passed to the callback is *not* safe to cache between invocations
450+
* of the callback.
451+
*
452+
* @param map A map.
453+
* @param callback A callback that maps a key-value pair into a new key-value pair.
454+
*/
455+
export function mapPairs<T, U>(map: Map<T>, callback: (entry: [string, T]) => [string, U]): Map<U> {
456+
let result: Map<U>;
457+
if (map) {
458+
result = createMap<U>();
459+
let inPair: [string, T];
460+
for (const key in map) {
461+
if (inPair) {
462+
inPair[0] = key;
463+
inPair[1] = map[key];
464+
}
465+
else {
466+
inPair = [key, map[key]];
467+
}
468+
469+
const outPair = callback(inPair);
470+
result[outPair[0]] = outPair[1];
471+
}
472+
}
473+
return result;
474+
}
475+
428476
/**
429477
* Returns true if a Map<T> has some matching property.
430478
*
@@ -504,9 +552,31 @@ namespace ts {
504552
return result;
505553
}
506554

555+
/**
556+
* Counts the properties of a map.
557+
*
558+
* NOTE: This is intended for use with Map<T> objects. For MapLike<T> objects, use
559+
* countOwnProperties instead as it offers better runtime safety.
560+
*
561+
* @param map A map whose properties should be counted.
562+
* @param predicate An optional callback used to limit which properties should be counted.
563+
*/
564+
export function countProperties<T>(map: Map<T>, predicate?: (value: T, key: string) => boolean) {
565+
let count = 0;
566+
for (const key in map) {
567+
if (!predicate || predicate(map[key], key)) {
568+
count++;
569+
}
570+
}
571+
return count;
572+
}
573+
507574
/**
508575
* Counts the owned properties of a map-like.
509576
*
577+
* NOTE: This is intended for use with MapLike<T> objects. For Map<T> objects, use
578+
* countProperties instead as it offers better performance.
579+
*
510580
* @param map A map-like whose properties should be counted.
511581
* @param predicate An optional callback used to limit which properties should be counted.
512582
*/
@@ -521,16 +591,42 @@ namespace ts {
521591
}
522592

523593
/**
524-
* Performs a shallow equality comparison of the contents of two map-likes.
594+
* Performs a shallow equality comparison of the contents of two maps.
595+
*
596+
* NOTE: This is intended for use with Map<T> objects. For MapLike<T> objects, use
597+
* equalOwnProperties instead as it offers better runtime safety.
525598
*
526599
* @param left A map whose properties should be compared.
527600
* @param right A map whose properties should be compared.
528601
*/
529-
export function equalOwnProperties<T>(left: MapLike<T>, right: MapLike<T>) {
602+
export function equalProperties<T>(left: Map<T>, right: Map<T>, equalityComparer?: (left: T, right: T) => boolean) {
603+
if (left === right) return true;
604+
if (!left || !right) return false;
605+
for (const key in left) {
606+
if (!(key in right)) return false;
607+
if (equalityComparer ? !equalityComparer(left[key], right[key]) : left[key] !== right[key]) return false;
608+
}
609+
for (const key in right) {
610+
if (!(key in left)) return false;
611+
}
612+
return true;
613+
}
614+
615+
/**
616+
* Performs a shallow equality comparison of the contents of two map-likes.
617+
*
618+
* NOTE: This is intended for use with MapLike<T> objects. For Map<T> objects, use
619+
* equalProperties instead as it offers better performance.
620+
*
621+
* @param left A map-like whose properties should be compared.
622+
* @param right A map-like whose properties should be compared.
623+
*/
624+
export function equalOwnProperties<T>(left: MapLike<T>, right: MapLike<T>, equalityComparer?: (left: T, right: T) => boolean) {
530625
if (left === right) return true;
531626
if (!left || !right) return false;
532627
for (const key in left) if (hasOwnProperty.call(left, key)) {
533-
if (!hasOwnProperty.call(right, key) === undefined || left[key] !== right[key]) return false;
628+
if (!hasOwnProperty.call(right, key) === undefined) return false;
629+
if (equalityComparer ? !equalityComparer(left[key], right[key]) : left[key] !== right[key]) return false;
534630
}
535631
for (const key in right) if (hasOwnProperty.call(right, key)) {
536632
if (!hasOwnProperty.call(left, key)) return false;
@@ -577,10 +673,12 @@ namespace ts {
577673
export function extend<T1 extends MapLike<{}>, T2 extends MapLike<{}>>(first: T1 , second: T2): T1 & T2 {
578674
const result: T1 & T2 = <any>{};
579675
for (const id in first) {
580-
(result as any)[id] = first[id];
676+
if (hasOwnProperty.call(first, id)) {
677+
(result as any)[id] = first[id];
678+
}
581679
}
582680
for (const id in second) {
583-
if (!hasProperty(result, id)) {
681+
if (hasOwnProperty.call(second, id) && !hasOwnProperty.call(result, id)) {
584682
(result as any)[id] = second[id];
585683
}
586684
}

0 commit comments

Comments
 (0)