Skip to content

Refactor uniqueMap. Add mergeMaps #2394

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Aug 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ import {
writeF32,
writeF64,
writeV128,
uniqueMap,
cloneMap,
isPowerOf2,
v128_zero,
readI32,
Expand Down Expand Up @@ -2848,7 +2848,7 @@ export class Compiler extends DiagnosticEmitter {
type = resolver.resolveType( // reports
typeNode,
flow.actualFunction,
uniqueMap(flow.contextualTypeArguments)
cloneMap(flow.contextualTypeArguments)
);
if (!type) continue;
this.checkTypeSupported(type, typeNode);
Expand Down Expand Up @@ -3626,7 +3626,7 @@ export class Compiler extends DiagnosticEmitter {
let toType = this.resolver.resolveType( // reports
assert(expression.toType),
flow.actualFunction,
uniqueMap(flow.contextualTypeArguments)
cloneMap(flow.contextualTypeArguments)
);
if (!toType) return this.module.unreachable();
return this.compileExpression(expression.expression, toType, inheritedConstraints | Constraints.CONV_EXPLICIT);
Expand Down Expand Up @@ -6419,7 +6419,7 @@ export class Compiler extends DiagnosticEmitter {
assert(typeParameterNodes),
typeArgumentNodes,
this.currentFlow.actualFunction.parent,
uniqueMap<string,Type>(this.currentFlow.contextualTypeArguments), // don't update
cloneMap(this.currentFlow.contextualTypeArguments), // don't update
expression
);
}
Expand Down Expand Up @@ -7333,7 +7333,7 @@ export class Compiler extends DiagnosticEmitter {
DecoratorFlags.NONE
);
var instance: Function | null;
var contextualTypeArguments = uniqueMap(flow.contextualTypeArguments);
var contextualTypeArguments = cloneMap(flow.contextualTypeArguments);
var module = this.module;

// compile according to context. this differs from a normal function in that omitted parameter
Expand Down Expand Up @@ -7715,7 +7715,7 @@ export class Compiler extends DiagnosticEmitter {
let functionInstance = this.resolver.resolveFunction(
functionPrototype,
null,
uniqueMap<string,Type>(flow.contextualTypeArguments)
cloneMap(flow.contextualTypeArguments)
);
if (!functionInstance || !this.compileFunction(functionInstance)) return module.unreachable();
if (functionInstance.hasDecorator(DecoratorFlags.BUILTIN)) {
Expand Down Expand Up @@ -7770,7 +7770,7 @@ export class Compiler extends DiagnosticEmitter {
var expectedType = this.resolver.resolveType(
expression.isType,
flow.actualFunction,
uniqueMap(flow.contextualTypeArguments)
cloneMap(flow.contextualTypeArguments)
);
if (!expectedType) {
this.currentType = Type.bool;
Expand Down Expand Up @@ -8148,7 +8148,7 @@ export class Compiler extends DiagnosticEmitter {
let instance = this.resolver.resolveFunction(
<FunctionPrototype>target,
null,
uniqueMap<string,Type>(),
new Map(),
ReportMode.SWALLOW
);
if (!instance) break;
Expand Down Expand Up @@ -8734,14 +8734,14 @@ export class Compiler extends DiagnosticEmitter {
classInstance = this.resolver.resolveClass(
classPrototype,
classReference.typeArguments,
uniqueMap<string,Type>(flow.contextualTypeArguments)
cloneMap(flow.contextualTypeArguments)
);
} else {
classInstance = this.resolver.resolveClassInclTypeArguments(
classPrototype,
typeArguments,
flow.actualFunction.parent, // relative to caller
uniqueMap<string,Type>(flow.contextualTypeArguments),
cloneMap(flow.contextualTypeArguments),
expression
);
}
Expand Down Expand Up @@ -8773,7 +8773,7 @@ export class Compiler extends DiagnosticEmitter {
// clone base constructor if a derived class. note that we cannot just
// call the base ctor since the derived class may have additional fields.
let baseClass = classInstance.base;
let contextualTypeArguments = uniqueMap(classInstance.contextualTypeArguments);
let contextualTypeArguments = cloneMap(classInstance.contextualTypeArguments);
if (baseClass) {
let baseCtor = this.ensureConstructor(baseClass, reportNode);
this.checkFieldInitialization(baseClass, reportNode);
Expand Down
4 changes: 2 additions & 2 deletions src/flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ import {

import {
BitSet,
uniqueMap
cloneMap
} from "./util";

import {
Expand Down Expand Up @@ -314,7 +314,7 @@ export class Flow {
branch.localFlags = this.localFlags.slice();
if (this.actualFunction.is(CommonFlags.CONSTRUCTOR)) {
let thisFieldFlags = assert(this.thisFieldFlags);
branch.thisFieldFlags = uniqueMap<Field,FieldFlags>(thisFieldFlags);
branch.thisFieldFlags = cloneMap(thisFieldFlags);
} else {
assert(!this.thisFieldFlags);
}
Expand Down
42 changes: 21 additions & 21 deletions src/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ import {
} from "./common";

import {
uniqueMap,
cloneMap,
isPowerOf2
} from "./util";

Expand Down Expand Up @@ -255,7 +255,7 @@ export class Resolver extends DiagnosticEmitter {
<ClassPrototype>element,
typeArgumentNodes,
ctxElement,
uniqueMap<string,Type>(ctxTypes), // don't inherit
cloneMap(ctxTypes), // don't inherit
node,
reportMode
);
Expand Down Expand Up @@ -309,7 +309,7 @@ export class Resolver extends DiagnosticEmitter {
typeParameterNodes,
typeArgumentNodes,
ctxElement,
ctxTypes = uniqueMap(ctxTypes), // update
ctxTypes = cloneMap(ctxTypes), // update
node,
reportMode
);
Expand Down Expand Up @@ -626,7 +626,7 @@ export class Resolver extends DiagnosticEmitter {
/** Contextual element. */
ctxElement: Element,
/** Contextual types, i.e. `T`. Updated in place with the new set of contextual types. */
ctxTypes: Map<string,Type> = uniqueMap<string,Type>(),
ctxTypes: Map<string,Type> = new Map(),
/** Alternative report node in case of empty type arguments. */
alternativeReportNode: Node | null = null,
/** How to proceed with eventual diagnostics. */
Expand Down Expand Up @@ -656,7 +656,7 @@ export class Resolver extends DiagnosticEmitter {
return null;
}
var typeArguments = new Array<Type>(maxParameterCount);
var oldCtxTypes = uniqueMap<string,Type>(ctxTypes);
var oldCtxTypes = cloneMap(ctxTypes);
ctxTypes.clear();
for (let i = 0; i < maxParameterCount; ++i) {
let type = i < argumentCount
Expand All @@ -669,7 +669,7 @@ export class Resolver extends DiagnosticEmitter {
: this.resolveType( // reports
assert(typeParameters[i].defaultType),
ctxElement,
uniqueMap<string,Type>(ctxTypes), // don't update
cloneMap(ctxTypes), // don't update
reportMode
);
if (!type) return null;
Expand Down Expand Up @@ -704,15 +704,15 @@ export class Resolver extends DiagnosticEmitter {
prototype,
typeArguments,
ctxFlow.actualFunction,
uniqueMap(ctxFlow.contextualTypeArguments), // don't inherit
cloneMap(ctxFlow.contextualTypeArguments), // don't inherit
node,
reportMode
);
}

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

// fill up contextual types with auto for each generic component
let typeParameterNodes = assert(prototype.typeParameterNodes);
Expand Down Expand Up @@ -780,13 +780,13 @@ export class Resolver extends DiagnosticEmitter {
return this.resolveFunction(
prototype,
resolvedTypeArguments,
uniqueMap<string,Type>(ctxFlow.contextualTypeArguments),
cloneMap(ctxFlow.contextualTypeArguments),
reportMode
);
}

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

/** Updates contextual types with a possibly encapsulated inferred type. */
Expand Down Expand Up @@ -1220,7 +1220,7 @@ export class Resolver extends DiagnosticEmitter {
var element = this.lookupIdentifierExpression(node, ctxFlow, ctxElement, reportMode);
if (!element) return null;
if (element.kind == ElementKind.FUNCTION_PROTOTYPE) {
let instance = this.resolveFunction(<FunctionPrototype>element, null, uniqueMap<string,Type>(), reportMode);
let instance = this.resolveFunction(<FunctionPrototype>element, null, new Map(), reportMode);
if (!instance) return null;
element = instance;
}
Expand Down Expand Up @@ -1357,7 +1357,7 @@ export class Resolver extends DiagnosticEmitter {
// Inherit from 'Function' if not overridden, i.e. fn.call
let ownMember = target.getMember(propertyName);
if (!ownMember) {
let functionInstance = this.resolveFunction(<FunctionPrototype>target, null, uniqueMap<string,Type>(), ReportMode.SWALLOW);
let functionInstance = this.resolveFunction(<FunctionPrototype>target, null, new Map(), ReportMode.SWALLOW);
if (functionInstance) {
let wrapper = functionInstance.type.getClassOrWrapper(this.program);
if (wrapper) target = wrapper;
Expand Down Expand Up @@ -2538,7 +2538,7 @@ export class Resolver extends DiagnosticEmitter {
<ClassPrototype>element,
node.typeArguments,
ctxFlow.actualFunction,
uniqueMap<string,Type>(ctxFlow.contextualTypeArguments),
cloneMap(ctxFlow.contextualTypeArguments),
node,
reportMode
);
Expand Down Expand Up @@ -2625,7 +2625,7 @@ export class Resolver extends DiagnosticEmitter {
/** Type arguments provided. */
typeArguments: Type[] | null,
/** Contextual types, i.e. `T`. */
ctxTypes: Map<string,Type> = uniqueMap<string,Type>(),
ctxTypes: Map<string,Type> = new Map(),
/** How to proceed with eventual diagnostics. */
reportMode: ReportMode = ReportMode.REPORT
): Function | null {
Expand Down Expand Up @@ -2927,7 +2927,7 @@ export class Resolver extends DiagnosticEmitter {
/** Type arguments provided. */
typeArguments: Type[] | null,
/** Contextual types, i.e. `T`. */
ctxTypes: Map<string,Type> = uniqueMap<string,Type>(),
ctxTypes: Map<string,Type> = new Map(),
/** How to proceed with eventual diagnostics. */
reportMode: ReportMode = ReportMode.REPORT
): Class | null {
Expand Down Expand Up @@ -2988,7 +2988,7 @@ export class Resolver extends DiagnosticEmitter {
basePrototype,
extendsNode.typeArguments,
prototype.parent, // relative to derived class
uniqueMap(ctxTypes), // don't inherit
cloneMap(ctxTypes), // don't inherit
extendsNode,
reportMode
);
Expand Down Expand Up @@ -3024,7 +3024,7 @@ export class Resolver extends DiagnosticEmitter {
interfacePrototype,
implementsNode.typeArguments,
prototype.parent,
uniqueMap(ctxTypes),
cloneMap(ctxTypes),
implementsNode,
reportMode
);
Expand Down Expand Up @@ -3346,14 +3346,14 @@ export class Resolver extends DiagnosticEmitter {
operatorInstance = this.resolveFunction(
boundPrototype,
null,
uniqueMap<string,Type>(),
new Map(),
reportMode
);
} else {
operatorInstance = this.resolveFunction(
overloadPrototype,
null,
uniqueMap<string,Type>(),
new Map(),
reportMode
);
}
Expand Down Expand Up @@ -3491,7 +3491,7 @@ export class Resolver extends DiagnosticEmitter {
let getterInstance = this.resolveFunction(
getterPrototype,
null,
uniqueMap<string,Type>(),
new Map(),
reportMode
);
if (getterInstance) {
Expand All @@ -3504,7 +3504,7 @@ export class Resolver extends DiagnosticEmitter {
let setterInstance = this.resolveFunction(
setterPrototype,
null,
uniqueMap<string,Type>(),
new Map(),
reportMode
);
if (setterInstance) {
Expand Down
51 changes: 36 additions & 15 deletions src/util/collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,47 @@
* @license Apache-2.0
*/

/** Makes a unique map. Typically used to track contextual type arguemnts. */
export function uniqueMap<K,V>(original: Map<K,V> | null = null, overrides: Map<K,V> | null = null): Map<K,V> {
var cloned = new Map<K,V>();
if (original) {
// TODO: for (let [k, v] of original) {
for (let _keys = Map_keys(original), i = 0, k = _keys.length; i < k; ++i) {
let k = unchecked(_keys[i]);
let v = assert(original.get(k));
cloned.set(k, v);
/** Clone map. Typically used to track contextual type arguments. */
export function cloneMap<K,V>(map: Map<K,V> | null): Map<K,V> {
if (!ASC_TARGET) { // JS
// fast path for js target
return new Map<K,V>(map);
} else {
let out = new Map<K,V>();
if (map) {
// TODO: for (let [k, v] of map) {
for (let _keys = Map_keys(map), i = 0, k = _keys.length; i < k; ++i) {
let k = unchecked(_keys[i]);
let v = assert(map.get(k));
out.set(k, v);
}
}
return out;
}
if (overrides) {
// TODO: for (let [k, v] of overrides) {
for (let _keys = Map_keys(overrides), i = 0, k = _keys.length; i < k; ++i) {
}

/** Merge two maps in into new one. */
export function mergeMaps<K,V>(map1: Map<K,V>, map2: Map<K,V>): Map<K,V> {
if (!ASC_TARGET) { // JS
let out = new Map<K,V>(map1);
map2.forEach((v, k) => out.set(k, v));
return out;
} else {
let out = new Map<K,V>();
// TODO: for (let [k, v] of map1) {
for (let _keys = Map_keys(map1), i = 0, k = _keys.length; i < k; ++i) {
let k = unchecked(_keys[i]);
let v = assert(map1.get(k));
out.set(k, v);
}
// TODO: for (let [k, v] of map2) {
for (let _keys = Map_keys(map2), i = 0, k = _keys.length; i < k; ++i) {
let k = unchecked(_keys[i]);
let v = assert(overrides.get(k));
cloned.set(k, v);
let v = assert(map2.get(k));
out.set(k, v);
}
return out;
}
return cloned;
}

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