Exemple #1
0
        /// <summary>Get whether a type has a method whose signature matches the one expected by a method reference.</summary>
        /// <param name="type">The type to check.</param>
        /// <param name="reference">The method reference.</param>
        public static bool HasMatchingSignature(Type type, MethodReference reference)
        {
            if (reference.Name == ".ctor")
            {
                return(type
                       .GetConstructors(BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.Public)
                       .Any(method => RewriteHelper.HasMatchingSignature(method, reference)));
            }

            return(type
                   .GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.Public)
                   .Any(method => RewriteHelper.HasMatchingSignature(method, reference)));
        }
Exemple #2
0
        /// <summary>Rewrite custom attributes if needed.</summary>
        /// <param name="attributes">The current custom attributes.</param>
        private bool RewriteCustomAttributes(Collection <CustomAttribute> attributes)
        {
            bool rewritten = false;

            for (int attrIndex = 0; attrIndex < attributes.Count; attrIndex++)
            {
                CustomAttribute attribute  = attributes[attrIndex];
                bool            curChanged = false;

                // attribute type
                TypeReference newAttrType = null;
                rewritten |= this.RewriteTypeReference(attribute.AttributeType, newType =>
                {
                    newAttrType = newType;
                    curChanged  = true;
                });

                // constructor arguments
                TypeReference[] argTypes = new TypeReference[attribute.ConstructorArguments.Count];
                for (int i = 0; i < argTypes.Length; i++)
                {
                    var arg = attribute.ConstructorArguments[i];

                    argTypes[i] = arg.Type;
                    rewritten  |= this.RewriteTypeReference(arg.Type, newType =>
                    {
                        argTypes[i] = newType;
                        curChanged  = true;
                    });
                }

                // swap attribute
                if (curChanged)
                {
                    // get constructor
                    MethodDefinition constructor = (newAttrType ?? attribute.AttributeType)
                                                   .Resolve()
                                                   .Methods
                                                   .Where(method => method.IsConstructor)
                                                   .FirstOrDefault(ctor => RewriteHelper.HasMatchingSignature(ctor, attribute.Constructor));
                    if (constructor == null)
                    {
                        throw new InvalidOperationException($"Can't rewrite attribute type '{attribute.AttributeType.FullName}' to '{newAttrType?.FullName}', no equivalent constructor found.");
                    }

                    // create new attribute
                    var newAttr = new CustomAttribute(this.Module.ImportReference(constructor));
                    for (int i = 0; i < argTypes.Length; i++)
                    {
                        newAttr.ConstructorArguments.Add(new CustomAttributeArgument(argTypes[i], attribute.ConstructorArguments[i].Value));
                    }
                    foreach (var prop in attribute.Properties)
                    {
                        newAttr.Properties.Add(new CustomAttributeNamedArgument(prop.Name, prop.Argument));
                    }
                    foreach (var field in attribute.Fields)
                    {
                        newAttr.Fields.Add(new CustomAttributeNamedArgument(field.Name, field.Argument));
                    }

                    // swap attribute
                    attributes[attrIndex] = newAttr;
                    rewritten             = true;
                }
            }

            return(rewritten);
        }