Browse Source

[nullsafety] check @:nullSafety meta on abstracts to handle Impl classes

Alexander Kuzmenko 6 years ago
parent
commit
73a39bde84

+ 5 - 4
src/typing/nullSafety.ml

@@ -1300,8 +1300,9 @@ class expr_checker mode immediate_execution report =
 	end
 
 class class_checker cls immediate_execution report  =
+	let cls_meta = cls.cl_meta @ (match cls.cl_kind with KAbstractImpl a -> a.a_meta | _ -> []) in
 	object (self)
-			val is_safe_class = safety_enabled cls.cl_meta
+			val is_safe_class = (safety_enabled cls_meta)
 			val mutable checker = new expr_checker SMLoose immediate_execution report
 			val mutable mode = None
 		(**
@@ -1315,14 +1316,14 @@ class class_checker cls immediate_execution report  =
 			let check_field is_static f =
 				(* if f.cf_name = "wtf_foo" then
 					Option.may (fun e -> print_endline (s_expr str_type e)) f.cf_expr; *)
-				match (safety_mode (cls.cl_meta @ f.cf_meta)) with
+				match (safety_mode (cls_meta @ f.cf_meta)) with
 					| SMOff -> ()
 					| mode ->
 						Option.may ((self#get_checker mode)#check_root_expr) f.cf_expr;
 						self#check_accessors is_static f
 			in
 			if is_safe_class then
-				Option.may ((self#get_checker (safety_mode cls.cl_meta))#check_root_expr) cls.cl_init;
+				Option.may ((self#get_checker (safety_mode cls_meta))#check_root_expr) cls.cl_init;
 			Option.may (check_field false) cls.cl_constructor;
 			List.iter (check_field false) cls.cl_ordered_fields;
 			List.iter (check_field true) cls.cl_ordered_statics;
@@ -1363,7 +1364,7 @@ class class_checker cls immediate_execution report  =
 			match mode with
 				| Some mode -> mode
 				| None ->
-					let m = safety_mode cls.cl_meta in
+					let m = safety_mode cls_meta in
 					mode <- Some m;
 					m
 		(**

+ 8 - 0
tests/nullsafety/src/cases/TestAbstract.hx

@@ -0,0 +1,8 @@
+package cases;
+
+@:nullSafety
+abstract TestAbstract(Null<Float>) from Null<Float> to Null<Float> {
+	public inline function testThis() {
+		Validator.shouldFail(var f:Float = this);
+	}
+}

+ 2 - 0
tests/nullsafety/src/TestSafeFieldInUnsafeClass.hx → tests/nullsafety/src/cases/TestSafeFieldInUnsafeClass.hx

@@ -1,3 +1,5 @@
+package cases;
+
 @:build(Validator.checkFields())
 class TestSafeFieldInUnsafeClass {
 	@:nullSafety

+ 0 - 1
tests/nullsafety/src/cases/TestStrict.hx

@@ -1,6 +1,5 @@
 package cases;
 
-import TestSafeFieldInUnsafeClass;
 import Validator.shouldFail;
 
 private enum DummyEnum {

+ 2 - 0
tests/nullsafety/test.hxml

@@ -2,6 +2,8 @@
 -D analyzer-optimize
 cases.TestStrict
 cases.TestLoose
+cases.TestSafeFieldInUnsafeClass
+cases.TestAbstract
 
 --macro nullSafety('cases.TestStrict', Strict)
 --macro nullSafety('cases.TestLoose', Loose)