瀏覽代碼

[java/cs] Support metadata on interfaces. Closes #2042

Cauê Waneck 10 年之前
父節點
當前提交
5bd0672933
共有 5 個文件被更改,包括 97 次插入16 次删除
  1. 44 0
      gencommon.ml
  2. 1 0
      gencs.ml
  3. 1 0
      genjava.ml
  4. 29 16
      std/haxe/rtti/Meta.hx
  5. 22 0
      tests/unit/src/unit/issues/Issue2042.hx

+ 44 - 0
gencommon.ml

@@ -11163,6 +11163,50 @@ struct
 
 end;;
 
+(* ******************************************* *)
+(* InterfaceMetas *)
+(* ******************************************* *)
+
+(*
+
+	Deal with metadata on interfaces by taking it off from interface, and adding a new class with `_HxMeta` suffix
+
+	dependencies:
+		Must run before InitFunction
+
+*)
+
+module InterfaceMetas =
+struct
+
+	let name = "interface_metas"
+
+	let priority = solve_deps name [ DBefore InitFunction.priority ]
+
+	let traverse gen =
+		let run md = match md with
+			| TClassDecl ({ cl_interface = true; cl_ordered_statics = (_ :: _) } as cl) ->
+				cl.cl_ordered_statics <- [];
+				let path = fst cl.cl_path,snd cl.cl_path ^ "_HxMeta" in
+				(match Codegen.build_metadata gen.gcon (TClassDecl cl) with
+					| Some expr ->
+						let ncls = mk_class cl.cl_module path cl.cl_pos in
+						let cf = mk_class_field "__meta__" expr.etype false expr.epos (Var { v_read = AccNormal; v_write = AccNormal }) [] in
+						cf.cf_expr <- Some expr;
+						ncls.cl_statics <- PMap.add "__meta__" cf ncls.cl_statics;
+						ncls.cl_ordered_statics <- cf :: ncls.cl_ordered_statics;
+						gen.gadd_to_module (TClassDecl(ncls)) priority;
+					| _ -> ())
+			| _ -> ()
+		in
+		run
+
+	let configure gen =
+		let map md = traverse gen md; Some(md) in
+		gen.gmodule_filters#add ~name:name ~priority:(PCustom priority) map
+
+end;;
+
 (*
 (* ******************************************* *)
 (* Example *)

+ 1 - 0
gencs.ml

@@ -3056,6 +3056,7 @@ let configure gen =
 	);
 
 	DefaultArguments.configure gen (DefaultArguments.traverse gen);
+	InterfaceMetas.configure gen;
 
 	CSharpSpecificSynf.configure gen (CSharpSpecificSynf.traverse gen runtime_cl);
 	CSharpSpecificESynf.configure gen (CSharpSpecificESynf.traverse gen runtime_cl);

+ 1 - 0
genjava.ml

@@ -2240,6 +2240,7 @@ let configure gen =
 	);
 
 	DefaultArguments.configure gen (DefaultArguments.traverse gen);
+	InterfaceMetas.configure gen;
 
 	JavaSpecificSynf.configure gen (JavaSpecificSynf.traverse gen runtime_cl);
 	JavaSpecificESynf.configure gen (JavaSpecificESynf.traverse gen runtime_cl);

+ 29 - 16
std/haxe/rtti/Meta.hx

@@ -30,23 +30,40 @@ class Meta {
 		Returns the metadata that were declared for the given type (class or enum)
 	**/
 	public static function getType( t : Dynamic ) : Dynamic<Array<Dynamic>> {
-		#if (java || cs)
-		var meta : Dynamic = Reflect.field(t, "__meta__");
-		#else
-		var meta : Dynamic = untyped t.__meta__;
-		#end
+		var meta = getMeta(t);
 		return (meta == null || meta.obj == null) ? {} : meta.obj;
 	}
 
+	private static function getMeta(t:Dynamic):Dynamic
+	{
+#if (java || cs)
+		var ret = Reflect.field(t, "__meta__");
+		if (ret == null && Std.is(t,Class))
+		{
+#if java
+			var interf = java.Lib.toNativeType(t).isInterface();
+#elseif cs
+			var interf = cs.Lib.toNativeType(t).IsInterface;
+#end
+			if (interf)
+			{
+				var name = Type.getClassName(t),
+				    cls = Type.resolveClass(name + '_HxMeta');
+				if (cls != null)
+					return Reflect.field(cls, "__meta__");
+			}
+		}
+		return ret;
+#else
+		return untyped t.__meta__;
+#end
+	}
+
 	/**
 		Returns the metadata that were declared for the given class static fields
 	**/
 	public static function getStatics( t : Dynamic ) : Dynamic<Dynamic<Array<Dynamic>>> {
-		#if (java || cs)
-		var meta : Dynamic = Reflect.field(t, "__meta__");
-		#else
-		var meta : Dynamic = untyped t.__meta__;
-		#end
+		var meta = getMeta(t);
 		return (meta == null || meta.statics == null) ? {} : meta.statics;
 	}
 
@@ -54,12 +71,8 @@ class Meta {
 		Returns the metadata that were declared for the given class fields or enum constructors
 	**/
 	public static function getFields( t : Dynamic ) : Dynamic<Dynamic<Array<Dynamic>>> {
-		#if (java || cs)
-		var meta : Dynamic = Reflect.field(t, "__meta__");
-		#else
-		var meta : Dynamic = untyped t.__meta__;
-		#end
+		var meta = getMeta(t);
 		return (meta == null || meta.fields == null) ? {} : meta.fields;
 	}
 
-}
+}

+ 22 - 0
tests/unit/src/unit/issues/Issue2042.hx

@@ -0,0 +1,22 @@
+package unit.issues;
+
+class Issue2042 extends Test
+{
+	public function test()
+	{
+		var m = haxe.rtti.Meta.getType(WithMeta);
+		t(m.someMeta != null);
+		eq(m.someMeta[0],1);
+		t(m.otherMeta != null);
+		eq(m.otherMeta[0],2);
+		t(haxe.rtti.Meta.getFields(WithMeta).testing != null);
+		eq(haxe.rtti.Meta.getFields(WithMeta).testing.varMeta[0], 3);
+	}
+}
+
+@someMeta(1) @otherMeta(2)
+@:keep private interface WithMeta
+{
+	@varMeta(3)
+	function testing():Void;
+}