[Xaml] more primitive types (#385)
* [Xaml] more builtin conversion, and more type primitives * [XamlC] more builtin conversion, more type primitives
This commit is contained in:
Родитель
0f7b22f49d
Коммит
3e0ee965d7
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -83,5 +83,6 @@
|
|||
<d:IgnorableElement />
|
||||
</ContentView.Content>
|
||||
</ContentView>
|
||||
<local:MockViewWithValues x:Name="mockView0" UShort="32" ADecimal="42" />
|
||||
</StackLayout>
|
||||
</ContentPage>
|
|
@ -2,6 +2,7 @@
|
|||
using System.Linq;
|
||||
|
||||
using NUnit.Framework;
|
||||
using Xamarin.Forms.Core.UnitTests;
|
||||
|
||||
namespace Xamarin.Forms.Xaml.UnitTests
|
||||
{
|
||||
|
@ -13,6 +14,12 @@ namespace Xamarin.Forms.Xaml.UnitTests
|
|||
}
|
||||
}
|
||||
|
||||
public class MockViewWithValues : View
|
||||
{
|
||||
public UInt16 UShort { get; set; }
|
||||
public decimal ADecimal { get; set; }
|
||||
}
|
||||
|
||||
public partial class SetValue : ContentPage
|
||||
{
|
||||
public SetValue ()
|
||||
|
@ -34,6 +41,18 @@ namespace Xamarin.Forms.Xaml.UnitTests
|
|||
[TestFixture]
|
||||
public class Tests
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Device.PlatformServices = new MockPlatformServices();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Device.PlatformServices = null;
|
||||
}
|
||||
|
||||
[TestCase (false)]
|
||||
[TestCase (true)]
|
||||
public void SetValueToBP (bool useCompiledXaml)
|
||||
|
@ -215,6 +234,15 @@ namespace Xamarin.Forms.Xaml.UnitTests
|
|||
var page = new SetValue(useCompiledXaml);
|
||||
Assert.That(page.contentview2.Content, Is.TypeOf<Label>());
|
||||
}
|
||||
|
||||
[TestCase(false)]
|
||||
[TestCase(true)]
|
||||
public void MorePrimitiveTypes(bool useCompiledXaml)
|
||||
{
|
||||
var page = new SetValue(useCompiledXaml);
|
||||
Assert.AreEqual((ushort)32, page.mockView0.UShort);
|
||||
Assert.AreEqual((decimal)42, page.mockView0.ADecimal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,6 +37,10 @@
|
|||
<x:TimeSpan x:Key="defaultTimeSpan"/>
|
||||
<x:Uri x:Key="anUri">http://xamarin.com/forms</x:Uri>
|
||||
<x:Uri x:Key="defaultUri"/>
|
||||
<x:SByte x:Key="aSByte">42</x:SByte>
|
||||
<x:UInt16 x:Key="aUInt16">43</x:UInt16>
|
||||
<x:UInt32 x:Key="aUInt32">44</x:UInt32>
|
||||
<x:UInt64 x:Key="aUInt64">45</x:UInt64>
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
</ContentPage>
|
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||
using NUnit.Framework;
|
||||
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Core.UnitTests;
|
||||
|
||||
namespace Xamarin.Forms.Xaml.UnitTests
|
||||
{
|
||||
|
@ -22,6 +23,18 @@ namespace Xamarin.Forms.Xaml.UnitTests
|
|||
[TestFixture]
|
||||
public class Tests
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Device.PlatformServices = new MockPlatformServices();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Device.PlatformServices = null;
|
||||
}
|
||||
|
||||
[TestCase (false)]
|
||||
[TestCase (true)]
|
||||
public void SupportsXString (bool useCompiledXaml)
|
||||
|
@ -144,11 +157,17 @@ namespace Xamarin.Forms.Xaml.UnitTests
|
|||
Assert.That (defaultDouble, Is.TypeOf<double> ());
|
||||
Assert.AreEqual (default(double), (double)defaultDouble, .0001d);
|
||||
|
||||
Assert.True (layout.Resources.ContainsKey ("aByte"));
|
||||
Assert.True(layout.Resources.ContainsKey("aByte"));
|
||||
var aByte = layout.Resources ["aByte"];
|
||||
Assert.NotNull (aByte);
|
||||
Assert.That (aByte, Is.TypeOf<byte> ());
|
||||
Assert.AreEqual (54, (byte)aByte);
|
||||
Assert.NotNull(aByte);
|
||||
Assert.That(aByte, Is.TypeOf<byte>());
|
||||
Assert.AreEqual(54, (byte)aByte);
|
||||
|
||||
Assert.True(layout.Resources.ContainsKey("aSByte"));
|
||||
var aSByte = layout.Resources ["aSByte"];
|
||||
Assert.NotNull(aSByte);
|
||||
Assert.That(aSByte, Is.TypeOf<sbyte>());
|
||||
Assert.AreEqual(42, (sbyte)aSByte);
|
||||
|
||||
Assert.True (layout.Resources.ContainsKey ("defaultByte"));
|
||||
var defaultByte = layout.Resources ["defaultByte"];
|
||||
|
@ -156,11 +175,17 @@ namespace Xamarin.Forms.Xaml.UnitTests
|
|||
Assert.That (defaultByte, Is.TypeOf<byte> ());
|
||||
Assert.AreEqual (default(byte), (byte)defaultByte);
|
||||
|
||||
Assert.True (layout.Resources.ContainsKey ("anInt16"));
|
||||
Assert.True(layout.Resources.ContainsKey("anInt16"));
|
||||
var anInt16 = layout.Resources ["anInt16"];
|
||||
Assert.NotNull (anInt16);
|
||||
Assert.That (anInt16, Is.TypeOf<short> ());
|
||||
Assert.AreEqual (43, (short)anInt16);
|
||||
Assert.NotNull(anInt16);
|
||||
Assert.That(anInt16, Is.TypeOf<short>());
|
||||
Assert.AreEqual(43, (short)anInt16);
|
||||
|
||||
Assert.True(layout.Resources.ContainsKey("aUInt16"));
|
||||
var aUInt16 = layout.Resources ["aUInt16"];
|
||||
Assert.NotNull(aUInt16);
|
||||
Assert.That(aUInt16, Is.TypeOf<ushort>());
|
||||
Assert.AreEqual(43, (ushort)aUInt16);
|
||||
|
||||
Assert.True (layout.Resources.ContainsKey ("defaultInt16"));
|
||||
var defaultInt16 = layout.Resources ["defaultInt16"];
|
||||
|
@ -168,11 +193,17 @@ namespace Xamarin.Forms.Xaml.UnitTests
|
|||
Assert.That (defaultInt16, Is.TypeOf<short> ());
|
||||
Assert.AreEqual (default(short), (short)defaultInt16);
|
||||
|
||||
Assert.True (layout.Resources.ContainsKey ("anInt32"));
|
||||
Assert.True(layout.Resources.ContainsKey("anInt32"));
|
||||
var anInt32 = layout.Resources ["anInt32"];
|
||||
Assert.NotNull (anInt32);
|
||||
Assert.That (anInt32, Is.TypeOf<int> ());
|
||||
Assert.AreEqual (44, (int)anInt32);
|
||||
Assert.NotNull(anInt32);
|
||||
Assert.That(anInt32, Is.TypeOf<int>());
|
||||
Assert.AreEqual(44, (int)anInt32);
|
||||
|
||||
Assert.True(layout.Resources.ContainsKey("aUInt32"));
|
||||
var aUInt32 = layout.Resources ["aUInt32"];
|
||||
Assert.NotNull(aUInt32);
|
||||
Assert.That(aUInt32, Is.TypeOf<uint>());
|
||||
Assert.AreEqual(44, (uint)aUInt32);
|
||||
|
||||
Assert.True (layout.Resources.ContainsKey ("defaultInt32"));
|
||||
var defaultInt32 = layout.Resources ["defaultInt32"];
|
||||
|
@ -180,11 +211,17 @@ namespace Xamarin.Forms.Xaml.UnitTests
|
|||
Assert.That (defaultInt32, Is.TypeOf<int> ());
|
||||
Assert.AreEqual (default(int), (int)defaultInt32);
|
||||
|
||||
Assert.True (layout.Resources.ContainsKey ("anInt64"));
|
||||
Assert.True(layout.Resources.ContainsKey("anInt64"));
|
||||
var anInt64 = layout.Resources ["anInt64"];
|
||||
Assert.NotNull (anInt64);
|
||||
Assert.That (anInt64, Is.TypeOf<long> ());
|
||||
Assert.AreEqual (45, (long)anInt64);
|
||||
Assert.NotNull(anInt64);
|
||||
Assert.That(anInt64, Is.TypeOf<long>());
|
||||
Assert.AreEqual(45, (long)anInt64);
|
||||
|
||||
Assert.True(layout.Resources.ContainsKey("aUInt64"));
|
||||
var aUInt64 = layout.Resources ["aUInt64"];
|
||||
Assert.NotNull(aUInt64);
|
||||
Assert.That(aUInt64, Is.TypeOf<ulong>());
|
||||
Assert.AreEqual(45, (ulong)aUInt64);
|
||||
|
||||
Assert.True (layout.Resources.ContainsKey ("defaultInt64"));
|
||||
var defaultInt64 = layout.Resources ["defaultInt64"];
|
||||
|
|
|
@ -296,73 +296,87 @@ namespace Xamarin.Forms.Xaml
|
|||
{
|
||||
var valuestring = ((ValueNode)node.CollectionItems[0]).Value as string;
|
||||
|
||||
if (nodeType == typeof (bool))
|
||||
if (nodeType == typeof(SByte)) {
|
||||
sbyte retval;
|
||||
if (sbyte.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
return retval;
|
||||
}
|
||||
if (nodeType == typeof(Int16)) {
|
||||
short retval;
|
||||
if (short.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
return retval;
|
||||
}
|
||||
if (nodeType == typeof(Int32)) {
|
||||
int retval;
|
||||
if (int.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
return retval;
|
||||
}
|
||||
if (nodeType == typeof(Int64)) {
|
||||
long retval;
|
||||
if (long.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
return retval;
|
||||
}
|
||||
if (nodeType == typeof(Byte)) {
|
||||
byte retval;
|
||||
if (byte.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
return retval;
|
||||
}
|
||||
if (nodeType == typeof(UInt16)) {
|
||||
ushort retval;
|
||||
if (ushort.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
return retval;
|
||||
}
|
||||
if (nodeType == typeof(UInt32)) {
|
||||
uint retval;
|
||||
if (uint.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
return retval;
|
||||
}
|
||||
if (nodeType == typeof(UInt64)) {
|
||||
ulong retval;
|
||||
if (ulong.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
return retval;
|
||||
}
|
||||
if (nodeType == typeof(Single)) {
|
||||
float retval;
|
||||
if (float.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
return retval;
|
||||
}
|
||||
if (nodeType == typeof(Double)) {
|
||||
double retval;
|
||||
if (double.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
return retval;
|
||||
}
|
||||
if (nodeType == typeof (Boolean))
|
||||
{
|
||||
bool outbool;
|
||||
if (bool.TryParse(valuestring, out outbool))
|
||||
value = outbool;
|
||||
return outbool;
|
||||
}
|
||||
else if (nodeType == typeof (char))
|
||||
if (nodeType == typeof(TimeSpan)) {
|
||||
TimeSpan retval;
|
||||
if (TimeSpan.TryParse(valuestring, CultureInfo.InvariantCulture, out retval))
|
||||
return retval;
|
||||
}
|
||||
if (nodeType == typeof (char))
|
||||
{
|
||||
char retval;
|
||||
if (char.TryParse(valuestring, out retval))
|
||||
value = retval;
|
||||
return retval;
|
||||
}
|
||||
else if (nodeType == typeof (string))
|
||||
value = valuestring;
|
||||
else if (nodeType == typeof (decimal))
|
||||
if (nodeType == typeof (string))
|
||||
return valuestring;
|
||||
if (nodeType == typeof (decimal))
|
||||
{
|
||||
decimal retval;
|
||||
if (decimal.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
value = retval;
|
||||
}
|
||||
else if (nodeType == typeof (float))
|
||||
{
|
||||
float retval;
|
||||
if (float.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
value = retval;
|
||||
}
|
||||
else if (nodeType == typeof (double))
|
||||
{
|
||||
double retval;
|
||||
if (double.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
value = retval;
|
||||
}
|
||||
else if (nodeType == typeof (byte))
|
||||
{
|
||||
byte retval;
|
||||
if (byte.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
value = retval;
|
||||
}
|
||||
else if (nodeType == typeof (short))
|
||||
{
|
||||
short retval;
|
||||
if (short.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
value = retval;
|
||||
}
|
||||
else if (nodeType == typeof (int))
|
||||
{
|
||||
int retval;
|
||||
if (int.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
value = retval;
|
||||
}
|
||||
else if (nodeType == typeof (long))
|
||||
{
|
||||
long retval;
|
||||
if (long.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
|
||||
value = retval;
|
||||
}
|
||||
else if (nodeType == typeof (TimeSpan))
|
||||
{
|
||||
TimeSpan retval;
|
||||
if (TimeSpan.TryParse(valuestring, CultureInfo.InvariantCulture, out retval))
|
||||
value = retval;
|
||||
return retval;
|
||||
}
|
||||
|
||||
else if (nodeType == typeof (Uri))
|
||||
{
|
||||
Uri retval;
|
||||
if (Uri.TryCreate(valuestring, UriKind.RelativeOrAbsolute, out retval))
|
||||
value = retval;
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
|
|
|
@ -130,23 +130,43 @@ namespace Xamarin.Forms.Xaml
|
|||
//Obvious Built-in conversions
|
||||
if (toType.GetTypeInfo().IsEnum)
|
||||
return Enum.Parse(toType, str);
|
||||
//TODO supports Int16, 64, Byte, Char, ...
|
||||
if (toType == typeof (Int32))
|
||||
if (toType == typeof(SByte))
|
||||
return SByte.Parse(str, CultureInfo.InvariantCulture);
|
||||
if (toType == typeof(Int16))
|
||||
return Int16.Parse(str, CultureInfo.InvariantCulture);
|
||||
if (toType == typeof(Int32))
|
||||
return Int32.Parse(str, CultureInfo.InvariantCulture);
|
||||
if (toType == typeof (float))
|
||||
if (toType == typeof(Int64))
|
||||
return Int64.Parse(str, CultureInfo.InvariantCulture);
|
||||
if (toType == typeof(Byte))
|
||||
return Byte.Parse(str, CultureInfo.InvariantCulture);
|
||||
if (toType == typeof(UInt16))
|
||||
return UInt16.Parse(str, CultureInfo.InvariantCulture);
|
||||
if (toType == typeof(UInt32))
|
||||
return UInt32.Parse(str, CultureInfo.InvariantCulture);
|
||||
if (toType == typeof(UInt64))
|
||||
return UInt64.Parse(str, CultureInfo.InvariantCulture);
|
||||
if (toType == typeof (Single))
|
||||
return Single.Parse(str, CultureInfo.InvariantCulture);
|
||||
if (toType == typeof (double))
|
||||
if (toType == typeof (Double))
|
||||
return Double.Parse(str, CultureInfo.InvariantCulture);
|
||||
if (toType == typeof (bool))
|
||||
if (toType == typeof (Boolean))
|
||||
return Boolean.Parse(str);
|
||||
if (toType == typeof (TimeSpan))
|
||||
return TimeSpan.Parse(str, CultureInfo.InvariantCulture);
|
||||
if (toType == typeof (DateTime))
|
||||
return DateTime.Parse(str, CultureInfo.InvariantCulture);
|
||||
if (toType == typeof (string) && str.StartsWith("{}", StringComparison.Ordinal))
|
||||
if (toType == typeof(Char)) {
|
||||
char c = '\0';
|
||||
Char.TryParse(str, out c);
|
||||
return c;
|
||||
}
|
||||
if (toType == typeof (String) && str.StartsWith("{}", StringComparison.Ordinal))
|
||||
return str.Substring(2);
|
||||
if (toType == typeof (string))
|
||||
if (toType == typeof (String))
|
||||
return value;
|
||||
if (toType == typeof(Decimal))
|
||||
return Decimal.Parse(str, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
//if there's an implicit conversion, convert
|
||||
|
|
Загрузка…
Ссылка в новой задаче