Yeah I had that one already :) BTW: You guys are broken on attribute.
http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.compilergeneratedattribute(v=vs.85).aspx [SerializableAttribute] [AttributeUsageAttribute(AttributeTargets.All, Inherited=true)] public sealed class CompilerGeneratedAttribute : Attribute So here are some extension methods that may help, never any issue to donate to OSS :) Think I got it all (no compiler in gmail :() public static class MethodDefinitionExtensions { public static bool IsGeneratedMethod(this MethodDefinition methodDefinition) { return methodDefinition.ContainsAttribute("CompilerGeneratedAttribute"); } public static IEnumerable<CustomAttribute> GetEffectiveAttributes(this MethodDefinition definition) { var same = true; foreach(var def in definition.GetInheritanceHierarchy()) { foreach (var attr in def.CustomAttributes) { if(same || attr.IsInheritable()) yield return attr; } same = false; } } public static class ICustomAttributeProviderExtensions { public static bool ContainsAttribute(this ICustomAttributeProvider provider, string name) { return provider.CustomAttributes.Where(x => x.AttributeType.Name == name). FirstOrDefault() != null; } } public static IEnumerable<MethodDefinition> GetInheritanceHierarchy(this MethodDefinition definition) { bool first = true; foreach(var t in definition.DeclaringType.WalkInheritance()) { var cur = t.ThreadSafeResolve().GetMethodDefinitionMatching(definition, first); if (cur != null) yield return cur; else yield break; first = false; } } public static MethodDefinition GetMethodDefinitionMatching(this TypeDefinition type, MethodDefinition toMatch, bool allowNonVirtual) { foreach (var m in type.Methods) { if (m.MethodMatch(toMatch, allowNonVirtual)) return m; } return null; } public static bool MethodMatch(this MethodDefinition candidate, MethodDefinition method) { return MethodMatch(candidate, method, false); } public static bool MethodMatch(this MethodDefinition candidate, MethodDefinition method, bool AllowShadows) { if (!candidate.IsVirtual && !AllowShadows) return false; if (candidate.Name != method.Name) return false; if (!TypeMatch(candidate.ReturnType, method.ReturnType)) return false; if (candidate.Parameters.Count != method.Parameters.Count) return false; for (int i = 0; i < candidate.Parameters.Count; i++) if (!TypeMatch(candidate.Parameters[i].ParameterType, method.Parameters[i].ParameterType)) return false; return true; } static bool TypeMatch(TypeReference a, TypeReference b) { if (a is GenericParameter) return true; if (a is TypeSpecification || b is TypeSpecification) { if (a.GetType() != b.GetType()) return false; return TypeMatch((TypeSpecification)a, (TypeSpecification)b); } return a.FullName == b.FullName; } static bool TypeMatch(TypeSpecification a, TypeSpecification b) { if (a is GenericInstanceType) return TypeMatch((GenericInstanceType)a, (GenericInstanceType)b); return TypeMatch(a.ElementType, b.ElementType); } static bool TypeMatch(GenericInstanceType a, GenericInstanceType b) { if (!TypeMatch(a.ElementType, b.ElementType)) return false; if (a.GenericArguments.Count != b.GenericArguments.Count) return false; if (a.GenericArguments.Count == 0) return true; for (int i = 0; i < a.GenericArguments.Count; i++) if (!TypeMatch(a.GenericArguments[i], b.GenericArguments[i])) return false; return true; } On Fri, Mar 4, 2011 at 7:43 PM, Daniel Grunwald <[email protected]> wrote: > No, that stuff depends on ILSpy's context for the "current class". > But here's the extension method for point 2: > public static bool IsCompilerGenerated(this ICustomAttributeProvider > provider) > { > if (provider.HasCustomAttributes) { > foreach (CustomAttribute a in provider.CustomAttributes) { > if (a.AttributeType.FullName > == "System.Runtime.CompilerServices.CompilerGeneratedAttribute") > return true; > } > } > return false; > } > > public static bool IsCompilerGeneratedOrIsInCompilerGeneratedClass(this IMemberDefinition > member) > { > if (member == null) > return false; > if (member.IsCompilerGenerated()) > return true; > return IsCompilerGeneratedOrIsInCompilerGeneratedClass(member.DeclaringType); > } > > On 3/5/2011 01:24, Greg Young wrote: > > Do you happen to have an extension method for this? :) > > On Fri, Mar 4, 2011 at 12:21 PM, Daniel Grunwald > <[email protected]> wrote: > > You mean anonymous methods / lambdas? > That's not possible; there isn't any unique attribute identifying them. > > The logic we're currently using in ILSpy is: > 1) Method name must start with "<" > 2) The [CompilerGenerated] attribute must be applied to the method or to > one of the method's declaring types (doesn't have to be the direct > containing type if there are nested lambdas) > 3) The method must be declared in the current class or in one of its > nested classes. > > Daniel > > On 3/4/2011 17:35, Greg Young wrote: > > Is there any way to reliably find delegate methods? I know I can > identify them as compiler generated. I also know they follow a naming > standard but would prefer to not lock myself into such decisions by > the compiler writer. > > My guess is that I will have to make the latter dependency but if > anyone has another way? > > > -- Les erreurs de grammaire et de syntaxe ont été incluses pour m'assurer de votre attention -- -- mono-cecil
