Browse Source

[typer] check final vars of parent classes

closes #10139
Simon Krajewski 2 years ago
parent
commit
bc65d959f4

+ 20 - 7
src/typing/typeloadCheck.ml

@@ -636,12 +636,22 @@ end
 
 let check_final_vars ctx e =
 	let final_vars = Hashtbl.create 0 in
-	List.iter (fun cf -> match cf.cf_kind with
-		| Var _ when (has_class_field_flag cf CfFinal) && cf.cf_expr = None ->
-			Hashtbl.add final_vars cf.cf_name cf
+	let ordered_fields = DynArray.create () in
+	let rec loop c =
+		List.iter (fun cf -> match cf.cf_kind with
+			| Var _ when (has_class_field_flag cf CfFinal) && cf.cf_expr = None && not (Hashtbl.mem final_vars cf.cf_name) ->
+				Hashtbl.add final_vars cf.cf_name false;
+				DynArray.add ordered_fields (c,cf)
+			| _ ->
+				()
+		) c.cl_ordered_fields;
+		match c.cl_super with
+		| Some(c,_) when has_class_flag c CAbstract && not (has_constructor c) ->
+			loop c
 		| _ ->
 			()
-	) ctx.curclass.cl_ordered_fields;
+	in
+	loop ctx.curclass;
 	if Hashtbl.length final_vars > 0 then begin
 		let rec find_inits e = match e.eexpr with
 			| TBinop(OpAssign,{eexpr = TField({eexpr = TConst TThis},fa)},e2) ->
@@ -651,7 +661,10 @@ let check_final_vars ctx e =
 				Type.iter find_inits e
 		in
 		find_inits e;
-		Hashtbl.iter (fun _ cf ->
-			display_error ctx.com ("final field " ^ cf.cf_name ^ " must be initialized immediately or in the constructor") cf.cf_pos;
-		) final_vars
+		if Hashtbl.length final_vars > 0 then
+			display_error ctx.com "Some final fields are uninitialized in this class" ctx.curclass.cl_name_pos;
+		DynArray.iter (fun (c,cf) ->
+			if Hashtbl.mem final_vars cf.cf_name then
+				display_error ~depth:1 ctx.com "Uninitialized field" cf.cf_name_pos
+		) ordered_fields
 	end

+ 11 - 0
tests/misc/projects/Issue10139/Main.hx

@@ -0,0 +1,11 @@
+abstract class A {
+	final x:Int;
+	final y:Int;
+}
+
+class B extends A {
+	final z:Int;
+	public function new() {}
+}
+
+function main() {}

+ 2 - 0
tests/misc/projects/Issue10139/compile-fail.hxml

@@ -0,0 +1,2 @@
+-main Main
+--interp

+ 4 - 0
tests/misc/projects/Issue10139/compile-fail.hxml.stderr

@@ -0,0 +1,4 @@
+Main.hx:6: characters 7-8 : Some final fields are uninitialized in this class
+Main.hx:7: characters 8-9 : Uninitialized field
+Main.hx:2: characters 8-9 : Uninitialized field
+Main.hx:3: characters 8-9 : Uninitialized field

+ 2 - 1
tests/misc/projects/Issue6584/compile4-fail.hxml.stderr

@@ -1 +1,2 @@
-Main4.hx:2: characters 2-14 : final field y must be initialized immediately or in the constructor
+Main4.hx:1: characters 7-11 : Some final fields are uninitialized in this class
+Main4.hx:2: characters 8-9 : Uninitialized field