public static MethodDefinition Execute(PropertyDefinition property_definition, MethodDefinition notify_method, DependencyMap map) { log.Trace("\t\t\t\t\tAdding collection notification method for " + property_definition.Name); // Create method TypeReference return_type = property_definition.Module.Import(typeof (void)); MethodDefinition collection_notification = new MethodDefinition(property_definition.Name + "CollectionNotification", Mono.Cecil.MethodAttributes.Private | Mono.Cecil.MethodAttributes.HideBySig, return_type); // Add parameters TypeReference sender_type = property_definition.Module.Import(typeof(object)); TypeReference args_type = property_definition.Module.Import(typeof(NotifyCollectionChangedEventArgs)); ParameterDefinition sender = new ParameterDefinition("sender", Mono.Cecil.ParameterAttributes.None, sender_type); ParameterDefinition args = new ParameterDefinition("args", Mono.Cecil.ParameterAttributes.None, args_type); collection_notification.Parameters.Add(sender); collection_notification.Parameters.Add(args); // Add notifications for dependent properties ILProcessor processor = collection_notification.Body.GetILProcessor(); foreach (var target in map.GetDependenciesFor(property_definition.Name)) { log.Trace("\t\t\t\t\t\tAdding dependency " + target); processor.Emit(OpCodes.Ldarg_0); processor.Emit(OpCodes.Ldstr, target); processor.Emit(OpCodes.Call, notify_method); } processor.Emit(OpCodes.Ret); // Add method to class property_definition.DeclaringType.Methods.Add(collection_notification); return collection_notification; }
public static void Execute(PropertyDefinition property_definition, MethodDefinition notify_method, DependencyMap map) { // Check if notifications are already call, if so bail out foreach (var instruction in property_definition.SetMethod.Body.Instructions) { if (instruction.OpCode == OpCodes.Call) { var method = instruction.Operand as MethodDefinition; if (method != null && method == notify_method) { log.Trace("\t\t\t\t\tBailing out, notification found in property"); return; } } } // Add notifications var ret = property_definition.SetMethod.Body.Instructions.Last(i => i.OpCode == OpCodes.Ret); ILProcessor processor = property_definition.SetMethod.Body.GetILProcessor(); // NotifyPropertyChanged(property) processor.InsertBefore(ret, processor.Create(OpCodes.Ldarg_0)); processor.InsertBefore(ret, processor.Create(OpCodes.Ldstr, property_definition.Name)); processor.InsertBefore(ret, processor.Create(OpCodes.Call, notify_method)); // Add notifications for dependent properties foreach (var target in map.GetDependenciesFor(property_definition.Name)) { log.Trace("\t\t\t\t\tAdding dependency " + target); processor.InsertBefore(ret, processor.Create(OpCodes.Ldarg_0)); processor.InsertBefore(ret, processor.Create(OpCodes.Ldstr, target)); processor.InsertBefore(ret, processor.Create(OpCodes.Call, notify_method)); } }
public static MethodDefinition Execute(PropertyDefinition property_definition, MethodDefinition notify_method, DependencyMap map) { log.Trace("\t\t\t\t\tAdding collection notification method for " + property_definition.Name); // Create method TypeReference return_type = property_definition.Module.Import(typeof(void)); MethodDefinition collection_notification = new MethodDefinition(property_definition.Name + "CollectionNotification", Mono.Cecil.MethodAttributes.Private | Mono.Cecil.MethodAttributes.HideBySig, return_type); // Add parameters TypeReference sender_type = property_definition.Module.Import(typeof(object)); TypeReference args_type = property_definition.Module.Import(typeof(NotifyCollectionChangedEventArgs)); ParameterDefinition sender = new ParameterDefinition("sender", Mono.Cecil.ParameterAttributes.None, sender_type); ParameterDefinition args = new ParameterDefinition("args", Mono.Cecil.ParameterAttributes.None, args_type); collection_notification.Parameters.Add(sender); collection_notification.Parameters.Add(args); // Add notifications for dependent properties ILProcessor processor = collection_notification.Body.GetILProcessor(); foreach (var target in map.GetDependenciesFor(property_definition.Name)) { log.Trace("\t\t\t\t\t\tAdding dependency " + target); processor.Emit(OpCodes.Ldarg_0); processor.Emit(OpCodes.Ldstr, target); processor.Emit(OpCodes.Call, notify_method); } processor.Emit(OpCodes.Ret); // Add method to class property_definition.DeclaringType.Methods.Add(collection_notification); return(collection_notification); }
public static void Execute(PropertyDefinition property_definition, MethodDefinition notify_method, DependencyMap map) { // Check if notifications are already call, if so bail out foreach (var instruction in property_definition.SetMethod.Body.Instructions) { if (instruction.OpCode == OpCodes.Call) { var method = instruction.Operand as MethodDefinition; if (method != null && method == notify_method) { log.Trace("\t\t\t\t\tBailing out, notification found in property"); return; } } } // Add notifications var ret = property_definition.SetMethod.Body.Instructions.Last(i => i.OpCode == OpCodes.Ret); ILProcessor processor = property_definition.SetMethod.Body.GetILProcessor(); // NotifyPropertyChanged(property) processor.InsertBefore(ret, processor.Create(OpCodes.Ldarg_0)); processor.InsertBefore(ret, processor.Create(OpCodes.Ldstr, property_definition.Name)); processor.InsertBefore(ret, processor.Create(OpCodes.Call, notify_method)); // Add notifications for dependent properties foreach (var target in map.GetDependenciesFor(property_definition.Name)) { log.Trace("\t\t\t\t\tAdding dependency " + target); processor.InsertBefore(ret, processor.Create(OpCodes.Ldarg_0)); processor.InsertBefore(ret, processor.Create(OpCodes.Ldstr, target)); processor.InsertBefore(ret, processor.Create(OpCodes.Call, notify_method)); } }
public static void Execute(PropertyDefinition property_definition, MethodDefinition notify_method, DependencyMap map) { FieldDefinition backing_field = property_definition.GetAutoPropertyBackingField(); // Clear custom attributes backing_field.CustomAttributes.Clear(); property_definition.GetMethod.CustomAttributes.Clear(); property_definition.SetMethod.CustomAttributes.Clear(); // Clear set method body property_definition.SetMethod.Body.Instructions.Clear(); ILProcessor processor = property_definition.SetMethod.Body.GetILProcessor(); Instruction ret = processor.Create(OpCodes.Ret); // if (value != property) processor.Emit(OpCodes.Ldarg_1); processor.Emit(OpCodes.Ldarg_0); processor.Emit(OpCodes.Ldfld, backing_field); processor.Emit(OpCodes.Ceq); processor.Emit(OpCodes.Brtrue_S, ret); // property = value processor.Emit(OpCodes.Ldarg_0); processor.Emit(OpCodes.Ldarg_1); processor.Emit(OpCodes.Stfld, backing_field); // NotifyPropertyChanged(property) processor.Emit(OpCodes.Ldarg_0); processor.Emit(OpCodes.Ldstr, property_definition.Name); processor.Emit(OpCodes.Call, notify_method); // Add notifications for dependent properties foreach (var target in map.GetDependenciesFor(property_definition.Name)) { log.Trace("\t\t\t\t\tAdding dependency " + target); processor.Emit(OpCodes.Ldarg_0); processor.Emit(OpCodes.Ldstr, target); processor.Emit(OpCodes.Call, notify_method); } processor.Append(ret); }
public static void Execute(PropertyDefinition property_definition, MethodDefinition notify_method, DependencyMap map) { FieldDefinition backing_field = property_definition.GetAutoPropertyBackingField(); // Clear custom attributes backing_field.CustomAttributes.Clear(); property_definition.GetMethod.CustomAttributes.Clear(); property_definition.SetMethod.CustomAttributes.Clear(); // Clear set method body property_definition.SetMethod.Body.Instructions.Clear(); ILProcessor processor = property_definition.SetMethod.Body.GetILProcessor(); Instruction ret = processor.Create(OpCodes.Ret); // if (value != property) processor.Emit(OpCodes.Ldarg_1); processor.Emit(OpCodes.Ldarg_0); processor.Emit(OpCodes.Ldfld, backing_field); processor.Emit(OpCodes.Ceq); processor.Emit(OpCodes.Brtrue_S, ret); // property = value processor.Emit(OpCodes.Ldarg_0); processor.Emit(OpCodes.Ldarg_1); processor.Emit(OpCodes.Stfld, backing_field); // NotifyPropertyChanged(property) processor.Emit(OpCodes.Ldarg_0); processor.Emit(OpCodes.Ldstr, property_definition.Name); processor.Emit(OpCodes.Call, notify_method); // Add notifications for dependent properties foreach (var target in map.GetDependenciesFor(property_definition.Name)) { log.Trace("\t\t\t\t\tAdding dependency " + target); processor.Emit(OpCodes.Ldarg_0); processor.Emit(OpCodes.Ldstr, target); processor.Emit(OpCodes.Call, notify_method); } processor.Append(ret); }