Browse Source

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

Dan Korostelev 6 years ago
parent
commit
5cce881e17
2 changed files with 41 additions and 0 deletions
  1. 11 0
      src/generators/genswf9.ml
  2. 30 0
      tests/unit/src/unit/issues/Issue8248.hx

+ 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
+}