private void Validate(IHasMethods holder, IList <IMethod> methods) { foreach (var pair in methods.GroupBy(m => ToString(m)).Where(g => g.Count() >= 2)) { foreach (var meth in pair) { var retType = abbreviations[meth.ReturnType]; if (retType == null) { continue; } var newSuffix = abbreviations[retType]; var newName = $"{meth.Name}_{newSuffix}"; meth.Rename(newName); } } foreach (var meth in methods.ToArray()) { if (meth.Name.Contains("#")) { meth.Rename(meth.Name.Replace("#", "Hash")); } else if (meth.Name.Equals("Equals") || meth.Name.Equals("GetHashCode") || meth.Name.Equals("Finalize") || meth.Name.Equals("ToString") || meth.Name.StartsWith("_<") || meth.ReturnType.Contains("Dictionary2") || meth.ReturnType.Contains("Func2")) { holder.Methods.Remove(meth); } } }
private static void CheckCalledMethod(ErrorsService errorsService, IHasMethods viewModelType, string calledMethodName, string propertyName) { if (calledMethodName.IsNullOrEmpty()) { return; } var calledMethodsBeforeGetProperty = viewModelType.GetMethods(calledMethodName).ToArray(); switch (calledMethodsBeforeGetProperty.Length) { case 0: errorsService.AddError($"Not found called method with name '{calledMethodName}', " + $"specified in '{nameof(PatchingPropertyAttribute)}' at property '{propertyName}'"); break; case 1: if (calledMethodsBeforeGetProperty.Single().ParameterTypes.Any()) { errorsService.AddError($"Called method '{calledMethodName}' can not have parameters, " + $"specified in '{nameof(PatchingPropertyAttribute)}' at property '{propertyName}'"); } break; default: errorsService.AddError($"Found several called methods with name '{calledMethodName}', " + $"specified in '{nameof(PatchingPropertyAttribute)}' at property '{propertyName}'"); break; } }
private void PatchGroup(ICommonAssembly assembly, IHasMethods viewModelBaseType, ICommonType viewModelType, PropertyGroup group) { RemoveDefaultField(viewModelType, group.Property.Name); var field = group.Field?.MonoCecil ?? CreateField(viewModelType, group.Property); GenerateGetMethodBody(viewModelType, group, field); GenerateSetMethodBody(assembly, viewModelBaseType, viewModelType, group, field); }
private void GenerateSetMethodBody(ICommonAssembly assembly, IHasMethods viewModelBaseType, ICommonType viewModelType, PropertyGroup group, FieldReference field) { log.Info("Generate set method body..."); var property = group.Property; if (property.SetMethod == null) { log.Debug($"Create set accessor method for property '{property.Name}'"); var setMethod = new MethodDefinition($"set_{property.Name}", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, assembly.MonoCecil.MainModule.TypeSystem.Void); setMethod.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.None, property.MonoCecil.PropertyType)); property.MonoCecil.SetMethod = setMethod; viewModelType.MonoCecil.Methods.Add(setMethod); } var setMethodFromViewModelBaseWithGeneric = new GenericInstanceMethod(viewModelBaseType.GetMethod("Set", new[] { typeof(string).FullName, "T&", "T", typeof(bool).FullName }, true).MonoCecil); setMethodFromViewModelBaseWithGeneric.GenericArguments.Add(property.MonoCecil.PropertyType); var importedSetMethodFromViewModelBaseWithGeneric = assembly.MonoCecil.MainModule.ImportReference(setMethodFromViewModelBaseWithGeneric); var callMethodAfterSetPropertyInstructions = CreateCallMethodInstructions(group.CalledMethodAfterSetProperty).ToArray(); property.MonoCecil.SetMethod.Body.Variables.Clear(); property.MonoCecil.SetMethod.Body.Instructions.Clear(); CreateCallMethodInstructions(group.CalledMethodBeforeSetProperty).ForEach(property.MonoCecil.SetMethod.Body.Instructions.Add); property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldstr, property.Name)); property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldflda, field)); property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_1)); property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4_0)); property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Call, importedSetMethodFromViewModelBaseWithGeneric)); var returnInstruction = Instruction.Create(OpCodes.Ret); if (group.CalledMethodAfterSuccessSetProperty != null) { var firstInstructionAfterJump = callMethodAfterSetPropertyInstructions.FirstOrDefault() ?? returnInstruction; property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Brfalse_S, firstInstructionAfterJump)); CreateCallMethodInstructions(group.CalledMethodAfterSuccessSetProperty).ForEach(property.MonoCecil.SetMethod.Body.Instructions.Add); } else { property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Pop)); } callMethodAfterSetPropertyInstructions.ForEach(property.MonoCecil.SetMethod.Body.Instructions.Add); property.MonoCecil.SetMethod.Body.Instructions.Add(returnInstruction); property.MonoCecil.SetMethod.RemoveAttributes <CompilerGeneratedAttribute>(); log.Info("Set method body was generated"); }
private ICommonMethod[] GetPatchingMethods(IHasMethods viewModelType, ViewModelPatchingType patchingType) { return(viewModelType.Methods .Where(method => method.NotContainsAttribute <NotPatchingCommandAttribute>() && method.ReturnType == typeof(void) && !method.ParameterTypes.Any() && (!applicationPatcherWpfConfiguration.SkipConnectingByNameIfNameIsInvalid || nameRulesService.IsNameValid(method.Name, UseNameRulesFor.CommandExecuteMethod)) && ( patchingType == ViewModelPatchingType.All || method.ContainsAttribute <PatchingCommandAttribute>() || method.ContainsAttribute <ConnectMethodToMethodAttribute>() || method.ContainsAttribute <ConnectMethodToPropertyAttribute>())) .ToArray()); }
private void SetVirtualOnMethods(IHasMethods type) { log.Info("Patching non static methods..."); var nonStaticMethods = type.Methods.Where(method => !method.MonoCecil.IsStatic).ToArray(); if (!nonStaticMethods.Any()) { log.Info("Not found non static methods"); return; } log.Debug("Non static methods found:", nonStaticMethods.Select(property => property.FullName)); foreach (var method in nonStaticMethods) { SetVirtualMethod(method.MonoCecil); } log.Info("Non static methods was patched"); }
public static IEnumerable <ICommonMethod> GetMethods(this IHasMethods hasMethods, string methodName) { return(hasMethods.MethodNameToMethods.TryGetValue(methodName, out var commonMethods) ? commonMethods : Enumerable.Empty <ICommonMethod>()); }
public static ICommonMethod GetMethod(this IHasMethods hasMethods, string methodName, string[] methodParameterTypeFullNames, bool throwExceptionIfNotFound = false) { return((hasMethods.MethodNameToMethods.TryGetValue(methodName, out var commonMethods) ? commonMethods : Enumerable.Empty <ICommonMethod>()).Where(method => method.ParameterTypes.Select(type => type.FullName.NullIfEmpty() ?? type.Name).SequenceEqual(methodParameterTypeFullNames ?? new string[0])).SingleOrDefault(throwExceptionIfNotFound, methodName)); }
public static ICommonMethod GetMethod(this IHasMethods hasMethods, string methodName, IHasType[] methodParameterHasTypes, bool throwExceptionIfNotFound = false) { return(hasMethods.GetMethod(methodName, methodParameterHasTypes.Select(type => type.Type).ToArray(), throwExceptionIfNotFound)); }
public static ICommonMethod GetMethod(this IHasMethods hasMethods, string methodName, bool throwExceptionIfNotFound = false) { return(hasMethods.GetMethod(methodName, Type.EmptyTypes, throwExceptionIfNotFound)); }
public static bool TryGetMethod(this IHasMethods hasMethods, string methodName, string[] methodParameterTypeFullNames, out ICommonMethod foundCommonMethod) { return((foundCommonMethod = hasMethods.GetMethod(methodName, methodParameterTypeFullNames)) != null); }
public static bool TryGetMethod(this IHasMethods hasMethods, string methodName, out ICommonMethod foundCommonMethod) { return((foundCommonMethod = hasMethods.GetMethod(methodName)) != null); }
public static IEnumerable <SyntaxNode> GetMethNodes(this SyntaxGenerator gen, IHasMethods holder) => holder.Methods.OfType <IHasSyntaxNodes>().SelectMany(n => n.GetNodes(gen));