Browse Source

[cs] Fix some enum-related problems, and fix spod SEnum creation

Cauê Waneck 10 years ago
parent
commit
719b5960f6

+ 12 - 6
gencs.ml

@@ -3162,18 +3162,24 @@ let convert_ilenum ctx p ilcls =
 	List.iter (fun f -> match f.fname with
 		| "value__" -> ()
 		| _ ->
-			let meta = match f.fconstant with
+			let meta, const = match f.fconstant with
 				| Some IChar i
 				| Some IByte i
 				| Some IShort i ->
-					[Meta.CsNative, [EConst (Int (string_of_int i) ), p], p ]
+					[Meta.CsNative, [EConst (Int (string_of_int i) ), p], p ], Int64.of_int i
 				| Some IInt i ->
-					[Meta.CsNative, [EConst (Int (Int32.to_string i) ), p], p ]
+					[Meta.CsNative, [EConst (Int (Int32.to_string i) ), p], p ], Int64.of_int32 i
+				| Some IFloat32 f | Some IFloat64 f ->
+					[], Int64.of_float f
+				| Some IInt64 i ->
+					[], i
 				| _ ->
-					[]
+					[], Int64.zero
 			in
-			data := { ec_name = f.fname; ec_doc = None; ec_meta = meta; ec_args = []; ec_pos = p; ec_params = []; ec_type = None; } :: !data;
+			data := ( { ec_name = f.fname; ec_doc = None; ec_meta = meta; ec_args = []; ec_pos = p; ec_params = []; ec_type = None; }, const) :: !data;
 	) ilcls.cfields;
+	let data = List.stable_sort (fun (_,i1) (_,i2) -> Int64.compare i1 i2) (List.rev !data) in
+
 	let _, c = netpath_to_hx ctx.nstd ilcls.cpath in
 	EEnum {
 		d_name = netname_to_hx c;
@@ -3181,7 +3187,7 @@ let convert_ilenum ctx p ilcls =
 		d_params = []; (* enums never have type parameters *)
 		d_meta = !meta;
 		d_flags = [EExtern];
-		d_data = List.rev !data;
+		d_data = List.map fst data;
 	}
 
 let rec has_unmanaged = function

+ 5 - 3
std/sys/db/RecordMacros.hx

