Explorar o código

[cs] Started to work on being culture invariant. Started to tackle Issue #996; Transformed Runtime.compare to haxe code. Fixed enum to int on native C# enums. Closes #2931

Cauê Waneck %!s(int64=11) %!d(string=hai) anos
pai
achega
1cd97a3fa4
Modificáronse 6 ficheiros con 101 adicións e 80 borrados
  1. 13 3
      gencs.ml
  2. 1 1
      libs
  3. 2 1
      std/cs/_std/String.hx
  4. 72 74
      std/cs/internal/Runtime.hx
  5. 4 0
      tests/unit/Test.hx
  6. 9 1
      typeload.ml

+ 13 - 3
gencs.ml

@@ -411,9 +411,9 @@ struct
 				| TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = "length" })) ->
 					{ e with eexpr = TField(run ef, FDynamic "Length") }
 				| TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = "toLowerCase" })) ->
-					{ e with eexpr = TField(run ef, FDynamic "ToLower") }
+					{ e with eexpr = TField(run ef, FDynamic "ToLowerInvariant") }
 				| TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = "toUpperCase" })) ->
-					{ e with eexpr = TField(run ef, FDynamic "ToUpper") }
+					{ e with eexpr = TField(run ef, FDynamic "ToUpperInvariant") }
 
 				| TCall( { eexpr = TField(_, FStatic({ cl_path = [], "String" }, { cf_name = "fromCharCode" })) }, [cc] ) ->
 					{ e with eexpr = TNew(get_cl_from_t basic.tstring, [], [mk_cast tchar (run cc); mk_int gen 1 cc.epos]) }
