summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Build.Tasks
diff options
context:
space:
mode:
authorStephane Delcroix <stephane@delcroix.org>2016-12-07 10:57:43 +0100
committerGitHub <noreply@github.com>2016-12-07 10:57:43 +0100
commit8181e6d4cbe8aac6eb29c5140262d8bc51dba7b7 (patch)
tree5e97231ce476ec38961cb5de9f2ca5ea24569625 /Xamarin.Forms.Build.Tasks
parent1dd4ce922e7d28038605a4476dce207f1440122f (diff)
downloadxamarin-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.cs95
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
+}