Skip to content

Commit 2a20187

Browse files
authored
Refactor uniqueMap. Add mergeMaps (#2394)
1 parent 7680aa1 commit 2a20187

File tree

4 files changed

+70
-49
lines changed

4 files changed

+70
-49
lines changed

src/compiler.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ import {
195195
writeF32,
196196
writeF64,
197197
writeV128,
198-
uniqueMap,
198+
cloneMap,
199199
isPowerOf2,
200200
v128_zero,
201201
readI32,
@@ -2848,7 +2848,7 @@ export class Compiler extends DiagnosticEmitter {
28482848
type = resolver.resolveType( // reports
28492849
typeNode,
28502850
flow.actualFunction,
2851-
uniqueMap(flow.contextualTypeArguments)
2851+
cloneMap(flow.contextualTypeArguments)
28522852
);
28532853
if (!type) continue;
28542854
this.checkTypeSupported(type, typeNode);
@@ -3626,7 +3626,7 @@ export class Compiler extends DiagnosticEmitter {
36263626
let toType = this.resolver.resolveType( // reports
36273627
assert(expression.toType),
36283628
flow.actualFunction,
3629-
uniqueMap(flow.contextualTypeArguments)
3629+
cloneMap(flow.contextualTypeArguments)
36303630
);
36313631
if (!toType) return this.module.unreachable();
36323632
return this.compileExpression(expression.expression, toType, inheritedConstraints | Constraints.CONV_EXPLICIT);
@@ -6419,7 +6419,7 @@ export class Compiler extends DiagnosticEmitter {
64196419
assert(typeParameterNodes),
64206420
typeArgumentNodes,
64216421
this.currentFlow.actualFunction.parent,
6422-
uniqueMap<string,Type>(this.currentFlow.contextualTypeArguments), // don't update
6422+
cloneMap(this.currentFlow.contextualTypeArguments), // don't update
64236423
expression
64246424
);
64256425
}
@@ -7333,7 +7333,7 @@ export class Compiler extends DiagnosticEmitter {
73337333
DecoratorFlags.NONE
73347334
);
73357335
var instance: Function | null;
7336-
var contextualTypeArguments = uniqueMap(flow.contextualTypeArguments);
7336+
var contextualTypeArguments = cloneMap(flow.contextualTypeArguments);
73377337
var module = this.module;
73387338

73397339
// compile according to context. this differs from a normal function in that omitted parameter
@@ -7715,7 +7715,7 @@ export class Compiler extends DiagnosticEmitter {
77157715
let functionInstance = this.resolver.resolveFunction(
77167716
functionPrototype,
77177717
null,
7718-
uniqueMap<string,Type>(flow.contextualTypeArguments)
7718+
cloneMap(flow.contextualTypeArguments)
77197719
);
77207720
if (!functionInstance || !this.compileFunction(functionInstance)) return module.unreachable();
77217721
if (functionInstance.hasDecorator(DecoratorFlags.BUILTIN)) {
@@ -7770,7 +7770,7 @@ export class Compiler extends DiagnosticEmitter {
77707770
var expectedType = this.resolver.resolveType(
77717771
expression.isType,
77727772
flow.actualFunction,
7773-
uniqueMap(flow.contextualTypeArguments)
7773+
cloneMap(flow.contextualTypeArguments)
77747774
);
77757775
if (!expectedType) {
77767776
this.currentType = Type.bool;
@@ -8148,7 +8148,7 @@ export class Compiler extends DiagnosticEmitter {
81488148
let instance = this.resolver.resolveFunction(
81498149
<FunctionPrototype>target,
81508150
null,
8151-
uniqueMap<string,Type>(),
8151+
new Map(),
81528152
ReportMode.SWALLOW
81538153
);
81548154
if (!instance) break;
@@ -8734,14 +8734,14 @@ export class Compiler extends DiagnosticEmitter {
87348734
classInstance = this.resolver.resolveClass(
87358735
classPrototype,
87368736
classReference.typeArguments,
8737-
uniqueMap<string,Type>(flow.contextualTypeArguments)
8737+
cloneMap(flow.contextualTypeArguments)
87388738
);
87398739
} else {
87408740
classInstance = this.resolver.resolveClassInclTypeArguments(
87418741
classPrototype,
87428742
typeArguments,
87438743
flow.actualFunction.parent, // relative to caller
8744-
uniqueMap<string,Type>(flow.contextualTypeArguments),
8744+
cloneMap(flow.contextualTypeArguments),
87458745
expression
87468746
);
87478747
}
@@ -8773,7 +8773,7 @@ export class Compiler extends DiagnosticEmitter {
87738773
// clone base constructor if a derived class. note that we cannot just
87748774
// call the base ctor since the derived class may have additional fields.
87758775
let baseClass = classInstance.base;
8776-
let contextualTypeArguments = uniqueMap(classInstance.contextualTypeArguments);
8776+
let contextualTypeArguments = cloneMap(classInstance.contextualTypeArguments);
87778777
if (baseClass) {
87788778
let baseCtor = this.ensureConstructor(baseClass, reportNode);
87798779
this.checkFieldInitialization(baseClass, reportNode);

src/flow.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ import {
8585

8686
import {
8787
BitSet,
88-
uniqueMap
88+
cloneMap
8989
} from "./util";
9090

9191
import {
@@ -314,7 +314,7 @@ export class Flow {
314314
branch.localFlags = this.localFlags.slice();
315315
if (this.actualFunction.is(CommonFlags.CONSTRUCTOR)) {
316316
let thisFieldFlags = assert(this.thisFieldFlags);
317-
branch.thisFieldFlags = uniqueMap<Field,FieldFlags>(thisFieldFlags);
317+
branch.thisFieldFlags = cloneMap(thisFieldFlags);
318318
} else {
319319
assert(!this.thisFieldFlags);
320320
}

src/resolver.ts

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ import {
9595
} from "./common";
9696

9797
import {
98-
uniqueMap,
98+
cloneMap,
9999
isPowerOf2
100100
} from "./util";
101101

@@ -255,7 +255,7 @@ export class Resolver extends DiagnosticEmitter {
255255
<ClassPrototype>element,
256256
typeArgumentNodes,
257257
ctxElement,
258-
uniqueMap<string,Type>(ctxTypes), // don't inherit
258+
cloneMap(ctxTypes), // don't inherit
259259
node,
260260
reportMode
261261
);
@@ -309,7 +309,7 @@ export class Resolver extends DiagnosticEmitter {
309309
typeParameterNodes,
310310
typeArgumentNodes,
311311
ctxElement,
312-
ctxTypes = uniqueMap(ctxTypes), // update
312+
ctxTypes = cloneMap(ctxTypes), // update
313313
node,
314314
reportMode
315315
);
@@ -626,7 +626,7 @@ export class Resolver extends DiagnosticEmitter {
626626
/** Contextual element. */
627627
ctxElement: Element,
628628
/** Contextual types, i.e. `T`. Updated in place with the new set of contextual types. */
629-
ctxTypes: Map<string,Type> = uniqueMap<string,Type>(),
629+
ctxTypes: Map<string,Type> = new Map(),
630630
/** Alternative report node in case of empty type arguments. */
631631
alternativeReportNode: Node | null = null,
632632
/** How to proceed with eventual diagnostics. */
@@ -656,7 +656,7 @@ export class Resolver extends DiagnosticEmitter {
656656
return null;
657657
}
658658
var typeArguments = new Array<Type>(maxParameterCount);
659-
var oldCtxTypes = uniqueMap<string,Type>(ctxTypes);
659+
var oldCtxTypes = cloneMap(ctxTypes);
660660
ctxTypes.clear();
661661
for (let i = 0; i < maxParameterCount; ++i) {
662662
let type = i < argumentCount
@@ -669,7 +669,7 @@ export class Resolver extends DiagnosticEmitter {
669669
: this.resolveType( // reports
670670
assert(typeParameters[i].defaultType),
671671
ctxElement,
672-
uniqueMap<string,Type>(ctxTypes), // don't update
672+
cloneMap(ctxTypes), // don't update
673673
reportMode
674674
);
675675
if (!type) return null;
@@ -704,15 +704,15 @@ export class Resolver extends DiagnosticEmitter {
704704
prototype,
705705
typeArguments,
706706
ctxFlow.actualFunction,
707-
uniqueMap(ctxFlow.contextualTypeArguments), // don't inherit
707+
cloneMap(ctxFlow.contextualTypeArguments), // don't inherit
708708
node,
709709
reportMode
710710
);
711711
}
712712

713713
// infer generic call if type arguments have been omitted
714714
if (prototype.is(CommonFlags.GENERIC)) {
715-
let contextualTypeArguments = uniqueMap<string,Type>(ctxFlow.contextualTypeArguments);
715+
let contextualTypeArguments = cloneMap(ctxFlow.contextualTypeArguments);
716716

717717
// fill up contextual types with auto for each generic component
718718
let typeParameterNodes = assert(prototype.typeParameterNodes);
@@ -780,13 +780,13 @@ export class Resolver extends DiagnosticEmitter {
780780
return this.resolveFunction(
781781
prototype,
782782
resolvedTypeArguments,
783-
uniqueMap<string,Type>(ctxFlow.contextualTypeArguments),
783+
cloneMap(ctxFlow.contextualTypeArguments),
784784
reportMode
785785
);
786786
}
787787

788788
// otherwise resolve the non-generic call as usual
789-
return this.resolveFunction(prototype, null, uniqueMap<string,Type>(), reportMode);
789+
return this.resolveFunction(prototype, null, new Map(), reportMode);
790790
}
791791

792792
/** Updates contextual types with a possibly encapsulated inferred type. */
@@ -1220,7 +1220,7 @@ export class Resolver extends DiagnosticEmitter {
12201220
var element = this.lookupIdentifierExpression(node, ctxFlow, ctxElement, reportMode);
12211221
if (!element) return null;
12221222
if (element.kind == ElementKind.FUNCTION_PROTOTYPE) {
1223-
let instance = this.resolveFunction(<FunctionPrototype>element, null, uniqueMap<string,Type>(), reportMode);
1223+
let instance = this.resolveFunction(<FunctionPrototype>element, null, new Map(), reportMode);
12241224
if (!instance) return null;
12251225
element = instance;
12261226
}
@@ -1357,7 +1357,7 @@ export class Resolver extends DiagnosticEmitter {
13571357
// Inherit from 'Function' if not overridden, i.e. fn.call
13581358
let ownMember = target.getMember(propertyName);
13591359
if (!ownMember) {
1360-
let functionInstance = this.resolveFunction(<FunctionPrototype>target, null, uniqueMap<string,Type>(), ReportMode.SWALLOW);
1360+
let functionInstance = this.resolveFunction(<FunctionPrototype>target, null, new Map(), ReportMode.SWALLOW);
13611361
if (functionInstance) {
13621362
let wrapper = functionInstance.type.getClassOrWrapper(this.program);
13631363
if (wrapper) target = wrapper;
@@ -2538,7 +2538,7 @@ export class Resolver extends DiagnosticEmitter {
25382538
<ClassPrototype>element,
25392539
node.typeArguments,
25402540
ctxFlow.actualFunction,
2541-
uniqueMap<string,Type>(ctxFlow.contextualTypeArguments),
2541+
cloneMap(ctxFlow.contextualTypeArguments),
25422542
node,
25432543
reportMode
25442544
);
@@ -2625,7 +2625,7 @@ export class Resolver extends DiagnosticEmitter {
26252625
/** Type arguments provided. */
26262626
typeArguments: Type[] | null,
26272627
/** Contextual types, i.e. `T`. */
2628-
ctxTypes: Map<string,Type> = uniqueMap<string,Type>(),
2628+
ctxTypes: Map<string,Type> = new Map(),
26292629
/** How to proceed with eventual diagnostics. */
26302630
reportMode: ReportMode = ReportMode.REPORT
26312631
): Function | null {
@@ -2927,7 +2927,7 @@ export class Resolver extends DiagnosticEmitter {
29272927
/** Type arguments provided. */
29282928
typeArguments: Type[] | null,
29292929
/** Contextual types, i.e. `T`. */
2930-
ctxTypes: Map<string,Type> = uniqueMap<string,Type>(),
2930+
ctxTypes: Map<string,Type> = new Map(),
29312931
/** How to proceed with eventual diagnostics. */
29322932
reportMode: ReportMode = ReportMode.REPORT
29332933
): Class | null {
@@ -2988,7 +2988,7 @@ export class Resolver extends DiagnosticEmitter {
29882988
basePrototype,
29892989
extendsNode.typeArguments,
29902990
prototype.parent, // relative to derived class
2991-
uniqueMap(ctxTypes), // don't inherit
2991+
cloneMap(ctxTypes), // don't inherit
29922992
extendsNode,
29932993
reportMode
29942994
);
@@ -3024,7 +3024,7 @@ export class Resolver extends DiagnosticEmitter {
30243024
interfacePrototype,
30253025
implementsNode.typeArguments,
30263026
prototype.parent,
3027-
uniqueMap(ctxTypes),
3027+
cloneMap(ctxTypes),
30283028
implementsNode,
30293029
reportMode
30303030
);
@@ -3346,14 +3346,14 @@ export class Resolver extends DiagnosticEmitter {
33463346
operatorInstance = this.resolveFunction(
33473347
boundPrototype,
33483348
null,
3349-
uniqueMap<string,Type>(),
3349+
new Map(),
33503350
reportMode
33513351
);
33523352
} else {
33533353
operatorInstance = this.resolveFunction(
33543354
overloadPrototype,
33553355
null,
3356-
uniqueMap<string,Type>(),
3356+
new Map(),
33573357
reportMode
33583358
);
33593359
}
@@ -3491,7 +3491,7 @@ export class Resolver extends DiagnosticEmitter {
34913491
let getterInstance = this.resolveFunction(
34923492
getterPrototype,
34933493
null,
3494-
uniqueMap<string,Type>(),
3494+
new Map(),
34953495
reportMode
34963496
);
34973497
if (getterInstance) {
@@ -3504,7 +3504,7 @@ export class Resolver extends DiagnosticEmitter {
35043504
let setterInstance = this.resolveFunction(
35053505
setterPrototype,
35063506
null,
3507-
uniqueMap<string,Type>(),
3507+
new Map(),
35083508
reportMode
35093509
);
35103510
if (setterInstance) {

src/util/collections.ts

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,47 @@
33
* @license Apache-2.0
44
*/
55

6-
/** Makes a unique map. Typically used to track contextual type arguemnts. */
7-
export function uniqueMap<K,V>(original: Map<K,V> | null = null, overrides: Map<K,V> | null = null): Map<K,V> {
8-
var cloned = new Map<K,V>();
9-
if (original) {
10-
// TODO: for (let [k, v] of original) {
11-
for (let _keys = Map_keys(original), i = 0, k = _keys.length; i < k; ++i) {
12-
let k = unchecked(_keys[i]);
13-
let v = assert(original.get(k));
14-
cloned.set(k, v);
6+
/** Clone map. Typically used to track contextual type arguments. */
7+
export function cloneMap<K,V>(map: Map<K,V> | null): Map<K,V> {
8+
if (!ASC_TARGET) { // JS
9+
// fast path for js target
10+
return new Map<K,V>(map);
11+
} else {
12+
let out = new Map<K,V>();
13+
if (map) {
14+
// TODO: for (let [k, v] of map) {
15+
for (let _keys = Map_keys(map), i = 0, k = _keys.length; i < k; ++i) {
16+
let k = unchecked(_keys[i]);
17+
let v = assert(map.get(k));
18+
out.set(k, v);
19+
}
1520
}
21+
return out;
1622
}
17-
if (overrides) {
18-
// TODO: for (let [k, v] of overrides) {
19-
for (let _keys = Map_keys(overrides), i = 0, k = _keys.length; i < k; ++i) {
23+
}
24+
25+
/** Merge two maps in into new one. */
26+
export function mergeMaps<K,V>(map1: Map<K,V>, map2: Map<K,V>): Map<K,V> {
27+
if (!ASC_TARGET) { // JS
28+
let out = new Map<K,V>(map1);
29+
map2.forEach((v, k) => out.set(k, v));
30+
return out;
31+
} else {
32+
let out = new Map<K,V>();
33+
// TODO: for (let [k, v] of map1) {
34+
for (let _keys = Map_keys(map1), i = 0, k = _keys.length; i < k; ++i) {
35+
let k = unchecked(_keys[i]);
36+
let v = assert(map1.get(k));
37+
out.set(k, v);
38+
}
39+
// TODO: for (let [k, v] of map2) {
40+
for (let _keys = Map_keys(map2), i = 0, k = _keys.length; i < k; ++i) {
2041
let k = unchecked(_keys[i]);
21-
let v = assert(overrides.get(k));
22-
cloned.set(k, v);
42+
let v = assert(map2.get(k));
43+
out.set(k, v);
2344
}
45+
return out;
2446
}
25-
return cloned;
2647
}
2748

2849
/** BitSet represent growable sequence of N bits. It's faster alternative of Set<i32> when elements

0 commit comments

Comments
 (0)