(node)
| 80481 | ts.forEachChild(node, checkSourceElement); |
| 80482 | } |
| 80483 | function checkConstructorDeclaration(node) { |
| 80484 | // Grammar check on signature of constructor and modifier of the constructor is done in checkSignatureDeclaration function. |
| 80485 | checkSignatureDeclaration(node); |
| 80486 | // Grammar check for checking only related to constructorDeclaration |
| 80487 | if (!checkGrammarConstructorTypeParameters(node)) |
| 80488 | checkGrammarConstructorTypeAnnotation(node); |
| 80489 | checkSourceElement(node.body); |
| 80490 | var symbol = getSymbolOfNode(node); |
| 80491 | var firstDeclaration = ts.getDeclarationOfKind(symbol, node.kind); |
| 80492 | // Only type check the symbol once |
| 80493 | if (node === firstDeclaration) { |
| 80494 | checkFunctionOrConstructorSymbol(symbol); |
| 80495 | } |
| 80496 | // exit early in the case of signature - super checks are not relevant to them |
| 80497 | if (ts.nodeIsMissing(node.body)) { |
| 80498 | return; |
| 80499 | } |
| 80500 | addLazyDiagnostic(checkConstructorDeclarationDiagnostics); |
| 80501 | return; |
| 80502 | function isInstancePropertyWithInitializerOrPrivateIdentifierProperty(n) { |
| 80503 | if (ts.isPrivateIdentifierClassElementDeclaration(n)) { |
| 80504 | return true; |
| 80505 | } |
| 80506 | return n.kind === 167 /* SyntaxKind.PropertyDeclaration */ && |
| 80507 | !ts.isStatic(n) && |
| 80508 | !!n.initializer; |
| 80509 | } |
| 80510 | function checkConstructorDeclarationDiagnostics() { |
| 80511 | // TS 1.0 spec (April 2014): 8.3.2 |
| 80512 | // Constructors of classes with no extends clause may not contain super calls, whereas |
| 80513 | // constructors of derived classes must contain at least one super call somewhere in their function body. |
| 80514 | var containingClassDecl = node.parent; |
| 80515 | if (ts.getClassExtendsHeritageElement(containingClassDecl)) { |
| 80516 | captureLexicalThis(node.parent, containingClassDecl); |
| 80517 | var classExtendsNull = classDeclarationExtendsNull(containingClassDecl); |
| 80518 | var superCall = findFirstSuperCall(node.body); |
| 80519 | if (superCall) { |
| 80520 | if (classExtendsNull) { |
| 80521 | error(superCall, ts.Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null); |
| 80522 | } |
| 80523 | // A super call must be root-level in a constructor if both of the following are true: |
| 80524 | // - The containing class is a derived class. |
| 80525 | // - The constructor declares parameter properties |
| 80526 | // or the containing class declares instance member variables with initializers. |
| 80527 | var superCallShouldBeRootLevel = (ts.getEmitScriptTarget(compilerOptions) !== 99 /* ScriptTarget.ESNext */ || !useDefineForClassFields) && |
| 80528 | (ts.some(node.parent.members, isInstancePropertyWithInitializerOrPrivateIdentifierProperty) || |
| 80529 | ts.some(node.parameters, function (p) { return ts.hasSyntacticModifier(p, 16476 /* ModifierFlags.ParameterPropertyModifier */); })); |
| 80530 | if (superCallShouldBeRootLevel) { |
| 80531 | // Until we have better flow analysis, it is an error to place the super call within any kind of block or conditional |
| 80532 | // See GH #8277 |
| 80533 | if (!superCallIsRootLevelInConstructor(superCall, node.body)) { |
| 80534 | error(superCall, ts.Diagnostics.A_super_call_must_be_a_root_level_statement_within_a_constructor_of_a_derived_class_that_contains_initialized_properties_parameter_properties_or_private_identifiers); |
| 80535 | } |
| 80536 | // Skip past any prologue directives to check statements for referring to 'super' or 'this' before a super call |
| 80537 | else { |
| 80538 | var superCallStatement = void 0; |
| 80539 | for (var _i = 0, _a = node.body.statements; _i < _a.length; _i++) { |
| 80540 | var statement = _a[_i]; |
no test coverage detected