Defer resolution of declared members in classes and interfaces

This commit is contained in:
Anders Hejlsberg 2015-04-21 11:19:44 -07:00
parent 7f8e21b9b8
commit ed9dceb501
2 changed files with 31 additions and 44 deletions

View file

@ -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 = <InterfaceType>createObjectType(TypeFlags.Class, symbol);
let kind = symbol.flags & SymbolFlags.Class ? TypeFlags.Class : TypeFlags.Interface;
let type = links.declaredType = <InterfaceType>createObjectType(kind, symbol);
let typeParameters = getTypeParametersOfClassOrInterface(symbol);
if (typeParameters) {
type.flags |= TypeFlags.Reference;
@ -2529,35 +2530,6 @@ module ts {
(<GenericType>type).target = <GenericType>type;
(<GenericType>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 <InterfaceType>links.declaredType;
}
function getDeclaredTypeOfInterface(symbol: Symbol): InterfaceType {
let links = getSymbolLinks(symbol);
if (!links.declaredType) {
let type = links.declaredType = <InterfaceType>createObjectType(TypeFlags.Interface, symbol);
let typeParameters = getTypeParametersOfClassOrInterface(symbol);
if (typeParameters) {
type.flags |= TypeFlags.Reference;
type.typeParameters = typeParameters;
(<GenericType>type).instantiations = {};
(<GenericType>type).instantiations[getTypeListId(type.typeParameters)] = <GenericType>type;
(<GenericType>type).target = <GenericType>type;
(<GenericType>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 <InterfaceType>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((<ClassDeclaration>declaration.parent).symbol) : undefined;
let classType = declaration.kind === SyntaxKind.Constructor ? getDeclaredTypeOfClassOrInterface((<ClassDeclaration>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) {

View file

@ -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 {