Skip to content

Commit a749af9

Browse files
committed
check that super() is the first statement in constructors of derived classes
1 parent 6e3c348 commit a749af9

File tree

4 files changed

+22
-1
lines changed

4 files changed

+22
-1
lines changed

src/ast.ts

+6
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@ export function nodeIsGenericCallable(kind: NodeKind): bool {
135135
return false;
136136
}
137137

138+
export function nodeIsSuperCall(node: Node): bool {
139+
if (node.kind == NodeKind.EXPRESSION) node = (<ExpressionStatement>node).expression;
140+
return node.kind == NodeKind.CALL
141+
&& (<CallExpression>node).expression.kind == NodeKind.SUPER;
142+
}
143+
138144
/** Base class of all nodes. */
139145
export abstract class Node {
140146

src/compiler.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ import {
144144
FieldDeclaration,
145145

146146
nodeIsConstantValue,
147+
nodeIsSuperCall,
147148
isLastStatement,
148149
findDecorator
149150
} from "./ast";
@@ -1075,7 +1076,18 @@ export class Compiler extends DiagnosticEmitter {
10751076
flow.finalize();
10761077
} else {
10771078
assert(body.kind == NodeKind.BLOCK);
1078-
let stmts = this.compileStatements((<BlockStatement>body).statements);
1079+
let statements = (<BlockStatement>body).statements;
1080+
if (isConstructor) { // make sure super() is called first if this is a derived class
1081+
let parent = assert(instance.parent);
1082+
assert(parent.kind == ElementKind.CLASS);
1083+
if ((<Class>parent).base && !(statements.length >= 1 && nodeIsSuperCall(statements[0]))) {
1084+
this.error(
1085+
DiagnosticCode.Constructors_for_derived_classes_must_call_super_first,
1086+
statements[0].range.atStart
1087+
);
1088+
}
1089+
}
1090+
let stmts = this.compileStatements(statements);
10791091
if (instance.is(CommonFlags.MAIN)) {
10801092
module.addGlobal("~started", NativeType.I32, true, module.createI32(0));
10811093
stmts.unshift(

src/diagnosticMessages.generated.ts

+2
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ export enum DiagnosticCode {
101101
The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access = 2357,
102102
The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access = 2364,
103103
Operator_0_cannot_be_applied_to_types_1_and_2 = 2365,
104+
Constructors_for_derived_classes_must_call_super_first = 2377,
104105
_get_and_set_accessor_must_have_the_same_type = 2380,
105106
Constructor_implementation_is_missing = 2390,
106107
Function_implementation_is_missing_or_not_immediately_following_the_declaration = 2391,
@@ -224,6 +225,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
224225
case 2357: return "The operand of an increment or decrement operator must be a variable or a property access.";
225226
case 2364: return "The left-hand side of an assignment expression must be a variable or a property access.";
226227
case 2365: return "Operator '{0}' cannot be applied to types '{1}' and '{2}'.";
228+
case 2377: return "Constructors for derived classes must call 'super' first.";
227229
case 2380: return "'get' and 'set' accessor must have the same type.";
228230
case 2390: return "Constructor implementation is missing.";
229231
case 2391: return "Function implementation is missing or not immediately following the declaration.";

src/diagnosticMessages.json

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
"The operand of an increment or decrement operator must be a variable or a property access.": 2357,
9696
"The left-hand side of an assignment expression must be a variable or a property access.": 2364,
9797
"Operator '{0}' cannot be applied to types '{1}' and '{2}'.": 2365,
98+
"Constructors for derived classes must call 'super' first.": 2377,
9899
"'get' and 'set' accessor must have the same type.": 2380,
99100
"Constructor implementation is missing.": 2390,
100101
"Function implementation is missing or not immediately following the declaration.": 2391,

0 commit comments

Comments
 (0)