Browse Source

[cs] Many changes to C# code generation:

- Now Class<> is a shorthand for System.Type - much better design due to the nature of classes
- Cleaned up all static helpers created by reflection
- First try at Type API
- Changed Reflection API to handle correctly overloads and Haxe-made constructs (e.g. Null<>)
many other small changes made to make it compile correctly
Caue Waneck 13 years ago
parent
commit
9e906ec4a9

+ 17 - 25
gencs.ml

@@ -630,13 +630,13 @@ let configure gen =
       | TInst ({ cl_kind = KTypeParameter; cl_path=p }, []) -> snd p
       | TMono r -> (match !r with | None -> "object" | Some t -> t_s (run_follow gen t))
       | TInst ({ cl_path = [], "String" }, []) -> "string"
-      | TInst ({ cl_path = [], "Class" }, _) | TInst ({ cl_path = [], "Enum" }, _) -> "haxe.lang.Class"
+      | TInst ({ cl_path = [], "Class" }, _) | TInst ({ cl_path = [], "Enum" }, _) -> "System.Type"
       | TEnum ({ e_path = p }, params) -> (path_s p)
       | TInst (({ cl_path = p } as cl), params) -> (path_param_s (TClassDecl cl) p params)
       | TType (({ t_path = p } as t), params) -> (path_param_s (TTypeDecl t) p params)
       | TAnon (anon) ->
         (match !(anon.a_status) with
-          | Statics _ | EnumStatics _ -> "haxe.lang.Class"
+          | Statics _ | EnumStatics _ -> "System.Type"
           | _ -> "object")
       | TDynamic _ -> "object"
       (* No Lazy type nor Function type made. That's because function types will be at this point be converted into other types *)
@@ -1474,12 +1474,10 @@ let configure gen =
   
   let rcf_ctx = ReflectionCFs.new_ctx gen closure_t object_iface true rcf_on_getset_field rcf_on_call_field (fun hash hash_array ->
     { hash with eexpr = TCall(rcf_static_find, [hash; hash_array]); etype=basic.tint }
-  ) (fun hash -> { hash with eexpr = TCall(rcf_static_lookup, [hash]); etype = gen.gcon.basic.tstring } ) true in
+  ) (fun hash -> { hash with eexpr = TCall(rcf_static_lookup, [hash]); etype = gen.gcon.basic.tstring } ) false in
   
   ReflectionCFs.UniversalBaseClass.default_config gen (get_cl (get_type gen (["haxe";"lang"],"HxObject")) ) object_iface dynamic_object;
   
-  ReflectionCFs.implement_class_methods rcf_ctx ( get_cl (get_type gen (["haxe";"lang"],"Class")) );
-  
   ReflectionCFs.configure_dynamic_field_access rcf_ctx false;
   
   (* let closure_func = ReflectionCFs.implement_closure_cl rcf_ctx ( get_cl (get_type gen (["haxe";"lang"],"Closure")) ) in *)
@@ -1642,30 +1640,12 @@ let configure gen =
       (fun v e -> e)
   );
   
-  let native_class_wrapper = get_cl (get_type gen (["haxe";"lang"], "NativeClassWrapper")) in
-  
   let get_typeof e =
     { e with eexpr = TCall( { eexpr = TLocal( alloc_var "__typeof__" t_dynamic ); etype = t_dynamic; epos = e.epos }, [e] ) }
   in
   
   ClassInstance.configure gen (ClassInstance.traverse gen (fun e mt ->
-    if is_hxgen mt then begin
-      {
-        eexpr = TCall({
-          eexpr = TField(e, gen.gmk_internal_name "hx" "getClassStatic");
-          etype = TFun([], e.etype);
-          epos = e.epos
-        }, []);
-        etype = e.etype;
-        epos = e.epos;
-      }
-    end else begin
-      {
-        eexpr = TNew(native_class_wrapper, [], [ get_typeof e ]);
-        etype = e.etype;
-        epos = e.epos
-      }
-    end
+    get_typeof e
   ));
   
   CastDetect.configure gen (CastDetect.default_implementation gen (Some (TEnum(empty_e, []))) false);
@@ -1758,8 +1738,20 @@ let before_generate con =
   List.iter (Codegen.fix_overrides con) con.types
 
 let generate con =
