diff options
author | Stephane Delcroix <stephane@delcroix.org> | 2016-12-07 10:57:43 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-07 10:57:43 +0100 |
commit | 8181e6d4cbe8aac6eb29c5140262d8bc51dba7b7 (patch) | |
tree | 5e97231ce476ec38961cb5de9f2ca5ea24569625 /Xamarin.Forms.Build.Tasks | |
parent | 1dd4ce922e7d28038605a4476dce207f1440122f (diff) | |
download | xamarin-forms-8181e6d4cbe8aac6eb29c5140262d8bc51dba7b7.tar.gz xamarin-forms-8181e6d4cbe8aac6eb29c5140262d8bc51dba7b7.tar.bz2 xamarin-forms-8181e6d4cbe8aac6eb29c5140262d8bc51dba7b7.zip |
[XamlC] Type ref tests, and fixes (#569)
* [XamlC] Add tests for TypeRefExts, fix and enhancements
* [XamlC] more fixes, more tests
* Fix failing test
Diffstat (limited to 'Xamarin.Forms.Build.Tasks')
-rw-r--r-- | Xamarin.Forms.Build.Tasks/TypeReferenceExtensions.cs | 95 |
1 files changed, 62 insertions, 33 deletions
diff --git a/Xamarin.Forms.Build.Tasks/TypeReferenceExtensions.cs b/Xamarin.Forms.Build.Tasks/TypeReferenceExtensions.cs index 613b0cc0..9e1cc165 100644 --- a/Xamarin.Forms.Build.Tasks/TypeReferenceExtensions.cs +++ b/Xamarin.Forms.Build.Tasks/TypeReferenceExtensions.cs @@ -6,6 +6,33 @@ using Mono.Cecil.Rocks; namespace Xamarin.Forms.Build.Tasks { + class TypeRefComparer : IEqualityComparer<TypeReference> + { + static string GetAssembly(TypeReference typeRef) + { + var md = typeRef.Scope as ModuleDefinition; + if (md != null) + return md.Assembly.FullName; + var anr = typeRef.Scope as AssemblyNameReference; + if (anr != null) + return anr.FullName; + throw new ArgumentOutOfRangeException(nameof(typeRef)); + } + + public bool Equals(TypeReference x, TypeReference y) + { + return GetAssembly(x) == GetAssembly(y) && x.FullName == y.FullName; + } + + public int GetHashCode(TypeReference obj) + { + return $"{GetAssembly(obj)}//{obj.FullName}".GetHashCode(); + } + + static TypeRefComparer s_default; + public static TypeRefComparer Default => s_default ?? (s_default = new TypeRefComparer()); + } + static class TypeReferenceExtensions { public static PropertyDefinition GetProperty(this TypeReference typeRef, Func<PropertyDefinition, bool> predicate, @@ -79,54 +106,56 @@ namespace Xamarin.Forms.Build.Tasks return false; } + static readonly string[] arrayInterfaces = { + "System.ICloneable", + "System.Collections.IEnumerable", + "System.Collections.IList", + "System.Collections.ICollection", + "System.Collections.IStructuralComparable", + "System.Collections.IStructuralEquatable", + }; + + static readonly string[] arrayGenericInterfaces = { + "System.Collections.Generic.IEnumerable`1", + "System.Collections.Generic.IList`1", + "System.Collections.Generic.ICollection`1", + "System.Collections.Generic.IReadOnlyCollection`1", + "System.Collections.Generic.IReadOnlyList`1", + }; + public static bool InheritsFromOrImplements(this TypeReference typeRef, TypeReference baseClass) { - if (typeRef.FullName == baseClass.FullName) + if (TypeRefComparer.Default.Equals(typeRef, baseClass)) return true; - var arrayInterfaces = new[] - { - "System.Collections.IEnumerable", - "System.Collections.IList", - "System.Collections.Collection" - }; - - var arrayGenericInterfaces = new[] - { - "System.Collections.IEnumerable`1", - "System.Collections.Generic.IList`1", - "System.Collections.Generic.IReadOnlyCollection<T>", - "System.Collections.Generic.IReadOnlyList<T>", - "System.Collections.Generic.Collection<T>" - }; - - if (typeRef.IsArray && baseClass.IsArray) { - typeRef = typeRef.Resolve(); - baseClass = baseClass.Resolve(); - } + if (typeRef.IsValueType) + return false; - if (typeRef.IsArray) - { + if (typeRef.IsArray) { + var array = (ArrayType)typeRef; var arrayType = typeRef.Resolve(); if (arrayInterfaces.Contains(baseClass.FullName)) return true; - if (arrayGenericInterfaces.Contains(baseClass.Resolve().FullName) && - baseClass.IsGenericInstance && - (baseClass as GenericInstanceType).GenericArguments[0].FullName == arrayType.FullName) + if (array.IsVector && //generic interfaces are not implemented on multidimensional arrays + arrayGenericInterfaces.Contains(baseClass.Resolve().FullName) && + baseClass.IsGenericInstance && + TypeRefComparer.Default.Equals((baseClass as GenericInstanceType).GenericArguments[0], arrayType)) return true; - return false; + return baseClass.FullName == "System.Object"; } + if (typeRef.FullName == "System.Object") + return false; var typeDef = typeRef.Resolve(); - if (typeDef.FullName == baseClass.FullName) + if (TypeRefComparer.Default.Equals(typeDef, baseClass.Resolve())) return true; - if (typeDef.Interfaces.Any(ir => ir.FullName == baseClass.FullName)) + if (typeDef.Interfaces.Any(ir => TypeRefComparer.Default.Equals(ir, baseClass))) return true; - if (typeDef.FullName == "System.Object") - return false; if (typeDef.BaseType == null) return false; - return typeDef.BaseType.InheritsFromOrImplements(baseClass); + + typeRef = typeDef.BaseType.ResolveGenericParameters(typeRef); + return typeRef.InheritsFromOrImplements(baseClass); } public static CustomAttribute GetCustomAttribute(this TypeReference typeRef, TypeReference attribute) @@ -248,4 +277,4 @@ namespace Xamarin.Forms.Build.Tasks return self.GetElementType().MakeGenericInstanceType(args.ToArray()); } } -}
\ No newline at end of file +} |