ソースを参照

[flash] fix #8227

I'm sure there are more edge cases but oh well
Dan Korostelev 6 年 前
コミット
e37249d400

+ 3 - 0
src/codegen/swfLoader.ml

@@ -195,6 +195,9 @@ let build_class com c file =
 				| HNNamespace ns ->
 					if not (c.hlc_interface || is_xml) then meta := (Meta.Ns,[String ns]) :: !meta;
 					[APublic,null_pos]
+				| HNInternal (Some ns) ->
+					if not (c.hlc_interface || is_xml) then meta := (Meta.Ns,[String ns; Ident "internal"]) :: !meta;
+					[APublic,null_pos]
 				| HNExplicit _ | HNInternal _ | HNPublic _ ->
 					[APublic,null_pos]
 				| HNStaticProtected _ | HNProtected _ ->

+ 23 - 2
src/generators/genswf9.ml

@@ -305,7 +305,22 @@ let make_class_ns c =
 
 let is_cf_protected cf = Meta.has Meta.Protected cf.cf_meta
 
+let ns_access cf = 
+	try
+		let (_,params,_) = Meta.get Meta.Ns cf.cf_meta in
+		match params with
+		| [(EConst (String ns),_)] ->
+			Some (HMName (cf.cf_name, HNNamespace ns))
+		| [(EConst (String ns),_); (EConst (Ident "internal"),_)] ->
+			Some (HMName (cf.cf_name, HNInternal (Some ns)))
+		| _ -> assert false
+	with Not_found ->
+		None
+
 let property ctx fa t =
+	match Option.map_default ns_access None (extract_field fa) with
+	| Some n -> n, None, false
+	| None ->
 	match fa with
 	| FStatic (c, cf) when is_cf_protected cf ->
 		HMName (reserved cf.cf_name, HNStaticProtected (Some (make_class_ns c))), None, false
@@ -371,8 +386,14 @@ let property ctx fa t =
 
 let this_property fa =
 	match fa with
-	| FInstance (c,_,cf) | FClosure (Some (c,_),cf) when is_cf_protected cf ->
-		HMName (reserved cf.cf_name, HNProtected (make_class_ns c))
+	| FInstance (c,_,cf) | FClosure (Some (c,_),cf) ->
+		if is_cf_protected cf then
+			HMName (reserved cf.cf_name, HNProtected (make_class_ns c))
+		else begin
+			match ns_access cf with
+			| Some n -> n
+			| None -> ident (field_name fa)
+		end
 	| _ ->
 		ident (field_name fa)
 

+ 15 - 0
tests/unit/native_swf/NsCls.as

@@ -0,0 +1,15 @@
+package {
+    public class NsCls {
+        ns1 var ns1v:int = 1;
+        ns2 var ns2v:int = 2;
+
+        ns1 function ns1f():int { return 1; }
+        ns2 function ns2f():int { return 2; }
+
+        ns1 static var ns1sv:int = 1;
+        ns2 static var ns2sv:int = 2;
+
+        ns1 static function ns1sf():int { return 1; }
+        ns2 static function ns2sf():int { return 2; }
+    }
+}

+ 3 - 0
tests/unit/native_swf/ns1.as

@@ -0,0 +1,3 @@
+package {
+    public namespace ns1;
+}

+ 3 - 0
tests/unit/native_swf/ns2.as

@@ -0,0 +1,3 @@
+package {
+    public namespace ns2 = "ns2";
+}

+ 59 - 0
tests/unit/src/unit/issues/Issue8227.hx

@@ -0,0 +1,59 @@
+package unit.issues;
+
+class Issue8227 extends unit.Test {
+	#if flash
+	function test() {
+		var ns = new NsCls();
+		eq(ns.ns1v, 1);
+		ns.ns1v = 50;
+		eq(ns.ns1v, 50);
+
+		eq(ns.ns2v, 2);
+		ns.ns2v = 10;
+		eq(ns.ns2v, 10);
+
+		new Child(this);
+	}
+	#end
+}
+
+#if flash
+@:access(unit.Test)
+private class Child extends NsCls {
+	public function new(test:unit.Test) {
+		super();
+
+		test.eq(ns1v, 1);
+		ns1v = 50;
+		test.eq(ns1v, 50);
+
+		test.eq(ns2v, 2);
+		ns2v = 10;
+		test.eq(ns2v, 10);
+
+		test.eq(ns1f(), 1);
+		test.eq(call(ns1f), 1);
+
+		test.eq(ns2f(), 2);
+		test.eq(call(ns2f), 2);
+
+		test.eq(NsCls.ns1sv, 1);
+		NsCls.ns1sv = 50;
+		test.eq(NsCls.ns1sv, 50);
+
+		test.eq(NsCls.ns2sv, 2);
+		NsCls.ns2sv = 10;
+		test.eq(NsCls.ns2sv, 10);
+
+		test.eq(NsCls.ns1sf(), 1);
+		test.eq(call(NsCls.ns1sf), 1);
+
+		test.eq(NsCls.ns2sf(), 2);
+		test.eq(call(NsCls.ns2sf), 2);
+	}
+
+	static function call(f:()->Int):Int {
+		return f();
+	}
+}
+#end