/// <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))); }
/// <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); }