@@ -6436,98 +6436,108 @@ namespace ts {
6436
6436
let classType = classDeclaration && <InterfaceType>getDeclaredTypeOfSymbol(getSymbolOfNode(classDeclaration));
6437
6437
let baseClassType = classType && getBaseTypes(classType)[0];
6438
6438
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
+
6439
6472
if (!baseClassType) {
6440
6473
if (!classDeclaration || !getClassExtendsHeritageClauseElement(classDeclaration)) {
6441
6474
error(node, Diagnostics.super_can_only_be_referenced_in_a_derived_class);
6442
6475
}
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
+
6443
6490
return unknownType;
6444
6491
}
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
+ }
6445
6507
6446
- let container = getSuperContainer(node, /*includeFunctions*/ true);
6447
-
6448
- if (container) {
6449
- let canUseSuperExpression = false;
6450
- let needToCaptureLexicalThis: boolean;
6451
6508
if (isCallExpression) {
6452
6509
// TS 1.0 SPEC (April 2014): 4.8.1
6453
6510
// Super calls are only permitted in constructors of derived classes
6454
- canUseSuperExpression = container.kind === SyntaxKind.Constructor;
6511
+ return container.kind === SyntaxKind.Constructor;
6455
6512
}
6456
6513
else {
6457
6514
// TS 1.0 SPEC (April 2014)
6458
6515
// 'super' property access is allowed
6459
6516
// - In a constructor, instance member function, instance member accessor, or instance member variable initializer where this references a derived class instance
6460
6517
// - In a static member function or static member accessor
6461
6518
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
-
6469
6519
// topmost container must be something that is directly nested in the class declaration
6470
6520
if (container && isClassLike(container.parent)) {
6471
6521
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;
6477
6526
}
6478
6527
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;
6487
6535
}
6488
6536
}
6489
6537
}
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
+ }
6531
6541
}
6532
6542
6533
6543
// Return contextual type of parameter or undefined if no contextual type is available
0 commit comments