Parcourir la source

[python] Implement _hx_ClassRegistry in Haxe and support @:nativeGen meta to disable adding reflection info to a class.

Dan Korostelev il y a 11 ans
Parent
commit
2820e1d1d9
3 fichiers modifiés avec 84 ajouts et 42 suppressions
  1. 1 1
      common.ml
  2. 9 6
      genpy.ml
  3. 74 35
      std/python/Boot.hx

+ 1 - 1
common.ml

@@ -400,7 +400,7 @@ module MetaInfo = struct
 		| MergeBlock -> ":mergeBlock",("Internally used by typer to mark block that should be merged into the outer scope",[Internal])
 		| MultiType -> ":multiType",("Specifies that an abstract chooses its this-type from its @:to functions",[UsedOn TAbstract; HasParam "Relevant type parameters"])
 		| Native -> ":native",("Rewrites the path of a class or enum during generation",[HasParam "Output type path";UsedOnEither [TClass;TEnum]])
-		| NativeGen -> ":nativeGen",("Annotates that a type should be treated as if it were an extern definition - platform native",[Platforms [Java;Cs]; UsedOnEither[TClass;TEnum]])
+		| NativeGen -> ":nativeGen",("Annotates that a type should be treated as if it were an extern definition - platform native",[Platforms [Java;Cs;Python]; UsedOnEither[TClass;TEnum]])
 		| NativeGeneric -> ":nativeGeneric",("Used internally to annotate native generic classes",[Platform Cs; UsedOnEither[TClass;TEnum]; Internal])
 		| NoCompletion -> ":noCompletion",("Prevents the compiler from suggesting completion on this field",[UsedOn TClassField])
 		| NoDebug -> ":noDebug",("Does not generate debug information into the Swf even if -debug is set",[UsedOnEither [TClass;TClassField];Platform Flash])

+ 9 - 6
genpy.ml

@@ -1608,7 +1608,7 @@ module Generator = struct
 		end
 
 	let gen_class_register ctx c cfd p_super p_interfaces p p_name =
-		print ctx "@_hx_classes.register_class(\"%s\"" p_name;
+		print ctx "@_hx_classes.registerClass(\"%s\"" p_name;
 
 		let add_names_arg lst arg_name =
 			match lst with
@@ -1631,7 +1631,7 @@ module Generator = struct
 
 		(match p_super with
 		| None -> ()
-		| Some ps -> print ctx ", super=%s" ps);
+		| Some ps -> print ctx ", superClass=%s" ps);
 
 		print ctx ")\n"
 
@@ -1772,7 +1772,8 @@ module Generator = struct
 			) c.cl_implements in
 
 			newline ctx;
-			gen_class_register ctx c x p_super p_interfaces p p_name;
+			if not (Meta.has Meta.NativeGen c.cl_meta) then
+				gen_class_register ctx c x p_super p_interfaces p p_name;
 			print ctx "class %s" p;
 			(match p_super with Some p -> print ctx "(%s)" p | _ -> ());
 			spr ctx ":";
@@ -1797,7 +1798,8 @@ module Generator = struct
 			in
 			if use_pass then spr_line ctx "\tpass\n";
  *)
-			gen_class_empty_constructor ctx p c.cl_ordered_fields;
+			if not (Meta.has Meta.NativeGen c.cl_meta) then
+				gen_class_empty_constructor ctx p c.cl_ordered_fields;
 		end;
 
 		gen_class_init ctx c
@@ -1825,7 +1827,7 @@ module Generator = struct
 		let enum_constructs_str = fix ^ (String.concat ("\",\"") (List.map (fun ef -> ef.ef_name) enum_constructs)) ^ fix in
 
 		newline ctx;
-		print ctx "@_hx_classes.register_enum(\"%s\", [%s])\n" p_name enum_constructs_str;
+		print ctx "@_hx_classes.registerEnum(\"%s\", [%s])\n" p_name enum_constructs_str;
 		print ctx "class %s(Enum):\n" p;
 		spr ctx "\tdef __init__(self, t, i, p):\n";
 		print ctx "\t\tsuper(%s,self).__init__(t, i, p)\n\n" p;
@@ -1879,7 +1881,7 @@ module Generator = struct
 		let mt = (t_infos (TAbstractDecl a)) in
 		let p = get_path mt in
 		let p_name = get_full_name mt in
