diff --git a/src/compiler.ts b/src/compiler.ts index 074da6fd..f01c6549 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -551,13 +551,15 @@ export class Compiler extends DiagnosticEmitter { // skip prototype and export instances case ElementKind.FUNCTION_PROTOTYPE: { - for (let instance of (<FunctionPrototype>element).instances.values()) { - let instanceName = name; - if (instance.is(CommonFlags.GENERIC)) { - let fullName = instance.internalName; - instanceName += fullName.substring(fullName.lastIndexOf("<")); + for (let instances of (<FunctionPrototype>element).instances.values()) { + for (let instance of instances.values()) { + let instanceName = name; + if (instance.is(CommonFlags.GENERIC)) { + let fullName = instance.internalName; + instanceName += fullName.substring(fullName.lastIndexOf("<")); + } + this.makeModuleExport(instanceName, instance, prefix); } - this.makeModuleExport(instanceName, instance, prefix); } break; } diff --git a/src/definitions.ts b/src/definitions.ts index 593fc058..1d054b89 100644 --- a/src/definitions.ts +++ b/src/definitions.ts @@ -105,8 +105,10 @@ abstract class ExportsWalker { } private visitFunctionInstances(element: FunctionPrototype): void { - for (let instance of element.instances.values()) { - if (instance.is(CommonFlags.COMPILED)) this.visitFunction(<Function>instance); + for (let instances of element.instances.values()) { + for (let instance of instances.values()) { + if (instance.is(CommonFlags.COMPILED)) this.visitFunction(<Function>instance); + } } } @@ -516,8 +518,10 @@ function hasCompiledMember(element: Element): bool { for (let member of members.values()) { switch (member.kind) { case ElementKind.FUNCTION_PROTOTYPE: { - for (let instance of (<FunctionPrototype>member).instances.values()) { - if (instance.is(CommonFlags.COMPILED)) return true; + for (let instances of (<FunctionPrototype>member).instances.values()) { + for (let instance of instances.values()) { + if (instance.is(CommonFlags.COMPILED)) return true; + } } break; } diff --git a/src/program.ts b/src/program.ts index 1a6a6a32..73336634 100644 --- a/src/program.ts +++ b/src/program.ts @@ -2391,8 +2391,8 @@ export class FunctionPrototype extends Element { declaration: FunctionDeclaration; /** If an instance method, the class prototype reference. */ classPrototype: ClassPrototype | null; - /** Resolved instances. */ - instances: Map<string,Function> = new Map(); + /** Resolved instances by class type arguments and function type arguments. */ + instances: Map<string,Map<string,Function>> = new Map(); /** Class type arguments, if a partially resolved method of a generic class. Not set otherwise. */ classTypeArguments: Type[] | null = null; /** Operator kind, if an overload. */ diff --git a/src/resolver.ts b/src/resolver.ts index 9e20b914..c55059aa 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -713,9 +713,14 @@ export class Resolver extends DiagnosticEmitter { contextualTypeArguments: Map<string,Type> | null = null, reportMode: ReportMode = ReportMode.REPORT ): Function | null { + var classTypeArguments = prototype.classTypeArguments; + var classInstanceKey = classTypeArguments ? typesToString(classTypeArguments) : ""; var instanceKey = typeArguments ? typesToString(typeArguments) : ""; - var instance = prototype.instances.get(instanceKey); - if (instance) return instance; + var classInstances = prototype.instances.get(classInstanceKey); + if (classInstances) { + let instance = classInstances.get(instanceKey); + if (instance) return instance; + } var declaration = prototype.declaration; var isInstance = prototype.is(CommonFlags.INSTANCE); @@ -734,7 +739,6 @@ export class Resolver extends DiagnosticEmitter { } // override with class type arguments if a partially resolved instance method - var classTypeArguments = prototype.classTypeArguments; if (classTypeArguments) { // set only if partially resolved assert(prototype.is(CommonFlags.INSTANCE)); let classDeclaration = assert(classPrototype).declaration; @@ -818,7 +822,7 @@ export class Resolver extends DiagnosticEmitter { var internalName = prototype.internalName; if (instanceKey.length) internalName += "<" + instanceKey + ">"; - instance = new Function( + var instance = new Function( prototype, internalName, signature, @@ -827,7 +831,8 @@ export class Resolver extends DiagnosticEmitter { : classPrototype, contextualTypeArguments ); - prototype.instances.set(instanceKey, instance); + if (!classInstances) prototype.instances.set(classInstanceKey, classInstances = new Map()); + classInstances.set(instanceKey, instance); this.program.instancesLookup.set(internalName, instance); return instance; } @@ -856,6 +861,7 @@ export class Resolver extends DiagnosticEmitter { partialPrototype.flags = prototype.flags; partialPrototype.operatorKind = prototype.operatorKind; partialPrototype.classTypeArguments = typeArguments; + partialPrototype.instances = prototype.instances; return partialPrototype; }