diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b2b44f98887..27e500bc3f8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4615,9 +4615,6 @@ namespace ts { result &= stringIndexTypesRelatedTo(source, target, reportErrors); if (result) { result &= numberIndexTypesRelatedTo(source, target, reportErrors); - // if(relation == subtypeRelation && result) { - // result &= abstractnessRelatedTo(source, target, reportErrors); - // } } } } @@ -4639,17 +4636,6 @@ namespace ts { return result; } - function abstractnessRelatedTo(source: ObjectType, target: ObjectType, reportErrors: boolean): Ternary { - if ( source.symbol && target.symbol && getDeclarationFlagsFromSymbol(source.symbol) & NodeFlags.Abstract && - !(getDeclarationFlagsFromSymbol(target.symbol) & NodeFlags.Abstract)) { - if (reportErrors) { - reportError(Diagnostics.Constructor_objects_of_abstract_type_cannot_be_assigned_to_constructor_objects_of_non_abstract_type); - } - return Ternary.False; - } - return Ternary.True; - } - function propertiesRelatedTo(source: ObjectType, target: ObjectType, reportErrors: boolean): Ternary { if (relation === identityRelation) { return propertiesIdenticalTo(source, target); @@ -7320,7 +7306,6 @@ namespace ts { return unknownType; } - // TODO: Why is this line here? getNodeLinks(node).resolvedSymbol = prop; if (prop.parent && prop.parent.flags & SymbolFlags.Class) { @@ -11609,16 +11594,18 @@ namespace ts { } checkClassLikeDeclaration(node); - forEach(node.members, node.flags & NodeFlags.Abstract ? - checkSourceElement : - element => { - checkSourceElement(element); + forEach(node.members, checkSourceElement); - // Classes containing abstract methods must be marked abstract - if (element.flags & NodeFlags.Abstract) { - error(node, Diagnostics.Classes_containing_abstract_methods_must_be_marked_abstract); - } - }); + // forEach(node.members, node.flags & NodeFlags.Abstract ? + // checkSourceElement : + // element => { + // checkSourceElement(element); + + // // Classes containing abstract methods must be marked abstract + // if (element.flags & NodeFlags.Abstract) { + // error(node, Diagnostics.Classes_containing_abstract_methods_must_be_marked_abstract); + // } + // }); } function checkClassLikeDeclaration(node: ClassLikeDeclaration) { @@ -11732,57 +11719,59 @@ namespace ts { Debug.assert(!!derived, "derived should point to something, even if it is the base class' declaration."); - if (derived === base) { - // derived class inherits base without override/redeclaration + if (derived) { + if (derived === base) { + // derived class inherits base without override/redeclaration - let derivedClassDecl = getDeclarationOfKind(type.symbol, SyntaxKind.ClassDeclaration); - Debug.assert(derivedClassDecl !== undefined); + let derivedClassDecl = getDeclarationOfKind(type.symbol, SyntaxKind.ClassDeclaration); + Debug.assert(derivedClassDecl !== undefined); - // It is an error to inherit an abstract member without implementing it or being declared abstract. - if ((baseDeclarationFlags & NodeFlags.Abstract) && !(derivedClassDecl.flags & NodeFlags.Abstract)) { - error(derivedClassDecl, Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2, - typeToString(type), symbolToString(baseProperty), typeToString(baseType)); - } - } - else { - // derived overrides base. - let derivedDeclarationFlags = getDeclarationFlagsFromSymbol(derived); - if ((baseDeclarationFlags & NodeFlags.Private) || (derivedDeclarationFlags & NodeFlags.Private)) { - // either base or derived property is private - not override, skip it - continue; + // It is an error to inherit an abstract member without implementing it or being declared abstract. + if ((baseDeclarationFlags & NodeFlags.Abstract) && !(derivedClassDecl.flags & NodeFlags.Abstract)) { + error(derivedClassDecl, Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2, + typeToString(type), symbolToString(baseProperty), typeToString(baseType)); + } } + else { + // derived overrides base. + let derivedDeclarationFlags = getDeclarationFlagsFromSymbol(derived); + if ((baseDeclarationFlags & NodeFlags.Private) || (derivedDeclarationFlags & NodeFlags.Private)) { + // either base or derived property is private - not override, skip it + continue; + } - if ((baseDeclarationFlags & NodeFlags.Static) !== (derivedDeclarationFlags & NodeFlags.Static)) { - // value of 'static' is not the same for properties - not override, skip it - continue; - } + if ((baseDeclarationFlags & NodeFlags.Static) !== (derivedDeclarationFlags & NodeFlags.Static)) { + // value of 'static' is not the same for properties - not override, skip it + continue; + } - if ((base.flags & derived.flags & SymbolFlags.Method) || ((base.flags & SymbolFlags.PropertyOrAccessor) && (derived.flags & SymbolFlags.PropertyOrAccessor))) { - // method is overridden with method or property/accessor is overridden with property/accessor - correct case - continue; - } + if ((base.flags & derived.flags & SymbolFlags.Method) || ((base.flags & SymbolFlags.PropertyOrAccessor) && (derived.flags & SymbolFlags.PropertyOrAccessor))) { + // method is overridden with method or property/accessor is overridden with property/accessor - correct case + continue; + } - let errorMessage: DiagnosticMessage; - if (base.flags & SymbolFlags.Method) { - if (derived.flags & SymbolFlags.Accessor) { - errorMessage = Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor; + let errorMessage: DiagnosticMessage; + if (base.flags & SymbolFlags.Method) { + if (derived.flags & SymbolFlags.Accessor) { + errorMessage = Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor; + } + else { + Debug.assert((derived.flags & SymbolFlags.Property) !== 0); + errorMessage = Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property; + } + } + else if (base.flags & SymbolFlags.Property) { + Debug.assert((derived.flags & SymbolFlags.Method) !== 0); + errorMessage = Diagnostics.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function; } else { - Debug.assert((derived.flags & SymbolFlags.Property) !== 0); - errorMessage = Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property; + Debug.assert((base.flags & SymbolFlags.Accessor) !== 0); + Debug.assert((derived.flags & SymbolFlags.Method) !== 0); + errorMessage = Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function; } - } - else if (base.flags & SymbolFlags.Property) { - Debug.assert((derived.flags & SymbolFlags.Method) !== 0); - errorMessage = Diagnostics.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function; - } - else { - Debug.assert((base.flags & SymbolFlags.Accessor) !== 0); - Debug.assert((derived.flags & SymbolFlags.Method) !== 0); - errorMessage = Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function; - } - error(derived.valueDeclaration.name, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type)); + error(derived.valueDeclaration.name, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type)); + } } } } @@ -13854,13 +13843,14 @@ namespace ts { if (!(node.parent.kind === SyntaxKind.ClassDeclaration && node.parent.flags & NodeFlags.Abstract)) { return grammarErrorOnNode(modifier, Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class); } + if (flags & NodeFlags.Static) { + return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract"); + } + if (flags & NodeFlags.Private) { + return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "private", "abstract"); + } } - if (flags & NodeFlags.Static) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract"); - } - if (flags & NodeFlags.Private) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "private", "abstract"); - } + flags |= NodeFlags.Abstract; break; } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 6ae06ba428f..ec4c777852b 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -62,9 +62,9 @@ namespace ts { export interface StringSet extends Map { } /** - * Iterates through 'array' by index and performs the callback on each element of array - * until the callback returns a truthy value, then returns that value. - * If no such value is found, the callback is applied to each element of array. + * Iterates through 'array' by index and performs the callback on each element of array until the callback + * returns a truthy value, then returns that value. + * If no such value is found, the callback is applied to each element of array and undefined is returned. */ export function forEach(array: T[], callback: (element: T, index: number) => U): U { if (array) { diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index d5109e40d56..b5da91f199d 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -387,7 +387,7 @@ namespace ts { Base_constructor_return_type_0_is_not_a_class_or_interface_type: { code: 2509, category: DiagnosticCategory.Error, key: "Base constructor return type '{0}' is not a class or interface type." }, Base_constructors_must_all_have_the_same_return_type: { code: 2510, category: DiagnosticCategory.Error, key: "Base constructors must all have the same return type." }, Cannot_create_an_instance_of_the_abstract_class_0: { code: 2511, category: DiagnosticCategory.Error, key: "Cannot create an instance of the abstract class '{0}'." }, - Overload_signatures_must_all_be_abstract_or_not_abstract: { code: 2512, category: DiagnosticCategory.Error, key: "Overload signatures must all be `abstract` or not `abstract." }, + Overload_signatures_must_all_be_abstract_or_not_abstract: { code: 2512, category: DiagnosticCategory.Error, key: "Overload signatures must all be abstract or not abstract." }, Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression: { code: 2513, category: DiagnosticCategory.Error, key: "Abstract method '{0}' in class '{1}' cannot be accessed via super expression." }, Classes_containing_abstract_methods_must_be_marked_abstract: { code: 2514, category: DiagnosticCategory.Error, key: "Classes containing abstract methods must be marked abstract." }, Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2: { code: 2515, category: DiagnosticCategory.Error, key: "Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 9bbd298c7cd..82d900056d1 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1535,7 +1535,7 @@ "category": "Error", "code": 2511 }, - "Overload signatures must all be `abstract` or not `abstract.": { + "Overload signatures must all be abstract or not abstract.": { "category": "Error", "code": 2512 },