Kaynağa Gözat

[typer] delay final field initialization check

closes #6772
Simon Krajewski 7 yıl önce
ebeveyn
işleme
f163a5eeb8

+ 23 - 1
src/typing/typeloadCheck.ml

@@ -456,4 +456,26 @@ module Inheritance = struct
 				None
 		) herits in
 		fl
-end
+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 Meta.has Meta.Final cf.cf_meta && cf.cf_expr = None ->
+			Hashtbl.add final_vars cf.cf_name cf
+		| _ ->
+			()
+	) ctx.curclass.cl_ordered_fields;
+	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) ->
+				Hashtbl.remove final_vars (field_name fa);
+				find_inits e2;
+			| _ ->
+				Type.iter find_inits e
+		in
+		find_inits e;
+		Hashtbl.iter (fun _ cf ->
+			display_error ctx ("final field " ^ cf.cf_name ^ " must be initialized immediately or in the constructor") cf.cf_pos;
+		) final_vars
+	end

+ 1 - 20
src/typing/typeloadFunction.ml

@@ -162,26 +162,7 @@ let type_function ctx args ret fmode f do_display p =
 	let e = if fmode <> FunConstructor then
 		e
 	else begin
-		let final_vars = Hashtbl.create 0 in
-		List.iter (fun cf -> match cf.cf_kind with
-			| Var _ when Meta.has Meta.Final cf.cf_meta && cf.cf_expr = None ->
-				Hashtbl.add final_vars cf.cf_name cf
-			| _ ->
-				()
-		) ctx.curclass.cl_ordered_fields;
-		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) ->
-					Hashtbl.remove final_vars (field_name fa);
-					find_inits e2;
-				| _ ->
-					Type.iter find_inits e
-			in
-			find_inits e;
-			Hashtbl.iter (fun _ cf ->
-				display_error ctx ("final field " ^ cf.cf_name ^ " must be initialized immediately or in the constructor") cf.cf_pos;
-			) final_vars
-		end;
+		delay ctx PForce (fun () -> TypeloadCheck.check_final_vars ctx e);
 		match has_super_constr() with
 		| Some (was_forced,t_super) ->
 			(try

+ 9 - 0
tests/misc/projects/Issue6772/Main.hx

@@ -0,0 +1,9 @@
+class Main {
+    public static function main() {
+        new Main();
+    }
+
+    final i:Int = 0;
+
+    function new() {}
+}

+ 2 - 0
tests/misc/projects/Issue6772/compile.hxml

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

+ 9 - 0
tests/unit/src/unit/issues/Issue6772.hx

@@ -0,0 +1,9 @@
+package unit.issues;
+
+private class Issue6772Class {
+    final i:Int = 0;
+
+    function new() {}
+}
+
+class Issue6772 extends unit.Test { }