private void AutoModifyField(TypeDefinition targetType, MemberActionAttribute fieldActionAttr, FieldDefinition yourField) { Log_modifying_member("field", yourField); (fieldActionAttr != null).AssertTrue(); var asModifies = fieldActionAttr as ModifiesMemberAttribute; string targetFieldName = null; ModificationScope scope; if (asModifies != null) { targetFieldName = asModifies.MemberName ?? yourField.Name; scope = asModifies.Scope; } else if (fieldActionAttr is NewMemberAttribute) { targetFieldName = yourField.Name; scope = ModificationScope.All; } else { throw Errors.Unknown_action_attribute(fieldActionAttr); } var targetField = targetType.GetField(targetFieldName); if (targetField == null) { throw Errors.Missing_member("field", yourField, targetFieldName); } if ((scope & ModificationScope.Accessibility) != 0) { targetField.SetAccessibility(yourField.GetAccessbility()); } if ((scope & ModificationScope.CustomAttributes) != 0) { CopyCustomAttributes(targetField, yourField); } if ((scope & ModificationScope.Body) != 0) { targetField.InitialValue = yourField.InitialValue; //dunno what this is used for targetField.Constant = yourField.Constant; } }
private void AutoModifyProperty(TypeDefinition targetType, MemberActionAttribute propActionAttr, PropertyDefinition yourProp) { Log_modifying_member("property", yourProp); var modifiesMemberAttr = propActionAttr as ModifiesMemberAttribute; var newMemberAttr = propActionAttr as NewMemberAttribute; string targetPropName; ModificationScope scope; if (modifiesMemberAttr != null) { targetPropName = modifiesMemberAttr.MemberName ?? yourProp.Name; scope = modifiesMemberAttr.Scope; } else if (newMemberAttr != null) { targetPropName = yourProp.Name; scope = ModificationScope.All; } else { throw Errors.Unknown_action_attribute(propActionAttr); } var targetProp = targetType.GetProperty(targetPropName, yourProp.Parameters.Select(x => x.ParameterType)); if (targetProp == null) { throw Errors.Missing_member("property", yourProp, targetPropName); } if ((scope & ModificationScope.CustomAttributes) != 0) { CopyCustomAttributes(targetProp, yourProp); for (int i = 0; i < yourProp.Parameters.Count; i++) { CopyCustomAttributes(targetProp.Parameters[i], yourProp.Parameters[i]); } } if ((scope & ModificationScope.Body) != 0) { targetProp.GetMethod = yourProp.GetMethod != null?FixMethodReference(yourProp.GetMethod).Resolve() : null; targetProp.SetMethod = yourProp.SetMethod != null?FixMethodReference(yourProp.SetMethod).Resolve() : null; targetProp.OtherMethods.Clear(); if (yourProp.HasOtherMethods) { //I have absolutely NO idea what this is used for foreach (var otherMethod in yourProp.OtherMethods) { targetProp.OtherMethods.Add(FixMethodReference(otherMethod).Resolve()); } } } }
private void AutoModifyMethod(TypeDefinition targetType, MethodDefinition yourMethod, MemberActionAttribute memberAction) { Log_modifying_member("method", yourMethod); var bodySource = yourMethod; var insertAttribute = yourMethod.GetCustomAttribute<DuplicatesBodyAttribute>(); if (insertAttribute != null) { //Note that the source type is resolved using yourMethod's module, which uses a different IMetadataResolver, //and thus will resolve the method from the target, unmodified assembly. var importSourceType = insertAttribute.SourceType != null ? yourMethod.Module.Import((TypeReference) insertAttribute.SourceType) : yourMethod.Module.Import(targetType); var importMethod = importSourceType.Resolve().GetMethods(insertAttribute.MethodName, yourMethod.Parameters.Select(x => x.ParameterType)).SingleOrDefault(); var others = importSourceType.Resolve().Methods.Where(x => x.Name == insertAttribute.MethodName).ToArray(); if (importMethod == null) { throw Errors.Missing_member("method", yourMethod, insertAttribute.MethodName); } bodySource = importMethod; } var modifiesMemberAttr = memberAction as ModifiesMemberAttribute; var newMemberAttr = memberAction as NewMemberAttribute; ModificationScope scope; string targetMethodName; if (modifiesMemberAttr != null) { targetMethodName = modifiesMemberAttr.MemberName ?? yourMethod.Name; scope = modifiesMemberAttr.Scope; } else if (newMemberAttr != null) { targetMethodName = yourMethod.Name; scope = ModificationScope.All; } else { throw Errors.Unknown_action_attribute(memberAction); } var targetMethod = targetType.GetMethods(targetMethodName, yourMethod.Parameters.Select(x => x.ParameterType)).FirstOrDefault(); if (targetMethod == null) { throw Errors.Missing_member("method", yourMethod, targetMethodName); } if (modifiesMemberAttr != null && targetMethod.IsAbstract && (scope & ModificationScope.Body) != 0) { throw Errors.Invalid_member("method", yourMethod, targetMethod.FullName, "You cannot modify the body of an abstract method."); } ModifyMethod(targetMethod, yourMethod, scope & ~ModificationScope.Body, newMemberAttr != null); ModifyMethod(targetMethod, bodySource, ModificationScope.Body & scope, false); }
private void AutoModifyMethod(TypeDefinition targetType, MethodDefinition yourMethod, MemberActionAttribute memberAction) { Log_modifying_member("method", yourMethod); var bodySource = yourMethod; var insertAttribute = yourMethod.GetCustomAttribute <DuplicatesBodyAttribute>(); if (insertAttribute != null) { //Note that the source type is resolved using yourMethod's module, which uses a different IMetadataResolver, //and thus will resolve the method from the target, unmodified assembly. var importSourceType = insertAttribute.SourceType != null ? yourMethod.Module.Import((TypeReference)insertAttribute.SourceType) : yourMethod.Module.Import(targetType); var importMethod = importSourceType.Resolve().GetMethods(insertAttribute.MethodName, yourMethod.Parameters.Select(x => x.ParameterType)).SingleOrDefault(); var others = importSourceType.Resolve().Methods.Where(x => x.Name == insertAttribute.MethodName).ToArray(); if (importMethod == null) { throw Errors.Missing_member("method", yourMethod, insertAttribute.MethodName); } bodySource = importMethod; } var modifiesMemberAttr = memberAction as ModifiesMemberAttribute; var newMemberAttr = memberAction as NewMemberAttribute; ModificationScope scope; string targetMethodName; if (modifiesMemberAttr != null) { targetMethodName = modifiesMemberAttr.MemberName ?? yourMethod.Name; scope = modifiesMemberAttr.Scope; } else if (newMemberAttr != null) { targetMethodName = yourMethod.Name; scope = ModificationScope.All; } else { throw Errors.Unknown_action_attribute(memberAction); } var targetMethod = targetType.GetMethods(targetMethodName, yourMethod.Parameters.Select(x => x.ParameterType)).FirstOrDefault(); if (targetMethod == null) { throw Errors.Missing_member("method", yourMethod, targetMethodName); } if (modifiesMemberAttr != null && targetMethod.IsAbstract && (scope & ModificationScope.Body) != 0) { throw Errors.Invalid_member("method", yourMethod, targetMethod.FullName, "You cannot modify the body of an abstract method."); } ModifyMethod(targetMethod, yourMethod, scope & ~ModificationScope.Body, newMemberAttr != null); ModifyMethod(targetMethod, bodySource, ModificationScope.Body & scope, false); }
private void AutoModifyProperty(TypeDefinition targetType, MemberActionAttribute propActionAttr, PropertyDefinition yourProp) { Log_modifying_member("property", yourProp); var modifiesMemberAttr = propActionAttr as ModifiesMemberAttribute; var newMemberAttr = propActionAttr as NewMemberAttribute; string targetPropName; ModificationScope scope; if (modifiesMemberAttr != null) { targetPropName = modifiesMemberAttr.MemberName ?? yourProp.Name; scope = modifiesMemberAttr.Scope; } else if (newMemberAttr != null) { targetPropName = yourProp.Name; scope = ModificationScope.All; } else { throw Errors.Unknown_action_attribute(propActionAttr); } var targetProp = targetType.GetProperty(targetPropName, yourProp.Parameters.Select(x => x.ParameterType)); if (targetProp == null) { throw Errors.Missing_member("property", yourProp, targetPropName); } if ((scope & ModificationScope.CustomAttributes) != 0) { CopyCustomAttributes(targetProp, yourProp); for (int i = 0; i < yourProp.Parameters.Count; i++) { CopyCustomAttributes(targetProp.Parameters[i], yourProp.Parameters[i]); } } if ((scope & ModificationScope.Body) != 0) { targetProp.GetMethod = yourProp.GetMethod != null ? FixMethodReference(yourProp.GetMethod).Resolve() : null; targetProp.SetMethod = yourProp.SetMethod != null ? FixMethodReference(yourProp.SetMethod).Resolve() : null; targetProp.OtherMethods.Clear(); if (yourProp.HasOtherMethods) { //I have absolutely NO idea what this is used for foreach (var otherMethod in yourProp.OtherMethods) { targetProp.OtherMethods.Add(FixMethodReference(otherMethod).Resolve()); } } } }