Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono-tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Pouliot <sebastien@ximian.com>2010-06-05 19:18:48 +0400
committerSebastien Pouliot <sebastien@ximian.com>2010-06-05 19:18:48 +0400
commit4ac0779583d931e69db7da0b99c0b9a974d40734 (patch)
tree0d590e1f857de4e6c483f26284d65700e29d01e6
parente5c7f584d4b5b11c0baf3192968d37ed2c5f8353 (diff)
2010-06-05 Sebastien Pouliot <sebastien@ximian.com>
* CecilRock.cs: Add a faster path (without multiple casting) for GetAssembly, fallback to existing (slow) code path if needed. Support all IMetadataTokenProvider types. Make Equals namespace aware and better deal with null assemblies. svn path=/trunk/mono-tools/; revision=158535
-rw-r--r--gendarme/framework/Gendarme.Framework.Rocks/CecilRocks.cs106
-rw-r--r--gendarme/framework/Gendarme.Framework.Rocks/ChangeLog7
2 files changed, 97 insertions, 16 deletions
diff --git a/gendarme/framework/Gendarme.Framework.Rocks/CecilRocks.cs b/gendarme/framework/Gendarme.Framework.Rocks/CecilRocks.cs
index da41a7f9..f1c57209 100644
--- a/gendarme/framework/Gendarme.Framework.Rocks/CecilRocks.cs
+++ b/gendarme/framework/Gendarme.Framework.Rocks/CecilRocks.cs
@@ -29,6 +29,9 @@
using System;
using Mono.Cecil;
+using Mono.Cecil.Metadata;
+
+using Gendarme.Framework.Helpers;
namespace Gendarme.Framework.Rocks {
@@ -45,29 +48,89 @@ namespace Gendarme.Framework.Rocks {
/// if none can be found</returns>
public static AssemblyDefinition GetAssembly (this IMetadataTokenProvider self)
{
- AssemblyDefinition ad = (self as AssemblyDefinition);
- if (ad != null)
- return ad;
+ if (self == null)
+ return null;
- TypeDefinition td = (self as TypeDefinition);
- if (td != null)
- return td.Module.Assembly;
+ MetadataToken token = self.MetadataToken;
+ switch (token.TokenType) {
+ case TokenType.Assembly:
+ return (self as AssemblyDefinition);
+ case TokenType.Module:
+ // Module == 0, so we need to handle MetadataToken.Zero here
+ if (token.RID == 0) {
+ // if we don't have a valid token then we take the slow path
+ return GetAssemblyUsingCasts (self);
+ } else {
+ return (self as ModuleDefinition).Assembly;
+ }
+ case TokenType.GenericParam:
+ return GetAssembly ((self as GenericParameter).DeclaringType);
+ case TokenType.TypeRef:
+ case TokenType.TypeDef:
+ return GetAssembly (self as TypeReference);
+ case TokenType.Method:
+ return GetAssembly (self as MethodReference);
+ case TokenType.Event:
+ return GetAssembly ((self as EventDefinition).DeclaringType);
+ case TokenType.Field:
+ return GetAssembly ((self as FieldDefinition).DeclaringType);
+ case TokenType.Property:
+ return GetAssembly ((self as PropertyDefinition).DeclaringType);
+ case TokenType.Param:
+ return GetAssembly ((self as ParameterDefinition).Method);
+ // NamespaceDefinition is a Gendarme "extention", i.e. not real metadata, and does not belong in a single assembly
+ case NamespaceDefinition.NamespaceTokenType:
+ return null;
+ default:
+ return GetAssemblyUsingCasts (self);
+ }
+ }
- MethodDefinition md = (self as MethodDefinition);
+ static AssemblyDefinition GetAssemblyUsingCasts (IMetadataTokenProvider metadata)
+ {
+ AssemblyDefinition ad = (metadata as AssemblyDefinition);
+ if (ad != null)
+ return ad;
+ ModuleDefinition md = (metadata as ModuleDefinition);
if (md != null)
- return md.DeclaringType.Module.Assembly;
-
- FieldDefinition fd = (self as FieldDefinition);
+ return md.Assembly;
+ GenericParameter gp = (metadata as GenericParameter); // needs to be before TypeReference
+ if (gp != null)
+ return GetAssembly (gp.DeclaringType);
+ TypeReference tr = (metadata as TypeReference);
+ if (tr != null)
+ return GetAssembly (tr);
+ MethodReference mr = (metadata as MethodReference);
+ if (mr != null)
+ return GetAssembly (mr);
+ EventDefinition ed = (metadata as EventDefinition);
+ if (ed != null)
+ return GetAssembly (ed.DeclaringType);
+ FieldDefinition fd = (metadata as FieldDefinition);
if (fd != null)
- return fd.DeclaringType.Module.Assembly;
-
- ParameterDefinition pd = (self as ParameterDefinition);
+ return GetAssembly (fd.DeclaringType);
+ PropertyDefinition pd = (metadata as PropertyDefinition);
if (pd != null)
- return pd.Method.DeclaringType.Module.Assembly;
-
+ return GetAssembly (pd.DeclaringType);
+ ParameterDefinition paramd = (metadata as ParameterDefinition);
+ if (paramd != null)
+ return GetAssembly (paramd.Method);
+ MethodReturnType mrt = (metadata as MethodReturnType);
+ if (mrt != null)
+ return GetAssembly (mrt.Method);
return null;
}
+ static AssemblyDefinition GetAssembly (TypeReference type)
+ {
+ return type.Module.Assembly;
+ }
+
+ static AssemblyDefinition GetAssembly (IMemberReference method)
+ {
+ return method.DeclaringType.Module.Assembly;
+ }
+
/// <summary>
/// Compare IMetadataTokenProvider instances based on their metadata token and their
/// assembly.
@@ -83,8 +146,19 @@ namespace Gendarme.Framework.Rocks {
return (self == null);
if (!self.MetadataToken.Equals (other.MetadataToken))
return false;
+
// metadata token is unique per assembly
- return GetAssembly (self).ToString () == GetAssembly (other).ToString ();
+ AssemblyDefinition self_assembly = GetAssembly (self);
+ if (self_assembly == null) {
+ // special case for Namespace (where GetAssembly would return null)
+ if (self.MetadataToken.TokenType == NamespaceDefinition.NamespaceTokenType)
+ return (self as NamespaceDefinition).Name == (other as NamespaceDefinition).Name;
+ else
+ return false;
+ }
+ AssemblyDefinition other_assembly = GetAssembly (other);
+ // compare assemblies tokens (but do not recurse)
+ return other == null ? false : self_assembly.MetadataToken.Equals (other_assembly.MetadataToken);
}
}
}
diff --git a/gendarme/framework/Gendarme.Framework.Rocks/ChangeLog b/gendarme/framework/Gendarme.Framework.Rocks/ChangeLog
index c865dcb6..90f73f99 100644
--- a/gendarme/framework/Gendarme.Framework.Rocks/ChangeLog
+++ b/gendarme/framework/Gendarme.Framework.Rocks/ChangeLog
@@ -1,3 +1,10 @@
+2010-06-05 Sebastien Pouliot <sebastien@ximian.com>
+
+ * CecilRock.cs: Add a faster path (without multiple casting) for
+ GetAssembly, fallback to existing (slow) code path if needed.
+ Support all IMetadataTokenProvider types. Make Equals namespace
+ aware and better deal with null assemblies.
+
2010-05-16 Sebastien Pouliot <sebastien@ximian.com>
* AssemblyRocks.cs: