@@ -161,6 +161,7 @@ namespace ts {
161
161
162
162
let resolutionTargets: Object[] = [];
163
163
let resolutionResults: boolean[] = [];
164
+ let resolutionKinds: TypeSystemObjectKind[] = [];
164
165
165
166
let mergedSymbols: Symbol[] = [];
166
167
let symbolLinks: SymbolLinks[] = [];
@@ -201,6 +202,13 @@ namespace ts {
201
202
let assignableRelation: Map<RelationComparisonResult> = {};
202
203
let identityRelation: Map<RelationComparisonResult> = {};
203
204
205
+ enum TypeSystemObjectKind {
206
+ Symbol,
207
+ Type,
208
+ SymbolLinks,
209
+ Signature
210
+ }
211
+
204
212
initializeTypeChecker();
205
213
206
214
return checker;
@@ -2184,13 +2192,14 @@ namespace ts {
2184
2192
// a unique identity for a particular type resolution result: Symbol instances are used to track resolution of
2185
2193
// SymbolLinks.type, SymbolLinks instances are used to track resolution of SymbolLinks.declaredType, and
2186
2194
// Signature instances are used to track resolution of Signature.resolvedReturnType.
2187
- function pushTypeResolution(target: Object): boolean {
2188
- let i = 0;
2195
+ function pushTypeResolution(target: Object, flags: TypeSystemObjectKind): boolean {
2189
2196
let count = resolutionTargets.length;
2190
- while (i < count && resolutionTargets[i] !== target) {
2191
- i++;
2197
+ let i = count - 1;
2198
+ let foundGoodType = false;
2199
+ while (i >= 0 && !(foundGoodType = !!hasType(resolutionTargets[i], resolutionKinds[i])) && resolutionTargets[i] !== target) {
2200
+ i--;
2192
2201
}
2193
- if (i < count ) {
2202
+ if (i >= 0 && !foundGoodType ) {
2194
2203
do {
2195
2204
resolutionResults[i++] = false;
2196
2205
}
@@ -2199,13 +2208,33 @@ namespace ts {
2199
2208
}
2200
2209
resolutionTargets.push(target);
2201
2210
resolutionResults.push(true);
2211
+ resolutionKinds.push(flags);
2202
2212
return true;
2203
2213
}
2204
2214
2215
+ function hasType(target: Object, flags: TypeSystemObjectKind): Type {
2216
+ if (flags === TypeSystemObjectKind.Symbol) {
2217
+ return getSymbolLinks(<Symbol>target).type;
2218
+ }
2219
+ else if (flags === TypeSystemObjectKind.Type) {
2220
+ Debug.assert(!!((<Type>target).flags & TypeFlags.Class));
2221
+ return (<InterfaceType>target).resolvedBaseConstructorType;
2222
+ }
2223
+ else if (flags === TypeSystemObjectKind.SymbolLinks) {
2224
+ return (<SymbolLinks>target).declaredType;
2225
+ }
2226
+ else if (flags === TypeSystemObjectKind.Signature) {
2227
+ return (<Signature>target).resolvedReturnType;
2228
+ }
2229
+
2230
+ Debug.fail("Unhandled TypeSystemObjectKind");
2231
+ }
2232
+
2205
2233
// Pop an entry from the type resolution stack and return its associated result value. The result value will
2206
2234
// be true if no circularities were detected, or false if a circularity was found.
2207
2235
function popTypeResolution(): boolean {
2208
2236
resolutionTargets.pop();
2237
+ resolutionKinds.pop();
2209
2238
return resolutionResults.pop();
2210
2239
}
2211
2240
@@ -2468,7 +2497,7 @@ namespace ts {
2468
2497
return links.type = checkExpression((<ExportAssignment>declaration).expression);
2469
2498
}
2470
2499
// Handle variable, parameter or property
2471
- if (!pushTypeResolution(symbol)) {
2500
+ if (!pushTypeResolution(symbol, TypeSystemObjectKind.Symbol )) {
2472
2501
return unknownType;
2473
2502
}
2474
2503
let type = getWidenedTypeForVariableLikeDeclaration(<VariableLikeDeclaration>declaration, /*reportErrors*/ true);
@@ -2509,7 +2538,7 @@ namespace ts {
2509
2538
function getTypeOfAccessors(symbol: Symbol): Type {
2510
2539
let links = getSymbolLinks(symbol);
2511
2540
if (!links.type) {
2512
- if (!pushTypeResolution(symbol)) {
2541
+ if (!pushTypeResolution(symbol, TypeSystemObjectKind.Symbol )) {
2513
2542
return unknownType;
2514
2543
}
2515
2544
let getter = <AccessorDeclaration>getDeclarationOfKind(symbol, SyntaxKind.GetAccessor);
@@ -2725,7 +2754,7 @@ namespace ts {
2725
2754
if (!baseTypeNode) {
2726
2755
return type.resolvedBaseConstructorType = undefinedType;
2727
2756
}
2728
- if (!pushTypeResolution(type)) {
2757
+ if (!pushTypeResolution(type, TypeSystemObjectKind.Type )) {
2729
2758
return unknownType;
2730
2759
}
2731
2760
let baseConstructorType = checkExpression(baseTypeNode.expression);
@@ -2852,7 +2881,7 @@ namespace ts {
2852
2881
if (!links.declaredType) {
2853
2882
// Note that we use the links object as the target here because the symbol object is used as the unique
2854
2883
// identity for resolution of the 'type' property in SymbolLinks.
2855
- if (!pushTypeResolution(links)) {
2884
+ if (!pushTypeResolution(links, TypeSystemObjectKind.SymbolLinks )) {
2856
2885
return unknownType;
2857
2886
}
2858
2887
let declaration = <TypeAliasDeclaration>getDeclarationOfKind(symbol, SyntaxKind.TypeAliasDeclaration);
@@ -3539,7 +3568,7 @@ namespace ts {
3539
3568
3540
3569
function getReturnTypeOfSignature(signature: Signature): Type {
3541
3570
if (!signature.resolvedReturnType) {
3542
- if (!pushTypeResolution(signature)) {
3571
+ if (!pushTypeResolution(signature, TypeSystemObjectKind.Signature )) {
3543
3572
return unknownType;
3544
3573
}
3545
3574
let type: Type;
0 commit comments