private void ModifyMethod(TypeDefinition targetType, MethodDefinition yourMethod, MemberActionAttribute memberAction, MethodDefinition targetMethod) { Log_modifying_member("method", yourMethod); var insertAttribute = yourMethod.GetCustomAttribute<DuplicatesBodyAttribute>(); var bodySource = insertAttribute == null ? yourMethod : GetBodySource(targetType, yourMethod, insertAttribute); ModificationScope scope = memberAction.Scope; if (scope.HasFlag(AdvancedModificationScope.ExplicitOverrides)) { targetMethod.Overrides.Clear(); foreach (var explicitOverride in yourMethod.Overrides) { targetMethod.Overrides.Add(FixMethodReference(explicitOverride)); } } var attrFilter = AttrFilter(scope); CopyCustomAttributes(targetMethod, yourMethod, attrFilter); CopyCustomAttributes(targetMethod.MethodReturnType, yourMethod.MethodReturnType, attrFilter); for (int i = 0; i < yourMethod.Parameters.Count; i++) { CopyCustomAttributes(targetMethod.Parameters[i], yourMethod.Parameters[i], attrFilter); } for (int i = 0; i < yourMethod.GenericParameters.Count; i++) { CopyCustomAttributes(targetMethod.GenericParameters[i], yourMethod.GenericParameters[i], attrFilter); } if ((scope & ModificationScope.Accessibility) != 0) { targetMethod.SetAccessibility(yourMethod.GetAccessbility()); } if (scope.HasFlag(ModificationScope.Body)) { if (yourMethod.Body != null) { TransferMethodBody(targetMethod, bodySource); } else { //this happens in abstract methods and some others. targetMethod.Body = null; } } if (EmbedHistory) { targetMethod.AddPatchedByMemberAttribute(yourMethod); } var toggleAttributesAttr = yourMethod.GetCustomAttribute<ToggleMethodAttributes>(); var toggleValue = toggleAttributesAttr?.Attributes ?? 0; targetMethod.Attributes ^= (MethodAttributes) toggleValue; }
/// <summary> /// Patches the target method by overwriting some aspects with your method, such as: its body and accessibility. Also allows adding custom attributes. /// </summary> /// <param name="targetMethod">The target method.</param> /// <param name="yourMethod">Your method.</param> /// <param name="scope">The extent to which to modify the method..</param> private void ModifyMethod(MethodDefinition targetMethod, MethodDefinition yourMethod, ModificationScope scope, bool isNew) { if ((scope & ModificationScope.Accessibility) != 0) { targetMethod.SetAccessibility(yourMethod.GetAccessbility()); } if (isNew) { //There is absolutely no point allowing you to modify the explicit overrides of existing methods. //I thought of adding an enum value, but it will just cause confusion. targetMethod.Overrides.Clear(); foreach (var explicitOverride in yourMethod.Overrides) { targetMethod.Overrides.Add(FixMethodReference(explicitOverride)); } } if ((scope & ModificationScope.CustomAttributes) != 0) { CopyCustomAttributes(targetMethod, yourMethod); CopyCustomAttributes(targetMethod.MethodReturnType, yourMethod.MethodReturnType); for (int i = 0; i < yourMethod.Parameters.Count; i++) { CopyCustomAttributes(targetMethod.Parameters[i], yourMethod.Parameters[i]); } for (int i = 0; i < yourMethod.GenericParameters.Count; i++) { CopyCustomAttributes(targetMethod.GenericParameters[i], yourMethod.GenericParameters[i]); } } if ((scope & ModificationScope.Body) == 0) { return; } if (yourMethod.Body != null) { TransferMethodBody(targetMethod, yourMethod); } else { //this happens in abstract methods and some others. targetMethod.Body = null; } }