diff --git a/.editorconfig b/.editorconfig index a5aac14529b..be48d69d356 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,4 +1,5 @@ root = true [*.{cs,xaml}] -indent_style = tab \ No newline at end of file +indent_style = tab +csharp_space_after_keywords_in_control_flow_statements = true \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 146cfee48af..872e8c49433 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "Xamarin.Forms.Build"] path = Xamarin.Forms.Build - url = https://github.com/xamarin/Xamarin.Forms.Build + url = ../../xamarin/Xamarin.Forms.Build diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e61d24f4652..f79d035eed1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,7 +16,7 @@ Check out [A Beginner's Guide for Contributing to Xamarin.Forms](https://blog.xa ### Bug Fixes -If you're looking for something to fix, please browse [open issues](https://github.com/xamarin/Xamarin.Forms/issues). Check for issues tagged help wanted and good first issue. +If you're looking for something to fix, please browse [open issues](https://github.com/xamarin/Xamarin.Forms/issues). Check for issues tagged help wanted and good first issue. Follow the style used by the [.NET Foundation](https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/coding-style.md), with two primary exceptions: diff --git a/EmbeddingTestBeds/Embedding.UWP/Embedding.UWP.csproj b/EmbeddingTestBeds/Embedding.UWP/Embedding.UWP.csproj index 7690cb130bb..ba2f897e6b8 100644 --- a/EmbeddingTestBeds/Embedding.UWP/Embedding.UWP.csproj +++ b/EmbeddingTestBeds/Embedding.UWP/Embedding.UWP.csproj @@ -18,6 +18,7 @@ {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} Embedding.UWP_TemporaryKey.pfx win10-arm;win10-arm-aot;win10-x86;win10-x86-aot;win10-x64;win10-x64-aot + False true @@ -105,7 +106,6 @@ Designer - diff --git a/EmbeddingTestBeds/Embedding.UWP/Embedding.UWP_TemporaryKey.pfx b/EmbeddingTestBeds/Embedding.UWP/Embedding.UWP_TemporaryKey.pfx deleted file mode 100644 index 279cbe7b4f6..00000000000 Binary files a/EmbeddingTestBeds/Embedding.UWP/Embedding.UWP_TemporaryKey.pfx and /dev/null differ diff --git a/PagesGallery/PagesGallery.UWP/Package.appxmanifest b/PagesGallery/PagesGallery.UWP/Package.appxmanifest index 41645b62e5e..e3b4e430d92 100644 --- a/PagesGallery/PagesGallery.UWP/Package.appxmanifest +++ b/PagesGallery/PagesGallery.UWP/Package.appxmanifest @@ -1,10 +1,10 @@  - + FPCL.WIndows - joaqu + Microsoft Assets\StoreLogo.png diff --git a/PagesGallery/PagesGallery.UWP/PagesGallery.UWP.csproj b/PagesGallery/PagesGallery.UWP/PagesGallery.UWP.csproj index 301e5c8e5b7..f047b6f148d 100644 --- a/PagesGallery/PagesGallery.UWP/PagesGallery.UWP.csproj +++ b/PagesGallery/PagesGallery.UWP/PagesGallery.UWP.csproj @@ -17,10 +17,9 @@ true 512 {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Xamarin.Forms.ControlGallery.WindowsUniversal_TemporaryKey.pfx - D160433BDC22781DEAE0558325140B91C02A6A20 True win10-arm;win10-arm-aot;win10-x86;win10-x86-aot;win10-x64;win10-x64-aot + False true @@ -92,8 +91,6 @@ true - - diff --git a/PagesGallery/PagesGallery.UWP/PagesGallery.UWP_TemporaryKey.pfx b/PagesGallery/PagesGallery.UWP/PagesGallery.UWP_TemporaryKey.pfx deleted file mode 100644 index c39eaec0bc2..00000000000 Binary files a/PagesGallery/PagesGallery.UWP/PagesGallery.UWP_TemporaryKey.pfx and /dev/null differ diff --git a/PagesGallery/PagesGallery.UWP/Xamarin.Forms.ControlGallery.WindowsUniversal_TemporaryKey.pfx b/PagesGallery/PagesGallery.UWP/Xamarin.Forms.ControlGallery.WindowsUniversal_TemporaryKey.pfx deleted file mode 100644 index 6d80e21fb65..00000000000 Binary files a/PagesGallery/PagesGallery.UWP/Xamarin.Forms.ControlGallery.WindowsUniversal_TemporaryKey.pfx and /dev/null differ diff --git a/Xamarin.Flex/Flex.cs b/Xamarin.Flex/Flex.cs index e26b4b3c961..104c11b1e75 100644 --- a/Xamarin.Flex/Flex.cs +++ b/Xamarin.Flex/Flex.cs @@ -188,7 +188,7 @@ enum Wrap } /// - /// Value for . + /// Value for . /// struct Basis { readonly bool _isRelative; @@ -241,7 +241,7 @@ class Item : IEnumerable IList Children { get; set; } bool ShouldOrderChildren { get; set; } - ///This property defines how the layout engine will distribute space between and around child items that have been laid out on multiple lines. This property is ignored if the root item does not have its property set to Wrap or WrapReverse. + ///This property defines how the layout engine will distribute space between and around child items that have been laid out on multiple lines. This property is ignored if the root item does not have its property set to Wrap or WrapReverse. ///The default value for this property is Stretch. /// The content of the align. public AlignContent AlignContent { get; set; } = AlignContent.Stretch; @@ -339,7 +339,7 @@ public int Order { /// The bottom edge padding space.Negative values are not allowed. public float PaddingTop { get; set; } = 0f; - /// This property defines whether the item should be positioned by the flexbox rules of the layout engine(Relative) or have an absolute fixed position (Absolute). If this property is set to Absolute, the, , and < see cref= "P:Xamarin.Flex.Item.Bottom" /> properties will then be used to determine the item's fixed position in its container. + /// This property defines whether the item should be positioned by the flexbox rules of the layout engine(Relative) or have an absolute fixed position (Absolute). If this property is set to Absolute, the, , and properties will then be used to determine the item's fixed position in its container. /// Any value part of the enumeration. /// The default value for this property is Relative public Position Position { get; set; } = Position.Relative; @@ -387,10 +387,6 @@ public Item(float width, float height) Height = height; } - /// The child item to be added. - /// Adds a given child item to the current item. - /// Thrown if the child has already been added to another item. - /// Child. public void Add(Item child) { ValidateChild(child); @@ -399,10 +395,10 @@ public void Add(Item child) ShouldOrderChildren |= child.Order != 0; } - public void InsertAt(uint index, Item child) + public void InsertAt(int index, Item child) { ValidateChild(child); - (Children ?? (Children = new List())).Insert((int)index, child); + (Children ?? (Children = new List())).Insert(index, child); child.Parent = this; ShouldOrderChildren |= child.Order != 0; } @@ -415,13 +411,13 @@ public Item RemoveAt(uint index) return child; } - public uint Count => - (uint)(Children?.Count ?? 0); + public int Count => + (Children?.Count ?? 0); - public Item ItemAt(uint index) => - Children?[(int)index]; + public Item ItemAt(int index) => + Children?[index]; - public Item this[uint index] { + public Item this[int index] { get => ItemAt(index); } @@ -434,9 +430,6 @@ public Item Root { } } - /// Determines the frames of each child(included nested ones) based on the flexbox rules that were applied on this item and the children themselves.After this method is called, the, , and < see cref= "P:Xamarin.Flex.Item.FrameHeight" /> properties can be accessed on child items. - /// This method must be called on a root (without parent) item where the and < see cref= "P:Xamarin.Flex.Item.Height" /> properties have also been set. - /// Thrown if the item has a parent (must be root) or if the item does not have a proper value set for < see cref = "P:Xamarin.Flex.Item.Width" /> and < see cref = "P:Xamarin.Flex.Item.Height" />. public void Layout() { if (Parent != null) @@ -448,14 +441,6 @@ public void Layout() layout_item(this, Width, Height); } - public float Padding { - set => PaddingTop = PaddingLeft = PaddingRight = PaddingBottom = value; - } - - public float Margin { - set => MarginTop = MarginLeft = MarginRight = MarginBottom = value; - } - public delegate void SelfSizingDelegate(Item item, ref float width, ref float height); public SelfSizingDelegate SelfSizing { get; set; } @@ -483,22 +468,17 @@ static void layout_item(Item item, float width, float height) layout.init(item, width, height); layout.reset(); - uint last_layout_child = 0; - uint relative_children_count = 0; - for (uint i = 0; i < item.Count; i++) { - Item child = layout.child_at(item, i); + int last_layout_child = 0; + int relative_children_count = 0; + for (int i = 0; i < item.Count; i++) { + var child = layout.child_at(item, i); // Items with an absolute position have their frames determined // directly and are skipped during layout. if (child.Position == Position.Absolute) { - float child_width = absolute_size(child.Width, child.Left, child.Right, width); - float child_height = absolute_size(child.Height, child.Top, child.Bottom, height); - float child_x = absolute_pos(child.Left, child.Right, child_width, width); - float child_y = absolute_pos(child.Top, child.Bottom, child_height, height); - - child.Frame[0] = child_x; - child.Frame[1] = child_y; - child.Frame[2] = child_width; - child.Frame[3] = child_height; + child.Frame[2] = absolute_size(child.Width, child.Left, child.Right, width); + child.Frame[3] = absolute_size(child.Height, child.Top, child.Bottom, height); + child.Frame[0] = absolute_pos(child.Left, child.Right, child.Frame[2], width); + child.Frame[1] = absolute_pos(child.Top, child.Bottom, child.Frame[3], height); // Now that the item has a frame, we can layout its children. layout_item(child, child.Frame[2], child.Frame[3]); @@ -512,22 +492,16 @@ static void layout_item(Item item, float width, float height) child.Frame[3] = child.Height; // Main axis size defaults to 0. - if (float.IsNaN(child.Frame[layout.frame_size_i])) { + if (float.IsNaN(child.Frame[layout.frame_size_i])) child.Frame[layout.frame_size_i] = 0; - } // Cross axis size defaults to the parent's size (or line size in wrap // mode, which is calculated later on). if (float.IsNaN(child.Frame[layout.frame_size2_i])) { - if (layout.wrap) { + if (layout.wrap) layout.need_lines = true; - } - else { - child.Frame[layout.frame_size2_i] = (layout.vertical ? width : height) - - (layout.vertical ? child.MarginLeft : child.MarginTop) - - (layout.vertical ? child.MarginRight : child.MarginBottom); - - } + else + child.Frame[layout.frame_size2_i] = (layout.vertical ? width : height) - child.MarginThickness(!layout.vertical); } // Call the self_sizing callback if provided. Only non-NAN values @@ -538,15 +512,13 @@ static void layout_item(Item item, float width, float height) child.SelfSizing(child, ref size[0], ref size[1]); - for (uint j = 0; j < 2; j++) { - uint size_off = j + 2; - if (size_off == layout.frame_size2_i && child_align(child, item) == AlignItems.Stretch) { + for (int j = 0; j < 2; j++) { + int size_off = j + 2; + if (size_off == layout.frame_size2_i && child_align(child, item) == AlignItems.Stretch) continue; - } float val = size[j]; - if (!float.IsNaN(val)) { + if (!float.IsNaN(val)) child.Frame[size_off] = val; - } } } @@ -557,7 +529,7 @@ static void layout_item(Item item, float width, float height) float basis = child.Basis.Length; if (child.Basis.IsRelative) basis *= (layout.vertical ? height : width); - child.Frame[layout.frame_size_i] = basis; + child.Frame[layout.frame_size_i] = basis - child.MarginThickness(layout.vertical); } float child_size = child.Frame[layout.frame_size_i]; @@ -573,8 +545,8 @@ static void layout_item(Item item, float width, float height) } float child_size2 = child.Frame[layout.frame_size2_i]; - if (!float.IsNaN(child_size2) && child_size2 > layout.line_dim) { - layout.line_dim = child_size2; + if (!float.IsNaN(child_size2) && child_size2 + child.MarginThickness(!layout.vertical) > layout.line_dim) { + layout.line_dim = child_size2 + child.MarginThickness(!layout.vertical); } } @@ -585,9 +557,7 @@ static void layout_item(Item item, float width, float height) layout.flex_grows += child.Grow; layout.flex_shrinks += child.Shrink; - layout.flex_dim -= child_size - + (layout.vertical ? child.MarginTop : child.MarginLeft) - + (layout.vertical ? child.MarginBottom : child.MarginRight); + layout.flex_dim -= child_size + child.MarginThickness(layout.vertical); relative_children_count++; @@ -627,7 +597,7 @@ static void layout_item(Item item, float width, float height) // Re-position the children of this line, honoring any child // alignment previously set within the line. - for (uint j = line.child_begin; j < line.child_end; j++) { + for (int j = line.child_begin; j < line.child_end; j++) { Item child = layout.child_at(item, j); if (child.Position == Position.Absolute) { // Should not be re-positioned. @@ -654,7 +624,10 @@ static void layout_item(Item item, float width, float height) layout.cleanup(); } - static void layout_align(Justify align, float flex_dim, uint children_count, ref float pos_p, ref float spacing_p) + float MarginThickness(bool vertical) => + vertical ? MarginTop + MarginBottom : MarginLeft + MarginRight; + + static void layout_align(Justify align, float flex_dim, int children_count, ref float pos_p, ref float spacing_p) { if (flex_dim < 0) throw new ArgumentException(); @@ -731,7 +704,7 @@ static void layout_align(AlignContent align, float flex_dim, uint children_count } } - static void layout_items(Item item, uint child_begin, uint child_end, uint children_count, ref flex_layout layout) + static void layout_items(Item item, int child_begin, int child_end, int children_count, ref flex_layout layout) { if (children_count > (child_end - child_begin)) throw new ArgumentException(); @@ -764,7 +737,7 @@ static void layout_items(Item item, uint child_begin, uint child_end, uint child layout.pos2 -= layout.line_dim; } - for (uint i = child_begin; i < child_end; i++) { + for (int i = child_begin; i < child_end; i++) { Item child = layout.child_at(item, i); if (child.Position == Position.Absolute) { @@ -877,7 +850,7 @@ struct flex_layout { public uint frame_pos2_i; // cross axis position public uint frame_size_i; // main axis size public uint frame_size2_i; // cross axis size - uint[] ordered_indices; + int[] ordered_indices; // Set for each line layout. public float line_dim; // the cross axis size @@ -893,8 +866,8 @@ struct flex_layout { public bool need_lines; public struct flex_layout_line { - public uint child_begin; - public uint child_end; + public int child_begin; + public int child_end; public float size; }; @@ -920,11 +893,8 @@ public void init(Item item, float width, float height) || item.PaddingBottom < 0) throw new ArgumentException(); - width -= item.PaddingLeft + item.PaddingRight; - height -= item.PaddingTop + item.PaddingBottom; - if ( width < 0 - || height < 0) - throw new ArgumentException(); + width = Math.Max(0, width - item.PaddingLeft + item.PaddingRight); + height = Math.Max(0, height - item.PaddingTop + item.PaddingBottom); reverse = item.Direction == Direction.RowReverse || item.Direction == Direction.ColumnReverse; vertical = true; @@ -952,18 +922,18 @@ public void init(Item item, float width, float height) ordered_indices = null; if (item.ShouldOrderChildren && item.Count > 0) { - var indices = new uint[item.Count]; + var indices = new int[item.Count]; // Creating a list of item indices sorted using the children's `order' // attribute values. We are using a simple insertion sort as we need // stability (insertion order must be preserved) and cross-platform // support. We should eventually switch to merge sort (or something // else) if the number of items becomes significant enough. - for (uint i = 0; i < item.Count; i++) { + for (int i = 0; i < item.Count; i++) { indices[i] = i; - for (uint j = i; j > 0; j--) { - uint prev = indices[j - 1]; - uint curr = indices[j]; - if (item.Children[(int)prev].Order <= item.Children[(int)curr].Order) { + for (int j = i; j > 0; j--) { + int prev = indices[j - 1]; + int curr = indices[j]; + if (item.Children[prev].Order <= item.Children[curr].Order) { break; } indices[j - 1] = curr; @@ -994,8 +964,8 @@ public void init(Item item, float width, float height) lines_sizes = 0; } - public Item child_at(Item item, uint i) => - item.Children[(int)(ordered_indices?[i] ?? i)]; + public Item child_at(Item item, int i) => + item.Children[(ordered_indices?[i] ?? i)]; public void cleanup() { diff --git a/Xamarin.Forms.Build b/Xamarin.Forms.Build index a886ee3ce28..dedf66f9e71 160000 --- a/Xamarin.Forms.Build +++ b/Xamarin.Forms.Build @@ -1 +1 @@ -Subproject commit a886ee3ce28128c7f8045394197cf000cf2ed2fa +Subproject commit dedf66f9e71d6a1b02f35c384f73cc17fa37a9b1 diff --git a/Xamarin.Forms.Build.Tasks/BindablePropertyReferenceExtensions.cs b/Xamarin.Forms.Build.Tasks/BindablePropertyReferenceExtensions.cs index 030a2a62b85..a2930579054 100644 --- a/Xamarin.Forms.Build.Tasks/BindablePropertyReferenceExtensions.cs +++ b/Xamarin.Forms.Build.Tasks/BindablePropertyReferenceExtensions.cs @@ -26,7 +26,7 @@ public static TypeReference GetBindablePropertyType(this FieldReference bpRef, I md.IsStatic && md.IsPublic && md.Parameters.Count == 1 && - md.Parameters[0].ParameterType.InheritsFromOrImplements(module.ImportReferenceCached(typeof(BindableObject))), module).SingleOrDefault()?.Item1; + md.Parameters[0].ParameterType.InheritsFromOrImplements(module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms", "BindableObject"))), module).SingleOrDefault()?.Item1; if (getter == null) throw new XamlParseException($"Missing a public static Get{bpName} or a public instance property getter for the attached property \"{bpRef.DeclaringType}.{bpRef.Name}\"", iXmlLineInfo); return getter.ResolveGenericReturnType(declaringTypeRef, module); @@ -43,7 +43,7 @@ public static TypeReference GetBindablePropertyTypeConverter(this FieldReference md.IsStatic && md.IsPublic && md.Parameters.Count == 1 && - md.Parameters[0].ParameterType.InheritsFromOrImplements(module.ImportReferenceCached(typeof(BindableObject))), module).SingleOrDefault()?.Item1; + md.Parameters[0].ParameterType.InheritsFromOrImplements(module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms", "BindableObject"))), module).SingleOrDefault()?.Item1; var attributes = new List(); if (property != null && property.HasCustomAttributes) diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/BindingTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/BindingTypeConverter.cs index 2eae874733e..575bb136b44 100644 --- a/Xamarin.Forms.Build.Tasks/CompiledConverters/BindingTypeConverter.cs +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/BindingTypeConverter.cs @@ -20,9 +20,7 @@ public IEnumerable ConvertFromString(string value, ILContext contex if (IsNullOrEmpty(value)) throw new XamlParseException($"Cannot convert \"{value}\" into {typeof(Binding)}", node); - var bindingCtor = module.ImportReferenceCached(typeof(Binding)).ResolveCached().Methods.FirstOrDefault(md => md.IsConstructor && md.Parameters.Count == 6); - var bindingCtorRef = module.ImportReference(bindingCtor); - + var bindingCtorRef = module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Binding"), paramCount: 6); yield return Instruction.Create(OpCodes.Ldstr, value); yield return Instruction.Create(OpCodes.Ldc_I4, (int)BindingMode.Default); yield return Instruction.Create(OpCodes.Ldnull); diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/BoundsTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/BoundsTypeConverter.cs index 9e4c8eac9b3..629afce8796 100644 --- a/Xamarin.Forms.Build.Tasks/CompiledConverters/BoundsTypeConverter.cs +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/BoundsTypeConverter.cs @@ -68,8 +68,7 @@ IEnumerable GenerateIL(double x, double y, double w, double h, Modu yield return Instruction.Create(OpCodes.Ldc_R8, w); yield return Instruction.Create(OpCodes.Ldc_R8, h); - var rectangleCtor = module.ImportReferenceCached(typeof(Rectangle)).ResolveCached().Methods.FirstOrDefault(md => md.IsConstructor && md.Parameters.Count == 4); - var rectangleCtorRef = module.ImportReference(rectangleCtor); + var rectangleCtorRef = module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Rectangle"), paramCount: 4); yield return Instruction.Create(OpCodes.Newobj, rectangleCtorRef); } } diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/ColorTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/ColorTypeConverter.cs index 6aefcfb8c01..4577bed5db7 100644 --- a/Xamarin.Forms.Build.Tasks/CompiledConverters/ColorTypeConverter.cs +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/ColorTypeConverter.cs @@ -28,10 +28,10 @@ public IEnumerable ConvertFromString(string value, ILContext contex 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.ImportReferenceCached(typeof(Color)).ResolveCached().Methods.FirstOrDefault( - md => md.IsConstructor && md.Parameters.Count == 4 && - md.Parameters.All(p => p.ParameterType.FullName == "System.Double")); - var colorCtorRef = module.ImportReference(colorCtor); + + var colorCtorRef = module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Color"), + paramCount: 4, + predicate: md => md.Parameters.All(p => p.ParameterType.FullName == "System.Double")); yield return Instruction.Create(OpCodes.Newobj, colorCtorRef); yield break; } @@ -39,14 +39,18 @@ public IEnumerable ConvertFromString(string value, ILContext contex if (parts.Length == 1 || (parts.Length == 2 && parts [0] == "Color")) { var color = parts [parts.Length - 1]; - var field = module.ImportReferenceCached(typeof(Color)).ResolveCached().Fields.SingleOrDefault(fd => fd.Name == color && fd.IsStatic); - if (field != null) { - yield return Instruction.Create(OpCodes.Ldsfld, module.ImportReference(field)); + var fieldReference = module.ImportFieldReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Color"), + color, + fd => fd.IsStatic); + if (fieldReference != null) { + yield return Instruction.Create(OpCodes.Ldsfld, fieldReference); yield break; } - var propertyGetter = module.ImportReferenceCached(typeof(Color)).ResolveCached().Properties.SingleOrDefault(pd => pd.Name == color && pd.GetMethod.IsStatic)?.GetMethod; - if (propertyGetter != null) { - yield return Instruction.Create(OpCodes.Call, module.ImportReference(propertyGetter)); + var propertyGetterReference = module.ImportPropertyGetterReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Color"), + color, + pd => pd.GetMethod.IsStatic); + if (propertyGetterReference != null) { + yield return Instruction.Create(OpCodes.Call, propertyGetterReference); yield break; } } diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/ConstraintTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/ConstraintTypeConverter.cs index 8dd6fd3617d..e130cc5fc7e 100644 --- a/Xamarin.Forms.Build.Tasks/CompiledConverters/ConstraintTypeConverter.cs +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/ConstraintTypeConverter.cs @@ -22,10 +22,11 @@ public IEnumerable ConvertFromString(string value, ILContext contex throw new XamlParseException($"Cannot convert \"{value}\" into {typeof(Constraint)}", node); yield return Instruction.Create(OpCodes.Ldc_R8, size); - - var constantDef = module.ImportReferenceCached(typeof(Constraint)).ResolveCached().Methods.FirstOrDefault(md => md.IsStatic && md.Name == "Constant"); - var constantRef = module.ImportReference(constantDef); - yield return Instruction.Create(OpCodes.Call, constantRef); + var constantReference = module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Constraint"), + methodName: "Constant", + paramCount: 1, + predicate: md => md.IsStatic); + yield return Instruction.Create(OpCodes.Call, constantReference); } } } diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/LayoutOptionsConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/LayoutOptionsConverter.cs index 82cc39a739c..f0a61657ca7 100644 --- a/Xamarin.Forms.Build.Tasks/CompiledConverters/LayoutOptionsConverter.cs +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/LayoutOptionsConverter.cs @@ -26,9 +26,11 @@ public IEnumerable ConvertFromString(string value, ILContext contex if (parts.Length == 1 || (parts.Length == 2 && parts [0] == "LayoutOptions")) { var options = parts [parts.Length - 1]; - var field = module.ImportReferenceCached(typeof(LayoutOptions)).ResolveCached().Fields.SingleOrDefault(fd => fd.Name == options && fd.IsStatic); - if (field != null) { - yield return Instruction.Create(OpCodes.Ldsfld, module.ImportReference(field)); + var fieldReference = module.ImportFieldReference(("Xamarin.Forms.Core", "Xamarin.Forms", "LayoutOptions"), + fieldName: options, + predicate: fd => fd.IsStatic); + if (fieldReference != null) { + yield return Instruction.Create(OpCodes.Ldsfld, fieldReference); yield break; } } diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/ListStringTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/ListStringTypeConverter.cs index 23966c37d7d..4bd2e07eb4c 100644 --- a/Xamarin.Forms.Build.Tasks/CompiledConverters/ListStringTypeConverter.cs +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/ListStringTypeConverter.cs @@ -22,21 +22,20 @@ public IEnumerable ConvertFromString(string value, ILContext contex } var parts = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToList(); - var listCtor = module.ImportReferenceCached(typeof(List<>)).ResolveCached().Methods.FirstOrDefault(md => md.IsConstructor && md.Parameters.Count == 1 && md.Parameters[0].ParameterType.FullName == "System.Int32"); - var listCtorRef = module.ImportReference(listCtor); - listCtorRef = module.ImportReference(listCtorRef.ResolveGenericParameters(module.ImportReferenceCached(typeof(List)), module)); - - var adder = module.ImportReferenceCached(typeof(ICollection<>)).ResolveCached().Methods.FirstOrDefault(md => md.Name == "Add" && md.Parameters.Count == 1); - var adderRef = module.ImportReference(adder); - adderRef = module.ImportReference(adderRef.ResolveGenericParameters(module.ImportReferenceCached(typeof(ICollection)), module)); + var add = module.ImportMethodReference(("mscorlib", "System.Collections.Generic", "ICollection`1"), + methodName: "Add", + paramCount: 1, + classArguments: new[] { ("mscorlib", "System", "String") }); yield return Instruction.Create(OpCodes.Ldc_I4, parts.Count); - yield return Instruction.Create(OpCodes.Newobj, listCtorRef); - + yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("System.Collections", "System.Collections.Generic", "List`1"), + paramCount: 1, + predicate: md => md.Parameters[0].ParameterType.FullName == "System.Int32", + classArguments: new[] { ("mscorlib", "System", "String") })); foreach (var part in parts) { yield return Instruction.Create(OpCodes.Dup); yield return Instruction.Create(OpCodes.Ldstr, part); - yield return Instruction.Create(OpCodes.Callvirt, adderRef); + yield return Instruction.Create(OpCodes.Callvirt, add); } } } diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/RDSourceTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/RDSourceTypeConverter.cs index be15fc66c6a..534ab755ca0 100644 --- a/Xamarin.Forms.Build.Tasks/CompiledConverters/RDSourceTypeConverter.cs +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/RDSourceTypeConverter.cs @@ -44,26 +44,18 @@ public IEnumerable ConvertFromString(string value, ILContext contex //keep the Uri for later yield return Create(Dup); - var uriVarDef = new VariableDefinition(module.ImportReferenceCached(typeof(Uri))); + var uriVarDef = new VariableDefinition(module.ImportReference(("System", "System", "Uri"))); body.Variables.Add(uriVarDef); yield return Create(Stloc, uriVarDef); - yield return Create(Ldstr, resourcePath); //resourcePath - - var getTypeFromHandle = module.ImportReferenceCached(typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) })); - var getTypeInfo = module.ImportReferenceCached(typeof(System.Reflection.IntrospectionExtensions).GetMethod("GetTypeInfo", new Type[] { typeof(Type) })); - var getAssembly = module.ImportReferenceCached(typeof(System.Reflection.TypeInfo).GetProperty("Assembly").GetMethod); yield return Create(Ldtoken, module.ImportReference(((ILRootNode)rootNode).TypeReference)); - yield return Create(Call, module.ImportReference(getTypeFromHandle)); - yield return Create(Call, module.ImportReference(getTypeInfo)); - yield return Create(Callvirt, module.ImportReference(getAssembly)); //assembly + yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", paramCount: 1, predicate: md => md.IsStatic)); + yield return Create(Call, module.ImportMethodReference(("mscorlib", "System.Reflection", "IntrospectionExtensions"), methodName: "GetTypeInfo", paramCount: 1, predicate: md => md.IsStatic)); + yield return Create(Callvirt, module.ImportPropertyGetterReference(("mscorlib", "System.Reflection", "TypeInfo"), propertyName: "Assembly", flatten: true)); foreach (var instruction in node.PushXmlLineInfo(context)) yield return instruction; //lineinfo - - var setAndLoadSource = module.ImportReferenceCached(typeof(ResourceDictionary).GetMethod("SetAndLoadSource")); - yield return Create(Callvirt, module.ImportReference(setAndLoadSource)); - + yield return Create(Callvirt, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms", "ResourceDictionary"), methodName: "SetAndLoadSource", paramCount: 4)); //ldloc the stored uri as return value yield return Create(Ldloc, uriVarDef); } @@ -71,7 +63,7 @@ public IEnumerable ConvertFromString(string value, ILContext contex internal static string GetPathForType(ModuleDefinition module, TypeReference type) { foreach (var ca in type.Module.GetCustomAttributes()) { - if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReferenceCached(typeof(XamlResourceIdAttribute)))) + if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "XamlResourceIdAttribute")))) continue; if (!TypeRefComparer.Default.Equals(ca.ConstructorArguments[2].Value as TypeReference, type)) continue; @@ -80,4 +72,4 @@ internal static string GetPathForType(ModuleDefinition module, TypeReference typ return null; } } -} +} \ No newline at end of file diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/RectangleTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/RectangleTypeConverter.cs index 844746f6b0c..219bdd41bcd 100644 --- a/Xamarin.Forms.Build.Tasks/CompiledConverters/RectangleTypeConverter.cs +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/RectangleTypeConverter.cs @@ -43,9 +43,7 @@ IEnumerable GenerateIL(double x, double y, double w, double h, Modu yield return Instruction.Create(OpCodes.Ldc_R8, w); yield return Instruction.Create(OpCodes.Ldc_R8, h); - var rectangleCtor = module.ImportReferenceCached(typeof(Rectangle)).ResolveCached().Methods.FirstOrDefault(md => md.IsConstructor && md.Parameters.Count == 4); - var rectangleCtorRef = module.ImportReference(rectangleCtor); - yield return Instruction.Create(OpCodes.Newobj, rectangleCtorRef); + yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Rectangle"), paramCount: 4)); } } } \ No newline at end of file diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/ThicknessTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/ThicknessTypeConverter.cs index 205215e84b3..459dc4d1ae0 100644 --- a/Xamarin.Forms.Build.Tasks/CompiledConverters/ThicknessTypeConverter.cs +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/ThicknessTypeConverter.cs @@ -45,9 +45,8 @@ IEnumerable GenerateIL(ModuleDefinition module, params double[] arg { foreach (var d in args) yield return Instruction.Create(OpCodes.Ldc_R8, d); - var thicknessCtor = module.ImportReferenceCached(typeof(Thickness)).ResolveCached().Methods.FirstOrDefault(md => md.IsConstructor && md.Parameters.Count == args.Length); - var thicknessCtorRef = module.ImportReference(thicknessCtor); - yield return Instruction.Create(OpCodes.Newobj, thicknessCtorRef); + yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Thickness"), + paramCount: args.Length)); } } diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/TypeTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/TypeTypeConverter.cs index e2ac1c3ede7..74c6a33223c 100644 --- a/Xamarin.Forms.Build.Tasks/CompiledConverters/TypeTypeConverter.cs +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/TypeTypeConverter.cs @@ -33,9 +33,9 @@ public IEnumerable ConvertFromString(string value, ILContext contex if (typeRef == null) goto error; - var getTypeFromHandle = module.ImportReferenceCached(typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) })); yield return Instruction.Create(OpCodes.Ldtoken, module.ImportReference(typeRef)); - yield return Instruction.Create(OpCodes.Call, module.ImportReference(getTypeFromHandle)); + yield return Instruction.Create(OpCodes.Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", paramCount: 1, predicate: md => md.IsStatic)); + yield break; error: diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/UriTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/UriTypeConverter.cs index 74e3b1c19a4..06f946017d3 100644 --- a/Xamarin.Forms.Build.Tasks/CompiledConverters/UriTypeConverter.cs +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/UriTypeConverter.cs @@ -24,9 +24,9 @@ public IEnumerable ConvertFromString(string value, ILContext contex yield break; } - var uriCtor = module.ImportReferenceCached(typeof(Uri)).ResolveCached().Methods.FirstOrDefault(md => md.IsConstructor && md.Parameters.Count == 2 && md.Parameters[1].ParameterType.FullName == "System.UriKind"); - var uriCtorRef = module.ImportReference(uriCtor); - + var uriCtorRef = module.ImportCtorReference(("System", "System", "Uri"), + paramCount: 2, + predicate: md => md.Parameters[1].ParameterType.FullName == "System.UriKind"); yield return Create(Ldstr, value); yield return Create(Ldc_I4_0); //UriKind.RelativeOrAbsolute yield return Create(Newobj, uriCtorRef); diff --git a/Xamarin.Forms.Build.Tasks/CompiledMarkupExtensions/TypeExtension.cs b/Xamarin.Forms.Build.Tasks/CompiledMarkupExtensions/TypeExtension.cs index cbda1fae135..dedff307006 100644 --- a/Xamarin.Forms.Build.Tasks/CompiledMarkupExtensions/TypeExtension.cs +++ b/Xamarin.Forms.Build.Tasks/CompiledMarkupExtensions/TypeExtension.cs @@ -12,7 +12,7 @@ class TypeExtension : ICompiledMarkupExtension { public IEnumerable ProvideValue(IElementNode node, ModuleDefinition module, ILContext context, out TypeReference memberRef) { - memberRef = module.ImportReferenceCached(typeof(Type)); + memberRef = module.ImportReference(("mscorlib", "System", "Type")); INode typeNameNode; var name = new XmlName("", "TypeName"); @@ -34,10 +34,10 @@ public IEnumerable ProvideValue(IElementNode node, ModuleDefinition context.TypeExtensions[node] = typeref; - var getTypeFromHandle = module.ImportReferenceCached(typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) })); return new List { Instruction.Create(OpCodes.Ldtoken, module.ImportReference(typeref)), - Instruction.Create(OpCodes.Call, module.ImportReference(getTypeFromHandle)) + Instruction.Create(OpCodes.Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", paramCount: 1, predicate: md => md.IsStatic)), + }; } } diff --git a/Xamarin.Forms.Build.Tasks/CompiledValueProviders/SetterValueProvider.cs b/Xamarin.Forms.Build.Tasks/CompiledValueProviders/SetterValueProvider.cs index cab40ba4e5a..96fb60bff77 100644 --- a/Xamarin.Forms.Build.Tasks/CompiledValueProviders/SetterValueProvider.cs +++ b/Xamarin.Forms.Build.Tasks/CompiledValueProviders/SetterValueProvider.cs @@ -34,9 +34,6 @@ public IEnumerable ProvideValue(VariableDefinitionReference vardefr var value = ((string)((ValueNode)valueNode).Value); - TypeReference _; - var setValueRef = module.ImportReference(module.ImportReferenceCached(typeof(Setter)).GetProperty(p => p.Name == "Value", out _).SetMethod); - //push the setter yield return Instruction.Create(OpCodes.Ldloc, vardefref.VariableDefinition); @@ -45,7 +42,7 @@ public IEnumerable ProvideValue(VariableDefinitionReference vardefr yield return instruction; //set the value - yield return Instruction.Create(OpCodes.Callvirt, setValueRef); + yield return Instruction.Create(OpCodes.Callvirt, module.ImportPropertySetterReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Setter"), propertyName: "Value")); } static bool SetterValueIsCollection(FieldReference bindablePropertyReference, ModuleDefinition module, BaseNode node, ILContext context) diff --git a/Xamarin.Forms.Build.Tasks/CompiledValueProviders/StyleSheetProvider.cs b/Xamarin.Forms.Build.Tasks/CompiledValueProviders/StyleSheetProvider.cs index 7f854a8bda6..aa6c8f079c5 100644 --- a/Xamarin.Forms.Build.Tasks/CompiledValueProviders/StyleSheetProvider.cs +++ b/Xamarin.Forms.Build.Tasks/CompiledValueProviders/StyleSheetProvider.cs @@ -32,26 +32,27 @@ public IEnumerable ProvideValue(VariableDefinitionReference vardefr styleNode = ((IElementNode)node).CollectionItems[0]; if (sourceNode != null && styleNode != null) - throw new XamlParseException($"StyleSheet can not have both a Source and a content", node); + throw new XamlParseException("StyleSheet can not have both a Source and a content", node); if (sourceNode == null && styleNode == null) - throw new XamlParseException($"StyleSheet require either a Source or a content", node); + throw new XamlParseException("StyleSheet require either a Source or a content", node); if (styleNode != null && !(styleNode is ValueNode)) - throw new XamlParseException($"Style property or Content is not a string literal", node); + throw new XamlParseException("Style property or Content is not a string literal", node); if (sourceNode != null && !(sourceNode is ValueNode)) - throw new XamlParseException($"Source property is not a string literal", node); + throw new XamlParseException("Source property is not a string literal", node); if (styleNode != null) { var style = (styleNode as ValueNode).Value as string; yield return Create(Ldstr, style); - - var fromString = module.ImportReferenceCached(typeof(StyleSheets.StyleSheet).GetMethods().FirstOrDefault(mi => mi.Name == nameof(StyleSheets.StyleSheet.FromString) && mi.GetParameters().Length == 1)); - yield return Create(Call, module.ImportReference(fromString)); + yield return Create(Call, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms.StyleSheets", "StyleSheet"), + methodName: "FromString", + paramCount: 1, + predicate: md => md.IsStatic)); } else { - string source = (sourceNode as ValueNode)?.Value as string; + var source = (sourceNode as ValueNode)?.Value as string; INode rootNode = node; while (!(rootNode is ILRootNode)) rootNode = rootNode.Parent; @@ -65,23 +66,24 @@ public IEnumerable ProvideValue(VariableDefinitionReference vardefr if (resourceId == null) throw new XamlParseException($"Resource '{source}' not found.", node); - var getTypeFromHandle = module.ImportReferenceCached(typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle), new[] { typeof(RuntimeTypeHandle) })); - var getAssembly = module.ImportReferenceCached(typeof(Type).GetProperty(nameof(Type.Assembly)).GetGetMethod()); yield return Create(Ldtoken, module.ImportReference(((ILRootNode)rootNode).TypeReference)); - yield return Create(Call, module.ImportReference(getTypeFromHandle)); - yield return Create(Callvirt, module.ImportReference(getAssembly)); //assembly + yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", paramCount: 1, predicate: md => md.IsStatic)); + yield return Create(Call, module.ImportMethodReference(("mscorlib", "System.Reflection", "IntrospectionExtensions"), methodName: "GetTypeInfo", paramCount: 1, predicate: md => md.IsStatic)); + yield return Create(Callvirt, module.ImportPropertyGetterReference(("mscorlib", "System.Reflection", "TypeInfo"), propertyName: "Assembly", flatten: true)); yield return Create(Ldstr, resourceId); //resourceId foreach (var instruction in node.PushXmlLineInfo(context)) yield return instruction; //lineinfo - var fromAssemblyResource = module.ImportReferenceCached(typeof(StyleSheets.StyleSheet).GetMethods().FirstOrDefault(mi => mi.Name == nameof(StyleSheets.StyleSheet.FromAssemblyResource) && mi.GetParameters().Length == 3)); - yield return Create(Call, module.ImportReference(fromAssemblyResource)); + yield return Create(Call, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms.StyleSheets", "StyleSheet"), + methodName: "FromAssemblyResource", + paramCount: 3, + predicate: md => md.IsStatic)); } //the variable is of type `object`. fix that - var vardef = new VariableDefinition(module.ImportReferenceCached(typeof(StyleSheets.StyleSheet))); + var vardef = new VariableDefinition(module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms.StyleSheets", "StyleSheet"))); yield return Create(Stloc, vardef); vardefref.VariableDefinition = vardef; } diff --git a/Xamarin.Forms.Build.Tasks/CreateObjectVisitor.cs b/Xamarin.Forms.Build.Tasks/CreateObjectVisitor.cs index ce73d5a5a1f..5a8a3b2c0d5 100644 --- a/Xamarin.Forms.Build.Tasks/CreateObjectVisitor.cs +++ b/Xamarin.Forms.Build.Tasks/CreateObjectVisitor.cs @@ -7,6 +7,9 @@ using Xamarin.Forms.Xaml; using System.Xml; +using static Mono.Cecil.Cil.Instruction; +using static Mono.Cecil.Cil.OpCodes; + namespace Xamarin.Forms.Build.Tasks { class CreateObjectVisitor : IXamlNodeVisitor @@ -53,7 +56,9 @@ public void Visit(ElementNode node, INode parentNode) } //if this is a MarkupExtension that can be compiled directly, compile and returns the value - var compiledMarkupExtensionName = typeref.GetCustomAttribute(Module.ImportReferenceCached(typeof(ProvideCompiledAttribute)))?.ConstructorArguments?[0].Value as string; + var compiledMarkupExtensionName = typeref + .GetCustomAttribute(Module, ("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "ProvideCompiledAttribute")) + ?.ConstructorArguments?[0].Value as string; Type compiledMarkupExtensionType; ICompiledMarkupExtension markupProvider; if (compiledMarkupExtensionName != null && @@ -337,207 +342,174 @@ static bool IsXaml2009LanguagePrimitive(IElementNode node) IEnumerable PushValueFromLanguagePrimitive(TypeDefinition typedef, ElementNode node) { + var module = Context.Body.Method.Module; 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.SByte": - sbyte outsbyte; - if (hasValue && sbyte.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outsbyte)) - yield return Instruction.Create(OpCodes.Ldc_I4, (int)outsbyte); + if (hasValue && sbyte.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out sbyte outsbyte)) + yield return Create(Ldc_I4, (int)outsbyte); else - yield return Instruction.Create(OpCodes.Ldc_I4, 0x00); + yield return Create(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); + if (hasValue && short.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out short outshort)) + yield return Create(Ldc_I4, outshort); else - yield return Instruction.Create(OpCodes.Ldc_I4, 0x00); + yield return Create(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); + if (hasValue && int.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out int outint)) + yield return Create(Ldc_I4, outint); else - yield return Instruction.Create(OpCodes.Ldc_I4, 0x00); + yield return Create(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); + if (hasValue && long.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out long outlong)) + yield return Create(Ldc_I8, outlong); else - yield return Instruction.Create(OpCodes.Ldc_I8, 0L); + yield return Create(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); + if (hasValue && byte.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out byte outbyte)) + yield return Create(Ldc_I4, (int)outbyte); else - yield return Instruction.Create(OpCodes.Ldc_I4, 0x00); + yield return Create(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); + if (hasValue && short.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out short outushort)) + yield return Create(Ldc_I4, outushort); else - yield return Instruction.Create(OpCodes.Ldc_I4, 0x00); + yield return Create(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); + if (hasValue && int.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out int outuint)) + yield return Create(Ldc_I4, outuint); else - yield return Instruction.Create(OpCodes.Ldc_I4, 0x00); + yield return Create(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); + if (hasValue && long.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out long outulong)) + yield return Create(Ldc_I8, outulong); else - yield return Instruction.Create(OpCodes.Ldc_I8, 0L); + yield return Create(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); + if (hasValue && bool.TryParse(valueString, out bool outbool)) + yield return Create(outbool ? Ldc_I4_1 : Ldc_I4_0); else - yield return Instruction.Create(OpCodes.Ldc_I4_0); + yield return Create(Ldc_I4_0); break; case "System.String": - yield return Instruction.Create(OpCodes.Ldstr, valueString); + yield return Create(Ldstr, valueString); break; case "System.Object": var ctorinfo = - Context.Body.Method.Module.TypeSystem.Object.ResolveCached() + module.TypeSystem.Object.ResolveCached() .Methods.FirstOrDefault(md => md.IsConstructor && !md.HasParameters); - var ctor = Context.Body.Method.Module.ImportReference(ctorinfo); - yield return Instruction.Create(OpCodes.Newobj, ctor); + var ctor = module.ImportReference(ctorinfo); + yield return Create(Newobj, ctor); break; case "System.Char": - char outchar; - if (hasValue && char.TryParse(valueString, out outchar)) - yield return Instruction.Create(OpCodes.Ldc_I4, outchar); + if (hasValue && char.TryParse(valueString, out char outchar)) + yield return Create(Ldc_I4, outchar); else - yield return Instruction.Create(OpCodes.Ldc_I4, 0x00); + yield return Create(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.ImportReferenceCached(typeof(decimal))); + var vardef = new VariableDefinition(module.ImportReference(("mscorlib", "System", "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.ImportReferenceCached(typeof(CultureInfo)) - .ResolveCached() - .Properties.FirstOrDefault(pd => pd.Name == "InvariantCulture") - .GetMethod; - var getInvariant = Context.Body.Method.Module.ImportReference(getInvariantInfo); - yield return Instruction.Create(OpCodes.Call, getInvariant); - yield return Instruction.Create(OpCodes.Ldloca, vardef); - var tryParseInfo = - Context.Body.Method.Module.ImportReferenceCached(typeof(decimal)) - .ResolveCached() - .Methods.FirstOrDefault(md => md.Name == "TryParse" && md.Parameters.Count == 4); - var tryParse = Context.Body.Method.Module.ImportReference(tryParseInfo); - yield return Instruction.Create(OpCodes.Call, tryParse); - yield return Instruction.Create(OpCodes.Pop); - yield return Instruction.Create(OpCodes.Ldloc, vardef); +// 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 Create(Ldstr, valueString); + yield return Create(Ldc_I4, 0x6f); //NumberStyles.Number + var getInvariant = module.ImportPropertyGetterReference(("mscorlib", "System.Globalization", "CultureInfo"), + propertyName: "InvariantCulture"); + yield return Create(Call, getInvariant); + yield return Create(Ldloca, vardef); + var tryParse = module.ImportMethodReference(("mscorlib", "System", "Decimal"), + methodName: "TryParse", + paramCount: 4); + yield return Create(Call, tryParse); + yield return Create(Pop); + yield return Create(Ldloc, vardef); } else { - yield return Instruction.Create(OpCodes.Ldc_I4_0); - var decimalctorinfo = - Context.Body.Method.Module.ImportReferenceCached(typeof(decimal)) - .ResolveCached() - .Methods.FirstOrDefault( - md => md.IsConstructor && md.Parameters.Count == 1 && md.Parameters [0].ParameterType.FullName == "System.Int32"); - var decimalctor = Context.Body.Method.Module.ImportReference(decimalctorinfo); - yield return Instruction.Create(OpCodes.Newobj, decimalctor); + yield return Create(Ldc_I4_0); + var decimalctor = module.ImportCtorReference(("mscorlib", "System", "Decimal"), + paramCount: 1, + predicate: md => md.Parameters[0].ParameterType.FullName == "System.Int32"); + yield return Create(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); + if (hasValue && float.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out float outfloat)) + yield return Create(Ldc_R4, outfloat); else - yield return Instruction.Create(OpCodes.Ldc_R4, 0f); + yield return Create(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); + if (hasValue && double.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out double outdouble)) + yield return Create(Ldc_R8, outdouble); else - yield return Instruction.Create(OpCodes.Ldc_R8, 0d); + yield return Create(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.ImportReferenceCached(typeof(TimeSpan))); + if (hasValue && TimeSpan.TryParse(valueString, CultureInfo.InvariantCulture, out TimeSpan outspan)) { + var vardef = new VariableDefinition(module.ImportReference(("mscorlib", "System", "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.ImportReferenceCached(typeof(CultureInfo)) - .ResolveCached() - .Properties.FirstOrDefault(pd => pd.Name == "InvariantCulture") - .GetMethod; - var getInvariant = Context.Body.Method.Module.ImportReference(getInvariantInfo); - yield return Instruction.Create(OpCodes.Call, getInvariant); - yield return Instruction.Create(OpCodes.Ldloca, vardef); - var tryParseInfo = - Context.Body.Method.Module.ImportReferenceCached(typeof(TimeSpan)) - .ResolveCached() - .Methods.FirstOrDefault(md => md.Name == "TryParse" && md.Parameters.Count == 3); - var tryParse = Context.Body.Method.Module.ImportReference(tryParseInfo); - yield return Instruction.Create(OpCodes.Call, tryParse); - yield return Instruction.Create(OpCodes.Pop); - yield return Instruction.Create(OpCodes.Ldloc, vardef); + yield return Create(Ldstr, valueString); + var getInvariant = module.ImportPropertyGetterReference(("mscorlib", "System.Globalization", "CultureInfo"), + propertyName: "InvariantCulture"); + yield return Create(Call, getInvariant); + yield return Create(Ldloca, vardef); + var tryParse = module.ImportMethodReference(("mscorlib", "System", "TimeSpan"), + methodName: "TryParse", + paramCount: 3); + + yield return Create(Call, tryParse); + yield return Create(Pop); + yield return Create(Ldloc, vardef); } else { - yield return Instruction.Create(OpCodes.Ldc_I8, 0L); - var timespanctorinfo = - Context.Body.Method.Module.ImportReferenceCached(typeof(TimeSpan)) - .ResolveCached() - .Methods.FirstOrDefault( - md => md.IsConstructor && md.Parameters.Count == 1 && md.Parameters [0].ParameterType.FullName == "System.Int64"); - var timespanctor = Context.Body.Method.Module.ImportReference(timespanctorinfo); - yield return Instruction.Create(OpCodes.Newobj, timespanctor); + yield return Create(Ldc_I8, 0L); + var timespanctor = module.ImportCtorReference(("mscorlib", "System", "TimeSpan"), + paramCount: 1, + predicate: md => md.Parameters[0].ParameterType.FullName == "System.Int64"); + yield return Create(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.ImportReferenceCached(typeof(Uri))); + if (hasValue && Uri.TryCreate(valueString, UriKind.RelativeOrAbsolute, out Uri outuri)) { + var vardef = new VariableDefinition(module.ImportReference(("System", "System", "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.ImportReferenceCached(typeof(Uri)) - .ResolveCached() - .Methods.FirstOrDefault(md => md.Name == "TryCreate" && md.Parameters.Count == 3); - var tryCreate = Context.Body.Method.Module.ImportReference(tryCreateInfo); - yield return Instruction.Create(OpCodes.Call, tryCreate); - yield return Instruction.Create(OpCodes.Pop); - yield return Instruction.Create(OpCodes.Ldloc, vardef); + yield return Create(Ldstr, valueString); + yield return Create(Ldc_I4, (int)UriKind.RelativeOrAbsolute); + yield return Create(Ldloca, vardef); + var tryCreate = module.ImportMethodReference(("System", "System", "Uri"), + methodName: "TryCreate", + paramCount: 3); + yield return Create(Call, tryCreate); + yield return Create(Pop); + yield return Create(Ldloc, vardef); } else - yield return Instruction.Create(OpCodes.Ldnull); + yield return Create(Ldnull); break; default: - var defaultctorinfo = typedef.Methods.FirstOrDefault(md => md.IsConstructor && !md.HasParameters); - if (defaultctorinfo != null) { - var defaultctor = Context.Body.Method.Module.ImportReference(defaultctorinfo); - yield return Instruction.Create(OpCodes.Newobj, defaultctor); - } else { + var defaultCtor = module.ImportCtorReference(typedef, paramCount: 0); + if (defaultCtor != null) + yield return Create(Newobj, defaultCtor); + else { //should never happen. but if it does, this prevents corrupting the IL stack - yield return Instruction.Create(OpCodes.Ldnull); + yield return Create(Ldnull); } break; } diff --git a/Xamarin.Forms.Build.Tasks/ModuleDefinitionExtensions.cs b/Xamarin.Forms.Build.Tasks/ModuleDefinitionExtensions.cs index 99bc6ed1623..65e5da0a3d4 100644 --- a/Xamarin.Forms.Build.Tasks/ModuleDefinitionExtensions.cs +++ b/Xamarin.Forms.Build.Tasks/ModuleDefinitionExtensions.cs @@ -1,32 +1,182 @@ using System; using System.Collections.Generic; - +using System.Linq; using Mono.Cecil; +using Mono.Cecil.Rocks; namespace Xamarin.Forms.Build.Tasks { static class ModuleDefinitionExtensions { - static readonly Dictionary, MethodReference> MbMr = - new Dictionary, MethodReference>(); + public static TypeReference ImportReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, (string assemblyName, string clrNamespace, string typeName)[] classArguments = null) + { + var typeRef = module.ImportReference(module.GetTypeDefinition(type)); + if (classArguments is null) + return typeRef; + return module.ImportReference(typeRef.MakeGenericInstanceType(classArguments.Select(gp => module.GetTypeDefinition((gp.assemblyName, gp.clrNamespace, gp.typeName))).ToArray())); + } + + public static TypeReference ImportArrayReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type) + { + var typeRef = module.ImportReference(type); + if (typeRef is null) + return null; + return module.ImportReference(typeRef.MakeArrayType()); + } + + public static MethodReference ImportCtorReference(this ModuleDefinition module, TypeReference type, int paramCount, TypeReference[] classArguments = null, Func predicate = null) + { + var ctor = module + .ImportReference(type) + .ResolveCached() + .Methods + .FirstOrDefault(md => + md.IsConstructor + && md.Parameters.Count == paramCount + && (predicate?.Invoke(md) ?? true)); + if (ctor is null) + return null; + var ctorRef = module.ImportReference(ctor); + if (classArguments == null) + return ctorRef; + return module.ImportReference(ctorRef.ResolveGenericParameters(type.MakeGenericInstanceType(classArguments), module)); + } + + public static MethodReference ImportCtorReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, int paramCount, (string assemblyName, string clrNamespace, string typeName)[] classArguments, Func predicate = null) + { + return module.ImportCtorReference(module.GetTypeDefinition(type), paramCount, classArguments?.Select(gp => module.GetTypeDefinition((gp.assemblyName, gp.clrNamespace, gp.typeName))).ToArray(), predicate); + } + + public static MethodReference ImportCtorReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, int paramCount, TypeReference[] classArguments, Func predicate = null) + { + return module.ImportCtorReference(module.GetTypeDefinition(type), paramCount, classArguments, predicate); + } + + public static MethodReference ImportCtorReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, int paramCount, Func predicate = null) + { + return module.ImportCtorReference(module.GetTypeDefinition(type), paramCount, null, predicate); + } + + public static MethodReference ImportPropertyGetterReference(this ModuleDefinition module, TypeReference type, string propertyName, Func predicate = null, bool flatten = false) + { + var properties = module.ImportReference(type).Resolve().Properties; + var getter = module + .ImportReference(type) + .ResolveCached() + .Properties(flatten) + .FirstOrDefault(pd => + pd.Name == propertyName + && (predicate?.Invoke(pd) ?? true)) + ?.GetMethod; + return getter == null ? null : module.ImportReference(getter); + } + + public static MethodReference ImportPropertyGetterReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, string propertyName, Func predicate = null, bool flatten = false) + { + return module.ImportPropertyGetterReference(module.GetTypeDefinition(type), propertyName, predicate, flatten); + } + + public static MethodReference ImportPropertySetterReference(this ModuleDefinition module, TypeReference type, string propertyName, Func predicate = null) + { + var setter = module + .ImportReference(type) + .ResolveCached() + .Properties + .FirstOrDefault(pd => + pd.Name == propertyName + && (predicate?.Invoke(pd) ?? true)) + ?.SetMethod; + return setter == null ? null : module.ImportReference(setter); + } + + public static MethodReference ImportPropertySetterReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, string propertyName, Func predicate = null) + { + return module.ImportPropertySetterReference(module.GetTypeDefinition(type), propertyName, predicate); + } + + public static FieldReference ImportFieldReference(this ModuleDefinition module, TypeReference type, string fieldName, Func predicate = null) + { + var field = module + .ImportReference(type) + .ResolveCached() + .Fields + .FirstOrDefault(fd => + fd.Name == fieldName + && (predicate?.Invoke(fd) ?? true)); + return field == null ? null : module.ImportReference(field); + } - static readonly Dictionary, TypeReference> TTr = - new Dictionary, TypeReference>(); + public static FieldReference ImportFieldReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, string fieldName, Func predicate = null) + { + return module.ImportFieldReference(module.GetTypeDefinition(type), fieldName: fieldName, predicate: predicate); + } + + public static MethodReference ImportMethodReference(this ModuleDefinition module, TypeReference type, string methodName, int paramCount, Func predicate = null, TypeReference[] classArguments = null) + { + var method = module + .ImportReference(type) + .ResolveCached() + .Methods + .FirstOrDefault(md => + !md.IsConstructor + && md.Name == methodName + && md.Parameters.Count == paramCount + && (predicate?.Invoke(md) ?? true)); + if (method is null) + return null; + var methodRef = module.ImportReference(method); + if (classArguments == null) + return methodRef; + return module.ImportReference(methodRef.ResolveGenericParameters(type.MakeGenericInstanceType(classArguments), module)); + } - public static MethodReference ImportReferenceCached(this ModuleDefinition module, System.Reflection.MethodBase method) + public static MethodReference ImportMethodReference(this ModuleDefinition module, + (string assemblyName, string clrNamespace, string typeName) type, + string methodName, int paramCount, Func predicate = null, + (string assemblyName, string clrNamespace, string typeName)[] classArguments = null) { - var key = new Tuple(module, method); - if (MbMr.TryGetValue(key, out var result)) - return result; - return MbMr[key] = module.ImportReference(method); + return module.ImportMethodReference(module.GetTypeDefinition(type), methodName, paramCount, predicate, + classArguments?.Select(gp => module.GetTypeDefinition((gp.assemblyName, gp.clrNamespace, gp.typeName))).ToArray()); + } + + static Dictionary<(ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName)), TypeDefinition> typeDefCache + = new Dictionary<(ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName)), TypeDefinition>(); + + public static TypeDefinition GetTypeDefinition(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type) + { + if (typeDefCache.TryGetValue((module, type), out TypeDefinition cachedTypeDefinition)) + return cachedTypeDefinition; + + var asm = module.Assembly.Name.Name == type.assemblyName + ? module.Assembly + : module.AssemblyResolver.Resolve(AssemblyNameReference.Parse(type.assemblyName)); + var typeDef = asm.MainModule.GetType($"{type.clrNamespace}.{type.typeName}"); + if (typeDef != null) { + typeDefCache.Add((module, type), typeDef); + return typeDef; + } + var exportedType = asm.MainModule.ExportedTypes.FirstOrDefault( + arg => arg.IsForwarder && arg.Namespace == type.clrNamespace && arg.Name == type.typeName); + if (exportedType != null) { + typeDef = exportedType.Resolve(); + typeDefCache.Add((module, type), typeDef); + return typeDef; + } + + //I hate you, netstandard + if (type.assemblyName == "mscorlib" && type.clrNamespace == "System.Reflection") + return module.GetTypeDefinition(("System.Reflection", type.clrNamespace, type.typeName)); + return null; } - public static TypeReference ImportReferenceCached(this ModuleDefinition module, Type type) + static IEnumerable Properties(this TypeDefinition typedef, bool flatten) { - var key = new Tuple(module, type); - if (TTr.TryGetValue(key, out var result)) - return result; - return TTr[key] = module.ImportReference(type); + foreach (var property in typedef.Properties) + yield return property; + if (!flatten || typedef.BaseType == null) + yield break; + foreach (var property in typedef.BaseType.ResolveCached().Properties(true)) + yield return property; } } } \ No newline at end of file diff --git a/Xamarin.Forms.Build.Tasks/NodeILExtensions.cs b/Xamarin.Forms.Build.Tasks/NodeILExtensions.cs index 4f8f4a0cb06..6d2c3e92b11 100644 --- a/Xamarin.Forms.Build.Tasks/NodeILExtensions.cs +++ b/Xamarin.Forms.Build.Tasks/NodeILExtensions.cs @@ -47,7 +47,7 @@ public static bool CanConvertValue(this ValueNode node, ILContext context, TypeR //If there's a [TypeConverter], use it if (typeConverter != null && str != null) { - var typeConvAttribute = typeConverter.GetCustomAttribute(module.ImportReferenceCached(typeof(TypeConversionAttribute))); + var typeConvAttribute = typeConverter.GetCustomAttribute(module, ("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "TypeConversionAttribute")); if (typeConvAttribute == null) //trust the unattributed TypeConverter return true; var toType = typeConvAttribute.ConstructorArguments.First().Value as TypeReference; @@ -98,7 +98,7 @@ public static IEnumerable PushConvertedValue(this ValueNode node, I var str = (string)node.Value; //If the TypeConverter has a ProvideCompiledAttribute that can be resolved, shortcut this - var compiledConverterName = typeConverter?.GetCustomAttribute (module.ImportReferenceCached(typeof(ProvideCompiledAttribute)))?.ConstructorArguments?.First().Value as string; + var compiledConverterName = typeConverter?.GetCustomAttribute(module, ("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "ProvideCompiledAttribute"))?.ConstructorArguments?.First().Value as string; Type compiledConverterType; if (compiledConverterName != null && (compiledConverterType = Type.GetType (compiledConverterName)) != null) { var compiledConverter = Activator.CreateInstance (compiledConverterType); @@ -115,11 +115,10 @@ public static IEnumerable PushConvertedValue(this ValueNode node, I //If there's a [TypeConverter], use it if (typeConverter != null) { - var isExtendedConverter = typeConverter.ImplementsInterface(module.ImportReferenceCached(typeof (IExtendedTypeConverter))); - var typeConverterCtor = typeConverter.ResolveCached().Methods.Single(md => md.IsConstructor && md.Parameters.Count == 0 && !md.IsStatic); - var typeConverterCtorRef = module.ImportReference(typeConverterCtor); + var isExtendedConverter = typeConverter.ImplementsInterface(module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms", "IExtendedTypeConverter"))); + var typeConverterCtorRef = module.ImportCtorReference(typeConverter, paramCount: 0, predicate: md => !md.IsStatic); var convertFromInvariantStringDefinition = isExtendedConverter - ? module.ImportReferenceCached(typeof (IExtendedTypeConverter)) + ? module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms", "IExtendedTypeConverter")) .ResolveCached() .Methods.FirstOrDefault(md => md.Name == "ConvertFromInvariantString" && md.Parameters.Count == 2) : typeConverter.ResolveCached() @@ -191,22 +190,14 @@ public static IEnumerable PushConvertedValue(this ValueNode node, I } else if (targetTypeRef.FullName == "System.TimeSpan") { var ts = TimeSpan.Parse(str, CultureInfo.InvariantCulture); var ticks = ts.Ticks; - var timeSpanCtor = - module.ImportReferenceCached(typeof(TimeSpan)) - .ResolveCached() - .Methods.FirstOrDefault(md => md.IsConstructor && md.Parameters.Count == 1); - var timeSpanCtorRef = module.ImportReference(timeSpanCtor); + var timeSpanCtorRef = module.ImportCtorReference(("mscorlib", "System", "TimeSpan"), paramCount: 1); yield return Instruction.Create(OpCodes.Ldc_I8, ticks); yield return Instruction.Create(OpCodes.Newobj, timeSpanCtorRef); } else if (targetTypeRef.FullName == "System.DateTime") { var dt = DateTime.Parse(str, CultureInfo.InvariantCulture); var ticks = dt.Ticks; - var dateTimeCtor = - module.ImportReferenceCached(typeof(DateTime)) - .ResolveCached() - .Methods.FirstOrDefault(md => md.IsConstructor && md.Parameters.Count == 1); - var dateTimeCtorRef = module.ImportReference(dateTimeCtor); + var dateTimeCtorRef = module.ImportCtorReference(("mscorlib", "System", "DateTime"), paramCount: 1); yield return Instruction.Create(OpCodes.Ldc_I8, ticks); yield return Instruction.Create(OpCodes.Newobj, dateTimeCtorRef); @@ -219,41 +210,32 @@ public static IEnumerable PushConvertedValue(this ValueNode node, I 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.ImportReferenceCached(typeof(decimal))); + var vardef = new VariableDefinition(module.ImportReference(("mscorlib", "System", "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 +// 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.ImportReferenceCached(typeof(CultureInfo)) - .ResolveCached() - .Properties.FirstOrDefault(pd => pd.Name == "InvariantCulture") - .GetMethod; - var getInvariant = context.Body.Method.Module.ImportReference(getInvariantInfo); + var getInvariant = module.ImportPropertyGetterReference(("mscorlib", "System.Globalization", "CultureInfo"), + propertyName: "InvariantCulture"); yield return Instruction.Create(OpCodes.Call, getInvariant); yield return Instruction.Create(OpCodes.Ldloca, vardef); - var tryParseInfo = - context.Body.Method.Module.ImportReferenceCached(typeof(decimal)) - .ResolveCached() - .Methods.FirstOrDefault(md => md.Name == "TryParse" && md.Parameters.Count == 4); - var tryParse = context.Body.Method.Module.ImportReference(tryParseInfo); + var tryParse = module.ImportMethodReference(("mscorlib", "System", "Decimal"), + methodName: "TryParse", + paramCount: 4); 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.ImportReferenceCached(typeof(decimal)) - .ResolveCached() - .Methods.FirstOrDefault( - md => md.IsConstructor && md.Parameters.Count == 1 && md.Parameters[0].ParameterType.FullName == "System.Int32"); - var decimalctor = context.Body.Method.Module.ImportReference(decimalctorinfo); + var decimalctor = module.ImportCtorReference(("mscorlib", "System", "Decimal"), + paramCount: 1, + predicate: md => md.Parameters[0].ParameterType.FullName == "System.Int32"); yield return Instruction.Create(OpCodes.Newobj, decimalctor); } } else if (implicitOperator != null) { @@ -357,18 +339,18 @@ public static IEnumerable PushXmlLineInfo(this INode node, ILContex var xmlLineInfo = node as IXmlLineInfo; if (xmlLineInfo == null) { - yield return Instruction.Create(OpCodes.Ldnull); + yield return Create(Ldnull); yield break; } MethodReference ctor; if (xmlLineInfo.HasLineInfo()) { - yield return Instruction.Create(OpCodes.Ldc_I4, xmlLineInfo.LineNumber); - yield return Instruction.Create(OpCodes.Ldc_I4, xmlLineInfo.LinePosition); - ctor = module.ImportReferenceCached(typeof(XmlLineInfo).GetConstructor(new[] { typeof(int), typeof(int) })); + yield return Create(Ldc_I4, xmlLineInfo.LineNumber); + yield return Create(Ldc_I4, xmlLineInfo.LinePosition); + ctor = module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "XmlLineInfo"), paramCount: 2); } else - ctor = module.ImportReferenceCached(typeof(XmlLineInfo).GetConstructor(new Type[] { })); - yield return Instruction.Create(OpCodes.Newobj, ctor); + ctor = module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "XmlLineInfo"), paramCount: 0); + yield return Create(Newobj, ctor); } public static IEnumerable PushParentObjectsArray(this INode node, ILContext context) @@ -417,7 +399,7 @@ public static IEnumerable PushParentObjectsArray(this INode node, I yield return Instruction.Create(OpCodes.Ldc_I4, nodes.Count); yield return Instruction.Create(OpCodes.Add); yield return Instruction.Create(OpCodes.Newarr, module.TypeSystem.Object); - var finalArray = new VariableDefinition(module.ImportReferenceCached(typeof (object[]))); + var finalArray = new VariableDefinition(module.ImportArrayReference(("mscorlib", "System", "Object"))); context.Body.Variables.Add(finalArray); yield return Instruction.Create(OpCodes.Stloc, finalArray); @@ -430,14 +412,11 @@ public static IEnumerable PushParentObjectsArray(this INode node, I yield return Instruction.Create(OpCodes.Ldloc, finalArray); //destinationArray yield return Instruction.Create(OpCodes.Ldc_I4, nodes.Count); //destinationIndex yield return Instruction.Create(OpCodes.Ldloc, parentObjectLength); //length - var arrayCopy = - module.ImportReferenceCached(typeof (Array)) - .ResolveCached() - .Methods.First( - md => - md.Name == "Copy" && md.Parameters.Count == 5 && - md.Parameters[1].ParameterType.FullName == module.TypeSystem.Int32.FullName); - yield return Instruction.Create(OpCodes.Call, module.ImportReference(arrayCopy)); + var arrayCopy = module.ImportMethodReference(("mscorlib", "System", "Array"), + methodName: "Copy", + paramCount: 5, + predicate: md => md.Parameters[1].ParameterType.FullName == "System.Int32"); + yield return Instruction.Create(OpCodes.Call, arrayCopy); } //Add nodes to array @@ -460,23 +439,17 @@ public static IEnumerable PushParentObjectsArray(this INode node, I static IEnumerable PushTargetProperty(FieldReference bpRef, PropertyReference propertyRef, TypeReference declaringTypeReference, ModuleDefinition module) { if (bpRef != null) { - yield return Instruction.Create(OpCodes.Ldsfld, bpRef); + yield return Create(Ldsfld, bpRef); yield break; } if (propertyRef != null) { -// IL_0000: ldtoken [mscorlib]System.String -// IL_0005: call class [mscorlib]System.Type class [mscorlib] System.Type::GetTypeFromHandle(valuetype [mscorlib] System.RuntimeTypeHandle) -// IL_000a: ldstr "Foo" -// IL_000f: callvirt instance class [mscorlib] System.Reflection.PropertyInfo class [mscorlib] System.Type::GetProperty(string) - var getTypeFromHandle = module.ImportReferenceCached(typeof(Type).GetMethod("GetTypeFromHandle", new [] { typeof(RuntimeTypeHandle) })); - var getPropertyInfo = module.ImportReferenceCached(typeof(Type).GetMethod("GetProperty", new [] { typeof(string) })); - yield return Instruction.Create(OpCodes.Ldtoken, module.ImportReference(declaringTypeReference ?? propertyRef.DeclaringType)); - yield return Instruction.Create(OpCodes.Call, module.ImportReference(getTypeFromHandle)); - yield return Instruction.Create(OpCodes.Ldstr, propertyRef.Name); - yield return Instruction.Create(OpCodes.Callvirt, module.ImportReference(getPropertyInfo)); + yield return Create(Ldtoken, module.ImportReference(declaringTypeReference ?? propertyRef.DeclaringType)); + yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", paramCount: 1, predicate: md => md.IsStatic)); + yield return Create(Ldstr, propertyRef.Name); + yield return Create(Call, module.ImportMethodReference(("System.Reflection.Extensions", "System.Reflection", "RuntimeReflectionExtensions"), methodName: "GetRuntimeProperty", paramCount: 2)); yield break; } - yield return Instruction.Create(OpCodes.Ldnull); + yield return Create(Ldnull); yield break; } @@ -489,26 +462,17 @@ public static IEnumerable PushServiceProvider(this INode node, ILCo yield break; #endif - var ctorinfo = typeof (XamlServiceProvider).GetConstructor(new Type[] { }); - var ctor = module.ImportReferenceCached(ctorinfo); - - var addServiceInfo = typeof (XamlServiceProvider).GetMethod("Add", new[] { typeof (Type), typeof (object) }); - var addService = module.ImportReferenceCached(addServiceInfo); + var addService = module.ImportMethodReference(("Xamarin.Forms.Xaml", "Xamarin.Forms.Xaml.Internals", "XamlServiceProvider"), methodName: "Add", paramCount: 2); + var getTypeFromHandle = module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", paramCount: 1, predicate: md => md.IsStatic); - var getTypeFromHandle = - module.ImportReferenceCached(typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) })); - var getTypeInfo = module.ImportReferenceCached(typeof(System.Reflection.IntrospectionExtensions).GetMethod("GetTypeInfo", new Type[] { typeof(Type)})); - var getAssembly = module.ImportReferenceCached(typeof(System.Reflection.TypeInfo).GetProperty("Assembly").GetMethod); - - yield return Instruction.Create(OpCodes.Newobj, ctor); + yield return Create(Newobj, module.ImportCtorReference(("Xamarin.Forms.Xaml", "Xamarin.Forms.Xaml.Internals", "XamlServiceProvider"), paramCount: 0)); //Add a SimpleValueTargetProvider var pushParentIl = node.PushParentObjectsArray(context).ToList(); - if (pushParentIl[pushParentIl.Count - 1].OpCode != OpCodes.Ldnull) - { - yield return Instruction.Create(OpCodes.Dup); //Keep the serviceProvider on the stack - yield return Instruction.Create(OpCodes.Ldtoken, module.ImportReferenceCached(typeof (IProvideValueTarget))); - yield return Instruction.Create(OpCodes.Call, module.ImportReference(getTypeFromHandle)); + if (pushParentIl[pushParentIl.Count - 1].OpCode != Ldnull) { + yield return Create(Dup); //Keep the serviceProvider on the stack + yield return Create(Ldtoken, module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "IProvideValueTarget"))); + yield return Create(Call, getTypeFromHandle); foreach (var instruction in pushParentIl) yield return instruction; @@ -516,68 +480,51 @@ public static IEnumerable PushServiceProvider(this INode node, ILCo foreach (var instruction in PushTargetProperty(bpRef, propertyRef, declaringTypeReference, module)) yield return instruction; - var targetProviderCtor = - module.ImportReferenceCached(typeof (SimpleValueTargetProvider).GetConstructor(new[] { typeof (object[]), typeof(object) })); - yield return Instruction.Create(OpCodes.Newobj, targetProviderCtor); - yield return Instruction.Create(OpCodes.Callvirt, addService); + yield return Create(Newobj, module.ImportCtorReference(("Xamarin.Forms.Xaml", "Xamarin.Forms.Xaml.Internals", "SimpleValueTargetProvider"), paramCount: 2)); + yield return Create(Callvirt, addService); } //Add a NamescopeProvider - if (context.Scopes.ContainsKey(node)) - { - yield return Instruction.Create(OpCodes.Dup); //Dupicate the serviceProvider - yield return Instruction.Create(OpCodes.Ldtoken, module.ImportReferenceCached(typeof (INameScopeProvider))); - yield return Instruction.Create(OpCodes.Call, module.ImportReference(getTypeFromHandle)); - var namescopeProviderCtor = module.ImportReferenceCached(typeof (NameScopeProvider).GetConstructor(new Type[] { })); - yield return Instruction.Create(OpCodes.Newobj, namescopeProviderCtor); - yield return Instruction.Create(OpCodes.Dup); //Duplicate the namescopeProvider - var setNamescope = module.ImportReferenceCached(typeof (NameScopeProvider).GetProperty("NameScope").GetSetMethod()); - - yield return Instruction.Create(OpCodes.Ldloc, context.Scopes[node].Item1); - yield return Instruction.Create(OpCodes.Callvirt, setNamescope); - yield return Instruction.Create(OpCodes.Callvirt, addService); + if (context.Scopes.ContainsKey(node)) { + yield return Create(Dup); //Dupicate the serviceProvider + yield return Create(Ldtoken, module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms.Xaml.Internals", "INameScopeProvider"))); + yield return Create(Call, getTypeFromHandle); + yield return Create(Newobj, module.ImportCtorReference(("Xamarin.Forms.Xaml", "Xamarin.Forms.Xaml.Internals", "NameScopeProvider"), paramCount: 0)); + yield return Create(Dup); //Duplicate the namescopeProvider + yield return Create(Ldloc, context.Scopes[node].Item1); + yield return Create(Callvirt, module.ImportPropertySetterReference(("Xamarin.Forms.Xaml", "Xamarin.Forms.Xaml.Internals", "NameScopeProvider"), propertyName: "NameScope")); + yield return Create(Callvirt, addService); } //Add a XamlTypeResolver - if (node.NamespaceResolver != null) - { + if (node.NamespaceResolver != null) { yield return Create(Dup); //Dupicate the serviceProvider - yield return Create(Ldtoken, module.ImportReferenceCached(typeof (IXamlTypeResolver))); - yield return Create(Call, module.ImportReference(getTypeFromHandle)); - var xmlNamespaceResolverCtor = module.ImportReferenceCached(typeof (XmlNamespaceResolver).GetConstructor(new Type[] { })); - var addNamespace = module.ImportReferenceCached(typeof (XmlNamespaceResolver).GetMethod("Add")); - yield return Create(Newobj, xmlNamespaceResolverCtor); - foreach (var kvp in node.NamespaceResolver.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml)) - { + yield return Create(Ldtoken, module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "IXamlTypeResolver"))); + yield return Create(Call, getTypeFromHandle); + yield return Create(Newobj, module.ImportCtorReference(("Xamarin.Forms.Xaml", "Xamarin.Forms.Xaml.Internals", "XmlNamespaceResolver"), paramCount: 0)); + foreach (var kvp in node.NamespaceResolver.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml)) { yield return Create(Dup); //dup the resolver yield return Create(Ldstr, kvp.Key); yield return Create(Ldstr, kvp.Value); - yield return Create(Callvirt, addNamespace); + yield return Create(Callvirt, module.ImportMethodReference(("Xamarin.Forms.Xaml", "Xamarin.Forms.Xaml.Internals", "XmlNamespaceResolver"), methodName: "Add", paramCount: 2)); } yield return Create(Ldtoken, context.Body.Method.DeclaringType); - yield return Create(Call, module.ImportReference(getTypeFromHandle)); - yield return Create(Call, module.ImportReference(getTypeInfo)); - yield return Create(Callvirt, getAssembly); - var xtr = module.ImportReferenceCached(typeof (XamlTypeResolver)).ResolveCached(); - var xamlTypeResolverCtor = module.ImportReference(xtr.Methods.First(md => md.IsConstructor && md.Parameters.Count == 2)); - yield return Create(Newobj, xamlTypeResolverCtor); + yield return Create(Call, getTypeFromHandle); + yield return Create(Call, module.ImportMethodReference(("mscorlib", "System.Reflection", "IntrospectionExtensions"), methodName: "GetTypeInfo", paramCount: 1, predicate: md => md.IsStatic)); + yield return Create(Callvirt, module.ImportPropertyGetterReference(("mscorlib", "System.Reflection", "TypeInfo"), propertyName: "Assembly", flatten: true)); + yield return Create(Newobj, module.ImportCtorReference(("Xamarin.Forms.Xaml", "Xamarin.Forms.Xaml.Internals", "XamlTypeResolver"), paramCount: 2)); yield return Create(Callvirt, addService); } - if (node is IXmlLineInfo) - { - yield return Instruction.Create(OpCodes.Dup); //Dupicate the serviceProvider - yield return Instruction.Create(OpCodes.Ldtoken, module.ImportReferenceCached(typeof (IXmlLineInfoProvider))); - yield return Instruction.Create(OpCodes.Call, module.ImportReference(getTypeFromHandle)); - + if (node is IXmlLineInfo) { + yield return Create(Dup); //Dupicate the serviceProvider + yield return Create(Ldtoken, module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "IXmlLineInfoProvider"))); + yield return Create(Call, getTypeFromHandle); foreach (var instruction in node.PushXmlLineInfo(context)) yield return instruction; - - var lip = module.ImportReferenceCached(typeof (XmlLineInfoProvider)).ResolveCached(); - var lineInfoProviderCtor = module.ImportReference(lip.Methods.First(md => md.IsConstructor && md.Parameters.Count == 1)); - yield return Instruction.Create(OpCodes.Newobj, lineInfoProviderCtor); - yield return Instruction.Create(OpCodes.Callvirt, addService); + yield return Create(Newobj, module.ImportCtorReference(("Xamarin.Forms.Xaml", "Xamarin.Forms.Xaml.Internals", "XmlLineInfoProvider"), paramCount: 1)); + yield return Create(Callvirt, addService); } } } -} +} \ No newline at end of file diff --git a/Xamarin.Forms.Build.Tasks/SetNamescopesAndRegisterNamesVisitor.cs b/Xamarin.Forms.Build.Tasks/SetNamescopesAndRegisterNamesVisitor.cs index 61af1288425..3d8efe29a27 100644 --- a/Xamarin.Forms.Build.Tasks/SetNamescopesAndRegisterNamesVisitor.cs +++ b/Xamarin.Forms.Build.Tasks/SetNamescopesAndRegisterNamesVisitor.cs @@ -48,7 +48,7 @@ public void Visit(ElementNode node, INode parentNode) namescopeVarDef = Context.Scopes[parentNode].Item1; namesInNamescope = Context.Scopes[parentNode].Item2; } - if (Context.Variables[node].VariableType.InheritsFromOrImplements(Context.Body.Method.Module.ImportReferenceCached(typeof (BindableObject)))) + if (Context.Variables[node].VariableType.InheritsFromOrImplements(Context.Body.Method.Module.ImportReference(("Xamarin.Forms.Core","Xamarin.Forms","BindableObject")))) SetNameScope(node, namescopeVarDef); Context.Scopes[node] = new System.Tuple>(namescopeVarDef, namesInNamescope); } @@ -57,7 +57,7 @@ public void Visit(RootNode node, INode parentNode) { var namescopeVarDef = CreateNamescope(); IList namesInNamescope = new List(); - if (Context.Variables[node].VariableType.InheritsFromOrImplements(Context.Body.Method.Module.ImportReferenceCached(typeof (BindableObject)))) + if (Context.Variables[node].VariableType.InheritsFromOrImplements(Context.Body.Method.Module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms", "BindableObject")))) SetNameScope(node, namescopeVarDef); Context.Scopes[node] = new System.Tuple>(namescopeVarDef, namesInNamescope); } @@ -100,13 +100,9 @@ static bool IsXNameProperty(ValueNode node, INode parentNode) VariableDefinition CreateNamescope() { var module = Context.Body.Method.Module; - var nsRef = module.ImportReferenceCached(typeof (NameScope)); - var vardef = new VariableDefinition(nsRef); + var vardef = new VariableDefinition(module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms.Internals", "NameScope"))); Context.Body.Variables.Add(vardef); - var nsDef = nsRef.ResolveCached(); - var ctorinfo = nsDef.Methods.First(md => md.IsConstructor && !md.HasParameters); - var ctor = module.ImportReference(ctorinfo); - Context.IL.Emit(OpCodes.Newobj, ctor); + Context.IL.Emit(OpCodes.Newobj, module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms.Internals", "NameScope"), paramCount: 0)); Context.IL.Emit(OpCodes.Stloc, vardef); return vardef; } @@ -114,13 +110,12 @@ VariableDefinition CreateNamescope() void SetNameScope(ElementNode node, VariableDefinition ns) { var module = Context.Body.Method.Module; - var nsRef = module.ImportReferenceCached(typeof (NameScope)); - var nsDef = nsRef.ResolveCached(); - var setNSInfo = nsDef.Methods.First(md => md.Name == "SetNameScope" && md.IsStatic); - var setNS = module.ImportReference(setNSInfo); Context.IL.Emit(OpCodes.Ldloc, Context.Variables[node]); Context.IL.Emit(OpCodes.Ldloc, ns); - Context.IL.Emit(OpCodes.Call, setNS); + Context.IL.Emit(OpCodes.Call, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms.Internals", "NameScope"), + methodName: "SetNameScope", + paramCount: 2, + predicate: md => md.IsStatic)); } void RegisterName(string str, VariableDefinition namescopeVarDef, IList namesInNamescope, VariableDefinition element, INode node) @@ -130,35 +125,28 @@ void RegisterName(string str, VariableDefinition namescopeVarDef, IList namesInNamescope.Add(str); var module = Context.Body.Method.Module; - var nsRef = module.ImportReferenceCached(typeof (INameScope)); - var nsDef = nsRef.ResolveCached(); - var registerInfo = nsDef.Methods.First(md => md.Name == nameof(INameScope.RegisterName) && md.Parameters.Count == 2); - var register = module.ImportReference(registerInfo); - Context.IL.Emit(OpCodes.Ldloc, namescopeVarDef); Context.IL.Emit(OpCodes.Ldstr, str); Context.IL.Emit(OpCodes.Ldloc, element); - Context.IL.Emit(OpCodes.Callvirt, register); + Context.IL.Emit(OpCodes.Callvirt, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms.Internals", "INameScope"), + methodName: "RegisterName", + paramCount: 2)); } void SetStyleId(string str, VariableDefinition element) { - if (!element.VariableType.InheritsFromOrImplements(Context.Body.Method.Module.ImportReferenceCached(typeof(Element)))) + if (!element.VariableType.InheritsFromOrImplements(Context.Body.Method.Module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Element")))) return; var module = Context.Body.Method.Module; - var eltDef = module.ImportReferenceCached(typeof(Element)).ResolveCached(); - var styleIdInfo = eltDef.Properties.First(pd => pd.Name == nameof(Element.StyleId)); - var getStyleId = module.ImportReference(styleIdInfo.GetMethod); - var setStyleId = module.ImportReference(styleIdInfo.SetMethod); var nop = Instruction.Create(OpCodes.Nop); Context.IL.Emit(OpCodes.Ldloc, element); - Context.IL.Emit(OpCodes.Callvirt, getStyleId); + Context.IL.Emit(OpCodes.Callvirt, module.ImportPropertyGetterReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Element"), propertyName: "StyleId")); Context.IL.Emit(OpCodes.Brtrue, nop); Context.IL.Emit(OpCodes.Ldloc, element); Context.IL.Emit(OpCodes.Ldstr, str); - Context.IL.Emit(OpCodes.Callvirt, setStyleId); + Context.IL.Emit(OpCodes.Callvirt, module.ImportPropertySetterReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Element"), propertyName: "StyleId")); Context.IL.Append(nop); } } diff --git a/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs b/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs index e328c8bd9a6..4412c30d00e 100644 --- a/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs +++ b/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs @@ -136,17 +136,18 @@ public void Visit(ElementNode node, INode parentNode) Context.IL.Append(AddToResourceDictionary(node, node, Context)); } // Collection element, implicit content, or implicit collection element. - else if (parentVar.VariableType.ImplementsInterface(Module.ImportReferenceCached(typeof (IEnumerable))) && parentVar.VariableType.GetMethods(md => md.Name == "Add" && md.Parameters.Count == 1, Module).Any()) { + else if ( parentVar.VariableType.ImplementsInterface(Module.ImportReference(("mscorlib", "System.Collections", "IEnumerable"))) + && parentVar.VariableType.GetMethods(md => md.Name == "Add" && md.Parameters.Count == 1, Module).Any()) { var elementType = parentVar.VariableType; var adderTuple = elementType.GetMethods(md => md.Name == "Add" && md.Parameters.Count == 1, Module).First(); var adderRef = Module.ImportReference(adderTuple.Item1); adderRef = Module.ImportReference(adderRef.ResolveGenericParameters(adderTuple.Item2, Module)); - Context.IL.Emit(OpCodes.Ldloc, parentVar); - Context.IL.Emit(OpCodes.Ldloc, vardef); - Context.IL.Emit(OpCodes.Callvirt, adderRef); + Context.IL.Emit(Ldloc, parentVar); + Context.IL.Emit(Ldloc, vardef); + Context.IL.Emit(Callvirt, adderRef); if (adderRef.ReturnType.FullName != "System.Void") - Context.IL.Emit(OpCodes.Pop); + Context.IL.Emit(Pop); } else if ((contentProperty = GetContentProperty(parentVar.VariableType)) != null) { var name = new XmlName(node.NamespaceURI, contentProperty); @@ -183,7 +184,9 @@ public void Visit(ElementNode node, INode parentNode) Context.IL.Append(AddToResourceDictionary(node, node, Context)); return; } - var adderTuple = propertyType.GetMethods(md => md.Name == "Add" && md.Parameters.Count == 1, Module).First(); + var adderTuple = propertyType.GetMethods(md => md.Name == "Add" && md.Parameters.Count == 1, Module).FirstOrDefault(); + if (adderTuple == null) + throw new XamlParseException($"Can not Add() elements to {parent.VariableType}.{localname}", node); var adderRef = Module.ImportReference(adderTuple.Item1); adderRef = Module.ImportReference(adderRef.ResolveGenericParameters(adderTuple.Item2, Module)); @@ -273,7 +276,7 @@ public static IEnumerable ProvideValue(VariableDefinitionReference else if (vardefref.VariableDefinition.VariableType.ImplementsGenericInterface("Xamarin.Forms.Xaml.IMarkupExtension`1", out markupExtension, out genericArguments)) { - var acceptEmptyServiceProvider = vardefref.VariableDefinition.VariableType.GetCustomAttribute(module.ImportReferenceCached(typeof(AcceptEmptyServiceProviderAttribute))) != null; + var acceptEmptyServiceProvider = vardefref.VariableDefinition.VariableType.GetCustomAttribute(module, ("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "AcceptEmptyServiceProviderAttribute")) != null; if (vardefref.VariableDefinition.VariableType.FullName == "Xamarin.Forms.Xaml.BindingExtension") foreach (var instruction in CompileBindingPath(node, context, vardefref.VariableDefinition)) yield return instruction; @@ -294,13 +297,9 @@ public static IEnumerable ProvideValue(VariableDefinitionReference yield return Instruction.Create(OpCodes.Callvirt, provideValue); yield return Instruction.Create(OpCodes.Stloc, vardefref.VariableDefinition); } - else if (context.Variables[node].VariableType.ImplementsInterface(module.ImportReferenceCached(typeof (IMarkupExtension)))) + else if (context.Variables[node].VariableType.ImplementsInterface(module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "IMarkupExtension")))) { - var acceptEmptyServiceProvider = context.Variables[node].VariableType.GetCustomAttribute(module.ImportReferenceCached(typeof(AcceptEmptyServiceProviderAttribute))) != null; - var markExt = module.ImportReferenceCached(typeof (IMarkupExtension)).ResolveCached(); - var provideValueInfo = markExt.Methods.First(md => md.Name == "ProvideValue"); - var provideValue = module.ImportReference(provideValueInfo); - + var acceptEmptyServiceProvider = context.Variables[node].VariableType.GetCustomAttribute(module, ("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "AcceptEmptyServiceProviderAttribute")) != null; vardefref.VariableDefinition = new VariableDefinition(module.TypeSystem.Object); yield return Instruction.Create(OpCodes.Ldloc, context.Variables[node]); if (acceptEmptyServiceProvider) @@ -308,15 +307,15 @@ public static IEnumerable ProvideValue(VariableDefinitionReference else foreach (var instruction in node.PushServiceProvider(context, bpRef, propertyRef, propertyDeclaringTypeRef)) yield return instruction; - yield return Instruction.Create(OpCodes.Callvirt, provideValue); + yield return Instruction.Create(OpCodes.Callvirt, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "IMarkupExtension"), methodName: "ProvideValue", paramCount: 1)); yield return Instruction.Create(OpCodes.Stloc, vardefref.VariableDefinition); } - else if (context.Variables[node].VariableType.ImplementsInterface(module.ImportReferenceCached(typeof (IValueProvider)))) + else if (context.Variables[node].VariableType.ImplementsInterface(module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "IValueProvider")))) { - var acceptEmptyServiceProvider = context.Variables[node].VariableType.GetCustomAttribute(module.ImportReferenceCached(typeof(AcceptEmptyServiceProviderAttribute))) != null; + var acceptEmptyServiceProvider = context.Variables[node].VariableType.GetCustomAttribute(module, ("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "AcceptEmptyServiceProviderAttribute")) != null; var valueProviderType = context.Variables[node].VariableType; //If the IValueProvider has a ProvideCompiledAttribute that can be resolved, shortcut this - var compiledValueProviderName = valueProviderType?.GetCustomAttribute(module.ImportReferenceCached(typeof(ProvideCompiledAttribute)))?.ConstructorArguments?[0].Value as string; + var compiledValueProviderName = valueProviderType?.GetCustomAttribute(module, ("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "ProvideCompiledAttribute"))?.ConstructorArguments?[0].Value as string; Type compiledValueProviderType; if (compiledValueProviderName != null && (compiledValueProviderType = Type.GetType(compiledValueProviderName)) != null) { var compiledValueProvider = Activator.CreateInstance(compiledValueProviderType); @@ -331,10 +330,6 @@ public static IEnumerable ProvideValue(VariableDefinitionReference yield break; } - var valueProviderDef = module.ImportReferenceCached(typeof (IValueProvider)).ResolveCached(); - var provideValueInfo = valueProviderDef.Methods.First(md => md.Name == "ProvideValue"); - var provideValue = module.ImportReference(provideValueInfo); - vardefref.VariableDefinition = new VariableDefinition(module.TypeSystem.Object); yield return Instruction.Create(OpCodes.Ldloc, context.Variables[node]); if (acceptEmptyServiceProvider) @@ -342,7 +337,9 @@ public static IEnumerable ProvideValue(VariableDefinitionReference else foreach (var instruction in node.PushServiceProvider(context, bpRef, propertyRef, propertyDeclaringTypeRef)) yield return instruction; - yield return Instruction.Create(OpCodes.Callvirt, provideValue); + yield return Instruction.Create(OpCodes.Callvirt, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "IValueProvider"), + methodName: "ProvideValue", + paramCount: 1)); yield return Instruction.Create(OpCodes.Stloc, vardefref.VariableDefinition); } } @@ -351,6 +348,7 @@ public static IEnumerable ProvideValue(VariableDefinitionReference static IEnumerable CompileBindingPath(ElementNode node, ILContext context, VariableDefinition bindingExt) { //TODO support casting operators + var module = context.Module; INode pathNode; if (!node.Properties.TryGetValue(new XmlName("", "Path"), out pathNode) && node.CollectionItems.Any()) @@ -375,23 +373,21 @@ static IEnumerable CompileBindingPath(ElementNode node, ILContext c var namespaceuri = dataType.Contains(":") ? node.NamespaceResolver.LookupNamespace(dataType.Split(':') [0].Trim()) : ""; var dtXType = new XmlType(namespaceuri, dataType, null); - var tSourceRef = dtXType.GetTypeReference(context.Module, (IXmlLineInfo)node); + var tSourceRef = dtXType.GetTypeReference(module, (IXmlLineInfo)node); if (tSourceRef == null) yield break; //throw - var properties = ParsePath(path, tSourceRef, node as IXmlLineInfo, context.Module); + var properties = ParsePath(path, tSourceRef, node as IXmlLineInfo, module); var tPropertyRef = properties != null && properties.Any() ? properties.Last().Item1.PropertyType : tSourceRef; - var funcRef = context.Module.ImportReference(context.Module.ImportReferenceCached(typeof(Func<,>)).MakeGenericInstanceType(new [] { tSourceRef, tPropertyRef })); - var actionRef = context.Module.ImportReference(context.Module.ImportReferenceCached(typeof(Action<,>)).MakeGenericInstanceType(new [] { tSourceRef, tPropertyRef })); - var funcObjRef = context.Module.ImportReference(context.Module.ImportReferenceCached(typeof(Func<,>)).MakeGenericInstanceType(new [] { tSourceRef, context.Module.TypeSystem.Object })); - var tupleRef = context.Module.ImportReference(context.Module.ImportReferenceCached(typeof(Tuple<,>)).MakeGenericInstanceType(new [] { funcObjRef, context.Module.TypeSystem.String})); - var typedBindingRef = context.Module.ImportReference(context.Module.ImportReferenceCached(typeof(TypedBinding<,>)).MakeGenericInstanceType(new [] { tSourceRef, tPropertyRef})); + var funcRef = module.ImportReference(module.ImportReference(("mscorlib", "System", "Func`2")).MakeGenericInstanceType(new [] { tSourceRef, tPropertyRef })); + var actionRef = module.ImportReference(module.ImportReference(("mscorlib", "System", "Action`2")).MakeGenericInstanceType(new [] { tSourceRef, tPropertyRef })); + var funcObjRef = module.ImportReference(module.ImportReference(("mscorlib", "System", "Func`2")).MakeGenericInstanceType(new [] { tSourceRef, module.TypeSystem.Object })); + var tupleRef = module.ImportReference(module.ImportReference(("mscorlib", "System", "Tuple`2")).MakeGenericInstanceType(new [] { funcObjRef, module.TypeSystem.String})); + var typedBindingRef = module.ImportReference(module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms.Internals", "TypedBinding`2")).MakeGenericInstanceType(new [] { tSourceRef, tPropertyRef})); - TypeReference _; - var ctorInfo = context.Module.ImportReference(typedBindingRef.ResolveCached().Methods.FirstOrDefault(md => md.IsConstructor && !md.IsStatic && md.Parameters.Count == 3 )); + var ctorInfo = module.ImportReference(typedBindingRef.ResolveCached().Methods.FirstOrDefault(md => md.IsConstructor && !md.IsStatic && md.Parameters.Count == 3 )); var ctorinforef = ctorInfo.MakeGeneric(typedBindingRef, funcRef, actionRef, tupleRef); - var setTypedBinding = context.Module.ImportReferenceCached(typeof(BindingExtension)).GetProperty(pd => pd.Name == "TypedBinding", out _).SetMethod; yield return Instruction.Create(OpCodes.Ldloc, bindingExt); foreach (var instruction in CompiledBindingGetGetter(tSourceRef, tPropertyRef, properties, node, context)) @@ -406,8 +402,8 @@ static IEnumerable CompileBindingPath(ElementNode node, ILContext c yield return instruction; } else yield return Create(Ldnull); - yield return Instruction.Create(OpCodes.Newobj, context.Module.ImportReference(ctorinforef)); - yield return Instruction.Create(OpCodes.Callvirt, context.Module.ImportReference(setTypedBinding)); + yield return Instruction.Create(OpCodes.Newobj, module.ImportReference(ctorinforef)); + yield return Instruction.Create(OpCodes.Callvirt, module.ImportPropertySetterReference(("Xamarin.Forms.Xaml", "Xamarin.Forms.Xaml", "BindingExtension"), propertyName: "TypedBinding")); } static IList> ParsePath(string path, TypeReference tSourceRef, IXmlLineInfo lineInfo, ModuleDefinition module) @@ -447,7 +443,7 @@ static IList> ParsePath(string path, TypeRefer previousPartTypeRef = property.PropertyType; } if (indexArg != null) { - var defaultMemberAttribute = previousPartTypeRef.GetCustomAttribute(module.ImportReferenceCached(typeof(System.Reflection.DefaultMemberAttribute))); + var defaultMemberAttribute = previousPartTypeRef.GetCustomAttribute(module, ("mscorlib", "System.Reflection", "DefaultMemberAttribute")); var indexerName = defaultMemberAttribute?.ConstructorArguments?.FirstOrDefault().Value as string ?? "Item"; var indexer = previousPartTypeRef.GetProperty(pd => pd.Name == indexerName && pd.GetMethod != null && pd.GetMethod.IsPublic, out _); properties.Add(new Tuple(indexer, indexArg)); @@ -472,7 +468,6 @@ static IEnumerable CompiledBindingGetGetter(TypeReference tSourceRe // } var module = context.Module; - var compilerGeneratedCtor = module.ImportReferenceCached(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute)).GetMethods(md => md.IsConstructor, module).First().Item1; var getter = new MethodDefinition($"<{context.Body.Method.Name}>typedBindingsM__{typedBindingCount++}", MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Static, tPropertyRef) { @@ -480,7 +475,7 @@ static IEnumerable CompiledBindingGetGetter(TypeReference tSourceRe new ParameterDefinition(tSourceRef) }, CustomAttributes = { - new CustomAttribute (context.Module.ImportReference(compilerGeneratedCtor)) + new CustomAttribute (module.ImportCtorReference(("mscorlib", "System.Runtime.CompilerServices", "CompilerGeneratedAttribute"), paramCount: 0)) } }; getter.Body.InitLocals = true; @@ -519,18 +514,13 @@ static IEnumerable CompiledBindingGetGetter(TypeReference tSourceRe } context.Body.Method.DeclaringType.Methods.Add(getter); - var funcRef = module.ImportReferenceCached(typeof(Func<,>)); - funcRef = module.ImportReference(funcRef.MakeGenericInstanceType(new [] { tSourceRef, tPropertyRef })); - var funcCtor = module.ImportReference(funcRef.ResolveCached().GetConstructors().First()); - funcCtor = funcCtor.MakeGeneric(funcRef, new [] { tSourceRef, tPropertyRef }); - // IL_0007: ldnull // IL_0008: ldftn string class Test::'
m__0'(class ViewModel) // IL_000e: newobj instance void class [mscorlib]System.Func`2::'.ctor'(object, native int) yield return Create(Ldnull); yield return Create(Ldftn, getter); - yield return Create(Newobj, module.ImportReference(funcCtor)); + yield return Create(Newobj, module.ImportCtorReference(("mscorlib", "System", "Func`2"), paramCount: 2, classArguments: new[] { tSourceRef, tPropertyRef })); } static IEnumerable CompiledBindingGetSetter(TypeReference tSourceRef, TypeReference tPropertyRef, IList> properties, ElementNode node, ILContext context) @@ -552,7 +542,6 @@ static IEnumerable CompiledBindingGetSetter(TypeReference tSourceRe // } var module = context.Module; - var compilerGeneratedCtor = module.ImportReferenceCached(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute)).GetMethods(md => md.IsConstructor, module).First().Item1; var setter = new MethodDefinition($"<{context.Body.Method.Name}>typedBindingsM__{typedBindingCount++}", MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Static, module.TypeSystem.Void) { @@ -561,7 +550,7 @@ static IEnumerable CompiledBindingGetSetter(TypeReference tSourceRe new ParameterDefinition(tPropertyRef) }, CustomAttributes = { - new CustomAttribute (module.ImportReference(compilerGeneratedCtor)) + new CustomAttribute (module.ImportCtorReference(("mscorlib", "System.Runtime.CompilerServices", "CompilerGeneratedAttribute"), paramCount: 0)) } }; setter.Body.InitLocals = true; @@ -622,17 +611,15 @@ static IEnumerable CompiledBindingGetSetter(TypeReference tSourceRe context.Body.Method.DeclaringType.Methods.Add(setter); - var actionRef = module.ImportReferenceCached(typeof(Action<,>)); - actionRef = module.ImportReference(actionRef.MakeGenericInstanceType(new [] { tSourceRef, tPropertyRef })); - var actionCtor = module.ImportReference(actionRef.ResolveCached().GetConstructors().First()); - actionCtor = actionCtor.MakeGeneric(actionRef, new [] { tSourceRef, tPropertyRef }); - // IL_0024: ldnull // IL_0025: ldftn void class Test::'
m__1'(class ViewModel, string) // IL_002b: newobj instance void class [mscorlib]System.Action`2::'.ctor'(object, native int) - yield return Instruction.Create(OpCodes.Ldnull); - yield return Instruction.Create(OpCodes.Ldftn, setter); - yield return Instruction.Create(OpCodes.Newobj, module.ImportReference(actionCtor)); + yield return Create(Ldnull); + yield return Create(Ldftn, setter); + yield return Create(Newobj, module.ImportCtorReference(("mscorlib", "System", "Action`2"), + paramCount: 2, + classArguments: + new[] { tSourceRef, tPropertyRef })); } static IEnumerable CompiledBindingGetHandlers(TypeReference tSourceRef, TypeReference tPropertyRef, IList> properties, ElementNode node, ILContext context) @@ -651,7 +638,6 @@ static IEnumerable CompiledBindingGetHandlers(TypeReference tSource // } var module = context.Module; - var compilerGeneratedCtor = module.ImportReferenceCached(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute)).GetMethods(md => md.IsConstructor, module).First().Item1; var partGetters = new List(); if (properties == null || properties.Count == 0) { @@ -666,7 +652,7 @@ static IEnumerable CompiledBindingGetHandlers(TypeReference tSource new ParameterDefinition(tSourceRef) }, CustomAttributes = { - new CustomAttribute (context.Module.ImportReference(compilerGeneratedCtor)) + new CustomAttribute (module.ImportCtorReference(("mscorlib", "System.Runtime.CompilerServices", "CompilerGeneratedAttribute"), paramCount: 0)) } }; partGetter.Body.InitLocals = true; @@ -716,8 +702,8 @@ static IEnumerable CompiledBindingGetHandlers(TypeReference tSource partGetters.Add(partGetter); } - var funcObjRef = context.Module.ImportReference(module.ImportReferenceCached(typeof(Func<,>)).MakeGenericInstanceType(new [] { tSourceRef, module.TypeSystem.Object })); - var tupleRef = context.Module.ImportReference(module.ImportReferenceCached(typeof(Tuple<,>)).MakeGenericInstanceType(new [] { funcObjRef, module.TypeSystem.String })); + var funcObjRef = context.Module.ImportReference(module.ImportReference(("mscorlib", "System", "Func`2")).MakeGenericInstanceType(new [] { tSourceRef, module.TypeSystem.Object })); + var tupleRef = context.Module.ImportReference(module.ImportReference(("mscorlib", "System", "Tuple`2")).MakeGenericInstanceType(new [] { funcObjRef, module.TypeSystem.String })); var funcCtor = module.ImportReference(funcObjRef.ResolveCached().GetConstructors().First()); funcCtor = funcCtor.MakeGeneric(funcObjRef, new [] { tSourceRef, module.TypeSystem.Object }); var tupleCtor = module.ImportReference(tupleRef.ResolveCached().GetConstructors().First()); @@ -903,15 +889,12 @@ static bool CanSetDynamicResource(FieldReference bpRef, INode valueNode, ILConte static IEnumerable SetDynamicResource(VariableDefinition parent, FieldReference bpRef, IElementNode elementNode, IXmlLineInfo iXmlLineInfo, ILContext context) { var module = context.Body.Method.Module; - var varValue = context.Variables [elementNode]; - var setDynamicResource = module.ImportReferenceCached(typeof(IDynamicResourceHandler)).ResolveCached().Methods.First(m => m.Name == "SetDynamicResource"); - var getKey = typeof(DynamicResource).GetProperty("Key").GetMethod; - yield return Instruction.Create(OpCodes.Ldloc, parent); - yield return Instruction.Create(OpCodes.Ldsfld, bpRef); - yield return Instruction.Create(OpCodes.Ldloc, varValue); - yield return Instruction.Create(OpCodes.Callvirt, module.ImportReferenceCached(getKey)); - yield return Instruction.Create(OpCodes.Callvirt, module.ImportReference(setDynamicResource)); + yield return Create(Ldloc, parent); + yield return Create(Ldsfld, bpRef); + yield return Create(Ldloc, context.Variables[elementNode]); + yield return Create(Callvirt, module.ImportPropertyGetterReference(("Xamarin.Forms.Core", "Xamarin.Forms.Internals", "DynamicResource"), propertyName: "Key")); + yield return Create(Callvirt, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms.Internals", "IDynamicResourceHandler"), methodName: "SetDynamicResource", paramCount: 2)); } static bool CanSetBinding(FieldReference bpRef, INode valueNode, ILContext context) @@ -927,29 +910,27 @@ static bool CanSetBinding(FieldReference bpRef, INode valueNode, ILContext conte VariableDefinition varValue; if (!context.Variables.TryGetValue(valueNode as IElementNode, out varValue)) return false; - var implicitOperator = varValue.VariableType.GetImplicitOperatorTo(module.ImportReferenceCached(typeof(BindingBase)), module); + var implicitOperator = varValue.VariableType.GetImplicitOperatorTo(module.ImportReference(("Xamarin.Forms.Core","Xamarin.Forms","BindingBase")), module); if (implicitOperator != null) return true; - return varValue.VariableType.InheritsFromOrImplements(module.ImportReferenceCached(typeof(BindingBase))); + return varValue.VariableType.InheritsFromOrImplements(module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms", "BindingBase"))); } static IEnumerable SetBinding(VariableDefinition parent, FieldReference bpRef, IElementNode elementNode, IXmlLineInfo iXmlLineInfo, ILContext context) { var module = context.Body.Method.Module; var varValue = context.Variables [elementNode]; - var implicitOperator = varValue.VariableType.GetImplicitOperatorTo(module.ImportReferenceCached(typeof(BindingBase)), module); + var implicitOperator = varValue.VariableType.GetImplicitOperatorTo(module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms", "BindingBase")), module); //TODO: check if parent is a BP - var setBinding = typeof(BindableObject).GetMethod("SetBinding", new [] { typeof(BindableProperty), typeof(BindingBase) }); - - yield return Instruction.Create(OpCodes.Ldloc, parent); - yield return Instruction.Create(OpCodes.Ldsfld, bpRef); - yield return Instruction.Create(OpCodes.Ldloc, varValue); + yield return Create(Ldloc, parent); + yield return Create(Ldsfld, bpRef); + yield return Create(Ldloc, varValue); if (implicitOperator != null) // IL_000f: call !0 class [Xamarin.Forms.Core]Xamarin.Forms.OnPlatform`1::op_Implicit(class [Xamarin.Forms.Core]Xamarin.Forms.OnPlatform`1) - yield return Instruction.Create(OpCodes.Call, module.ImportReference(implicitOperator)); - yield return Instruction.Create(OpCodes.Callvirt, module.ImportReferenceCached(setBinding)); + yield return Create(Call, module.ImportReference(implicitOperator)); + yield return Create(Callvirt, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms", "BindableObject"), methodName: "SetBinding", paramCount: 2)); } static bool CanSetValue(FieldReference bpRef, bool attached, INode node, IXmlLineInfo iXmlLineInfo, ILContext context) @@ -995,7 +976,7 @@ static bool CanGetValue(VariableDefinition parent, FieldReference bpRef, bool at if (bpRef == null) return false; - if (!parent.VariableType.InheritsFromOrImplements(module.ImportReferenceCached(typeof(BindableObject)))) + if (!parent.VariableType.InheritsFromOrImplements(module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms", "BindableObject")))) return false; propertyType = bpRef.GetBindablePropertyType(iXmlLineInfo, module); @@ -1004,7 +985,6 @@ static bool CanGetValue(VariableDefinition parent, FieldReference bpRef, bool at static IEnumerable SetValue(VariableDefinition parent, FieldReference bpRef, INode node, IXmlLineInfo iXmlLineInfo, ILContext context) { - var setValue = typeof(BindableObject).GetMethod("SetValue", new [] { typeof(BindableProperty), typeof(object) }); var valueNode = node as ValueNode; var elementNode = node as IElementNode; var module = context.Body.Method.Module; @@ -1014,8 +994,8 @@ static IEnumerable SetValue(VariableDefinition parent, FieldReferen // IL_000d: ldstr "foo" // IL_0012: callvirt instance void class [Xamarin.Forms.Core]Xamarin.Forms.BindableObject::SetValue(class [Xamarin.Forms.Core]Xamarin.Forms.BindableProperty, object) - yield return Instruction.Create(OpCodes.Ldloc, parent); - yield return Instruction.Create(OpCodes.Ldsfld, bpRef); + yield return Create(Ldloc, parent); + yield return Create(Ldsfld, bpRef); if (valueNode != null) { foreach (var instruction in valueNode.PushConvertedValue(context, bpRef, valueNode.PushServiceProvider(context, bpRef:bpRef), true, false)) @@ -1025,28 +1005,26 @@ static IEnumerable SetValue(VariableDefinition parent, FieldReferen var varDef = context.Variables[elementNode]; var varType = varDef.VariableType; var implicitOperator = varDef.VariableType.GetImplicitOperatorTo(bpTypeRef, module); - yield return Instruction.Create(OpCodes.Ldloc, varDef); + yield return Create(Ldloc, varDef); if (implicitOperator != null) { - yield return Instruction.Create(OpCodes.Call, module.ImportReference(implicitOperator)); + yield return Create(Call, module.ImportReference(implicitOperator)); varType = module.ImportReference(bpTypeRef); } if (varType.IsValueType) - yield return Instruction.Create(OpCodes.Box, varType); + yield return Create(Box, varType); } - - yield return Instruction.Create(OpCodes.Callvirt, module.ImportReferenceCached(setValue)); + yield return Create(Callvirt, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms", "BindableObject"), methodName: "SetValue", paramCount: 2)); } static IEnumerable GetValue(VariableDefinition parent, FieldReference bpRef, IXmlLineInfo iXmlLineInfo, ILContext context, out TypeReference propertyType) { - var getValue = typeof(BindableObject).GetMethod("GetValue", new[] { typeof(BindableProperty) }); var module = context.Body.Method.Module; propertyType = bpRef.GetBindablePropertyType(iXmlLineInfo, module); return new[] { - Instruction.Create(OpCodes.Ldloc, parent), - Instruction.Create(OpCodes.Ldsfld, bpRef), - Instruction.Create(OpCodes.Callvirt, module.ImportReferenceCached(getValue)), + Create(Ldloc, parent), + Create(Ldsfld, bpRef), + Create(Callvirt, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms", "BindableObject"), methodName: "GetValue", paramCount: 1)), }; } @@ -1213,10 +1191,10 @@ static bool CanAddToResourceDictionary(TypeReference collectionType, IElementNod //is there a RD.Add() overrides that accepts this ? var nodeTypeRef = context.Variables[node].VariableType; var module = context.Body.Method.Module; - if (module.ImportReferenceCached(typeof(ResourceDictionary)).ResolveCached().Methods.Any(md => - md.Name == "Add" - && md.Parameters.Count == 1 - && TypeRefComparer.Default.Equals(md.Parameters[0].ParameterType, nodeTypeRef))) + if (module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms", "ResourceDictionary"), + methodName: "Add", + paramCount: 1, + predicate: md => TypeRefComparer.Default.Equals(md.Parameters[0].ParameterType, nodeTypeRef)) != null) return true; throw new XamlParseException("resources in ResourceDictionary require a x:Key attribute", lineInfo); @@ -1267,23 +1245,16 @@ static IEnumerable AddToResourceDictionary(IElementNode node, IXmlL yield return Create(Ldloc, varDef); if (varDef.VariableType.IsValueType) yield return Create(Box, module.ImportReference(varDef.VariableType)); - yield return Create(Callvirt, - module.ImportReference( - module.ImportReferenceCached(typeof(ResourceDictionary)) - .ResolveCached() - .Methods.Single(md => md.Name == "Add" && md.Parameters.Count == 2))); + yield return Create(Callvirt, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms", "ResourceDictionary"), + methodName: "Add", paramCount: 2)); yield break; } var nodeTypeRef = context.Variables[node].VariableType; yield return Create(Ldloc, context.Variables[node]); - yield return Create(Callvirt, - module.ImportReference( - module.ImportReferenceCached(typeof(ResourceDictionary)) - .ResolveCached() - .Methods.Single(md => md.Name == "Add" - && md.Parameters.Count == 1 - && TypeRefComparer.Default.Equals(md.Parameters[0].ParameterType, nodeTypeRef)))); + yield return Create(Callvirt, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms", "ResourceDictionary"), + methodName: "Add", paramCount: 1, + predicate: md => TypeRefComparer.Default.Equals(md.Parameters[0].ParameterType, nodeTypeRef))); yield break; } @@ -1322,17 +1293,15 @@ static void SetDataTemplate(IElementNode parentNode, ElementNode node, ILContext var module = parentContext.Module; - var compilerGeneratedCtor = module.ImportReferenceCached(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute)).GetMethods(md => md.IsConstructor, module).First().Item1; var anonType = new TypeDefinition( null, "<" + parentContext.Body.Method.Name + ">_anonXamlCDataTemplate_" + dtcount++, TypeAttributes.BeforeFieldInit | TypeAttributes.Sealed | - TypeAttributes.NestedPrivate) - { + TypeAttributes.NestedPrivate) { BaseType = module.TypeSystem.Object, CustomAttributes = { - new CustomAttribute (module.ImportReference(compilerGeneratedCtor)) + new CustomAttribute (module.ImportCtorReference(("mscorlib", "System.Runtime.CompilerServices", "CompilerGeneratedAttribute"), paramCount: 0)), } }; @@ -1345,7 +1314,7 @@ static void SetDataTemplate(IElementNode parentNode, ElementNode node, ILContext loadTemplate.Body.InitLocals = true; anonType.Methods.Add(loadTemplate); - var parentValues = new FieldDefinition("parentValues", FieldAttributes.Assembly, module.ImportReferenceCached(typeof (object[]))); + var parentValues = new FieldDefinition("parentValues", FieldAttributes.Assembly, module.ImportArrayReference(("mscorlib", "System", "Object"))); anonType.Fields.Add(parentValues); TypeReference rootType = null; @@ -1396,20 +1365,12 @@ static void SetDataTemplate(IElementNode parentNode, ElementNode node, ILContext parentIl.Emit(OpCodes.Stfld, root); //SetDataTemplate - parentIl.Emit(OpCodes.Ldftn, loadTemplate); - var funcObjRef = module.ImportReferenceCached(typeof(Func)); - var funcCtor = - funcObjRef - .ResolveCached() - .Methods.First(md => md.IsConstructor && md.Parameters.Count == 2) - .ResolveGenericParameters(funcObjRef, module); - parentIl.Emit(OpCodes.Newobj, module.ImportReference(funcCtor)); - -#pragma warning disable 0612 - var propertySetter = - module.ImportReferenceCached(typeof (IDataTemplate)).ResolveCached().Properties.First(p => p.Name == "LoadTemplate").SetMethod; -#pragma warning restore 0612 - parentContext.IL.Emit(OpCodes.Callvirt, module.ImportReference(propertySetter)); + parentIl.Emit(Ldftn, loadTemplate); + parentIl.Emit(Newobj, module.ImportCtorReference(("mscorlib", "System", "Func`1"), + paramCount: 2, + classArguments: new[] { ("mscorlib", "System", "Object") })); + + parentContext.IL.Emit(OpCodes.Callvirt, module.ImportPropertySetterReference(("Xamarin.Forms.Core", "Xamarin.Forms.Internals", "IDataTemplate"), propertyName: "LoadTemplate")); loadTemplate.Body.Optimize(); } diff --git a/Xamarin.Forms.Build.Tasks/TypeDefinitionExtensions.cs b/Xamarin.Forms.Build.Tasks/TypeDefinitionExtensions.cs index 1723c2c0ac8..6de4c5c419e 100644 --- a/Xamarin.Forms.Build.Tasks/TypeDefinitionExtensions.cs +++ b/Xamarin.Forms.Build.Tasks/TypeDefinitionExtensions.cs @@ -12,30 +12,23 @@ static class TypeDefinitionExtensions { public static MethodDefinition AddDefaultConstructor(this TypeDefinition targetType) { - var parentType = typeof (object); + var module = targetType.Module; + var parentType = module.ImportReference(("mscorlib", "System", "Object")); return AddDefaultConstructor(targetType, parentType); } - public static MethodDefinition AddDefaultConstructor(this TypeDefinition targetType, Type parentType) + public static MethodDefinition AddDefaultConstructor(this TypeDefinition targetType, TypeReference parentType) { var module = targetType.Module; - var voidType = module.ImportReferenceCached(typeof (void)); + var voidType = module.ImportReference(("mscorlib", "System", "Void")); var methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; - var flags = BindingFlags.Public | - BindingFlags.NonPublic | - BindingFlags.Instance; - - var objectConstructor = parentType.GetConstructor(flags, null, new Type[0], null); - - if (objectConstructor == null) - objectConstructor = typeof (object).GetConstructor(new Type[0]); - - var baseConstructor = module.ImportReferenceCached(objectConstructor); + var parentctor = module.ImportCtorReference(parentType, paramCount: 0, predicate: md => (!md.IsPrivate && !md.IsStatic)) + ?? module.ImportCtorReference(("mscorlib", "System", "Object"), paramCount: 0); var ctor = new MethodDefinition(".ctor", methodAttributes, voidType) { @@ -47,7 +40,7 @@ public static MethodDefinition AddDefaultConstructor(this TypeDefinition targetT var IL = ctor.Body.GetILProcessor(); IL.Emit(OpCodes.Ldarg_0); - IL.Emit(OpCodes.Call, baseConstructor); + IL.Emit(OpCodes.Call, parentctor); IL.Emit(OpCodes.Ret); targetType.Methods.Add(ctor); diff --git a/Xamarin.Forms.Build.Tasks/TypeReferenceExtensions.cs b/Xamarin.Forms.Build.Tasks/TypeReferenceExtensions.cs index ba569fbe6e4..3666dda228c 100644 --- a/Xamarin.Forms.Build.Tasks/TypeReferenceExtensions.cs +++ b/Xamarin.Forms.Build.Tasks/TypeReferenceExtensions.cs @@ -200,7 +200,7 @@ public static bool InheritsFromOrImplements(this TypeReference typeRef, TypeRefe return typeRef.InheritsFromOrImplements(baseClass); } - public static CustomAttribute GetCustomAttribute(this TypeReference typeRef, TypeReference attribute) + static CustomAttribute GetCustomAttribute(this TypeReference typeRef, TypeReference attribute) { var typeDef = typeRef.ResolveCached(); //FIXME: avoid string comparison. make sure the attribute TypeRef is the same one @@ -213,6 +213,11 @@ public static CustomAttribute GetCustomAttribute(this TypeReference typeRef, Typ return null; } + public static CustomAttribute GetCustomAttribute(this TypeReference typeRef, ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) attributeType) + { + return typeRef.GetCustomAttribute(module.ImportReference(module.GetTypeDefinition(attributeType))); + } + [Obsolete] public static MethodDefinition GetMethod(this TypeReference typeRef, Func predicate) { diff --git a/Xamarin.Forms.Build.Tasks/XamlCAssemblyResolver.cs b/Xamarin.Forms.Build.Tasks/XamlCAssemblyResolver.cs index 04f72c12e72..15ad5385abc 100644 --- a/Xamarin.Forms.Build.Tasks/XamlCAssemblyResolver.cs +++ b/Xamarin.Forms.Build.Tasks/XamlCAssemblyResolver.cs @@ -1,3 +1,4 @@ +using System; using Mono.Cecil; namespace Xamarin.Forms.Build.Tasks @@ -11,5 +12,36 @@ public void AddAssembly(string p) AssemblyResolver = this })); } + + public override AssemblyDefinition Resolve(AssemblyNameReference name) + { + if (TryResolve(name, out AssemblyDefinition assembly)) + return assembly; + if ( IsMscorlib(name) + && ( TryResolve(AssemblyNameReference.Parse("mscorlib"), out assembly) + || TryResolve(AssemblyNameReference.Parse("netstandard"), out assembly) + || TryResolve(AssemblyNameReference.Parse("System.Runtime"), out assembly))) + return assembly; + throw new AssemblyResolutionException(name); + } + + bool TryResolve(AssemblyNameReference assemblyNameReference, out AssemblyDefinition assembly) + { + try { + assembly = base.Resolve(assemblyNameReference); + return true; + } + catch (AssemblyResolutionException) { + assembly = null; + return false; + } + } + + static bool IsMscorlib(AssemblyNameReference name) + { + return name.Name == "mscorlib" + || name.Name == "System.Runtime" + || name.Name == "netstandard"; + } } } \ No newline at end of file diff --git a/Xamarin.Forms.Build.Tasks/XamlCTask.cs b/Xamarin.Forms.Build.Tasks/XamlCTask.cs index 258730ddde2..0f0a6c5de27 100644 --- a/Xamarin.Forms.Build.Tasks/XamlCTask.cs +++ b/Xamarin.Forms.Build.Tasks/XamlCTask.cs @@ -272,30 +272,22 @@ bool TryCoreCompile(MethodDefinition initComp, MethodDefinition initCompRuntime, //First using the ResourceLoader var nop = Instruction.Create(Nop); - var getResourceProvider = module.ImportReference(module.ImportReferenceCached(typeof(Internals.ResourceLoader)) - .ResolveCached() - .Properties.FirstOrDefault(pd => pd.Name == "ResourceProvider") - .GetMethod); + var getResourceProvider = module.ImportPropertyGetterReference(("Xamarin.Forms.Core", "Xamarin.Forms.Internals", "ResourceLoader"), "ResourceProvider"); il.Emit(Call, getResourceProvider); il.Emit(Brfalse, nop); il.Emit(Call, getResourceProvider); - var getTypeFromHandle = module.ImportReferenceCached(typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) })); - var getTypeInfo = module.ImportReferenceCached(typeof(System.Reflection.IntrospectionExtensions).GetMethod("GetTypeInfo", new Type[] { typeof(Type) })); - var getAssembly = module.ImportReferenceCached(typeof(Type).GetProperty("Assembly").GetMethod); - var getAssemblyName = module.ImportReferenceCached(typeof(System.Reflection.Assembly).GetMethod("GetName", new Type[] { })); il.Emit(Ldtoken, module.ImportReference(initComp.DeclaringType)); - il.Emit(Call, module.ImportReference(getTypeFromHandle)); - il.Emit(Call, module.ImportReference(getTypeInfo)); - il.Emit(Callvirt, module.ImportReference(getAssembly)); - il.Emit(Callvirt, module.ImportReference(getAssemblyName)); //assemblyName - - il.Emit(Ldstr, resourcePath); //resourcePath - var func = module.ImportReference(module.ImportReferenceCached(typeof(Func)) - .ResolveCached() - .Methods.FirstOrDefault(md => md.Name == "Invoke")); - func = func.ResolveGenericParameters(module.ImportReferenceCached(typeof(Func)), module); - il.Emit(Callvirt, func); + il.Emit(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", paramCount: 1, predicate: md => md.IsStatic)); + il.Emit(Call, module.ImportMethodReference(("mscorlib", "System.Reflection", "IntrospectionExtensions"), methodName: "GetTypeInfo", paramCount: 1, predicate: md => md.IsStatic)); + il.Emit(Callvirt, module.ImportPropertyGetterReference(("mscorlib", "System.Reflection", "TypeInfo"), propertyName: "Assembly", flatten: true)); + il.Emit(Callvirt, module.ImportMethodReference(("mscorlib", "System.Reflection", "Assembly"), methodName: "GetName", paramCount: 0)); //assemblyName + + il.Emit(Ldstr, resourcePath); //resourcePath + il.Emit(Callvirt, module.ImportMethodReference(("mscorlib", "System", "Func`3"), + methodName: "Invoke", + paramCount: 2, + classArguments: new[] { ("mscorlib", "System.Reflection", "AssemblyName"), ("mscorlib", "System", "String"), ("mscorlib", "System", "String") })); il.Emit(Brfalse, nop); il.Emit(Ldarg_0); il.Emit(Call, initCompRuntime); @@ -304,26 +296,17 @@ bool TryCoreCompile(MethodDefinition initComp, MethodDefinition initCompRuntime, //Or using the deprecated XamlLoader nop = Instruction.Create(Nop); -#pragma warning disable 0618 - var getXamlFileProvider = module.ImportReference(module.ImportReferenceCached(typeof(Xaml.Internals.XamlLoader)) - .ResolveCached() - .Properties.FirstOrDefault(pd => pd.Name == "XamlFileProvider") - .GetMethod); -#pragma warning restore 0618 + var getXamlFileProvider = module.ImportPropertyGetterReference(("Xamarin.Forms.Xaml", "Xamarin.Forms.Xaml.Internals", "XamlLoader"), propertyName: "XamlFileProvider"); il.Emit(Call, getXamlFileProvider); il.Emit(Brfalse, nop); il.Emit(Call, getXamlFileProvider); il.Emit(Ldarg_0); - var getType = module.ImportReference(module.ImportReferenceCached(typeof(object)) - .ResolveCached() - .Methods.FirstOrDefault(md => md.Name == "GetType")); - il.Emit(Call, getType); - func = module.ImportReference(module.ImportReferenceCached(typeof(Func)) - .ResolveCached() - .Methods.FirstOrDefault(md => md.Name == "Invoke")); - func = func.ResolveGenericParameters(module.ImportReferenceCached(typeof(Func)), module); - il.Emit(Callvirt, func); + il.Emit(Call, module.ImportMethodReference(("mscorlib", "System", "Object"), methodName: "GetType", paramCount: 0)); + il.Emit(Callvirt, module.ImportMethodReference(("mscorlib", "System", "Func`2"), + methodName: "Invoke", + paramCount: 1, + classArguments: new[] { ("mscorlib", "System", "Type"), ("mscorlib", "System", "String")})); il.Emit(Brfalse, nop); il.Emit(Ldarg_0); il.Emit(Call, initCompRuntime); @@ -356,7 +339,7 @@ internal static string GetPathForType(ModuleDefinition module, TypeReference typ { foreach (var ca in type.Module.GetCustomAttributes()) { - if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReferenceCached(typeof(XamlResourceIdAttribute)))) + if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "XamlResourceIdAttribute")))) continue; if (!TypeRefComparer.Default.Equals(ca.ConstructorArguments[2].Value as TypeReference, type)) continue; @@ -369,7 +352,7 @@ internal static string GetResourceIdForPath(ModuleDefinition module, string path { foreach (var ca in module.GetCustomAttributes()) { - if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReferenceCached(typeof(XamlResourceIdAttribute)))) + if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "XamlResourceIdAttribute")))) continue; if (ca.ConstructorArguments[1].Value as string != path) continue; diff --git a/Xamarin.Forms.Build.Tasks/XamlTask.cs b/Xamarin.Forms.Build.Tasks/XamlTask.cs index 6e54b133085..4f32d6d3c5b 100644 --- a/Xamarin.Forms.Build.Tasks/XamlTask.cs +++ b/Xamarin.Forms.Build.Tasks/XamlTask.cs @@ -111,7 +111,7 @@ public static bool IsXaml(this EmbeddedResource resource, ModuleDefinition modul static TypeReference GetTypeForResourceId(ModuleDefinition module, string resourceId) { foreach (var ca in module.GetCustomAttributes()) { - if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReferenceCached(typeof(XamlResourceIdAttribute)))) + if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "XamlResourceIdAttribute")))) continue; if (ca.ConstructorArguments[0].Value as string != resourceId) continue; diff --git a/Xamarin.Forms.Build.Tasks/XmlTypeExtensions.cs b/Xamarin.Forms.Build.Tasks/XmlTypeExtensions.cs index 9ff32eb76ac..e21626cf242 100644 --- a/Xamarin.Forms.Build.Tasks/XmlTypeExtensions.cs +++ b/Xamarin.Forms.Build.Tasks/XmlTypeExtensions.cs @@ -114,19 +114,7 @@ public static TypeReference GetTypeReference(this XmlType xmlType, ModuleDefinit clrNamespace += '.' + typeName.Substring(0, typeName.LastIndexOf('.')); typeName = typeName.Substring(typeName.LastIndexOf('.') + 1); } - var assemblydefinition = module.Assembly.Name.Name == asm.AssemblyName ? - module.Assembly : - module.AssemblyResolver.Resolve(AssemblyNameReference.Parse(asm.AssemblyName)); - - type = assemblydefinition.MainModule.GetType(clrNamespace + "." + typeName); - if (type == null) - { - var exportedtype = - assemblydefinition.MainModule.ExportedTypes.FirstOrDefault( - (ExportedType arg) => arg.IsForwarder && arg.Namespace == clrNamespace && arg.Name == typeName); - if (exportedtype != null) - type = exportedtype.Resolve(); - } + type = module.GetTypeDefinition((asm.AssemblyName, clrNamespace, typeName)); } } diff --git a/Xamarin.Forms.ControlGallery.Android/CustomRenderers.cs b/Xamarin.Forms.ControlGallery.Android/CustomRenderers.cs index 28083bb7208..623f27a9a30 100644 --- a/Xamarin.Forms.ControlGallery.Android/CustomRenderers.cs +++ b/Xamarin.Forms.ControlGallery.Android/CustomRenderers.cs @@ -30,6 +30,8 @@ [assembly: ExportRenderer(typeof(Bugzilla42000._42000NumericEntryNoDecimal), typeof(EntryRendererNoDecimal))] [assembly: ExportRenderer(typeof(Bugzilla42000._42000NumericEntryNoNegative), typeof(EntryRendererNoNegative))] +[assembly: ExportRenderer(typeof(Issue1683.EntryKeyboardFlags), typeof(EntryRendererKeyboardFlags))] +[assembly: ExportRenderer(typeof(Issue1683.EditorKeyboardFlags), typeof(EditorRendererKeyboardFlags))] //[assembly: ExportRenderer(typeof(AndroidHelpText.HintLabel), typeof(HintLabel))] [assembly: ExportRenderer(typeof(QuickCollectNavigationPage), typeof(QuickCollectNavigationPageRenderer))] @@ -122,7 +124,7 @@ public void pChange() public class NativeListViewRenderer : ViewRenderer { -#pragma warning disable 618 +#pragma warning disable 618 public NativeListViewRenderer() #pragma warning restore 618 { @@ -514,10 +516,12 @@ public CustomNativeButton(Context context, IAttributeSet attrs, int defStyleAttr } } -#pragma warning disable 618 public class CustomButtonRenderer : ButtonRenderer -#pragma warning restore 618 { + public CustomButtonRenderer(Context context) : base(context) + { + } + protected override AButton CreateNativeControl() { return new CustomNativeButton(Context); @@ -536,11 +540,12 @@ protected override void OnElementChanged(ElementChangedEventArgs