diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d5e5b5c67e4..261924dd9a4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2516,10 +2516,11 @@ module ts { } } - function getDeclaredTypeOfClass(symbol: Symbol): InterfaceType { + function getDeclaredTypeOfClassOrInterface(symbol: Symbol): InterfaceType { let links = getSymbolLinks(symbol); if (!links.declaredType) { - let type = links.declaredType = createObjectType(TypeFlags.Class, symbol); + let kind = symbol.flags & SymbolFlags.Class ? TypeFlags.Class : TypeFlags.Interface; + let type = links.declaredType = createObjectType(kind, symbol); let typeParameters = getTypeParametersOfClassOrInterface(symbol); if (typeParameters) { type.flags |= TypeFlags.Reference; @@ -2529,35 +2530,6 @@ module ts { (type).target = type; (type).typeArguments = type.typeParameters; } - - type.declaredProperties = getNamedMembers(symbol.members); - type.declaredCallSignatures = emptyArray; - type.declaredConstructSignatures = emptyArray; - type.declaredStringIndexType = getIndexTypeOfSymbol(symbol, IndexKind.String); - type.declaredNumberIndexType = getIndexTypeOfSymbol(symbol, IndexKind.Number); - } - return links.declaredType; - } - - function getDeclaredTypeOfInterface(symbol: Symbol): InterfaceType { - let links = getSymbolLinks(symbol); - if (!links.declaredType) { - let type = links.declaredType = createObjectType(TypeFlags.Interface, symbol); - let typeParameters = getTypeParametersOfClassOrInterface(symbol); - if (typeParameters) { - type.flags |= TypeFlags.Reference; - type.typeParameters = typeParameters; - (type).instantiations = {}; - (type).instantiations[getTypeListId(type.typeParameters)] = type; - (type).target = type; - (type).typeArguments = type.typeParameters; - } - - type.declaredProperties = getNamedMembers(symbol.members); - type.declaredCallSignatures = getSignaturesOfSymbol(symbol.members["__call"]); - type.declaredConstructSignatures = getSignaturesOfSymbol(symbol.members["__new"]); - type.declaredStringIndexType = getIndexTypeOfSymbol(symbol, IndexKind.String); - type.declaredNumberIndexType = getIndexTypeOfSymbol(symbol, IndexKind.Number); } return links.declaredType; } @@ -2613,11 +2585,8 @@ module ts { function getDeclaredTypeOfSymbol(symbol: Symbol): Type { Debug.assert((symbol.flags & SymbolFlags.Instantiated) === 0); - if (symbol.flags & SymbolFlags.Class) { - return getDeclaredTypeOfClass(symbol); - } - if (symbol.flags & SymbolFlags.Interface) { - return getDeclaredTypeOfInterface(symbol); + if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { + return getDeclaredTypeOfClassOrInterface(symbol); } if (symbol.flags & SymbolFlags.TypeAlias) { return getDeclaredTypeOfTypeAlias(symbol); @@ -2666,7 +2635,24 @@ module ts { } } + function getDeclaredPropertiesOfClassOrInterface(type: InterfaceType): Symbol[] { + resolveDeclaredMembers(type); + return type.declaredProperties; + } + + function resolveDeclaredMembers(type: InterfaceType) { + if (!type.declaredProperties) { + var symbol = type.symbol; + type.declaredProperties = getNamedMembers(symbol.members); + type.declaredCallSignatures = getSignaturesOfSymbol(symbol.members["__call"]); + type.declaredConstructSignatures = getSignaturesOfSymbol(symbol.members["__new"]); + type.declaredStringIndexType = getIndexTypeOfSymbol(symbol, IndexKind.String); + type.declaredNumberIndexType = getIndexTypeOfSymbol(symbol, IndexKind.Number); + } + } + function resolveClassOrInterfaceMembers(type: InterfaceType): void { + resolveDeclaredMembers(type); let members = type.symbol.members; let callSignatures = type.declaredCallSignatures; let constructSignatures = type.declaredConstructSignatures; @@ -2688,6 +2674,7 @@ module ts { function resolveTypeReferenceMembers(type: TypeReference): void { let target = type.target; + resolveDeclaredMembers(target); let mapper = createTypeMapper(target.typeParameters, type.typeArguments); let members = createInstantiatedSymbolTable(target.declaredProperties, mapper); let callSignatures = instantiateList(target.declaredCallSignatures, mapper, instantiateSignature); @@ -2843,7 +2830,7 @@ module ts { callSignatures = getSignaturesOfSymbol(symbol); } if (symbol.flags & SymbolFlags.Class) { - let classType = getDeclaredTypeOfClass(symbol); + let classType = getDeclaredTypeOfClassOrInterface(symbol); constructSignatures = getSignaturesOfSymbol(symbol.members["__constructor"]); if (!constructSignatures.length) { constructSignatures = getDefaultConstructSignatures(classType); @@ -3084,7 +3071,7 @@ module ts { function getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature { let links = getNodeLinks(declaration); if (!links.resolvedSignature) { - let classType = declaration.kind === SyntaxKind.Constructor ? getDeclaredTypeOfClass((declaration.parent).symbol) : undefined; + let classType = declaration.kind === SyntaxKind.Constructor ? getDeclaredTypeOfClassOrInterface((declaration.parent).symbol) : undefined; let typeParameters = classType ? classType.typeParameters : declaration.typeParameters ? getTypeParametersFromDeclaration(declaration.typeParameters) : undefined; let parameters: Symbol[] = []; @@ -10152,7 +10139,7 @@ module ts { } let seen: Map<{ prop: Symbol; containingType: Type }> = {}; - forEach(type.declaredProperties, p => { seen[p.name] = { prop: p, containingType: type }; }); + forEach(getDeclaredPropertiesOfClassOrInterface(type), p => { seen[p.name] = { prop: p, containingType: type }; }); let ok = true; for (let base of baseTypes) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index bff15a1ab9d..54f2e5e2bd4 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1485,11 +1485,11 @@ module ts { // Class and interface types (TypeFlags.Class and TypeFlags.Interface) export interface InterfaceType extends ObjectType { typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic) - declaredProperties: Symbol[]; // Declared members - declaredCallSignatures: Signature[]; // Declared call signatures - declaredConstructSignatures: Signature[]; // Declared construct signatures - declaredStringIndexType: Type; // Declared string index type - declaredNumberIndexType: Type; // Declared numeric index type + declaredProperties: Symbol[]; // Declared members (computed by resolveDeclaredMembers) + declaredCallSignatures: Signature[]; // Declared call signatures (computed by resolveDeclaredMembers) + declaredConstructSignatures: Signature[]; // Declared construct signatures (computed by resolveDeclaredMembers) + declaredStringIndexType: Type; // Declared string index type (computed by resolveDeclaredMembers) + declaredNumberIndexType: Type; // Declared numeric index type (computed by resolveDeclaredMembers) } export interface InterfaceTypeWithBaseTypes extends InterfaceType {