@@ -6436,98 +6436,108 @@ namespace ts {
64366436 let classType = classDeclaration && <InterfaceType>getDeclaredTypeOfSymbol(getSymbolOfNode(classDeclaration));
64376437 let baseClassType = classType && getBaseTypes(classType)[0];
64386438
6439+ let container = getSuperContainer(node, /*includeFunctions*/ true);
6440+ let needToCaptureLexicalThis = false;
6441+
6442+ if (!isCallExpression) {
6443+ // adjust the container reference in case if super is used inside arrow functions with arbitrary deep nesting
6444+ while (container && container.kind === SyntaxKind.ArrowFunction) {
6445+ container = getSuperContainer(container, /*includeFunctions*/ true);
6446+ needToCaptureLexicalThis = languageVersion < ScriptTarget.ES6;
6447+ }
6448+ }
6449+
6450+ let canUseSuperExpression = isLegalUsageOfSuperExpression(container);
6451+ let nodeCheckFlag: NodeCheckFlags = 0;
6452+
6453+ // always set NodeCheckFlags for 'super' expression node
6454+ if (canUseSuperExpression) {
6455+ if ((container.flags & NodeFlags.Static) || isCallExpression) {
6456+ nodeCheckFlag = NodeCheckFlags.SuperStatic;
6457+ }
6458+ else {
6459+ nodeCheckFlag = NodeCheckFlags.SuperInstance;
6460+ }
6461+
6462+ getNodeLinks(node).flags |= nodeCheckFlag;
6463+
6464+ if (needToCaptureLexicalThis) {
6465+ // call expressions are allowed only in constructors so they should always capture correct 'this'
6466+ // super property access expressions can also appear in arrow functions -
6467+ // in this case they should also use correct lexical this
6468+ captureLexicalThis(node.parent, container);
6469+ }
6470+ }
6471+
64396472 if (!baseClassType) {
64406473 if (!classDeclaration || !getClassExtendsHeritageClauseElement(classDeclaration)) {
64416474 error(node, Diagnostics.super_can_only_be_referenced_in_a_derived_class);
64426475 }
6476+ return unknownType;
6477+ }
6478+
6479+ if (!canUseSuperExpression) {
6480+ if (container && container.kind === SyntaxKind.ComputedPropertyName) {
6481+ error(node, Diagnostics.super_cannot_be_referenced_in_a_computed_property_name);
6482+ }
6483+ else if (isCallExpression) {
6484+ error(node, Diagnostics.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors);
6485+ }
6486+ else {
6487+ error(node, Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class);
6488+ }
6489+
64436490 return unknownType;
64446491 }
6492+
6493+ if (container.kind === SyntaxKind.Constructor && isInConstructorArgumentInitializer(node, container)) {
6494+ // issue custom error message for super property access in constructor arguments (to be aligned with old compiler)
6495+ error(node, Diagnostics.super_cannot_be_referenced_in_constructor_arguments);
6496+ return unknownType;
6497+ }
6498+
6499+ return nodeCheckFlag === NodeCheckFlags.SuperStatic
6500+ ? getBaseConstructorTypeOfClass(classType)
6501+ : baseClassType;
6502+
6503+ function isLegalUsageOfSuperExpression(container: Node): boolean {
6504+ if (!container) {
6505+ return false;
6506+ }
64456507
6446- let container = getSuperContainer(node, /*includeFunctions*/ true);
6447-
6448- if (container) {
6449- let canUseSuperExpression = false;
6450- let needToCaptureLexicalThis: boolean;
64516508 if (isCallExpression) {
64526509 // TS 1.0 SPEC (April 2014): 4.8.1
64536510 // Super calls are only permitted in constructors of derived classes
6454- canUseSuperExpression = container.kind === SyntaxKind.Constructor;
6511+ return container.kind === SyntaxKind.Constructor;
64556512 }
64566513 else {
64576514 // TS 1.0 SPEC (April 2014)
64586515 // 'super' property access is allowed
64596516 // - In a constructor, instance member function, instance member accessor, or instance member variable initializer where this references a derived class instance
64606517 // - In a static member function or static member accessor
64616518
6462- // super property access might appear in arrow functions with arbitrary deep nesting
6463- needToCaptureLexicalThis = false;
6464- while (container && container.kind === SyntaxKind.ArrowFunction) {
6465- container = getSuperContainer(container, /*includeFunctions*/ true);
6466- needToCaptureLexicalThis = languageVersion < ScriptTarget.ES6;
6467- }
6468-
64696519 // topmost container must be something that is directly nested in the class declaration
64706520 if (container && isClassLike(container.parent)) {
64716521 if (container.flags & NodeFlags.Static) {
6472- canUseSuperExpression =
6473- container.kind === SyntaxKind.MethodDeclaration ||
6474- container.kind === SyntaxKind.MethodSignature ||
6475- container.kind === SyntaxKind.GetAccessor ||
6476- container.kind === SyntaxKind.SetAccessor;
6522+ return container.kind === SyntaxKind.MethodDeclaration ||
6523+ container.kind === SyntaxKind.MethodSignature ||
6524+ container.kind === SyntaxKind.GetAccessor ||
6525+ container.kind === SyntaxKind.SetAccessor;
64776526 }
64786527 else {
6479- canUseSuperExpression =
6480- container.kind === SyntaxKind.MethodDeclaration ||
6481- container.kind === SyntaxKind.MethodSignature ||
6482- container.kind === SyntaxKind.GetAccessor ||
6483- container.kind === SyntaxKind.SetAccessor ||
6484- container.kind === SyntaxKind.PropertyDeclaration ||
6485- container.kind === SyntaxKind.PropertySignature ||
6486- container.kind === SyntaxKind.Constructor;
6528+ return container.kind === SyntaxKind.MethodDeclaration ||
6529+ container.kind === SyntaxKind.MethodSignature ||
6530+ container.kind === SyntaxKind.GetAccessor ||
6531+ container.kind === SyntaxKind.SetAccessor ||
6532+ container.kind === SyntaxKind.PropertyDeclaration ||
6533+ container.kind === SyntaxKind.PropertySignature ||
6534+ container.kind === SyntaxKind.Constructor;
64876535 }
64886536 }
64896537 }
6490-
6491- if (canUseSuperExpression) {
6492- let returnType: Type;
6493-
6494- if ((container.flags & NodeFlags.Static) || isCallExpression) {
6495- getNodeLinks(node).flags |= NodeCheckFlags.SuperStatic;
6496- returnType = getBaseConstructorTypeOfClass(classType);
6497- }
6498- else {
6499- getNodeLinks(node).flags |= NodeCheckFlags.SuperInstance;
6500- returnType = baseClassType;
6501- }
6502-
6503- if (container.kind === SyntaxKind.Constructor && isInConstructorArgumentInitializer(node, container)) {
6504- // issue custom error message for super property access in constructor arguments (to be aligned with old compiler)
6505- error(node, Diagnostics.super_cannot_be_referenced_in_constructor_arguments);
6506- returnType = unknownType;
6507- }
6508-
6509- if (!isCallExpression && needToCaptureLexicalThis) {
6510- // call expressions are allowed only in constructors so they should always capture correct 'this'
6511- // super property access expressions can also appear in arrow functions -
6512- // in this case they should also use correct lexical this
6513- captureLexicalThis(node.parent, container);
6514- }
6515-
6516- return returnType;
6517- }
6518- }
6519-
6520- if (container && container.kind === SyntaxKind.ComputedPropertyName) {
6521- error(node, Diagnostics.super_cannot_be_referenced_in_a_computed_property_name);
6522- }
6523- else if (isCallExpression) {
6524- error(node, Diagnostics.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors);
6525- }
6526- else {
6527- error(node, Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class);
6528- }
6529-
6530- return unknownType;
6538+
6539+ return false;
6540+ }
65316541 }
65326542
65336543 // Return contextual type of parameter or undefined if no contextual type is available
0 commit comments