Skip to content

Commit de8eb22

Browse files
committed
Adding comments and doing a bit of renaming
1 parent d09d61f commit de8eb22

File tree

2 files changed

+31
-22
lines changed

2 files changed

+31
-22
lines changed

src/compiler/checker.ts

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2623,11 +2623,16 @@ module ts {
26232623
return signatures;
26242624
}
26252625

2626+
// The base constructor of a class can resolve to
2627+
// undefinedType if the class has no extends clause,
2628+
// unknownType if an error occurred during resolution of the extends expression,
2629+
// nullType if the extends expression is the null value, or
2630+
// an object type with at least one construct signature.
26262631
function getBaseConstructorTypeOfClass(type: InterfaceType): ObjectType {
2627-
if (!type.baseConstructorType) {
2632+
if (!type.resolvedBaseConstructorType) {
26282633
let baseTypeNode = getBaseTypeNodeOfClass(type);
26292634
if (!baseTypeNode) {
2630-
return type.baseConstructorType = undefinedType;
2635+
return type.resolvedBaseConstructorType = undefinedType;
26312636
}
26322637
if (!pushTypeResolution(type)) {
26332638
return unknownType;
@@ -2639,45 +2644,50 @@ module ts {
26392644
}
26402645
if (!popTypeResolution()) {
26412646
error(type.symbol.valueDeclaration, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, symbolToString(type.symbol));
2642-
return type.baseConstructorType = unknownType;
2647+
return type.resolvedBaseConstructorType = unknownType;
26432648
}
26442649
if (baseConstructorType !== unknownType && baseConstructorType !== nullType && !isConstructorType(baseConstructorType)) {
26452650
error(baseTypeNode.expression, Diagnostics.Base_expression_is_not_of_a_constructor_function_type);
2646-
return type.baseConstructorType = unknownType;
2651+
return type.resolvedBaseConstructorType = unknownType;
26472652
}
2648-
type.baseConstructorType = baseConstructorType;
2653+
type.resolvedBaseConstructorType = baseConstructorType;
26492654
}
2650-
return type.baseConstructorType;
2655+
return type.resolvedBaseConstructorType;
26512656
}
26522657

26532658
function getBaseTypes(type: InterfaceType): ObjectType[] {
2654-
let typeWithBaseTypes = <InterfaceTypeWithBaseTypes>type;
2655-
if (!typeWithBaseTypes.baseTypes) {
2659+
if (!type.resolvedBaseTypes) {
26562660
if (type.symbol.flags & SymbolFlags.Class) {
2657-
resolveBaseTypesOfClass(typeWithBaseTypes);
2661+
resolveBaseTypesOfClass(type);
26582662
}
26592663
else if (type.symbol.flags & SymbolFlags.Interface) {
2660-
resolveBaseTypesOfInterface(typeWithBaseTypes);
2664+
resolveBaseTypesOfInterface(type);
26612665
}
26622666
else {
26632667
Debug.fail("type must be class or interface");
26642668
}
26652669
}
2666-
return typeWithBaseTypes.baseTypes;
2670+
return type.resolvedBaseTypes;
26672671
}
26682672

2669-
function resolveBaseTypesOfClass(type: InterfaceTypeWithBaseTypes): void {
2670-
type.baseTypes = emptyArray;
2673+
function resolveBaseTypesOfClass(type: InterfaceType): void {
2674+
type.resolvedBaseTypes = emptyArray;
26712675
let baseContructorType = getBaseConstructorTypeOfClass(type);
26722676
if (!(baseContructorType.flags & TypeFlags.ObjectType)) {
26732677
return;
26742678
}
26752679
let baseTypeNode = getBaseTypeNodeOfClass(type);
26762680
let baseType: Type;
26772681
if (baseContructorType.symbol && baseContructorType.symbol.flags & SymbolFlags.Class) {
2682+
// When base constructor type is a class we know that the constructors all have the same type parameters as the
2683+
// class and all return the instance type of the class. There is no need for further checks and we can apply the
2684+
// type arguments in the same manner as a type reference to get the same error reporting experience.
26782685
baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseContructorType.symbol);
26792686
}
26802687
else {
2688+
// The class derives from a "class-like" constructor function, check that we have at least one construct signature
2689+
// with a matching number of type parameters and use the return type of the first instantiated signature. Elsewhere
2690+
// we check that all instantiated signatures return the same type.
26812691
let constructors = getInstantiatedConstructorsForTypeArguments(baseContructorType, baseTypeNode.typeArguments);
26822692
if (!constructors.length) {
26832693
error(baseTypeNode.expression, Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments);
@@ -2697,19 +2707,19 @@ module ts {
26972707
typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType));
26982708
return;
26992709
}
2700-
type.baseTypes = [baseType];
2710+
type.resolvedBaseTypes = [baseType];
27012711
}
27022712

2703-
function resolveBaseTypesOfInterface(type: InterfaceTypeWithBaseTypes): void {
2704-
type.baseTypes = [];
2713+
function resolveBaseTypesOfInterface(type: InterfaceType): void {
2714+
type.resolvedBaseTypes = [];
27052715
for (let declaration of type.symbol.declarations) {
27062716
if (declaration.kind === SyntaxKind.InterfaceDeclaration && getInterfaceBaseTypeNodes(<InterfaceDeclaration>declaration)) {
27072717
for (let node of getInterfaceBaseTypeNodes(<InterfaceDeclaration>declaration)) {
27082718
let baseType = getTypeFromTypeNode(node);
27092719
if (baseType !== unknownType) {
27102720
if (getTargetType(baseType).flags & (TypeFlags.Class | TypeFlags.Interface)) {
27112721
if (type !== baseType && !hasBaseType(<InterfaceType>baseType, type)) {
2712-
type.baseTypes.push(baseType);
2722+
type.resolvedBaseTypes.push(baseType);
27132723
}
27142724
else {
27152725
error(declaration, Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType));
@@ -7421,6 +7431,8 @@ module ts {
74217431
if (node.expression.kind === SyntaxKind.SuperKeyword) {
74227432
let superType = checkSuperExpression(node.expression);
74237433
if (superType !== unknownType) {
7434+
// In super call, the candidate signatures are the matching arity signatures of the base constructor function instantiated
7435+
// with the type arguments specified in the extends clause.
74247436
let baseTypeNode = getClassExtendsHeritageClauseElement(<ClassDeclaration>getAncestor(node, SyntaxKind.ClassDeclaration));
74257437
let baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments);
74267438
return resolveCall(node, baseConstructors, candidatesOutArray);

src/compiler/types.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1660,11 +1660,8 @@ module ts {
16601660
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
16611661
outerTypeParameters: TypeParameter[]; // Outer type parameters (undefined if none)
16621662
localTypeParameters: TypeParameter[]; // Local type parameters (undefined if none)
1663-
baseConstructorType?: Type; // Base constructor type of class
1664-
}
1665-
1666-
export interface InterfaceTypeWithBaseTypes extends InterfaceType {
1667-
baseTypes: ObjectType[];
1663+
resolvedBaseConstructorType?: Type; // Resolved base constructor type of class
1664+
resolvedBaseTypes: ObjectType[]; // Resolved base types
16681665
}
16691666

16701667
export interface InterfaceTypeWithDeclaredMembers extends InterfaceType {

0 commit comments

Comments
 (0)