Prechádzať zdrojové kódy

[flash] generate protected namespace for classes that have protected methods anywhere in their heritage (closes #8248) (#8256)

Dan Korostelev 6 rokov pred
rodič
commit
5cce881e17

+ 11 - 0
src/generators/genswf9.ml

@@ -2080,6 +2080,9 @@ let check_constructor ctx c f =
 	with Exit ->
 		()
 
+let has_protected_meta = Meta.Custom ":has_protected"
+let mark_has_protected c = c.cl_meta <- (has_protected_meta,[],null_pos) :: c.cl_meta
+
 let generate_class ctx c =
 	let name = type_path ctx c.cl_path in
 	ctx.cur_class <- c;
@@ -2210,6 +2213,14 @@ let generate_class ctx c =
 		| None -> false
 		| Some (c,_) -> is_dynamic c
 	in
+	if !has_protected <> None then
+		mark_has_protected c (* class has its own protected methods - add meta for the child classes *)
+	else Option.may (fun (csup,_) -> (* child has no own protected methods, check whether parent was marked with the meta *)
+		if Meta.has has_protected_meta csup.cl_meta then begin
+			has_protected := Some (make_class_ns c);
+			mark_has_protected c (* also mark this class with the meta for further child classes *)
+		end
+	) c.cl_super;
 	{
 		hlc_index = 0;
 		hlc_name = name;

+ 30 - 0
tests/unit/src/unit/issues/Issue8248.hx

@@ -0,0 +1,30 @@
+package unit.issues;
+
+#if flash
+private class NoProtected {}
+
+private class Base extends NoProtected {
+	public var x:Int;
+
+	public function new() {
+		x = f();
+	}
+
+	@:protected function f() return 1;
+}
+
+private class Child extends Base {
+}
+
+private class GrandChild extends Child {
+	override function f() return 2;
+}
+#end
+
+class Issue8248 extends unit.Test {
+	#if flash
+	function test() {
+		eq(new GrandChild().x, 2);
+	}
+	#end
+}