diff options
Diffstat (limited to 'Xamarin.Forms.Build.Tasks')
13 files changed, 394 insertions, 9 deletions
diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/BindablePropertyConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/BindablePropertyConverter.cs new file mode 100644 index 00000000..92a53539 --- /dev/null +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/BindablePropertyConverter.cs @@ -0,0 +1,84 @@ +using System.Collections.Generic; +using System.Linq; +using Mono.Cecil; +using Mono.Cecil.Cil; + +using Xamarin.Forms.Build.Tasks; +using Xamarin.Forms.Xaml; + +using static System.String; + +namespace Xamarin.Forms.Core.XamlC +{ + class BindablePropertyConverter : ICompiledTypeConverter + { + public IEnumerable<Instruction> ConvertFromString(string value, ModuleDefinition module, BaseNode node) + { + if (IsNullOrEmpty(value)) { + yield return Instruction.Create(OpCodes.Ldnull); + yield break; + } + + FieldReference bpRef = null; + string typeName = null, propertyName = null; + + var parts = value.Split('.'); + if (parts.Length == 1) { + var parent = node.Parent?.Parent as IElementNode; + if ((node.Parent as ElementNode)?.XmlType.NamespaceUri == "http://xamarin.com/schemas/2014/forms" && (node.Parent as ElementNode)?.XmlType.Name == "Setter") { + if (parent.XmlType.NamespaceUri == "http://xamarin.com/schemas/2014/forms" && + (parent.XmlType.Name == "Trigger" || parent.XmlType.Name == "DataTrigger" || parent.XmlType.Name == "MultiTrigger" || parent.XmlType.Name == "Style")) { + var ttnode = (parent as ElementNode).Properties [new XmlName("", "TargetType")]; + if (ttnode is ValueNode) + typeName = (ttnode as ValueNode).Value as string; + else if (ttnode is IElementNode) + typeName = ((ttnode as IElementNode).CollectionItems.FirstOrDefault() as ValueNode)?.Value as string ?? ((ttnode as IElementNode).Properties [new XmlName("", "TypeName")] as ValueNode)?.Value as string; + } + } else if ((node.Parent as ElementNode)?.XmlType.NamespaceUri == "http://xamarin.com/schemas/2014/forms" && (node.Parent as ElementNode)?.XmlType.Name == "Trigger") + typeName = ((node.Parent as ElementNode).Properties [new XmlName("", "TargetType")] as ValueNode).Value as string; + propertyName = parts [0]; + } else if (parts.Length == 2) { + typeName = parts [0]; + propertyName = parts [1]; + } else + throw new XamlParseException($"Cannot convert \"{value}\" into {typeof(BindableProperty)}", node); + + var typeRef = GetTypeReference(typeName, module, node); + if (typeRef == null) + throw new XamlParseException($"Can't resolve {typeName}", node); + bpRef = GetBindablePropertyFieldReference(typeRef, propertyName, module); + if (bpRef == null) + throw new XamlParseException($"Can't resolve {propertyName} on {typeRef.Name}", node); + yield return Instruction.Create(OpCodes.Ldsfld, bpRef); + } + + public static TypeReference GetTypeReference(string xmlType, ModuleDefinition module, BaseNode iNode) + { + var split = xmlType.Split(':'); + if (split.Length > 2) + throw new XamlParseException($"Type \"{xmlType}\" is invalid", iNode); + + string prefix, name; + if (split.Length == 2) { + prefix = split [0]; + name = split [1]; + } else { + prefix = ""; + name = split [0]; + } + var namespaceuri = iNode.NamespaceResolver.LookupNamespace(prefix) ?? ""; + return XmlTypeExtensions.GetTypeReference(namespaceuri, name, module, iNode); + } + + public static FieldReference GetBindablePropertyFieldReference(TypeReference typeRef, string propertyName, ModuleDefinition module) + { + TypeReference declaringTypeReference; + FieldReference bpRef = typeRef.GetField(fd => fd.Name == $"{propertyName}Property" && fd.IsStatic && fd.IsPublic, out declaringTypeReference); + if (bpRef != null) { + bpRef = module.Import(bpRef.ResolveGenericParameters(declaringTypeReference)); + bpRef.FieldType = module.Import(bpRef.FieldType); + } + return bpRef; + } + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/BindingTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/BindingTypeConverter.cs new file mode 100644 index 00000000..74990a86 --- /dev/null +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/BindingTypeConverter.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using System.Linq; + +using Mono.Cecil; +using Mono.Cecil.Cil; + +using Xamarin.Forms.Xaml; + +using static System.String; + +namespace Xamarin.Forms.Core.XamlC +{ + class BindingTypeConverter : ICompiledTypeConverter + { + public IEnumerable<Instruction> ConvertFromString(string value, ModuleDefinition module, BaseNode node) + { + if (IsNullOrEmpty(value)) + throw new XamlParseException($"Cannot convert \"{value}\" into {typeof(Binding)}", node); + + var bindingCtor = module.Import(typeof(Binding)).Resolve().Methods.FirstOrDefault(md => md.IsConstructor && md.Parameters.Count == 6); + var bindingCtorRef = module.Import(bindingCtor); + + yield return Instruction.Create(OpCodes.Ldstr, value); + yield return Instruction.Create(OpCodes.Ldc_I4, (int)BindingMode.Default); + yield return Instruction.Create(OpCodes.Ldnull); + yield return Instruction.Create(OpCodes.Ldnull); + yield return Instruction.Create(OpCodes.Ldnull); + yield return Instruction.Create(OpCodes.Ldnull); + yield return Instruction.Create(OpCodes.Newobj, bindingCtorRef); + } + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/BoundsTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/BoundsTypeConverter.cs new file mode 100644 index 00000000..1cc64fc5 --- /dev/null +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/BoundsTypeConverter.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; + +using Mono.Cecil; +using Mono.Cecil.Cil; + +using Xamarin.Forms.Xaml; + +namespace Xamarin.Forms.Core.XamlC +{ + class BoundsTypeConverter : ICompiledTypeConverter + { + IEnumerable<Instruction> ICompiledTypeConverter.ConvertFromString(string value, ModuleDefinition module, BaseNode node) + { + if (string.IsNullOrEmpty(value)) + throw new XamlParseException($"Cannot convert \"{value}\" into {typeof(Rectangle)}", node); + + double x = -1, y = -1, w = -1, h = -1; + bool hasX, hasY, hasW, hasH; + var xywh = value.Split(','); + + if (xywh.Length != 2 && xywh.Length != 4) + throw new XamlParseException($"Cannot convert \"{value}\" into {typeof(Rectangle)}", node); + + hasX = (xywh.Length == 2 || xywh.Length == 4) && double.TryParse(xywh [0], NumberStyles.Number, CultureInfo.InvariantCulture, out x); + hasY = (xywh.Length == 2 || xywh.Length == 4) && double.TryParse(xywh [1], NumberStyles.Number, CultureInfo.InvariantCulture, out y); + hasW = xywh.Length == 4 && double.TryParse(xywh [2], NumberStyles.Number, CultureInfo.InvariantCulture, out w); + hasH = xywh.Length == 4 && double.TryParse(xywh [3], NumberStyles.Number, CultureInfo.InvariantCulture, out h); + + if (!hasW && xywh.Length == 4 && string.Compare("AutoSize", xywh [2].Trim(), StringComparison.OrdinalIgnoreCase) == 0) { + hasW = true; + w = AbsoluteLayout.AutoSize; + } + + if (!hasH && xywh.Length == 4 && string.Compare("AutoSize", xywh [3].Trim(), StringComparison.OrdinalIgnoreCase) == 0) { + hasH = true; + h = AbsoluteLayout.AutoSize; + } + + if (hasX && hasY && xywh.Length == 2) { + hasW = true; + w = AbsoluteLayout.AutoSize; + hasH = true; + h = AbsoluteLayout.AutoSize; + } + + if (!hasX || !hasY || !hasW || !hasH) + throw new XamlParseException($"Cannot convert \"{value}\" into {typeof(Rectangle)}", node); + + return GenerateIL(x, y, w, h, module); + } + + IEnumerable<Instruction> GenerateIL(double x, double y, double w, double h, ModuleDefinition module) + { +// IL_0000: ldc.r8 3.1000000000000001 +// IL_0009: ldc.r8 4.2000000000000002 +// IL_0012: ldc.r8 5.2999999999999998 +// IL_001b: ldc.r8 6.4000000000000004 +// IL_0024: newobj instance void valuetype Test.Rectangle::'.ctor'(float64, float64, float64, float64) + + yield return Instruction.Create(OpCodes.Ldc_R8, x); + yield return Instruction.Create(OpCodes.Ldc_R8, y); + yield return Instruction.Create(OpCodes.Ldc_R8, w); + yield return Instruction.Create(OpCodes.Ldc_R8, h); + + var rectangleCtor = module.Import(typeof(Rectangle)).Resolve().Methods.FirstOrDefault(md => md.IsConstructor && md.Parameters.Count == 4); + var rectangleCtorRef = module.Import(rectangleCtor); + yield return Instruction.Create(OpCodes.Newobj, rectangleCtorRef); + } + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/ColorTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/ColorTypeConverter.cs new file mode 100644 index 00000000..39527954 --- /dev/null +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/ColorTypeConverter.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Mono.Cecil; +using Mono.Cecil.Cil; + +using Xamarin.Forms.Xaml; + +namespace Xamarin.Forms.Core.XamlC +{ + class ColorTypeConverter : ICompiledTypeConverter + { + public IEnumerable<Instruction> ConvertFromString(string value, ModuleDefinition module, BaseNode node) + { + do { + if (string.IsNullOrEmpty(value)) + break; + + value = value.Trim(); + + if (value.StartsWith("#", StringComparison.Ordinal)) { + var color = Color.FromHex(value); + yield return Instruction.Create(OpCodes.Ldc_R8, color.R); + yield return Instruction.Create(OpCodes.Ldc_R8, color.G); + yield return Instruction.Create(OpCodes.Ldc_R8, color.B); + yield return Instruction.Create(OpCodes.Ldc_R8, color.A); + var colorCtor = module.Import(typeof(Color)).Resolve().Methods.FirstOrDefault( + md => md.IsConstructor && md.Parameters.Count == 4 && + md.Parameters.All(p => p.ParameterType.FullName == "System.Double")); + var colorCtorRef = module.Import(colorCtor); + yield return Instruction.Create(OpCodes.Newobj, colorCtorRef); + yield break; + } + var parts = value.Split('.'); + if (parts.Length == 1 || (parts.Length == 2 && parts [0] == "Color")) { + var color = parts [parts.Length - 1]; + + var field = module.Import(typeof(Color)).Resolve().Fields.SingleOrDefault(fd => fd.Name == color && fd.IsStatic); + if (field != null) { + yield return Instruction.Create(OpCodes.Ldsfld, module.Import(field)); + yield break; + } + var propertyGetter = module.Import(typeof(Color)).Resolve().Properties.SingleOrDefault(pd => pd.Name == color && pd.GetMethod.IsStatic)?.GetMethod; + if (propertyGetter != null) { + yield return Instruction.Create(OpCodes.Call, module.Import(propertyGetter)); + yield break; + } + } + } while (false); + + throw new XamlParseException($"Cannot convert \"{value}\" into {typeof(Color)}", node); + } + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/ICompiledTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/ICompiledTypeConverter.cs new file mode 100644 index 00000000..5ed88d0a --- /dev/null +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/ICompiledTypeConverter.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using Mono.Cecil.Cil; +using Mono.Cecil; +using System.Xml; + +namespace Xamarin.Forms.Xaml +{ + interface ICompiledTypeConverter + { + IEnumerable<Instruction> ConvertFromString(string value, ModuleDefinition module, BaseNode node); + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/LayoutOptionsConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/LayoutOptionsConverter.cs new file mode 100644 index 00000000..e252ed9d --- /dev/null +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/LayoutOptionsConverter.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Mono.Cecil; +using Mono.Cecil.Cil; + +using Xamarin.Forms.Xaml; + +namespace Xamarin.Forms.Core.XamlC +{ + class LayoutOptionsConverter : ICompiledTypeConverter + { + public IEnumerable<Instruction> ConvertFromString(string value, ModuleDefinition module, BaseNode node) + { + do { + if (string.IsNullOrEmpty(value)) + break; + + value = value.Trim(); + + var parts = value.Split('.'); + if (parts.Length == 1 || (parts.Length == 2 && parts [0] == "LayoutOptions")) { + var options = parts [parts.Length - 1]; + + var field = module.Import(typeof(LayoutOptions)).Resolve().Fields.SingleOrDefault(fd => fd.Name == options && fd.IsStatic); + if (field != null) { + yield return Instruction.Create(OpCodes.Ldsfld, module.Import(field)); + yield break; + } + } + } while (false); + + throw new XamlParseException(String.Format("Cannot convert \"{0}\" into {1}", value, typeof(LayoutOptions)), node); + } + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/RectangleTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/RectangleTypeConverter.cs new file mode 100644 index 00000000..af480667 --- /dev/null +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/RectangleTypeConverter.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; + +using Mono.Cecil; +using Mono.Cecil.Cil; + +using Xamarin.Forms.Xaml; + +namespace Xamarin.Forms.Core.XamlC +{ + class RectangleTypeConverter : ICompiledTypeConverter + { + public IEnumerable<Instruction> ConvertFromString(string value, ModuleDefinition module, BaseNode node) + { + if (string.IsNullOrEmpty(value)) + throw new XamlParseException($"Cannot convert \"{value}\" into {typeof(Rectangle)}", node); + double x, y, w, h; + var xywh = value.Split(','); + if (xywh.Length != 4 || + !double.TryParse(xywh [0], NumberStyles.Number, CultureInfo.InvariantCulture, out x) || + !double.TryParse(xywh [1], NumberStyles.Number, CultureInfo.InvariantCulture, out y) || + !double.TryParse(xywh [2], NumberStyles.Number, CultureInfo.InvariantCulture, out w) || + !double.TryParse(xywh [3], NumberStyles.Number, CultureInfo.InvariantCulture, out h)) + throw new XamlParseException($"Cannot convert \"{value}\" into {typeof(Rectangle)}", node); + + return GenerateIL(x, y, w, h, module); + } + + IEnumerable<Instruction> GenerateIL(double x, double y, double w, double h, ModuleDefinition module) + { +// IL_0000: ldc.r8 3.1000000000000001 +// IL_0009: ldc.r8 4.2000000000000002 +// IL_0012: ldc.r8 5.2999999999999998 +// IL_001b: ldc.r8 6.4000000000000004 +// IL_0024: newobj instance void valuetype Test.Rectangle::'.ctor'(float64, float64, float64, float64) + + yield return Instruction.Create(OpCodes.Ldc_R8, x); + yield return Instruction.Create(OpCodes.Ldc_R8, y); + yield return Instruction.Create(OpCodes.Ldc_R8, w); + yield return Instruction.Create(OpCodes.Ldc_R8, h); + + var rectangleCtor = module.Import(typeof(Rectangle)).Resolve().Methods.FirstOrDefault(md => md.IsConstructor && md.Parameters.Count == 4); + var rectangleCtorRef = module.Import(rectangleCtor); + yield return Instruction.Create(OpCodes.Newobj, rectangleCtorRef); + } + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Build.Tasks/CreateObjectVisitor.cs b/Xamarin.Forms.Build.Tasks/CreateObjectVisitor.cs index 449b887f..33a9a7f5 100644 --- a/Xamarin.Forms.Build.Tasks/CreateObjectVisitor.cs +++ b/Xamarin.Forms.Build.Tasks/CreateObjectVisitor.cs @@ -121,7 +121,7 @@ namespace Xamarin.Forms.Build.Tasks } if (parameterizedCtorInfo != null && ValidateCtorArguments(parameterizedCtorInfo, node)) { ctorInfo = parameterizedCtorInfo; - // IL_0000: ldstr "foo" +// IL_0000: ldstr "foo" Context.IL.Append(PushCtorArguments(parameterizedCtorInfo, node)); } ctorInfo = ctorInfo ?? typedef.Methods.FirstOrDefault(md => md.IsConstructor && !md.HasParameters && !md.IsStatic); @@ -198,9 +198,9 @@ namespace Xamarin.Forms.Build.Tasks type = type.Contains(":") ? type.Split(':') [1].Trim() : type; Context.TypeExtensions [node] = new XmlType(namespaceuri, type, null).GetTypeReference(Module, node); - node.Properties.Clear(); - node.CollectionItems.Clear(); - + if (!node.SkipProperties.Contains(new XmlName("", "TypeName"))) + node.SkipProperties.Add(new XmlName("", "TypeName")); + var vardefref = new VariableDefinitionReference(vardef); Context.IL.Append(SetPropertiesVisitor.ProvideValue(vardefref, Context, Module, node)); if (vardef != vardefref.VariableDefinition) { @@ -213,8 +213,8 @@ namespace Xamarin.Forms.Build.Tasks public void Visit(RootNode node, INode parentNode) { - // IL_0013: ldarg.0 - // IL_0014: stloc.3 +// IL_0013: ldarg.0 +// IL_0014: stloc.3 var ilnode = (ILRootNode)node; var typeref = ilnode.TypeReference; @@ -256,7 +256,8 @@ namespace Xamarin.Forms.Build.Tasks .ConstructorArguments.First() .Value as string; var node = enode.Properties[new XmlName("", propname)]; - enode.Properties.Remove(new XmlName("", propname)); + if (!enode.SkipProperties.Contains(new XmlName("", propname))) + enode.SkipProperties.Add(new XmlName("", propname)); VariableDefinition vardef; ValueNode vnode = null; diff --git a/Xamarin.Forms.Build.Tasks/ExpandMarkupsVisitor.cs b/Xamarin.Forms.Build.Tasks/ExpandMarkupsVisitor.cs index feafe214..26e241ab 100644 --- a/Xamarin.Forms.Build.Tasks/ExpandMarkupsVisitor.cs +++ b/Xamarin.Forms.Build.Tasks/ExpandMarkupsVisitor.cs @@ -49,6 +49,8 @@ namespace Xamarin.Forms.Build.Tasks return; if (skips.Contains(propertyName)) return; + if (parentNode is IElementNode && ((IElementNode)parentNode).SkipProperties.Contains (propertyName)) + return; var markupString = markupnode.MarkupString; var node = ParseExpression(ref markupString, Context, markupnode.NamespaceResolver, markupnode) as IElementNode; if (node != null) diff --git a/Xamarin.Forms.Build.Tasks/NodeILExtensions.cs b/Xamarin.Forms.Build.Tasks/NodeILExtensions.cs index 084151ba..a7fed895 100644 --- a/Xamarin.Forms.Build.Tasks/NodeILExtensions.cs +++ b/Xamarin.Forms.Build.Tasks/NodeILExtensions.cs @@ -51,6 +51,21 @@ namespace Xamarin.Forms.Build.Tasks var module = context.Body.Method.Module; var str = (string)node.Value; + //If the TypeConverter has a ProvideCompiledAttribute that can be resolved, shortcut this + var compiledConverterName = typeConverter?.GetCustomAttribute (module.Import(typeof(ProvideCompiledAttribute)))?.ConstructorArguments?.First().Value as string; + Type compiledConverterType; + if (compiledConverterName != null && (compiledConverterType = Type.GetType (compiledConverterName)) != null) { + var compiledConverter = Activator.CreateInstance (compiledConverterType); + var converter = typeof(ICompiledTypeConverter).GetMethods ().FirstOrDefault (md => md.Name == "ConvertFromString"); + var instructions = (IEnumerable<Instruction>)converter.Invoke (compiledConverter, new object[] { + node.Value as string, context.Body.Method.Module, node as BaseNode}); + foreach (var i in instructions) + yield return i; + if (targetTypeRef.IsValueType && boxValueTypes) + yield return Instruction.Create (OpCodes.Box, module.Import (targetTypeRef)); + yield break; + } + //If there's a [TypeConverter], use it if (typeConverter != null) { diff --git a/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs b/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs index 734a34c2..f481cbee 100644 --- a/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs +++ b/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs @@ -60,6 +60,8 @@ namespace Xamarin.Forms.Build.Tasks if (skips.Contains(propertyName)) return; + if (parentNode is IElementNode && ((IElementNode)parentNode).SkipProperties.Contains (propertyName)) + return; if (propertyName.NamespaceURI == "http://schemas.openxmlformats.org/markup-compatibility/2006" && propertyName.LocalName == "Ignorable") return; @@ -105,6 +107,11 @@ namespace Xamarin.Forms.Build.Tasks if (propertyName != XmlName.Empty) { + if (skips.Contains(propertyName)) + return; + if (parentNode is IElementNode && ((IElementNode)parentNode).SkipProperties.Contains (propertyName)) + return; + if (propertyName == XmlName._CreateContent) SetDataTemplate((IElementNode)parentNode, node, Context, node); else @@ -136,6 +143,8 @@ namespace Xamarin.Forms.Build.Tasks var name = new XmlName(node.NamespaceURI, contentProperty); if (skips.Contains(name)) return; + if (parentNode is IElementNode && ((IElementNode)parentNode).SkipProperties.Contains (propertyName)) + return; Context.IL.Append(SetPropertyValue(Context.Variables[(IElementNode)parentNode], name, node, Context, node)); } } @@ -151,7 +160,8 @@ namespace Xamarin.Forms.Build.Tasks if (skips.Contains(parentList.XmlName)) return; - + if (parentNode is IElementNode && ((IElementNode)parentNode).SkipProperties.Contains (propertyName)) + return; var elementType = parent.VariableType; var localname = parentList.XmlName.LocalName; @@ -775,4 +785,4 @@ namespace Xamarin.Forms.Build.Tasks return vardefref.VariableDefinition; } } -}
\ No newline at end of file +} diff --git a/Xamarin.Forms.Build.Tasks/Xamarin.Forms.Build.Tasks.csproj b/Xamarin.Forms.Build.Tasks/Xamarin.Forms.Build.Tasks.csproj index d24f42fc..b7250038 100644 --- a/Xamarin.Forms.Build.Tasks/Xamarin.Forms.Build.Tasks.csproj +++ b/Xamarin.Forms.Build.Tasks/Xamarin.Forms.Build.Tasks.csproj @@ -91,6 +91,13 @@ <Compile Include="CompiledMarkupExtensions\StaticExtension.cs" /> <Compile Include="CompiledMarkupExtensions\ICompiledMarkupExtension.cs" /> <Compile Include="BindablePropertyReferenceExtensions.cs" /> + <Compile Include="CompiledConverters\BindablePropertyConverter.cs" /> + <Compile Include="CompiledConverters\BindingTypeConverter.cs" /> + <Compile Include="CompiledConverters\BoundsTypeConverter.cs" /> + <Compile Include="CompiledConverters\ColorTypeConverter.cs" /> + <Compile Include="CompiledConverters\ICompiledTypeConverter.cs" /> + <Compile Include="CompiledConverters\LayoutOptionsConverter.cs" /> + <Compile Include="CompiledConverters\RectangleTypeConverter.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Target Name="AfterBuild"> @@ -126,4 +133,7 @@ </PropertyGroup> <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" /> </Target> + <ItemGroup> + <Folder Include="CompiledConverters\" /> + </ItemGroup> </Project> diff --git a/Xamarin.Forms.Build.Tasks/XmlTypeExtensions.cs b/Xamarin.Forms.Build.Tasks/XmlTypeExtensions.cs index 52460418..db182847 100644 --- a/Xamarin.Forms.Build.Tasks/XmlTypeExtensions.cs +++ b/Xamarin.Forms.Build.Tasks/XmlTypeExtensions.cs @@ -10,6 +10,11 @@ namespace Xamarin.Forms.Build.Tasks { static class XmlTypeExtensions { + public static TypeReference GetTypeReference (string namespaceURI, string typename, ModuleDefinition module, IXmlLineInfo xmlInfo) + { + return new XmlType (namespaceURI, typename, null).GetTypeReference (module, xmlInfo); + } + public static TypeReference GetTypeReference(this XmlType xmlType, ModuleDefinition module, IXmlLineInfo xmlInfo) { var namespaceURI = xmlType.NamespaceUri; |