Clean up pushTypeResolution
This commit is contained in:
parent
c0b3835b19
commit
3b78377cf0
2 changed files with 53 additions and 38 deletions
|
@ -159,9 +159,9 @@ namespace ts {
|
||||||
let emitAwaiter = false;
|
let emitAwaiter = false;
|
||||||
let emitGenerator = false;
|
let emitGenerator = false;
|
||||||
|
|
||||||
let resolutionTargets: Object[] = [];
|
let resolutionTargets: TypeSystemEntity[] = [];
|
||||||
let resolutionResults: boolean[] = [];
|
let resolutionResults: boolean[] = [];
|
||||||
let resolutionKinds: TypeSystemObjectKind[] = [];
|
let resolutionPropertyNames: TypeSystemPropertyName[] = [];
|
||||||
|
|
||||||
let mergedSymbols: Symbol[] = [];
|
let mergedSymbols: Symbol[] = [];
|
||||||
let symbolLinks: SymbolLinks[] = [];
|
let symbolLinks: SymbolLinks[] = [];
|
||||||
|
@ -202,11 +202,11 @@ namespace ts {
|
||||||
let assignableRelation: Map<RelationComparisonResult> = {};
|
let assignableRelation: Map<RelationComparisonResult> = {};
|
||||||
let identityRelation: Map<RelationComparisonResult> = {};
|
let identityRelation: Map<RelationComparisonResult> = {};
|
||||||
|
|
||||||
enum TypeSystemObjectKind {
|
enum TypeSystemPropertyName {
|
||||||
Symbol,
|
|
||||||
Type,
|
Type,
|
||||||
SymbolLinks,
|
ResolvedBaseConstructorType,
|
||||||
Signature
|
DeclaredType,
|
||||||
|
ResolvedReturnType
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeTypeChecker();
|
initializeTypeChecker();
|
||||||
|
@ -2185,45 +2185,58 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push an entry on the type resolution stack. If an entry with the given target is not already on the stack,
|
/**
|
||||||
// a new entry with that target and an associated result value of true is pushed on the stack, and the value
|
* Push an entry on the type resolution stack. If an entry with the given target and the given property name
|
||||||
// true is returned. Otherwise, a circularity has occurred and the result values of the existing entry and
|
* is already on the stack, and no entries in between already have a type, then a circularity has occurred.
|
||||||
// all entries pushed after it are changed to false, and the value false is returned. The target object provides
|
* In this case, the result values of the existing entry and all entries pushed after it are changed to false,
|
||||||
// a unique identity for a particular type resolution result: Symbol instances are used to track resolution of
|
* and the value false is returned. Otherwise, the new entry is just pushed onto the stack, and true is returned.
|
||||||
// SymbolLinks.type, SymbolLinks instances are used to track resolution of SymbolLinks.declaredType, and
|
* In order to see if the same query has already been done before, the target object and the propertyName both
|
||||||
// Signature instances are used to track resolution of Signature.resolvedReturnType.
|
* must match the one passed in.
|
||||||
function pushTypeResolution(target: Object, flags: TypeSystemObjectKind): boolean {
|
*
|
||||||
let count = resolutionTargets.length;
|
* @param target The symbol, type, or signature whose type is being queried
|
||||||
let i = count - 1;
|
* @param propertyName The property name that should be used to query the target for its type
|
||||||
let foundGoodType = false;
|
*/
|
||||||
while (i >= 0 && !(foundGoodType = !!hasType(resolutionTargets[i], resolutionKinds[i])) && resolutionTargets[i] !== target) {
|
function pushTypeResolution(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): boolean {
|
||||||
i--;
|
let resolutionCycleStartIndex = findResolutionCycleStartIndex(target, propertyName);
|
||||||
}
|
if (resolutionCycleStartIndex >= 0) {
|
||||||
if (i >= 0 && !foundGoodType) {
|
// A cycle was found
|
||||||
do {
|
let { length } = resolutionTargets;
|
||||||
resolutionResults[i++] = false;
|
for (let i = resolutionCycleStartIndex; i < length; i++) {
|
||||||
|
resolutionResults[i] = false;
|
||||||
}
|
}
|
||||||
while (i < count);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
resolutionTargets.push(target);
|
resolutionTargets.push(target);
|
||||||
resolutionResults.push(true);
|
resolutionResults.push(true);
|
||||||
resolutionKinds.push(flags);
|
resolutionPropertyNames.push(propertyName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasType(target: Object, flags: TypeSystemObjectKind): Type {
|
function findResolutionCycleStartIndex(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): number {
|
||||||
if (flags === TypeSystemObjectKind.Symbol) {
|
for (let i = resolutionTargets.length - 1; i >= 0; i--) {
|
||||||
|
if (hasType(resolutionTargets[i], resolutionPropertyNames[i])) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (resolutionTargets[i] === target && resolutionPropertyNames[i] === propertyName) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasType(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): Type {
|
||||||
|
if (propertyName === TypeSystemPropertyName.Type) {
|
||||||
return getSymbolLinks(<Symbol>target).type;
|
return getSymbolLinks(<Symbol>target).type;
|
||||||
}
|
}
|
||||||
else if (flags === TypeSystemObjectKind.Type) {
|
else if (propertyName === TypeSystemPropertyName.DeclaredType) {
|
||||||
|
return getSymbolLinks(<Symbol>target).declaredType;
|
||||||
|
}
|
||||||
|
else if (propertyName === TypeSystemPropertyName.ResolvedBaseConstructorType) {
|
||||||
Debug.assert(!!((<Type>target).flags & TypeFlags.Class));
|
Debug.assert(!!((<Type>target).flags & TypeFlags.Class));
|
||||||
return (<InterfaceType>target).resolvedBaseConstructorType;
|
return (<InterfaceType>target).resolvedBaseConstructorType;
|
||||||
}
|
}
|
||||||
else if (flags === TypeSystemObjectKind.SymbolLinks) {
|
else if (propertyName === TypeSystemPropertyName.ResolvedReturnType) {
|
||||||
return (<SymbolLinks>target).declaredType;
|
|
||||||
}
|
|
||||||
else if (flags === TypeSystemObjectKind.Signature) {
|
|
||||||
return (<Signature>target).resolvedReturnType;
|
return (<Signature>target).resolvedReturnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2234,7 +2247,7 @@ namespace ts {
|
||||||
// be true if no circularities were detected, or false if a circularity was found.
|
// be true if no circularities were detected, or false if a circularity was found.
|
||||||
function popTypeResolution(): boolean {
|
function popTypeResolution(): boolean {
|
||||||
resolutionTargets.pop();
|
resolutionTargets.pop();
|
||||||
resolutionKinds.pop();
|
resolutionPropertyNames.pop();
|
||||||
return resolutionResults.pop();
|
return resolutionResults.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2497,7 +2510,7 @@ namespace ts {
|
||||||
return links.type = checkExpression((<ExportAssignment>declaration).expression);
|
return links.type = checkExpression((<ExportAssignment>declaration).expression);
|
||||||
}
|
}
|
||||||
// Handle variable, parameter or property
|
// Handle variable, parameter or property
|
||||||
if (!pushTypeResolution(symbol, TypeSystemObjectKind.Symbol)) {
|
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
|
||||||
return unknownType;
|
return unknownType;
|
||||||
}
|
}
|
||||||
let type = getWidenedTypeForVariableLikeDeclaration(<VariableLikeDeclaration>declaration, /*reportErrors*/ true);
|
let type = getWidenedTypeForVariableLikeDeclaration(<VariableLikeDeclaration>declaration, /*reportErrors*/ true);
|
||||||
|
@ -2538,7 +2551,7 @@ namespace ts {
|
||||||
function getTypeOfAccessors(symbol: Symbol): Type {
|
function getTypeOfAccessors(symbol: Symbol): Type {
|
||||||
let links = getSymbolLinks(symbol);
|
let links = getSymbolLinks(symbol);
|
||||||
if (!links.type) {
|
if (!links.type) {
|
||||||
if (!pushTypeResolution(symbol, TypeSystemObjectKind.Symbol)) {
|
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
|
||||||
return unknownType;
|
return unknownType;
|
||||||
}
|
}
|
||||||
let getter = <AccessorDeclaration>getDeclarationOfKind(symbol, SyntaxKind.GetAccessor);
|
let getter = <AccessorDeclaration>getDeclarationOfKind(symbol, SyntaxKind.GetAccessor);
|
||||||
|
@ -2754,7 +2767,7 @@ namespace ts {
|
||||||
if (!baseTypeNode) {
|
if (!baseTypeNode) {
|
||||||
return type.resolvedBaseConstructorType = undefinedType;
|
return type.resolvedBaseConstructorType = undefinedType;
|
||||||
}
|
}
|
||||||
if (!pushTypeResolution(type, TypeSystemObjectKind.Type)) {
|
if (!pushTypeResolution(type, TypeSystemPropertyName.ResolvedBaseConstructorType)) {
|
||||||
return unknownType;
|
return unknownType;
|
||||||
}
|
}
|
||||||
let baseConstructorType = checkExpression(baseTypeNode.expression);
|
let baseConstructorType = checkExpression(baseTypeNode.expression);
|
||||||
|
@ -2881,7 +2894,7 @@ namespace ts {
|
||||||
if (!links.declaredType) {
|
if (!links.declaredType) {
|
||||||
// Note that we use the links object as the target here because the symbol object is used as the unique
|
// Note that we use the links object as the target here because the symbol object is used as the unique
|
||||||
// identity for resolution of the 'type' property in SymbolLinks.
|
// identity for resolution of the 'type' property in SymbolLinks.
|
||||||
if (!pushTypeResolution(links, TypeSystemObjectKind.SymbolLinks)) {
|
if (!pushTypeResolution(symbol, TypeSystemPropertyName.DeclaredType)) {
|
||||||
return unknownType;
|
return unknownType;
|
||||||
}
|
}
|
||||||
let declaration = <TypeAliasDeclaration>getDeclarationOfKind(symbol, SyntaxKind.TypeAliasDeclaration);
|
let declaration = <TypeAliasDeclaration>getDeclarationOfKind(symbol, SyntaxKind.TypeAliasDeclaration);
|
||||||
|
@ -3568,7 +3581,7 @@ namespace ts {
|
||||||
|
|
||||||
function getReturnTypeOfSignature(signature: Signature): Type {
|
function getReturnTypeOfSignature(signature: Signature): Type {
|
||||||
if (!signature.resolvedReturnType) {
|
if (!signature.resolvedReturnType) {
|
||||||
if (!pushTypeResolution(signature, TypeSystemObjectKind.Signature)) {
|
if (!pushTypeResolution(signature, TypeSystemPropertyName.ResolvedReturnType)) {
|
||||||
return unknownType;
|
return unknownType;
|
||||||
}
|
}
|
||||||
let type: Type;
|
let type: Type;
|
||||||
|
|
|
@ -1904,6 +1904,8 @@ namespace ts {
|
||||||
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
|
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type TypeSystemEntity = Symbol | Type | Signature;
|
||||||
|
|
||||||
export const enum IndexKind {
|
export const enum IndexKind {
|
||||||
String,
|
String,
|
||||||
Number,
|
Number,
|
||||||
|
|
Loading…
Reference in a new issue