Commit 2fef85e7 authored by vosen's avatar vosen

Add support for enums in non-default constructor initalization and fix earlier test

parent b772a7bc
...@@ -1469,6 +1469,7 @@ static List<FieldInfo> GetSettableFields(Type t) ...@@ -1469,6 +1469,7 @@ static List<FieldInfo> GetSettableFields(Type t)
il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Stloc_0);
var properties = GetSettableProps(type); var properties = GetSettableProps(type);
var fields = GetSettableFields(type); var fields = GetSettableFields(type);
int enumOffset = 0;
if (length == -1) if (length == -1)
{ {
length = reader.FieldCount - startBound; length = reader.FieldCount - startBound;
...@@ -1510,15 +1511,32 @@ static List<FieldInfo> GetSettableFields(Type t) ...@@ -1510,15 +1511,32 @@ static List<FieldInfo> GetSettableFields(Type t)
{ {
types[i - startBound] = reader.GetFieldType(i); types[i - startBound] = reader.GetFieldType(i);
} }
var ctorWithParameters = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, types, null); var constructors = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (ctorWithParameters != null) foreach(ConstructorInfo ctor in constructors)
{ {
var ctorParams = ctorWithParameters.GetParameters(); ParameterInfo[] ctorParameters = ctor.GetParameters();
for(int i =0; i< ctorParams.Length; i++) if (ctorParameters.Length != types.Length)
continue;
int i = 0;
int ctorEnums = 0;
for (; i < ctorParameters.Length; i++)
{
if (!String.Equals(ctorParameters[i].Name, names[i], StringComparison.OrdinalIgnoreCase)
|| (types[i] != ctorParameters[i].ParameterType
#if CSHARP30
))
#else
&& (ctorParameters[i].ParameterType.IsEnum && ctorParameters[i].ParameterType.GetEnumUnderlyingType() != types[i])))
#endif
break;
if (ctorParameters[i].ParameterType.IsEnum)
ctorEnums++;
}
if (i == ctorParameters.Length)
{ {
if (!String.Equals(ctorParams[i].Name, names[i], StringComparison.OrdinalIgnoreCase)) specializedConstructor = ctor;
enumOffset = ctorEnums;
break; break;
specializedConstructor = ctorWithParameters;
} }
} }
if(specializedConstructor == null) if(specializedConstructor == null)
...@@ -1546,6 +1564,9 @@ static List<FieldInfo> GetSettableFields(Type t) ...@@ -1546,6 +1564,9 @@ static List<FieldInfo> GetSettableFields(Type t)
bool first = true; bool first = true;
var allDone = il.DefineLabel(); var allDone = il.DefineLabel();
if (!haveEnumLocal)
il.DeclareLocal(typeof(string));
foreach (var item in setters) foreach (var item in setters)
{ {
if (item.Property != null || item.Field != null) if (item.Property != null || item.Field != null)
...@@ -1581,12 +1602,6 @@ static List<FieldInfo> GetSettableFields(Type t) ...@@ -1581,12 +1602,6 @@ static List<FieldInfo> GetSettableFields(Type t)
if (unboxType.IsEnum) if (unboxType.IsEnum)
{ {
if (!haveEnumLocal)
{
il.DeclareLocal(typeof(string));
haveEnumLocal = true;
}
Label isNotString = il.DefineLabel(); Label isNotString = il.DefineLabel();
il.Emit(OpCodes.Dup); // stack is now [target][target][value][value] il.Emit(OpCodes.Dup); // stack is now [target][target][value][value]
il.Emit(OpCodes.Isinst, typeof(string)); // stack is now [target][target][value-as-object][string or null] il.Emit(OpCodes.Isinst, typeof(string)); // stack is now [target][target][value-as-object][string or null]
...@@ -1668,9 +1683,9 @@ static List<FieldInfo> GetSettableFields(Type t) ...@@ -1668,9 +1683,9 @@ static List<FieldInfo> GetSettableFields(Type t)
if (itemType.IsValueType) if (itemType.IsValueType)
{ {
il.DeclareLocal(itemType); il.DeclareLocal(itemType);
il.Emit(OpCodes.Ldloca_S, (byte)(index + 2)); il.Emit(OpCodes.Ldloca_S, (byte)(index + enumOffset + 2));
il.Emit(OpCodes.Initobj, itemType); il.Emit(OpCodes.Initobj, itemType);
il.Emit(OpCodes.Ldloc, (short)(index + 2)); il.Emit(OpCodes.Ldloc, (short)(index + enumOffset + 2));
} }
else else
{ {
......
...@@ -48,7 +48,7 @@ public NoDefaultConstructor(int a, float f, ShortEnum e) ...@@ -48,7 +48,7 @@ public NoDefaultConstructor(int a, float f, ShortEnum e)
public void TestNoDefaultConstructor() public void TestNoDefaultConstructor()
{ {
NoDefaultConstructor nodef = connection.Query<NoDefaultConstructor>("select CAST(NULL AS integer) A, CAST(NULL AS real) f, cast(null as smallint) E").First(); NoDefaultConstructor nodef = connection.Query<NoDefaultConstructor>("select CAST(NULL AS integer) A, CAST(NULL AS real) f, cast(2 as smallint) E").First();
nodef.A.IsEqualTo(0); nodef.A.IsEqualTo(0);
nodef.F.IsEqualTo(0); nodef.F.IsEqualTo(0);
nodef.E.IsEqualTo(ShortEnum.Two); nodef.E.IsEqualTo(ShortEnum.Two);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment