Merge pull request #550 from Microsoft/deferredTypeLiterals

Deferred resolution of object literal members to support recursive types.
This commit is contained in:
Anders Hejlsberg 2014-09-03 11:03:24 -07:00
commit dab3691af6
4 changed files with 38 additions and 29 deletions

View file

@ -1801,27 +1801,39 @@ module ts {
function resolveAnonymousTypeMembers(type: ObjectType) {
var symbol = type.symbol;
var members = emptySymbols;
var callSignatures = emptyArray;
var constructSignatures = emptyArray;
if (symbol.flags & SymbolFlags.HasExports) {
members = symbol.exports;
if (symbol.flags & SymbolFlags.TypeLiteral) {
var members = symbol.members;
var callSignatures = getSignaturesOfSymbol(members["__call"]);
var constructSignatures = getSignaturesOfSymbol(members["__new"]);
var stringIndexType = getIndexTypeOfSymbol(symbol, IndexKind.String);
var numberIndexType = getIndexTypeOfSymbol(symbol, IndexKind.Number);
}
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) {
callSignatures = getSignaturesOfSymbol(symbol);
}
if (symbol.flags & SymbolFlags.Class) {
var classType = getDeclaredTypeOfClass(symbol);
constructSignatures = getSignaturesOfSymbol(symbol.members["__constructor"]);
if (!constructSignatures.length) constructSignatures = getDefaultConstructSignatures(classType);
if (classType.baseTypes.length) {
var members = createSymbolTable(getNamedMembers(members));
addInheritedMembers(members, getPropertiesOfType(getTypeOfSymbol(classType.baseTypes[0].symbol)));
else {
// Combinations of function, class, enum and module
var members = emptySymbols;
var callSignatures: Signature[] = emptyArray;
var constructSignatures: Signature[] = emptyArray;
if (symbol.flags & SymbolFlags.HasExports) {
members = symbol.exports;
}
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) {
callSignatures = getSignaturesOfSymbol(symbol);
}
if (symbol.flags & SymbolFlags.Class) {
var classType = getDeclaredTypeOfClass(symbol);
constructSignatures = getSignaturesOfSymbol(symbol.members["__constructor"]);
if (!constructSignatures.length) {
constructSignatures = getDefaultConstructSignatures(classType);
}
if (classType.baseTypes.length) {
members = createSymbolTable(getNamedMembers(members));
addInheritedMembers(members, getPropertiesOfType(getTypeOfSymbol(classType.baseTypes[0].symbol)));
}
}
var stringIndexType: Type = undefined;
var numberIndexType: Type = (symbol.flags & SymbolFlags.Enum) ? stringType : undefined;
}
var numberIndexType = (symbol.flags & SymbolFlags.Enum) ? stringType : undefined;
setObjectTypeMembers(type, members, callSignatures, constructSignatures, /* stringIndexType */ undefined, numberIndexType);
setObjectTypeMembers(type, members, callSignatures, constructSignatures, stringIndexType, numberIndexType);
}
function resolveObjectTypeMembers(type: ObjectType): ResolvedObjectType {
@ -2276,13 +2288,8 @@ module ts {
function getTypeFromTypeLiteralNode(node: TypeLiteralNode): Type {
var links = getNodeLinks(node);
if (!links.resolvedType) {
var symbol = node.symbol;
var members = symbol.members;
var callSignatures = getSignaturesOfSymbol(members["__call"]);
var constructSignatures = getSignaturesOfSymbol(members["__new"]);
var stringIndexType = getIndexTypeOfSymbol(symbol, IndexKind.String);
var numberIndexType = getIndexTypeOfSymbol(symbol, IndexKind.Number);
links.resolvedType = createAnonymousType(symbol, members, callSignatures, constructSignatures, stringIndexType, numberIndexType);
// Deferred resolution of members is handled by resolveObjectTypeMembers
links.resolvedType = createObjectType(TypeFlags.Anonymous, node.symbol);
}
return links.resolvedType;
}

View file

@ -68,7 +68,7 @@ declare function f(n: typeof f): string;
declare function f(n: typeof g): string;
declare function g(n: typeof g): number;
declare function g(n: typeof f): number;
declare var b: any;
declare var b: () => any;
declare function b1(): typeof b1;
declare function foo(): typeof foo;
declare var foo1: typeof foo;

View file

@ -29,8 +29,8 @@ function g() { return undefined; }
>undefined : undefined
var b: () => typeof b;
>b : any
>b : any
>b : () => any
>b : () => any
function b1() {
>b1 : () => typeof b1

View file

@ -1,4 +1,4 @@
==== tests/cases/compiler/recursiveFunctionTypes.ts (12 errors) ====
==== tests/cases/compiler/recursiveFunctionTypes.ts (13 errors) ====
function fn(): typeof fn { return 1; }
~
!!! Type 'number' is not assignable to type '() => typeof fn'.
@ -39,6 +39,8 @@
var f4: () => typeof f4;
f4 = 3; // error
~~
!!! Type 'number' is not assignable to type '() => any'.
function f5() { return f5; }