-		print ctx "@_hx_classes.register_abstract(\"%s\")\n" p_name;
+		print ctx "@_hx_classes.registerAbstract(\"%s\")\n" p_name;
 		print ctx "class %s" p;
 		spr ctx ":";
 		match a.a_impl with
@@ -1932,6 +1934,7 @@ module Generator = struct
 			Hashtbl.add used_paths path true;
 			Utils.find_type ctx.com path
 		in
+		gen_type ctx (find_type ([],"_hx_ClassRegistry"));
 		gen_type ctx (find_type (["python"],"Boot"));
 		gen_type ctx (find_type ([],"Enum"));
 		gen_type ctx (find_type ([],"HxOverrides"));

+ 74 - 35
std/python/Boot.hx

@@ -20,45 +20,84 @@ private extern class Set<T> {
 @:import("math") private extern class Math {}
 @:import("inspect") private extern class Inspect {}
 
+typedef HxClassBase = {
+    _hx_class:Dynamic,
+    _hx_class_name:String
+}
+
+private typedef HxAbstract = {
+    >HxClassBase,
+}
+
+private typedef HxEnum = {
+    >HxClassBase,
+    _hx_constructs:Array<String>
+}
+
+private typedef HxClass = {
+    >HxClassBase,
+    _hx_fields:Array<String>,
+    _hx_props:Array<String>,
+    _hx_methods:Array<String>,
+    _hx_statics:Array<String>,
+    _hx_interfaces:Array<HxClassBase>,
+    _hx_super:HxClass
+}
+
+@:keep
+@:nativeGen
+@:native("_hx_ClassRegistry")
+private class ClassRegistry extends python.lib.Dict<String, HxClassBase> {
+    function _register(cls:HxClassBase, name:String):Void {
+        cls._hx_class = cls;
+        cls._hx_class_name = name;
+        set(name, cls);
+    }
+
+    function registerAbstract(name:String):HxAbstract->HxAbstract {
+        function wrapper(cls:HxAbstract):HxAbstract {
+            _register(cls, name);
+            return cls;
+        }
+        return wrapper;
+    }
+
+    function registerEnum(name:String, constructs:Array<String>):HxEnum->HxEnum {
+        function wrapper(cls:HxEnum):HxEnum {
+            _register(cls, name);
+            cls._hx_constructs = constructs;
+            return cls;
+        }
+        return wrapper;
+    }
+
+    function registerClass(name:String, ?fields:Array<String>, ?props:Array<String>, ?methods:Array<String>, ?statics:Array<String>, ?interfaces:Array<HxClassBase>, ?superClass:HxClass):HxClass->HxClass {
+        if (fields == null) fields = [];
+        if (props == null) props = [];
+        if (methods == null) methods = [];
+        if (statics == null) statics = [];
+        if (interfaces == null) interfaces = [];
+        function wrapper(cls:HxClass):HxClass {
+            _register(cls, name);
+            cls._hx_fields = fields;
+            cls._hx_props = props;
+            cls._hx_methods = methods;
+            cls._hx_statics = statics;
+            cls._hx_interfaces = interfaces;
+            if (superClass != null)
+                cls._hx_super = superClass;
+            return cls;
+        }
+        return wrapper;
+    }
+}
+
 @:preCode("
+_hx_classes = _hx_ClassRegistry()
+
 class _hx_AnonObject(object):
 	def __init__(self, fields):
 		self.__dict__ = fields
-
-class _hx_ClassRegistry(dict):
-
-	def _register(self, cls, name):
-		cls._hx_class = cls
-		cls._hx_class_name = name
-		self[name] = cls
-
-	def register_class(self, name, fields=[], props=[], methods=[], statics=[], interfaces=[], super=None):
-		def wrapper(cls):
-			self._register(cls, name)
-			cls._hx_fields = fields
-			cls._hx_props = props
-			cls._hx_methods = methods
-			cls._hx_statics = statics
-			cls._hx_interfaces = interfaces
-			if super is not None:
-				cls._hx_super = super
-			return cls
-		return wrapper
-
-	def register_abstract(self, name):
-		def wrapper(cls):
-			self._register(cls, name)
-			return cls
-		return wrapper
-
-	def register_enum(self, name, constructs):
-		def wrapper(cls):
-			self._register(cls, name)
-			cls._hx_constructs = constructs
-			return cls
-		return wrapper
-
-_hx_classes = _hx_ClassRegistry()
 ")
 @:keep class Boot {