-  let gen = new_ctx con in
   (try
+    let gen = new_ctx con in
+    let basic = con.basic in
+    
+    (* make the basic functions in C# *)
+    let type_cl = get_cl ( get_type gen (["System"], "Type")) in
+    let basic_fns = 
+    [
+      mk_class_field "Equals" (TFun(["obj",false,t_dynamic], basic.tbool)) true Ast.null_pos (Method MethNormal) [];
+      mk_class_field "ToString" (TFun([], basic.tstring)) true Ast.null_pos (Method MethNormal) [];
+      mk_class_field "GetHashCode" (TFun([], basic.tint)) true Ast.null_pos (Method MethNormal) [];
+      mk_class_field "GetType" (TFun([], TInst(type_cl, []))) true Ast.null_pos (Method MethNormal) [];
+    ] in
+    List.iter (fun cf -> gen.gbase_class_fields <- PMap.add cf.cf_name cf gen.gbase_class_fields) basic_fns;
     configure gen
   with | TypeNotFound path -> 
     con.error ("Error. Module '" ^ (path_s path) ^ "' is required and was not included in build.")  Ast.null_pos);

+ 43 - 15
std/cs/Lib.hx

@@ -2,24 +2,38 @@ package cs;
 import system.Type;
 
 /**
- * ...
- * @author waneck
- */
+	Platform-specific C# Library. Provides some platform-specific functions for the C# target,
+	such as conversion from haxe types to native types.
+**/
 
 class Lib 
 {
-
+	/**
+		Returns a native array from the supplied Array. This native array is unsafe to be written on,
+		as it may or may not be linked to the actual Array implementation.
+		
+		If equalLengthRequired is true, the result might be a copy of an array with the correct size.
+	**/
 	public static function toNativeReadOnlyArray<T>(arr:Array<T>, equalLengthRequired:Bool):NativeArray<T>
 	{
 		var native:NativeArray<T> = untyped arr.__a;
-		if (native.Length == arr.length)
+		var len = arr.length;
+		if (!equalLengthRequired || native.Length == len)
 		{
 			return native;
 		} else {
-			return null;
+			var ret = new NativeArray<T>(len);
+			system.Array.Copy(native, 0, ret, 0, len);
+			return ret;
 		}
 	}
 	
+	/**
+		Provides support for the "as" keyword in C#.
+		If the object is not of the supplied type "T", it will return null instead of rasing an exception.
+		
+		This function will not work with Value Types (such as Int, Float, Bool...) conversion
+	**/
 	@:functionBody('
 			throw new haxe.lang.HaxeException("This function cannot be accessed at runtime");
 	')
@@ -28,22 +42,36 @@ class Lib
 		return untyped __as__(obj, cl);
 	}
 	
-	public static function toNativeType(cl:Class<Dynamic>):Type
+	/**
+		Returns a Class<> equivalent to the native System.Type type.
+		
+		Currently Haxe's Class<> is equivalent to System.Type, but this is an implementation detail.
+		This may change in the future, so use this function whenever you need to perform such conversion.
+	**/
+	public static inline function fromNativeType(t:system.Type):Class<Dynamic>
+	{
+		return untyped t;
+	}
+	
+	/**
+		Returns a System.Type equivalent to the Haxe Class<> type.
+		
+		Currently Haxe's Class<> is equivalent to System.Type, but this is an implementation detail.
+		This may change in the future, so use this function whenever you need to perform such conversion.
+	**/
+	public static inline function toNativeType(cl:Class<Dynamic>):Type
 	{
-		return untyped cl.nativeType();
+		return untyped cl;
 	}
 	
+	/**
+		Gets the native System.Type from the supplied object. Will throw an exception in case of null being passed.
+	**/
 	@:functionBody('
 			return obj.GetType();
 	')
 	public static function getNativeType(obj:Dynamic):Type
 	{
-		return null;
-	}
-	
-	@:functionBody('System.Console.ReadLine();')
-	public static function wait():Void
-	{
-		
+		return untyped obj.GetType();
 	}
 }

+ 4 - 4
std/cs/_std/Reflect.hx

@@ -35,7 +35,7 @@ import haxe.lang.Function;
 	**/
 	@:functionBody('
 		if (o is haxe.lang.IHxObject)
-		return ((haxe.lang.IHxObject) o).__hx_getField(field, haxe.lang.FieldLookup.hash(field), false, false, true) != haxe.lang.Runtime.undefined;
+			return ((haxe.lang.IHxObject) o).__hx_getField(field, haxe.lang.FieldLookup.hash(field), false, true) != haxe.lang.Runtime.undefined;
 		
 		return haxe.lang.Runtime.slowHasField(o, field);
 	')
@@ -49,7 +49,7 @@ import haxe.lang.Function;
 	**/
 	@:functionBody('
 		if (o is haxe.lang.IHxObject)
-		return ((haxe.lang.IHxObject) o).__hx_getField(field, haxe.lang.FieldLookup.hash(field), false, false, false);
+			return ((haxe.lang.IHxObject) o).__hx_getField(field, haxe.lang.FieldLookup.hash(field), false, false);
 		
 		return haxe.lang.Runtime.slowGetField(o, field, false);
 	')
@@ -64,7 +64,7 @@ import haxe.lang.Function;
 	**/
 	@:functionBody('
 		if (o is haxe.lang.IHxObject)
-			((haxe.lang.IHxObject) o).__hx_setField(field, haxe.lang.FieldLookup.hash(field), false, value);
+			((haxe.lang.IHxObject) o).__hx_setField(field, haxe.lang.FieldLookup.hash(field), value);
 		else
 			haxe.lang.Runtime.slowSetField(o, field, value);
 	')
@@ -107,7 +107,7 @@ import haxe.lang.Function;
 		if (o is haxe.lang.IHxObject)
 		{
 			Array<object> ret = new Array<object>();
-			((haxe.lang.IHxObject) o).__hx_getFields(ret, false);
+				((haxe.lang.IHxObject) o).__hx_getFields(ret);
 			return ret;
 		} else {
 			Array<object> ret = new Array<object>();

+ 134 - 36
std/cs/_std/Type.hx

@@ -1,3 +1,6 @@
+import cs.Lib;
+import haxe.lang.HxObject;
+import haxe.lang.Runtime;
 /*
  * Copyright (c) 2005, The haXe Project Contributors
  * All rights reserved.
@@ -36,53 +39,113 @@ enum ValueType {
 }
 
 @:core_api class Type {
-
+	
 	public static function getClass<T>( o : T ) : Class<T> untyped 
 	{
-		return null;
+		return cast o.GetType();
 	}
-
+	
 	public static function getEnum( o : EnumValue ) : Enum<Dynamic> untyped 
 	{
-		return null;
+		return cast Lib.getNativeType(o);
 	}
 
-
-	public static function getSuperClass( c : Class<Dynamic> ) : Class<Dynamic> untyped 
+	public static function getSuperClass( c : Class<Dynamic> ) : Class<Dynamic> 
 	{
-		return null;
+		var t:system.Type = Lib.toNativeType(c);
+		var base = t.BaseType;
+		if (base == null || (base + "") == "haxe.lang.HxObject")
+		{
+			return null;
+		}
+		
+		return Lib.fromNativeType(base);
 	}
 
 	public static function getClassName( c : Class<Dynamic> ) : String {
-		return null;
+		var ret:String = cast Lib.toNativeType(c);
+#if no-root
+		if (ret.length > 10 && StringTools.startsWith(ret, "haxe.root."))
+			ret = ret.substr(10);
+#end
+		
+		return switch(ret)
+		{
+			case "System.Int32": "Int";
+			case "System.Double": "Float";
+			case "System.String": "String";
+			default: ret;
+		}
 	}
 
 	public static function getEnumName( e : Enum<Dynamic> ) : String 
 	{
-		return null;
-	}
-
-	public static function resolveClass( name : String ) : Class<Dynamic> untyped 
+		var ret:String = cast Lib.toNativeType(untyped e);
+#if no-root
+		if (ret.length > 10 && StringTools.startsWith(ret, "haxe.root."))
+			ret = ret.substr(10);
+#end
+		if (ret.length == 14 && ret == "System.Boolean") 
+			return "Bool";
+		return ret;
+	}
+	
+	public static function resolveClass( name : String ) : Class<Dynamic> 
 	{
-		return null;
-	}
-
-
-	public static function resolveEnum( name : String ) : Enum<Dynamic> untyped 
+#if no-root
+		if (name.indexOf(".") == -1)
+			name = "haxe.root." + name;
+#end
+		var t:system.Type = system.Type.GetType(name);
+		if (t == null)
+		{
+			switch(name)
+			{
+				case "Int": return Int;
+				case "Float": return Float;
+				case "Class": return Class;
+				default: return null;
+			}
+		} else if (t.IsInterface && t.IsAssignableFrom(untyped __typeof__(IGenericObject))) { 
+			//return t.Get
+			return null;
+		} else {
+			return Lib.fromNativeType(t);
+		}
+	}
+
+
+	public static function resolveEnum( name : String ) : Enum<Dynamic> untyped
 	{
-		return null;
+		if (name == "Bool") return Bool;
+		return cast resolveClass(name);
 	}
 
-	public static function createInstance<T>( cl : Class<T>, args : Array<Dynamic> ) : T untyped 
+	public static function createInstance<T>( cl : Class<T>, args : Array<Dynamic> ) : T
 	{
-		return null;
+		var t:system.Type = Lib.toNativeType(cl);
+		var ctors = t.GetConstructors();
+		return Runtime.callMethod(t, cast ctors, ctors.Length, args);
 	}
 
-	public static function createEmptyInstance<T>( cl : Class<T> ) : T untyped 
+	public static function createEmptyInstance<T>( cl : Class<T> ) : T 
 	{
-		return null;
-	}
-
+		if (Reflect.hasField(cl, "__hx_createEmpty"))
+			return untyped cl.__hx_createEmpty();
+		return createInstance(cl, []);
+	}
+	
+	@:functionBody('
+		if (@params == null) 
+		{
+			object ret = haxe.lang.Runtime.slowGetField(e, constr, false);
+			if (ret is haxe.lang.Function)
+				throw haxe.lang.HaxeException.wrap("Constructor " + constr + " needs parameters");
+			return (T) ret;
+		} else {
+			return (T) haxe.lang.Runtime.slowCallField(e, constr, @params);
+		}
+	')
 	public static function createEnum<T>( e : Enum<T>, constr : String, ?params : Array<Dynamic> ) : T 
 	{
 		return null;
@@ -91,43 +154,78 @@ enum ValueType {
 	public static function createEnumIndex<T>( e : Enum<T>, index : Int, ?params : Array<Dynamic> ) : T {
 		return null;
 	}
+	
+	@:functionBody('
+		Array<object> ret = new Array<object>();
 
-	static function describe( t : Dynamic, fact : Bool ) : Array<String> untyped {
-		return null;
-	}
+        System.Reflection.MemberInfo[] mis = c.GetMembers(System.Reflection.BindingFlags.Public);
+        for (int i = 0; i < mis.Length; i++)
+        {
+            ret.push(mis[i].Name);
+        }
 
+		return ret;
+	')
 	public static function getInstanceFields( c : Class<Dynamic> ) : Array<String> {
 		return null;
 	}
+	
+	@:functionBody('
+		Array<object> ret = new Array<object>();
 
+        System.Reflection.MemberInfo[] mis = c.GetMembers(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
+        for (int i = 0; i < mis.Length; i++)
+        {
+            ret.push(mis[i].Name);
+        }
+
+        return ret;
+	')
 	public static function getClassFields( c : Class<Dynamic> ) : Array<String> {
 		return null;
 	}
 
 	public static function getEnumConstructs( e : Enum<Dynamic> ) : Array<String> {
-		return null;
+		if (Reflect.hasField(e, "constructs"))
+			return untyped e.constructs;
+		return getClassFields(cast e);
 	}
 
-	public static function typeof( v : Dynamic ) : ValueType untyped 
+	public static function typeof( v : Dynamic ) : ValueType 
 	{
 		return null;
 	}
 
-	public static function enumEq<T>( a : T, b : T ) : Bool untyped 
+	public static function enumEq<T>( a : T, b : T ) : Bool 
 	{
-		return true;
-	}
-
+		return untyped a.Equals(b);
+	}
+	
+	@:functionBody('
+		if (e is System.Enum)
+			return e + "";
+		else
+			return ((haxe.lang.Enum) e).getTag();
+	')
 	public static function enumConstructor( e : EnumValue ) : String untyped
 	{
 		return e.tag;
 	}
-
+	
+	@:functionBody('
+		return ( e is System.Enum ) ? new Array<object>() : ((haxe.lang.Enum) e).@params;
+	')
 	public static function enumParameters( e : EnumValue ) : Array<Dynamic> untyped
 	{
-		return if( e.params == null ) [] else e.params;
+		return null;
 	}
-
+	
+	@:functionBody('
+		if (e is System.Enum)
+			return ((System.IConvertible) e).ToInt32(null);
+		else
+			return ((haxe.lang.Enum) e).index;
+	')
 	public inline static function enumIndex( e : EnumValue ) : Int  untyped
 	{
 		return e.index;

File diff suppressed because it is too large
+ 0 - 0
std/cs/_std/haxe/lang/HxObject.hx


+ 16 - 0
std/cs/_std/haxe/lang/Null.hx

@@ -1,5 +1,21 @@
 package haxe.lang;
 
+@:classContents('
+	//This function is here to be used with Reflection, when the haxe.lang.Null type is known
+	public static haxe.lang.Null<T> _ofDynamic(object obj)
+	{
+		if (obj == null)
+		{
+			return new haxe.lang.Null<T>(default(T), false);
+		} else if (typeof(T).Equals(typeof(double))) {
+			return new haxe.lang.Null<T>((T) (object) haxe.lang.Runtime.toDouble(obj), true);
+		} else if (typeof(T).Equals(typeof(int))) {
+			return new haxe.lang.Null<T>((T) (object) haxe.lang.Runtime.toInt(obj), true);
+		} else {
+			return new haxe.lang.Null<T>((T) obj, true);
+		}
+	}
+')
 @:struct @:nativegen @:native("haxe.lang.Null") private class Nullable<T>
 {
 	

+ 165 - 56
std/cs/_std/haxe/lang/Runtime.hx

@@ -1,4 +1,11 @@
 package haxe.lang;
+import cs.Lib;
+import cs.NativeArray;
+import cs.NativeArray;
+import system.Activator;
+import system.IConvertible;
+import system.reflection.MethodBase;
+import system.Type;
 
 /**
  This class is meant for internal compiler use only. It provides the Haxe runtime
@@ -10,28 +17,28 @@ package haxe.lang;
 	public static object getField(haxe.lang.HxObject obj, string field, int fieldHash, bool throwErrors)
 	{
 		if (obj == null && !throwErrors) return null;
-		return obj.__hx_getField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, false, throwErrors, false);
+		return obj.__hx_getField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors, false);
 	}
 	
 	public static double getField_f(haxe.lang.HxObject obj, string field, int fieldHash, bool throwErrors)
 	{
 		if (obj == null && !throwErrors) return 0.0;
-		return obj.__hx_getField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, false, throwErrors);
+		return obj.__hx_getField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors);
 	}
 	
 	public static object setField(haxe.lang.HxObject obj, string field, int fieldHash, object value)
 	{
-		return obj.__hx_setField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, false, value);
+		return obj.__hx_setField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value);
 	}
 	
 	public static double setField_f(haxe.lang.HxObject obj, string field, int fieldHash, double value)
 	{
-		return obj.__hx_setField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, false, value);
+		return obj.__hx_setField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value);
 	}
 	
 	public static object callField(haxe.lang.HxObject obj, string field, int fieldHash, Array args)
 	{
-		return obj.__hx_invokeField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, false, args);
+		return obj.__hx_invokeField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, args);
 	}
 ')
 @:keep class Runtime 
@@ -193,22 +200,25 @@ package haxe.lang;
 				return null;
 		
 		System.Type t = obj as System.Type;
+		System.Reflection.BindingFlags bf;
         if (t == null)
 		{
 			t = obj.GetType();
+			bf = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy;
 		} else {
 			obj = null;
+			bf = System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public;
 		}
 
-		System.Reflection.FieldInfo f = t.GetField(field, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
+		System.Reflection.FieldInfo f = t.GetField(field, bf);
 		if (f != null)
 		{
-			return f.GetValue(obj);
+			return haxe.lang.Runtime.unbox(f.GetValue(obj));
 		} else {
-			System.Reflection.PropertyInfo prop = t.GetProperty(field, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
+			System.Reflection.PropertyInfo prop = t.GetProperty(field, bf);
 			if (prop == null)
 			{
-				System.Reflection.MethodInfo m = t.GetMethod(field,  System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
+				System.Reflection.MethodInfo m = t.GetMethod(field, bf);
 				if (m != null)
 				{
 					return new haxe.lang.Closure(obj, field, 0);
@@ -219,7 +229,7 @@ package haxe.lang;
 						return null;
 				}
 			}
-			return prop.GetValue(obj, null);
+			return haxe.lang.Runtime.unbox(prop.GetValue(obj, null));
 		}
 	
 	')
@@ -231,14 +241,17 @@ package haxe.lang;
 	@:functionBody('
 		if (obj == null) return false;
 		System.Type t = obj as System.Type;
+		System.Reflection.BindingFlags bf;
         if (t == null)
 		{
 			t = obj.GetType();
+			bf = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy;
 		} else {
 			obj = null;
+			bf = System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public;
 		}
 
-		System.Reflection.MemberInfo[] mi = t.GetMember(field, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
+		System.Reflection.MemberInfo[] mi = t.GetMember(field, bf);
 		return mi != null && mi.Length > 0;
 	')
 	public static function slowHasField(obj:Dynamic, field:String):Bool
@@ -251,20 +264,37 @@ package haxe.lang;
 			throw new System.NullReferenceException("Cannot access field \'" + field + "\' of null.");
 		
 		System.Type t = obj as System.Type;
+		System.Reflection.BindingFlags bf;
         if (t == null)
 		{
 			t = obj.GetType();
+			bf = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy;
 		} else {
 			obj = null;
+			bf = System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public;
 		}
 
-		System.Reflection.FieldInfo f = t.GetField(field, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
+		System.Reflection.FieldInfo f = t.GetField(field, bf);
 		if (f != null)
 		{
+			if (f.FieldType.ToString().StartsWith("haxe.lang.Null"))
+			{
+				@value = haxe.lang.Runtime.mkNullable(@value, f.FieldType);
+			}
+			
 			f.SetValue(obj, @value);
 			return @value;
 		} else {
-			System.Reflection.PropertyInfo prop = t.GetProperty(field, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
+			System.Reflection.PropertyInfo prop = t.GetProperty(field, bf);
+			if (prop == null)
+			{
+				throw haxe.lang.HaxeException.wrap("Field \'" + field + "\' not found for writing from Class " + t);
+			}
+			
+			if (prop.PropertyType.ToString().StartsWith("haxe.lang.Null"))
+			{
+				@value = haxe.lang.Runtime.mkNullable(@value, prop.PropertyType);
+			}
 			prop.SetValue(obj, @value, null);
 
 			return @value;
@@ -277,17 +307,113 @@ package haxe.lang;
 		throw "Not implemented";
 	}
 	
+	public static function callMethod(obj:Dynamic, methods:NativeArray<MethodBase>, methodLength:Int, args:Array<Dynamic>):Dynamic
+	{
+		var length = args.length;
+		var oargs:NativeArray<Dynamic> = new NativeArray(length);
+		var ts:NativeArray<system.Type> = new NativeArray(length);
+		
+		for (i in 0...length)
+		{
+			oargs[i] = args[i];
+			ts[i] = Lib.getNativeType(args[i]);
+		}
+		
+		var last = 0;
+		
+		//first filter by number of parameters and if it is assignable
+		if (methodLength > 1)
+		{
+			for (i in 0...methodLength)
+			{
+				var params = methods[i].GetParameters();
+				if (params.Length != length) {
+					continue;
+				} else {
+					var fits = true;
+					for (i in 0...params.Length)
+					{
+						var param = params[i].ParameterType;
+						var strParam = param + "";
+						if (untyped strParam.StartsWith("haxe.lang.Null") || ( (oargs[i] == null || Std.is(oargs[i], IConvertible) ) && cast(untyped __typeof__(IConvertible), Type).IsAssignableFrom(param) ))
+						{
+							continue;
+						} else if (!param.ContainsGenericParameters && !param.IsAssignableFrom(ts[i])) {
+							fits = false;
+							break;
+						}
+					}
+					
+					if (fits)
+					{
+						methods[last++] = methods[i];
+					}
+				}
+			}
+			
+			methodLength = last;
+		}
+		
+		//At this time, we should be left with only one method.
+		//Of course, realistically, we can be left with plenty of methods, if there are lots of variants with IConvertible
+		//But at this time we still aren't rating the best methods
+		//FIXME rate best methods
+		
+		if (methodLength == 0)
+			throw "Invalid calling parameters for method " + methods[0].Name;
+		
+		var params = methods[0].GetParameters();
+		for (i in 0...params.Length)
+		{
+			var param = params[i].ParameterType;
+			var strParam = param + "";
+			if (StringTools.startsWith(strParam, "haxe.lang.Null"))
+			{
+				oargs[i] = mkNullable(oargs[i], param);
+			} else if (cast(untyped __typeof__(IConvertible), Type).IsAssignableFrom(param)) {
+				if (oargs[i] == null) {
+					if (param.IsValueType)
+						oargs[i] = Activator.CreateInstance(param);
+				} else {
+					oargs[i] = cast(oargs[i], IConvertible).ToType(param, null);
+				}
+			}
+		}
+		
+		var ret = methods[0].Invoke(obj, oargs);
+		return unbox(ret);
+	}
+	
+	public static function unbox(dyn:Dynamic):Dynamic
+	{
+		if (dyn != null && untyped (Lib.getNativeType(dyn) + "").StartsWith("haxe.lang.Null"))
+		{
+			return dyn.toDynamic();
+		} else {
+			return dyn;
+		}
+	}
+	
+	@:functionBody('
+		return nullableType.GetMethod("_ofDynamic").Invoke(null, new object[] { obj });
+	')
+	public static function mkNullable(obj:Dynamic, nullableType:system.Type):Dynamic
+	{
+		return null;
+	}
+	
 	@:functionBody('
 		if (args == null) args = new Array<object>();
 		
+		System.Reflection.BindingFlags bf;
 		System.Type t = obj as System.Type;
 		if (t == null)
 		{
 			t = obj.GetType();
-		}
-		else
-		{
+			bf = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy;
+		} else {
 			obj = null;
+			bf = System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public;
 		}
 
 		int length = (int)haxe.lang.Runtime.getField_f(args, "length", 520590566, true);
@@ -298,9 +424,23 @@ package haxe.lang;
 			oargs[i] = args[i];
 			ts[i] = oargs[i].GetType();
 		}
-
-		System.Reflection.MethodInfo mi = t.GetMethod(field, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance, null, ts, null);
-		return mi.Invoke(obj, oargs);
+		
+		System.Reflection.MethodInfo[] mis = t.GetMethods(bf);
+		int last = 0;
+		for (int i = 0; i < mis.Length; i++)
+		{
+			if (mis[i].Name.Equals(field))
+			{
+				mis[last++] = mis[i];
+			}
+		}
+		
+		if (last == 0)
+		{
+			throw haxe.lang.HaxeException.wrap("Method \'" + field + "\' not found on type " + t);
+		}
+		
+		return haxe.lang.Runtime.callMethod(obj, mis, last, args);
 	')
 	public static function slowCallField(obj:Dynamic, field:String, args:Array<Dynamic>):Dynamic
 	{
@@ -310,7 +450,7 @@ package haxe.lang;
 	@:functionBody('
 		haxe.lang.HxObject hxObj = obj as haxe.lang.HxObject;
 		if (hxObj != null)
-			return hxObj.__hx_invokeField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, false, args);
+			return hxObj.__hx_invokeField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, args);
 		
 		return slowCallField(obj, field, args);
 	')
@@ -323,7 +463,7 @@ package haxe.lang;
 	
 		haxe.lang.HxObject hxObj = obj as haxe.lang.HxObject;
 		if (hxObj != null)
-			return hxObj.__hx_getField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, false, throwErrors, false);
+			return hxObj.__hx_getField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors, false);
 		
 		return slowGetField(obj, field, throwErrors);
 	
@@ -337,7 +477,7 @@ package haxe.lang;
 	
 		haxe.lang.HxObject hxObj = obj as haxe.lang.HxObject;
 		if (hxObj != null)
-			return hxObj.__hx_getField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, false, throwErrors);
+			return hxObj.__hx_getField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors);
 		
 		return (double)slowGetField(obj, field, throwErrors);
 	
@@ -351,7 +491,7 @@ package haxe.lang;
 	
 		haxe.lang.HxObject hxObj = obj as haxe.lang.HxObject;
 		if (hxObj != null)
-			return hxObj.__hx_setField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, false, value);
+			return hxObj.__hx_setField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value);
 		
 		return slowSetField(obj, field, value);
 	
@@ -362,10 +502,10 @@ package haxe.lang;
 	}
 	
 	@:functionBody('
-	
+
 		haxe.lang.HxObject hxObj = obj as haxe.lang.HxObject;
 		if (hxObj != null)
-			return hxObj.__hx_setField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, false, value);
+			return hxObj.__hx_setField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value);
 		
 		return (double)slowSetField(obj, field, value);
 	
@@ -375,37 +515,6 @@ package haxe.lang;
 		return 0.0;
 	}
 	
-	
-	private static var classes:Hash<Class<Dynamic>> = new Hash();
-	
-	public static function registerClass(name:String, cl:Class<Dynamic>):Void
-	{
-		classes.set(name, cl);
-	}
-	
-	public static function getClass(name:String, t:system.Type):Class<Dynamic>
-	{
-		var ret:Class<Dynamic> = classes.get(name);
-		if (ret == null)
-			return slowGetClass(name, t);
-		else
-			return ret;
-	}
-	
-	@:functionBody('
-	if (t == null)
-		t = System.Type.GetType(name, false, true);
-	
-	if (t == null)
-		return null;
-	
-	return null;
-	')
-	public static function slowGetClass(name:String, t:system.Type):Class<Dynamic>
-	{
-		return null;
-	}
-	
 	public static function toString(obj:Dynamic):String
 	{
 		if (obj == null) 

+ 6 - 0
std/cs/_std/system/Activator.hx

@@ -0,0 +1,6 @@
+package system;
+
+@:native('System.Activator') extern class Activator 
+{
+	static function CreateInstance(t:system.Type):Dynamic;
+}

+ 6 - 0
std/cs/_std/system/IConvertible.hx

@@ -0,0 +1,6 @@
+package system;
+
+@:native("System.IConvertible") extern interface IConvertible
+{
+	function ToType(conversionType:system.Type, provider:IFormatProvider):Dynamic;
+}

+ 6 - 0
std/cs/_std/system/IFormatProvider.hx

@@ -0,0 +1,6 @@
+package system;
+
+@:native("System.IFormatProvider") extern interface IFormatProvider
+{
+	
+}

+ 8 - 1
std/cs/_std/system/Type.hx

@@ -1,9 +1,16 @@
 package system;
+import cs.NativeArray;
+import system.reflection.ConstructorInfo;
 
 @:native("System.Type")
 extern class Type 
 {
-	
+	public var BaseType(default, null):Type;
+	public var IsInterface(default, null):Bool;
+	public var ContainsGenericParameters(default, null):Bool;
+	public var IsValueType(default, null):Bool;
 	public function IsAssignableFrom(c:Type):Bool;
 	
+	public static function GetType(name:String):Null<Type>;
+	public function GetConstructors():NativeArray<ConstructorInfo>;
 }

+ 6 - 0
std/cs/_std/system/reflection/ConstructorInfo.hx

@@ -0,0 +1,6 @@
+package system.reflection;
+import cs.NativeArray;
+
+@:native('System.Reflection.ConstructorInfo') extern class ConstructorInfo extends MethodBase
+{
+}

+ 9 - 0
std/cs/_std/system/reflection/MethodBase.hx

@@ -0,0 +1,9 @@
+package system.reflection;
+import cs.NativeArray;
+
+@:native('System.Reflection.MethodBase') extern class MethodBase 
+{
+	var Name(default, null):String;
+	function GetParameters():NativeArray<ParameterInfo>;
+	function Invoke(obj:Dynamic, args:NativeArray<Dynamic>):Dynamic;
+}

+ 6 - 0
std/cs/_std/system/reflection/ParameterInfo.hx

@@ -0,0 +1,6 @@
+package system.reflection;
+
+@:native('System.Reflection.ParameterInfo') extern class ParameterInfo 
+{
+	var ParameterType(default, null):system.Type;
+}

+ 2 - 3
std/java/_std/Type.hx

@@ -83,7 +83,6 @@ enum ValueType {
 			case "int", "java.lang.Integer": "Int";
 			case "double", "java.lang.Double": "Float";
 			case "java.lang.String": "String";
-			case "boolean", "java.lang.Boolean": "Bool";
 			default: name;
 		}
 	}
@@ -247,10 +246,10 @@ enum ValueType {
 	@:functionBody('
 		if (params == null) 
 		{
-			T ret = (T) haxe.lang.Runtime.slowGetField(e, constr, false);
+			java.lang.Object ret = haxe.lang.Runtime.slowGetField(e, constr, false);
 			if (ret instanceof haxe.lang.Function)
 				throw haxe.lang.HaxeException.wrap("Constructor " + constr + " needs parameters");
-			return ret;
+			return (T) ret;
 		} else {
 			return (T) haxe.lang.Runtime.slowCallField(e, constr, params);
 		}

Some files were not shown because too many files changed in this diff