Forráskód Böngészése

Fix @:using for interfaces and abstracts (#8310)

* fix @:using for child classes

* refactoring; support @:using on abstracts and interfaces

* make impl classes inherit @:using meta from abstracts
Aleksandr Kuzmenko 6 éve
szülő
commit
2d978c876f

+ 1 - 1
src/typing/fields.ml

@@ -316,7 +316,7 @@ let rec using_field ctx mode e i p =
 	with Not_found -> try
 		(* type using from `@:using(Path)` *)
 		let mt = module_type_of_type e.etype in
-		loop  (t_infos mt).mt_using
+		loop (t_infos mt).mt_using
 	with Not_found | Exit -> try
 		(* global using *)
 		let acc = loop ctx.g.global_using in

+ 16 - 1
src/typing/typeloadFields.ml

@@ -412,7 +412,11 @@ let build_module_def ctx mt meta fvars context_init fbuild =
 				try
 					let path = List.rev (string_pos_list_of_expr_path_raise e) in
 					let types,filter_classes = handle_using ctx path (pos e) in
-					let ti = t_infos mt in
+					let ti =
+						match mt with
+							| TClassDecl { cl_kind = KAbstractImpl a } -> t_infos (TAbstractDecl a)
+							| _ -> t_infos mt
+					in
 					ti.mt_using <- (filter_classes types) @ ti.mt_using;
 				with Exit ->
 					error "dot path expected" (pos e)
@@ -423,6 +427,17 @@ let build_module_def ctx mt meta fvars context_init fbuild =
 	in
 	(* let errors go through to prevent resume if build fails *)
 	let f_build,f_enum = List.fold_left loop ([],None) meta in
+	(* Go for @:using in parents and interfaces *)
+	(match mt with
+		| TClassDecl { cl_super = csup; cl_implements = interfaces; cl_kind = kind } ->
+			let ti = t_infos mt in
+			let inherit_using (c,_) =
+				ti.mt_using <- ti.mt_using @ (t_infos (TClassDecl c)).mt_using
+			in
+			Option.may inherit_using csup;
+			List.iter inherit_using interfaces
+		| _ -> ()
+	);
 	List.iter (fun f -> f()) (List.rev f_build);
 	(match f_enum with None -> () | Some f -> f())
 

+ 1 - 1
src/typing/typeloadModule.ml

@@ -322,7 +322,7 @@ let module_pass_1 ctx m tdecls loadp =
 				(match !decls with
 				| (TClassDecl c,_) :: _ ->
 					List.iter (fun m -> match m with
-						| ((Meta.Build | Meta.CoreApi | Meta.Allow | Meta.Access | Meta.Enum | Meta.Dce | Meta.Native | Meta.HlNative | Meta.JsRequire | Meta.PythonImport | Meta.Expose | Meta.Deprecated | Meta.PhpGlobal),_,_) ->
+						| ((Meta.Using | Meta.Build | Meta.CoreApi | Meta.Allow | Meta.Access | Meta.Enum | Meta.Dce | Meta.Native | Meta.HlNative | Meta.JsRequire | Meta.PythonImport | Meta.Expose | Meta.Deprecated | Meta.PhpGlobal),_,_) ->
 							c.cl_meta <- m :: c.cl_meta;
 						| _ ->
 							()

+ 51 - 0
tests/unit/src/unit/issues/Issue8188.hx

@@ -0,0 +1,51 @@
+package unit.issues;
+
+class Issue8188 extends unit.Test {
+	function test() {
+		t(new Dummy().checkClass());
+		t(new DummyChild().checkClass());
+
+		t(new IDummyInst().checkInterface());
+		t(new IDummyChildInst().checkInterface());
+
+		t(new ADummy().checkAbstract());
+	}
+
+	static function checkClass(d:Dummy):Bool {
+		return true;
+	}
+
+	static function checkInterface(d:IDummy):Bool {
+		return true;
+	}
+
+	static function checkAbstract(d:ADummy):Bool {
+		return true;
+	}
+}
+
+@:using(unit.issues.Issue8188)
+private class Dummy {
+	public function new() {}
+}
+
+private class DummyChild extends Dummy {}
+
+@:using(unit.issues.Issue8188)
+private interface IDummy {}
+private interface IDummyChild extends IDummy {}
+
+private class IDummyInst implements IDummy {
+	public function new() {}
+}
+
+private class IDummyChildInst implements IDummyChild {
+	public function new() {}
+}
+
+@:using(unit.issues.Issue8188)
+private abstract ADummy(String) {
+	public inline function new() {
+		this = '';
+	}
+}