From 58cbf9171191ad2b0e4ac1ac6eb23e86fa7185ec Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 16 Jul 2015 13:41:19 -0700 Subject: [PATCH] Add check for super when extending null --- src/compiler/checker.ts | 12 +++++++++--- src/compiler/diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 ++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f8bafa7a38f..634d64516a4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10248,19 +10248,25 @@ namespace ts { // TS 1.0 spec (April 2014): 8.3.2 // Constructors of classes with no extends clause may not contain super calls, whereas // constructors of derived classes must contain at least one super call somewhere in their function body. - if (getClassExtendsHeritageClauseElement(node.parent)) { + let containingClassDecl = node.parent; + if (getClassExtendsHeritageClauseElement(containingClassDecl)) { + let baseConstructorType = getBaseConstructorTypeOfClass(containingClassDecl); if (containsSuperCall(node.body)) { + if (baseConstructorType === nullType) { + error(node, Diagnostics.A_constructor_can_not_contain_super_call_when_a_class_extends_null); + } + // The first statement in the body of a constructor must be a super call if both of the following are true: // - The containing class is a derived class. // - The constructor declares parameter properties // or the containing class declares instance member variables with initializers. + let statements = (node.body).statements; let superCallShouldBeFirst = forEach((node.parent).members, isInstancePropertyWithInitializer) || forEach(node.parameters, p => p.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected)); if (superCallShouldBeFirst) { - let statements = (node.body).statements; if (!statements.length || statements[0].kind !== SyntaxKind.ExpressionStatement || !isSuperCallExpression((statements[0]).expression)) { error(node, Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties); } @@ -10270,7 +10276,7 @@ namespace ts { } } } - else { + else if (baseConstructorType !== nullType) { error(node, Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call); } } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index a0a95d47c8c..80698217a4b 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -613,5 +613,6 @@ namespace ts { Expected_corresponding_JSX_closing_tag_for_0: { code: 17002, category: DiagnosticCategory.Error, key: "Expected corresponding JSX closing tag for '{0}'." }, JSX_attribute_expected: { code: 17003, category: DiagnosticCategory.Error, key: "JSX attribute expected." }, Cannot_use_JSX_unless_the_jsx_flag_is_provided: { code: 17004, category: DiagnosticCategory.Error, key: "Cannot use JSX unless the '--jsx' flag is provided." }, + A_constructor_can_not_contain_super_call_when_a_class_extends_null: { code: 17005, category: DiagnosticCategory.Error, key: "A constructor can not contain super call when a class extends null" }, }; } \ No newline at end of file diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index acf4e74ae9f..6f1185eb250 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2445,5 +2445,9 @@ "Cannot use JSX unless the '--jsx' flag is provided.": { "category": "Error", "code": 17004 + }, + "A constructor can not contain super call when a class extends null": { + "category": "Error", + "code": 17005 } }