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

Reply via email to