@@ -1171,7 +1171,7 @@ class RecordMacros {
 
 	static var isNeko = Context.defined("neko");
 
-	static function buildField( f : Field, fields : Array<Field>, ft : ComplexType, rt : ComplexType ) {
+	static function buildField( f : Field, fields : Array<Field>, ft : ComplexType, rt : ComplexType, isNull=false ) {
 		var p = switch( ft ) {
 		case TPath(p): p;
 		default: return;
@@ -1236,13 +1236,15 @@ class RecordMacros {
 				args : [{ name : "_v", opt : false, type : t, value : null }],
 				params : [],
 				ret : t,
-				expr : macro { $efield = _v == null ? null : cast Type.enumIndex(_v); return _v; },
+				expr : (Context.defined('cs') && !isNull) ?
+					macro { $efield = cast Type.enumIndex(_v); return _v; } :
+					macro { $efield = _v == null ? null : cast Type.enumIndex(_v); return _v; },
 			};
 			fields.push( { name : "get_" + f.name, pos : pos, meta : meta, access : [APrivate], doc : null, kind : FFun(get) } );
 			fields.push( { name : "set_" + f.name, pos : pos, meta : meta, access : [APrivate], doc : null, kind : FFun(set) } );
 			fields.push( { name : dataName, pos : pos, meta : [meta[0], { name:":skip", params:[], pos:pos } ], access : [APrivate], doc : null, kind : FVar(macro : Null<Int>, null) } );
 		case "SNull", "Null":
-			buildField(f, fields, t, rt);
+			buildField(f, fields, t, rt,true);
 		}
 	}
 

+ 2 - 0
tests/unit/native_cs/hxcs_build.txt

@@ -8,6 +8,8 @@ M haxe.test.MyClass
 C haxe.test.MyClass
 M haxe.test.TEnum
 E haxe.test.TEnum
+M haxe.test.TEnumWithValue
+E haxe.test.TEnumWithValue
 M haxe.test.Base
 C haxe.test.Base
 M haxe.test.Generic1

+ 9 - 0
tests/unit/native_cs/src/haxe/test/TEnumWithValue.cs

@@ -0,0 +1,9 @@
+namespace haxe.test
+{
+
+public enum TEnumWithValue
+{
+	TVA = 0x100,TVB = 0x1,TVD = 0x10, TVC = 0x20
+}
+
+}

+ 9 - 0
tests/unit/src/unit/SimpleEnum.hx

@@ -0,0 +1,9 @@
+package unit;
+
+enum SimpleEnum
+{
+	SE_A;
+	SE_B;
+	SE_C;
+	SE_D;
+}

+ 54 - 0
tests/unit/src/unit/TestCSharp.hx

@@ -3,6 +3,7 @@ import haxe.io.Bytes;
 import haxe.test.Base;
 import haxe.test.Base.Base_InnerClass;
 import haxe.test.TEnum;
+import haxe.test.TEnumWithValue;
 #if unsafe
 import cs.Pointer;
 #end
@@ -233,8 +234,61 @@ class TestCSharp extends Test
 				t(false);
 		}
 		eq("TA",Type.enumConstructor(e));
+
+		eq(0, Type.enumIndex(TEnum.TA));
+		eq(0, Type.enumIndex(getTA()));
+		eq(3, Type.enumIndex(TEnumWithValue.TVA));
+		eq(3, Type.enumIndex(getTVA()));
+
+		eq(0, Type.enumIndex(TEnumWithValue.TVB));
+		eq(0, Type.enumIndex(getTVB()));
+		eq(1, Type.enumIndex(TEnum.TB));
+		eq(1, Type.enumIndex(getTB()));
+
+		eq(2, Type.enumIndex(TEnum.TC));
+		eq(2, Type.enumIndex(getTC()));
+		eq(2, Type.enumIndex(TEnumWithValue.TVC));
+		eq(2, Type.enumIndex(getTVC()));
+
+		eq(1, Type.enumIndex(TEnumWithValue.TVD));
+		eq(1, Type.enumIndex(getTVD()));
+
+		checkEnum(TEnum,0,TEnum.TA);
+		checkEnum(TEnum,1,TEnum.TB);
+		checkEnum(TEnum,2,TEnum.TC);
+
+		checkEnum(TEnumWithValue,3,TEnumWithValue.TVA);
+		checkEnum(TEnumWithValue,0,TEnumWithValue.TVB);
+		checkEnum(TEnumWithValue,2,TEnumWithValue.TVC);
+		checkEnum(TEnumWithValue,1,TEnumWithValue.TVD);
+		// trace( getArray(cs.system.Enum.GetValues(untyped TEnum)) );
+		// trace( getArray(cs.system.Enum.GetNames(untyped TEnum)) );
+		// trace( getArray(cs.system.Enum.GetValues(untyped TEnumWithValue)) );
+		// trace( getArray(cs.system.Enum.GetNames(untyped TEnumWithValue)) );
+		// trace( Type.getEnumConstructs(TEnum) );
+		// trace( Type.getEnumConstructs(TEnumWithValue) );
+		// trace( Type.allEnums(TEnum) );
+		// trace( Type.allEnums(TEnumWithValue) );
 	}
 
+	private static function getArray(arr:cs.system.Array)
+	{
+		return [ for (i in 0...arr.Length) arr.GetValue(i) ];
+	}
+
+	function checkEnum<T>(e:Enum<T>,idx:Int,v:T,?pos:haxe.PosInfos)
+	{
+		eq(v,Type.createEnumIndex(e,idx),pos);
+	}
+
+	function getTA() return TEnum.TA;
+	function getTVA() return TEnumWithValue.TVA;
+	function getTB() return TEnum.TB;
+	function getTVB() return TEnumWithValue.TVB;
+	function getTC() return TEnum.TC;
+	function getTVC() return TEnumWithValue.TVC;
+	function getTVD() return TEnumWithValue.TVD;
+
 	@:skipReflection private function refTest(i:cs.Ref<Int>):Void
 	{
 		i *= 2;

+ 7 - 1
tests/unit/src/unit/TestSerialize.hx

@@ -138,6 +138,12 @@ class TestSerialize extends Test {
 			case C(_,_): true;
 			default: false;
 		});
+
+		eq( id(SimpleEnum.SE_A), SimpleEnum.SE_A );
+		eq( id(SimpleEnum.SE_B), SimpleEnum.SE_B );
+		eq( id(SimpleEnum.SE_C), SimpleEnum.SE_C );
+		eq( id(SimpleEnum.SE_D), SimpleEnum.SE_D );
+		t( id(SimpleEnum.SE_A) == SimpleEnum.SE_A );
 	}
 
 	function doTestCollection( a : Array<Dynamic> ) {
@@ -164,4 +170,4 @@ class TestSerialize extends Test {
 		infos(null);
 	}
 
-}
+}