@@ -2927,7 +2927,17 @@ let convert_ilenum ctx p ilcls =
 	List.iter (fun f -> match f.fname with
 		| "value__" -> ()
 		| _ ->
-			data := { ec_name = f.fname; ec_doc = None; ec_meta = []; ec_args = []; ec_pos = p; ec_params = []; ec_type = None; } :: !data;
+			let meta = match f.fconstant with
+				| Some IChar i
+				| Some IByte i
+				| Some IShort i ->
+					[Meta.CsNative, [EConst (Int (string_of_int i) ), p], p ]
+				| Some IInt i ->
+					[Meta.CsNative, [EConst (Int (Int32.to_string i) ), p], p ]
+				| _ ->
+					[]
+			in
+			data := { ec_name = f.fname; ec_doc = None; ec_meta = meta; ec_args = []; ec_pos = p; ec_params = []; ec_type = None; } :: !data;
 	) ilcls.cfields;
 	let _, c = netpath_to_hx ctx.nstd ilcls.cpath in
 	EEnum {

+ 1 - 1
libs

@@ -1 +1 @@
-Subproject commit 0da911f4d0d9d2dc2972cf21db3b0b7d6e1e6bf4
+Subproject commit 99fff320911ee1cc513f473fc32b68a5cbaddc36

+ 2 - 1
std/cs/_std/String.hx

@@ -23,7 +23,8 @@ import cs.StdTypes;
 
 @:coreApi extern class String implements ArrayAccess<Char16> {
 
-	private static function Compare(s1:String, s2:String):Int;
+	@:overload private static function Compare(s1:String, s2:String):Int;
+	@:overload private static function Compare(s1:String, s2:String, kind:cs.system.StringComparison):Int;
 
 	var length(default,null) : Int;
 

+ 72 - 74
std/cs/internal/Runtime.hx

@@ -25,9 +25,11 @@ import cs.NativeArray;
 import cs.NativeArray;
 import cs.system.Activator;
 import cs.system.IConvertible;
+import cs.system.IComparable;
 import cs.system.reflection.MethodBase;
 import cs.system.reflection.MethodInfo;
 import cs.system.Type;
+import cs.system.Object;
 
 /**
  This class is meant for internal compiler use only. It provides the Haxe runtime
@@ -36,6 +38,7 @@ import cs.system.Type;
 
 @:nativeGen
 @:native('haxe.lang.Runtime')
+@:access(String)
 @:classCode('
 	public static object getField(haxe.lang.HxObject obj, string field, int fieldHash, bool throwErrors)
 	{
@@ -225,87 +228,82 @@ import cs.system.Type;
 		return false;
 	}
 
-	@:functionCode('
-			if (v1 == v2) return 0;
-			if (v1 == null) return -1;
-			if (v2 == null) return 1;
-			System.IConvertible cv1 = v1 as System.IConvertible;
-			if (cv1 != null)
-			{
-				System.IConvertible cv2 = v2 as System.IConvertible;
-
-				if (cv2 == null)
-				{
-					throw new System.ArgumentException("Cannot compare " + v1.GetType().ToString() + " and " + v2.GetType().ToString());
-				}
+	public static function compare(v1:Dynamic, v2:Dynamic):Int
+	{
+		if (Object.ReferenceEquals(v1,v2)) return 0;
+		if (Object.ReferenceEquals(v1,null)) return -1;
+		if (Object.ReferenceEquals(v2,null)) return 1;
 
-				switch(cv1.GetTypeCode())
-				{
-					case System.TypeCode.String:
-						if (cv2.GetTypeCode() != System.TypeCode.String)
-							throw new System.ArgumentException("Cannot compare " + v1.GetType().ToString() + " and " + v2.GetType().ToString());
-						string s1 = v1 as string;
-						string s2 = v2 as string;
-						int i =0;
-						int l1 = s1.Length;
-						int l2 = s2.Length;
-						bool active = true;
-						while(active)
-						{
-							char h1; char h2;
-							if (i >= l1)
-							{
-								h1 = (char) 0;
-								active = false;
-							} else {
-								h1 = s1[i];
-							}
-
-							if (i >= l2)
-							{
-								h2 = (char) 0;
-								active = false;
-							} else {
-								h2 = s2[i];
-							}
-
-							int v = h1 - h2;
-							if (v > 0)
-								return 1;
-							else if (v < 0)
-								return -1;
-
-							i++;
-						}
-						return 0;
-					case System.TypeCode.Double:
-					double d1 = (double) v1;
-					double d2 = cv2.ToDouble(null);
+		var cv1 = Lib.as(v1, IConvertible);
+		if (cv1 != null)
+		{
+			var cv2 = Lib.as(v2, IConvertible);
 
-          return (d1 < d2) ? -1 : (d1 > d2) ? 1 : 0;
-					default:
-            double d1d = cv1.ToDouble(null);
-            double d2d = cv2.ToDouble(null);
-            return (d1d < d2d) ? -1 : (d1d > d2d) ? 1 : 0;
-				}
+			if (cv2 == null)
+			{
+				throw new cs.system.ArgumentException("Cannot compare " + v1.GetType().ToString() + " and " + v2.GetType().ToString());
 			}
 
-			System.IComparable c1 = v1 as System.IComparable;
-			System.IComparable c2 = v2 as System.IComparable;
-
-			if (c1 == null || c2 == null)
+			switch(cv1.GetTypeCode())
 			{
-				if (c1 == c2)
-					return 0;
-
-				throw new System.ArgumentException("Cannot compare " + v1.GetType().ToString() + " and " + v2.GetType().ToString());
+				case cs.system.TypeCode.String:
+					if (cv2.GetTypeCode() != cs.system.TypeCode.String)
+						throw new cs.system.ArgumentException("Cannot compare " + v1.GetType().ToString() + " and " + v2.GetType().ToString());
+					var s1 = Lib.as(v1,String);
+					var s2 = Lib.as(v2,String);
+					var i = 0,
+							l1 = s1.length,
+							l2 = s2.length;
+					return String.Compare(s1,s2, cs.system.StringComparison.Ordinal);
+					// bool active = true;
+					// while(active)
+					// {
+					// 	char h1; char h2;
+					// 	if (i >= l1)
+					// 	{
+					// 		h1 = (char) 0;
+					// 		active = false;
+					// 	} else {
+					// 		h1 = s1[i];
+					// 	}
+
+					// 	if (i >= l2)
+					// 	{
+					// 		h2 = (char) 0;
+					// 		active = false;
+					// 	} else {
+					// 		h2 = s2[i];
+					// 	}
+
+					// 	int v = h1 - h2;
+					// 	if (v > 0)
+					// 		return 1;
+					// 	else if (v < 0)
+					// 		return -1;
+
+					// 	i++;
+					// }
+					// return 0;
+				case cs.system.TypeCode.Double:
+					var d1:Float = cast v1,
+							d2:Float = cv2.ToDouble(null);
+					return (d1 < d2) ? -1 : (d1 > d2) ? 1 : 0;
+				default:
+					var d1d = cv1.ToDouble(null);
+					var d2d = cv2.ToDouble(null);
+					return (d1d < d2d) ? -1 : (d1d > d2d) ? 1 : 0;
 			}
+		}
 
-			return c1.CompareTo(c2);
-	')
-	public static function compare(v1:Dynamic, v2:Dynamic):Int
-	{
-		return 0;
+		var c1 = Lib.as(v1, IComparable);
+		var c2 = Lib.as(v2, IComparable);
+
+		if (c1 == null || c2 == null)
+		{
+			throw new cs.system.ArgumentException("Cannot compare " + v1.GetType().ToString() + " and " + v2.GetType().ToString());
+		}
+
+		return c1.CompareTo(c2);
 	}
 
 	@:functionCode('

+ 4 - 0
tests/unit/Test.hx

@@ -228,6 +228,10 @@ class Test #if swf_mark implements mt.Protect #end {
 	}
 
 	static function main() {
+		#if cs //"Turkey Test" - Issue #996
+		cs.system.threading.Thread.CurrentThread.CurrentCulture = new cs.system.globalization.CultureInfo('tr-TR');
+		cs.Lib.applyCultureChanges();
+		#end
 		#if neko
 		if( neko.Web.isModNeko )
 			neko.Web.setHeader("Content-Type","text/plain");

+ 9 - 1
typeload.ml

@@ -2527,12 +2527,20 @@ let rec init_module_type ctx context_init do_init (decl,p) =
 					) l, rt)
 			) in
 			if PMap.mem c.ec_name e.e_constrs then error ("Duplicate constructor " ^ c.ec_name) p;
+			let eindex = try
+				match Meta.get Meta.CsNative c.ec_meta with
+					| (Meta.CsNative,[EConst (Int i), _], _) ->
+							int_of_string i
+					| _ -> raise Not_found
+				with Not_found ->
+					!index
+			in
 			let f = {
 				ef_name = c.ec_name;
 				ef_type = t;
 				ef_pos = p;
 				ef_doc = c.ec_doc;
-				ef_index = !index;
+				ef_index = eindex;
 				ef_params = params;
 				ef_meta = c.ec_meta;
 			} in