summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Build.Tasks
diff options
context:
space:
mode:
authorStephane Delcroix <stephane@delcroix.org>2016-09-27 20:10:39 +0200
committerJason Smith <jason.smith@xamarin.com>2016-09-27 11:10:39 -0700
commit3e0ee965d710768f1c434b469f8c1c8371b7659a (patch)
tree1c5fe29f542e098ec68f3f0a029df380e07c41e6 /Xamarin.Forms.Build.Tasks
parent0f7b22f49d767c3ae522641c324e7ef6928719b4 (diff)
downloadxamarin-forms-3e0ee965d710768f1c434b469f8c1c8371b7659a.tar.gz
xamarin-forms-3e0ee965d710768f1c434b469f8c1c8371b7659a.tar.bz2
xamarin-forms-3e0ee965d710768f1c434b469f8c1c8371b7659a.zip
[Xaml] more primitive types (#385)
* [Xaml] more builtin conversion, and more type primitives * [XamlC] more builtin conversion, more type primitives
Diffstat (limited to 'Xamarin.Forms.Build.Tasks')
-rw-r--r--Xamarin.Forms.Build.Tasks/CreateObjectVisitor.cs410
-rw-r--r--Xamarin.Forms.Build.Tasks/NodeILExtensions.cs72
2 files changed, 272 insertions, 210 deletions
diff --git a/Xamarin.Forms.Build.Tasks/CreateObjectVisitor.cs b/Xamarin.Forms.Build.Tasks/CreateObjectVisitor.cs
index 33a9a7f5..6d6405e1 100644
--- a/Xamarin.Forms.Build.Tasks/CreateObjectVisitor.cs
+++ b/Xamarin.Forms.Build.Tasks/CreateObjectVisitor.cs
@@ -317,18 +317,22 @@ namespace Xamarin.Forms.Build.Tasks
if (node.NamespaceURI != "clr-namespace:System;assembly=mscorlib")
return false;
var name = node.XmlType.Name.Split(':')[1];
- if (name == "Boolean" ||
- name == "String" ||
- name == "Char" ||
- name == "Decimal" ||
- name == "Single" ||
- name == "Double" ||
- name == "Byte" ||
- name == "Int16" ||
- name == "Int32" ||
- name == "Int64" ||
- name == "TimeSpan" ||
- name == "Uri")
+ if (name == "SByte" ||
+ name == "Int16" ||
+ name == "Int32" ||
+ name == "Int64" ||
+ name == "Byte" ||
+ name == "UInt16" ||
+ name == "UInt32" ||
+ name == "UInt64" ||
+ name == "Single" ||
+ name == "Double" ||
+ name == "Boolean" ||
+ name == "String" ||
+ name == "Char" ||
+ name == "Decimal" ||
+ name == "TimeSpan" ||
+ name == "Uri")
return true;
return false;
}
@@ -338,190 +342,206 @@ namespace Xamarin.Forms.Build.Tasks
var hasValue = node.CollectionItems.Count == 1 && node.CollectionItems[0] is ValueNode &&
((ValueNode)node.CollectionItems[0]).Value is string;
var valueString = hasValue ? ((ValueNode)node.CollectionItems[0]).Value as string : string.Empty;
- switch (typedef.FullName)
- {
- case "System.Boolean":
- bool outbool;
- if (hasValue && bool.TryParse(valueString, out outbool))
- yield return Instruction.Create(outbool ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
- else
- yield return Instruction.Create(OpCodes.Ldc_I4_0);
- break;
- case "System.String":
+ switch (typedef.FullName) {
+ case "System.SByte":
+ sbyte outsbyte;
+ if (hasValue && sbyte.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outsbyte))
+ yield return Instruction.Create(OpCodes.Ldc_I4, (int)outsbyte);
+ else
+ yield return Instruction.Create(OpCodes.Ldc_I4, 0x00);
+ break;
+ case "System.Int16":
+ short outshort;
+ if (hasValue && short.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outshort))
+ yield return Instruction.Create(OpCodes.Ldc_I4, outshort);
+ else
+ yield return Instruction.Create(OpCodes.Ldc_I4, 0x00);
+ break;
+ case "System.Int32":
+ int outint;
+ if (hasValue && int.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outint))
+ yield return Instruction.Create(OpCodes.Ldc_I4, outint);
+ else
+ yield return Instruction.Create(OpCodes.Ldc_I4, 0x00);
+ break;
+ case "System.Int64":
+ long outlong;
+ if (hasValue && long.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outlong))
+ yield return Instruction.Create(OpCodes.Ldc_I8, outlong);
+ else
+ yield return Instruction.Create(OpCodes.Ldc_I8, 0L);
+ break;
+ case "System.Byte":
+ byte outbyte;
+ if (hasValue && byte.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outbyte))
+ yield return Instruction.Create(OpCodes.Ldc_I4, (int)outbyte);
+ else
+ yield return Instruction.Create(OpCodes.Ldc_I4, 0x00);
+ break;
+ case "System.UInt16":
+ short outushort;
+ if (hasValue && short.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outushort))
+ yield return Instruction.Create(OpCodes.Ldc_I4, outushort);
+ else
+ yield return Instruction.Create(OpCodes.Ldc_I4, 0x00);
+ break;
+ case "System.UInt32":
+ int outuint;
+ if (hasValue && int.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outuint))
+ yield return Instruction.Create(OpCodes.Ldc_I4, outuint);
+ else
+ yield return Instruction.Create(OpCodes.Ldc_I4, 0x00);
+ break;
+ case "System.UInt64":
+ long outulong;
+ if (hasValue && long.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outulong))
+ yield return Instruction.Create(OpCodes.Ldc_I8, outulong);
+ else
+ yield return Instruction.Create(OpCodes.Ldc_I8, 0L);
+ break;
+ case "System.Boolean":
+ bool outbool;
+ if (hasValue && bool.TryParse(valueString, out outbool))
+ yield return Instruction.Create(outbool ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
+ else
+ yield return Instruction.Create(OpCodes.Ldc_I4_0);
+ break;
+ case "System.String":
+ yield return Instruction.Create(OpCodes.Ldstr, valueString);
+ break;
+ case "System.Object":
+ var ctorinfo =
+ Context.Body.Method.Module.TypeSystem.Object.Resolve()
+ .Methods.FirstOrDefault(md => md.IsConstructor && !md.HasParameters);
+ var ctor = Context.Body.Method.Module.Import(ctorinfo);
+ yield return Instruction.Create(OpCodes.Newobj, ctor);
+ break;
+ case "System.Char":
+ char outchar;
+ if (hasValue && char.TryParse(valueString, out outchar))
+ yield return Instruction.Create(OpCodes.Ldc_I4, outchar);
+ else
+ yield return Instruction.Create(OpCodes.Ldc_I4, 0x00);
+ break;
+ case "System.Decimal":
+ decimal outdecimal;
+ if (hasValue && decimal.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outdecimal)) {
+ var vardef = new VariableDefinition(Context.Body.Method.Module.Import(typeof(decimal)));
+ Context.Body.Variables.Add(vardef);
+ //Use an extra temp var so we can push the value to the stack, just like other cases
+ // IL_0003: ldstr "adecimal"
+ // IL_0008: ldc.i4.s 0x6f
+ // IL_000a: call class [mscorlib]System.Globalization.CultureInfo class [mscorlib]System.Globalization.CultureInfo::get_InvariantCulture()
+ // IL_000f: ldloca.s 0
+ // IL_0011: call bool valuetype [mscorlib]System.Decimal::TryParse(string, valuetype [mscorlib]System.Globalization.NumberStyles, class [mscorlib]System.IFormatProvider, [out] valuetype [mscorlib]System.Decimal&)
+ // IL_0016: pop
yield return Instruction.Create(OpCodes.Ldstr, valueString);
- break;
- case "System.Object":
- var ctorinfo =
- Context.Body.Method.Module.TypeSystem.Object.Resolve()
- .Methods.FirstOrDefault(md => md.IsConstructor && !md.HasParameters);
- var ctor = Context.Body.Method.Module.Import(ctorinfo);
- yield return Instruction.Create(OpCodes.Newobj, ctor);
- break;
- case "System.Char":
- char outchar;
- if (hasValue && char.TryParse(valueString, out outchar))
- yield return Instruction.Create(OpCodes.Ldc_I4, outchar);
- else
- yield return Instruction.Create(OpCodes.Ldc_I4, 0x00);
- break;
- case "System.Decimal":
- decimal outdecimal;
- if (hasValue && decimal.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outdecimal))
- {
- var vardef = new VariableDefinition(Context.Body.Method.Module.Import(typeof (decimal)));
- Context.Body.Variables.Add(vardef);
- //Use an extra temp var so we can push the value to the stack, just like other cases
- // IL_0003: ldstr "adecimal"
- // IL_0008: ldc.i4.s 0x6f
- // IL_000a: call class [mscorlib]System.Globalization.CultureInfo class [mscorlib]System.Globalization.CultureInfo::get_InvariantCulture()
- // IL_000f: ldloca.s 0
- // IL_0011: call bool valuetype [mscorlib]System.Decimal::TryParse(string, valuetype [mscorlib]System.Globalization.NumberStyles, class [mscorlib]System.IFormatProvider, [out] valuetype [mscorlib]System.Decimal&)
- // IL_0016: pop
- yield return Instruction.Create(OpCodes.Ldstr, valueString);
- yield return Instruction.Create(OpCodes.Ldc_I4, 0x6f); //NumberStyles.Number
- var getInvariantInfo =
- Context.Body.Method.Module.Import(typeof (CultureInfo))
- .Resolve()
- .Properties.FirstOrDefault(pd => pd.Name == "InvariantCulture")
- .GetMethod;
- var getInvariant = Context.Body.Method.Module.Import(getInvariantInfo);
- yield return Instruction.Create(OpCodes.Call, getInvariant);
- yield return Instruction.Create(OpCodes.Ldloca, vardef);
- var tryParseInfo =
- Context.Body.Method.Module.Import(typeof (decimal))
- .Resolve()
- .Methods.FirstOrDefault(md => md.Name == "TryParse" && md.Parameters.Count == 4);
- var tryParse = Context.Body.Method.Module.Import(tryParseInfo);
- yield return Instruction.Create(OpCodes.Call, tryParse);
- yield return Instruction.Create(OpCodes.Pop);
- yield return Instruction.Create(OpCodes.Ldloc, vardef);
- }
- else
- {
- yield return Instruction.Create(OpCodes.Ldc_I4_0);
- var decimalctorinfo =
- Context.Body.Method.Module.Import(typeof (decimal))
- .Resolve()
- .Methods.FirstOrDefault(
- md => md.IsConstructor && md.Parameters.Count == 1 && md.Parameters[0].ParameterType.FullName == "System.Int32");
- var decimalctor = Context.Body.Method.Module.Import(decimalctorinfo);
- yield return Instruction.Create(OpCodes.Newobj, decimalctor);
- }
- break;
- case "System.Single":
- float outfloat;
- if (hasValue && float.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outfloat))
- yield return Instruction.Create(OpCodes.Ldc_R4, outfloat);
- else
- yield return Instruction.Create(OpCodes.Ldc_R4, 0f);
- break;
- case "System.Double":
- double outdouble;
- if (hasValue && double.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outdouble))
- yield return Instruction.Create(OpCodes.Ldc_R8, outdouble);
- else
- yield return Instruction.Create(OpCodes.Ldc_R8, 0d);
- break;
- case "System.Byte":
- byte outbyte;
- if (hasValue && byte.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outbyte))
- yield return Instruction.Create(OpCodes.Ldc_I4, (int)outbyte);
- else
- yield return Instruction.Create(OpCodes.Ldc_I4, 0x00);
- break;
- case "System.Int16":
- short outshort;
- if (hasValue && short.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outshort))
- yield return Instruction.Create(OpCodes.Ldc_I4, outshort);
- else
- yield return Instruction.Create(OpCodes.Ldc_I4, 0x00);
- break;
- case "System.Int32":
- int outint;
- if (hasValue && int.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outint))
- yield return Instruction.Create(OpCodes.Ldc_I4, outint);
- else
- yield return Instruction.Create(OpCodes.Ldc_I4, 0x00);
- break;
- case "System.Int64":
- long outlong;
- if (hasValue && long.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outlong))
- yield return Instruction.Create(OpCodes.Ldc_I8, outlong);
- else
- yield return Instruction.Create(OpCodes.Ldc_I8, 0L);
- break;
- case "System.TimeSpan":
- TimeSpan outspan;
- if (hasValue && TimeSpan.TryParse(valueString, CultureInfo.InvariantCulture, out outspan))
- {
- var vardef = new VariableDefinition(Context.Body.Method.Module.Import(typeof (TimeSpan)));
- Context.Body.Variables.Add(vardef);
- //Use an extra temp var so we can push the value to the stack, just like other cases
- yield return Instruction.Create(OpCodes.Ldstr, valueString);
- var getInvariantInfo =
- Context.Body.Method.Module.Import(typeof (CultureInfo))
- .Resolve()
- .Properties.FirstOrDefault(pd => pd.Name == "InvariantCulture")
- .GetMethod;
- var getInvariant = Context.Body.Method.Module.Import(getInvariantInfo);
- yield return Instruction.Create(OpCodes.Call, getInvariant);
- yield return Instruction.Create(OpCodes.Ldloca, vardef);
- var tryParseInfo =
- Context.Body.Method.Module.Import(typeof (TimeSpan))
- .Resolve()
- .Methods.FirstOrDefault(md => md.Name == "TryParse" && md.Parameters.Count == 3);
- var tryParse = Context.Body.Method.Module.Import(tryParseInfo);
- yield return Instruction.Create(OpCodes.Call, tryParse);
- yield return Instruction.Create(OpCodes.Pop);
- yield return Instruction.Create(OpCodes.Ldloc, vardef);
- }
- else
- {
- yield return Instruction.Create(OpCodes.Ldc_I8, 0L);
- var timespanctorinfo =
- Context.Body.Method.Module.Import(typeof (TimeSpan))
- .Resolve()
- .Methods.FirstOrDefault(
- md => md.IsConstructor && md.Parameters.Count == 1 && md.Parameters[0].ParameterType.FullName == "System.Int64");
- var timespanctor = Context.Body.Method.Module.Import(timespanctorinfo);
- yield return Instruction.Create(OpCodes.Newobj, timespanctor);
- }
- break;
- case "System.Uri":
- Uri outuri;
- if (hasValue && Uri.TryCreate(valueString, UriKind.RelativeOrAbsolute, out outuri))
- {
- var vardef = new VariableDefinition(Context.Body.Method.Module.Import(typeof (Uri)));
- Context.Body.Variables.Add(vardef);
- //Use an extra temp var so we can push the value to the stack, just like other cases
- yield return Instruction.Create(OpCodes.Ldstr, valueString);
- yield return Instruction.Create(OpCodes.Ldc_I4, (int)UriKind.RelativeOrAbsolute);
- yield return Instruction.Create(OpCodes.Ldloca, vardef);
- var tryCreateInfo =
- Context.Body.Method.Module.Import(typeof (Uri))
- .Resolve()
- .Methods.FirstOrDefault(md => md.Name == "TryCreate" && md.Parameters.Count == 3);
- var tryCreate = Context.Body.Method.Module.Import(tryCreateInfo);
- yield return Instruction.Create(OpCodes.Call, tryCreate);
- yield return Instruction.Create(OpCodes.Pop);
- yield return Instruction.Create(OpCodes.Ldloc, vardef);
- }
- else
- yield return Instruction.Create(OpCodes.Ldnull);
- break;
- default:
- var defaultctorinfo = typedef.Methods.FirstOrDefault(md => md.IsConstructor && !md.HasParameters);
- if (defaultctorinfo != null)
- {
- var defaultctor = Context.Body.Method.Module.Import(defaultctorinfo);
- yield return Instruction.Create(OpCodes.Newobj, defaultctor);
- }
- else
- {
- //should never happen. but if it does, this prevents corrupting the IL stack
- yield return Instruction.Create(OpCodes.Ldnull);
- }
- break;
+ yield return Instruction.Create(OpCodes.Ldc_I4, 0x6f); //NumberStyles.Number
+ var getInvariantInfo =
+ Context.Body.Method.Module.Import(typeof(CultureInfo))
+ .Resolve()
+ .Properties.FirstOrDefault(pd => pd.Name == "InvariantCulture")
+ .GetMethod;
+ var getInvariant = Context.Body.Method.Module.Import(getInvariantInfo);
+ yield return Instruction.Create(OpCodes.Call, getInvariant);
+ yield return Instruction.Create(OpCodes.Ldloca, vardef);
+ var tryParseInfo =
+ Context.Body.Method.Module.Import(typeof(decimal))
+ .Resolve()
+ .Methods.FirstOrDefault(md => md.Name == "TryParse" && md.Parameters.Count == 4);
+ var tryParse = Context.Body.Method.Module.Import(tryParseInfo);
+ yield return Instruction.Create(OpCodes.Call, tryParse);
+ yield return Instruction.Create(OpCodes.Pop);
+ yield return Instruction.Create(OpCodes.Ldloc, vardef);
+ } else {
+ yield return Instruction.Create(OpCodes.Ldc_I4_0);
+ var decimalctorinfo =
+ Context.Body.Method.Module.Import(typeof(decimal))
+ .Resolve()
+ .Methods.FirstOrDefault(
+ md => md.IsConstructor && md.Parameters.Count == 1 && md.Parameters [0].ParameterType.FullName == "System.Int32");
+ var decimalctor = Context.Body.Method.Module.Import(decimalctorinfo);
+ yield return Instruction.Create(OpCodes.Newobj, decimalctor);
+ }
+ break;
+ case "System.Single":
+ float outfloat;
+ if (hasValue && float.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outfloat))
+ yield return Instruction.Create(OpCodes.Ldc_R4, outfloat);
+ else
+ yield return Instruction.Create(OpCodes.Ldc_R4, 0f);
+ break;
+ case "System.Double":
+ double outdouble;
+ if (hasValue && double.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outdouble))
+ yield return Instruction.Create(OpCodes.Ldc_R8, outdouble);
+ else
+ yield return Instruction.Create(OpCodes.Ldc_R8, 0d);
+ break;
+ case "System.TimeSpan":
+ TimeSpan outspan;
+ if (hasValue && TimeSpan.TryParse(valueString, CultureInfo.InvariantCulture, out outspan)) {
+ var vardef = new VariableDefinition(Context.Body.Method.Module.Import(typeof(TimeSpan)));
+ Context.Body.Variables.Add(vardef);
+ //Use an extra temp var so we can push the value to the stack, just like other cases
+ yield return Instruction.Create(OpCodes.Ldstr, valueString);
+ var getInvariantInfo =
+ Context.Body.Method.Module.Import(typeof(CultureInfo))
+ .Resolve()
+ .Properties.FirstOrDefault(pd => pd.Name == "InvariantCulture")
+ .GetMethod;
+ var getInvariant = Context.Body.Method.Module.Import(getInvariantInfo);
+ yield return Instruction.Create(OpCodes.Call, getInvariant);
+ yield return Instruction.Create(OpCodes.Ldloca, vardef);
+ var tryParseInfo =
+ Context.Body.Method.Module.Import(typeof(TimeSpan))
+ .Resolve()
+ .Methods.FirstOrDefault(md => md.Name == "TryParse" && md.Parameters.Count == 3);
+ var tryParse = Context.Body.Method.Module.Import(tryParseInfo);
+ yield return Instruction.Create(OpCodes.Call, tryParse);
+ yield return Instruction.Create(OpCodes.Pop);
+ yield return Instruction.Create(OpCodes.Ldloc, vardef);
+ } else {
+ yield return Instruction.Create(OpCodes.Ldc_I8, 0L);
+ var timespanctorinfo =
+ Context.Body.Method.Module.Import(typeof(TimeSpan))
+ .Resolve()
+ .Methods.FirstOrDefault(
+ md => md.IsConstructor && md.Parameters.Count == 1 && md.Parameters [0].ParameterType.FullName == "System.Int64");
+ var timespanctor = Context.Body.Method.Module.Import(timespanctorinfo);
+ yield return Instruction.Create(OpCodes.Newobj, timespanctor);
+ }
+ break;
+ case "System.Uri":
+ Uri outuri;
+ if (hasValue && Uri.TryCreate(valueString, UriKind.RelativeOrAbsolute, out outuri)) {
+ var vardef = new VariableDefinition(Context.Body.Method.Module.Import(typeof(Uri)));
+ Context.Body.Variables.Add(vardef);
+ //Use an extra temp var so we can push the value to the stack, just like other cases
+ yield return Instruction.Create(OpCodes.Ldstr, valueString);
+ yield return Instruction.Create(OpCodes.Ldc_I4, (int)UriKind.RelativeOrAbsolute);
+ yield return Instruction.Create(OpCodes.Ldloca, vardef);
+ var tryCreateInfo =
+ Context.Body.Method.Module.Import(typeof(Uri))
+ .Resolve()
+ .Methods.FirstOrDefault(md => md.Name == "TryCreate" && md.Parameters.Count == 3);
+ var tryCreate = Context.Body.Method.Module.Import(tryCreateInfo);
+ yield return Instruction.Create(OpCodes.Call, tryCreate);
+ yield return Instruction.Create(OpCodes.Pop);
+ yield return Instruction.Create(OpCodes.Ldloc, vardef);
+ } else
+ yield return Instruction.Create(OpCodes.Ldnull);
+ break;
+ default:
+ var defaultctorinfo = typedef.Methods.FirstOrDefault(md => md.IsConstructor && !md.HasParameters);
+ if (defaultctorinfo != null) {
+ var defaultctor = Context.Body.Method.Module.Import(defaultctorinfo);
+ yield return Instruction.Create(OpCodes.Newobj, defaultctor);
+ } else {
+ //should never happen. but if it does, this prevents corrupting the IL stack
+ yield return Instruction.Create(OpCodes.Ldnull);
+ }
+ break;
}
}
}
diff --git a/Xamarin.Forms.Build.Tasks/NodeILExtensions.cs b/Xamarin.Forms.Build.Tasks/NodeILExtensions.cs
index a7fed895..31c1a1a8 100644
--- a/Xamarin.Forms.Build.Tasks/NodeILExtensions.cs
+++ b/Xamarin.Forms.Build.Tasks/NodeILExtensions.cs
@@ -114,58 +114,100 @@ namespace Xamarin.Forms.Build.Tasks
yield return Instruction.Create(OpCodes.Ldc_I4, ParseEnum(targetTypeRef, str, node));
else if (targetTypeRef.FullName == "System.Char")
yield return Instruction.Create(OpCodes.Ldc_I4, Char.Parse(str));
- else if (targetTypeRef.FullName == "System.Byte")
- yield return Instruction.Create(OpCodes.Ldc_I4, Byte.Parse(str, CultureInfo.InvariantCulture));
+ else if (targetTypeRef.FullName == "System.SByte")
+ yield return Instruction.Create(OpCodes.Ldc_I4, SByte.Parse(str, CultureInfo.InvariantCulture));
else if (targetTypeRef.FullName == "System.Int16")
yield return Instruction.Create(OpCodes.Ldc_I4, Int16.Parse(str, CultureInfo.InvariantCulture));
else if (targetTypeRef.FullName == "System.Int32")
yield return Instruction.Create(OpCodes.Ldc_I4, Int32.Parse(str, CultureInfo.InvariantCulture));
else if (targetTypeRef.FullName == "System.Int64")
yield return Instruction.Create(OpCodes.Ldc_I8, Int64.Parse(str, CultureInfo.InvariantCulture));
+ else if (targetTypeRef.FullName == "System.Byte")
+ yield return Instruction.Create(OpCodes.Ldc_I4, Byte.Parse(str, CultureInfo.InvariantCulture));
+ else if (targetTypeRef.FullName == "System.UInt16")
+ yield return Instruction.Create(OpCodes.Ldc_I4, UInt16.Parse(str, CultureInfo.InvariantCulture));
+ else if (targetTypeRef.FullName == "System.UInt32")
+ yield return Instruction.Create(OpCodes.Ldc_I4, UInt32.Parse(str, CultureInfo.InvariantCulture));
+ else if (targetTypeRef.FullName == "System.UInt64")
+ yield return Instruction.Create(OpCodes.Ldc_I8, UInt64.Parse(str, CultureInfo.InvariantCulture));
else if (targetTypeRef.FullName == "System.Single")
yield return Instruction.Create(OpCodes.Ldc_R4, Single.Parse(str, CultureInfo.InvariantCulture));
else if (targetTypeRef.FullName == "System.Double")
yield return Instruction.Create(OpCodes.Ldc_R8, Double.Parse(str, CultureInfo.InvariantCulture));
- else if (targetTypeRef.FullName == "System.Boolean")
- {
+ else if (targetTypeRef.FullName == "System.Boolean") {
if (Boolean.Parse(str))
yield return Instruction.Create(OpCodes.Ldc_I4_1);
else
yield return Instruction.Create(OpCodes.Ldc_I4_0);
- }
- else if (targetTypeRef.FullName == "System.TimeSpan")
- {
+ } else if (targetTypeRef.FullName == "System.TimeSpan") {
var ts = TimeSpan.Parse(str, CultureInfo.InvariantCulture);
var ticks = ts.Ticks;
var timeSpanCtor =
- module.Import(typeof (TimeSpan))
+ module.Import(typeof(TimeSpan))
.Resolve()
.Methods.FirstOrDefault(md => md.IsConstructor && md.Parameters.Count == 1);
var timeSpanCtorRef = module.Import(timeSpanCtor);
yield return Instruction.Create(OpCodes.Ldc_I8, ticks);
yield return Instruction.Create(OpCodes.Newobj, timeSpanCtorRef);
- }
- else if (targetTypeRef.FullName == "System.DateTime")
- {
+ } else if (targetTypeRef.FullName == "System.DateTime") {
var dt = DateTime.Parse(str, CultureInfo.InvariantCulture);
var ticks = dt.Ticks;
var dateTimeCtor =
- module.Import(typeof (DateTime))
+ module.Import(typeof(DateTime))
.Resolve()
.Methods.FirstOrDefault(md => md.IsConstructor && md.Parameters.Count == 1);
var dateTimeCtorRef = module.Import(dateTimeCtor);
yield return Instruction.Create(OpCodes.Ldc_I8, ticks);
yield return Instruction.Create(OpCodes.Newobj, dateTimeCtorRef);
- }
- else if (targetTypeRef.FullName == "System.String" && str.StartsWith("{}", StringComparison.Ordinal))
+ } else if (targetTypeRef.FullName == "System.String" && str.StartsWith("{}", StringComparison.Ordinal))
yield return Instruction.Create(OpCodes.Ldstr, str.Substring(2));
else if (targetTypeRef.FullName == "System.String")
yield return Instruction.Create(OpCodes.Ldstr, str);
else if (targetTypeRef.FullName == "System.Object")
yield return Instruction.Create(OpCodes.Ldstr, str);
- else
+ else if (targetTypeRef.FullName == "System.Decimal") {
+ decimal outdecimal;
+ if (decimal.TryParse(str, NumberStyles.Number, CultureInfo.InvariantCulture, out outdecimal)) {
+ var vardef = new VariableDefinition(context.Body.Method.Module.Import(typeof(decimal)));
+ context.Body.Variables.Add(vardef);
+ //Use an extra temp var so we can push the value to the stack, just like other cases
+ // IL_0003: ldstr "adecimal"
+ // IL_0008: ldc.i4.s 0x6f
+ // IL_000a: call class [mscorlib]System.Globalization.CultureInfo class [mscorlib]System.Globalization.CultureInfo::get_InvariantCulture()
+ // IL_000f: ldloca.s 0
+ // IL_0011: call bool valuetype [mscorlib]System.Decimal::TryParse(string, valuetype [mscorlib]System.Globalization.NumberStyles, class [mscorlib]System.IFormatProvider, [out] valuetype [mscorlib]System.Decimal&)
+ // IL_0016: pop
+ yield return Instruction.Create(OpCodes.Ldstr, str);
+ yield return Instruction.Create(OpCodes.Ldc_I4, 0x6f); //NumberStyles.Number
+ var getInvariantInfo =
+ context.Body.Method.Module.Import(typeof(CultureInfo))
+ .Resolve()
+ .Properties.FirstOrDefault(pd => pd.Name == "InvariantCulture")
+ .GetMethod;
+ var getInvariant = context.Body.Method.Module.Import(getInvariantInfo);
+ yield return Instruction.Create(OpCodes.Call, getInvariant);
+ yield return Instruction.Create(OpCodes.Ldloca, vardef);
+ var tryParseInfo =
+ context.Body.Method.Module.Import(typeof(decimal))
+ .Resolve()
+ .Methods.FirstOrDefault(md => md.Name == "TryParse" && md.Parameters.Count == 4);
+ var tryParse = context.Body.Method.Module.Import(tryParseInfo);
+ yield return Instruction.Create(OpCodes.Call, tryParse);
+ yield return Instruction.Create(OpCodes.Pop);
+ yield return Instruction.Create(OpCodes.Ldloc, vardef);
+ } else {
+ yield return Instruction.Create(OpCodes.Ldc_I4_0);
+ var decimalctorinfo =
+ context.Body.Method.Module.Import(typeof(decimal))
+ .Resolve()
+ .Methods.FirstOrDefault(
+ md => md.IsConstructor && md.Parameters.Count == 1 && md.Parameters [0].ParameterType.FullName == "System.Int32");
+ var decimalctor = context.Body.Method.Module.Import(decimalctorinfo);
+ yield return Instruction.Create(OpCodes.Newobj, decimalctor);
+ }
+ } else
yield return Instruction.Create(OpCodes.Ldnull);
if (isNullable)