コード例 #1
0
 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);
         }
     }
 }
コード例 #2
0
        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");
        }
コード例 #5
0
 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());
 }
コード例 #6
0
        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");
        }
コード例 #7
0
 public static IEnumerable <ICommonMethod> GetMethods(this IHasMethods hasMethods, string methodName)
 {
     return(hasMethods.MethodNameToMethods.TryGetValue(methodName, out var commonMethods) ? commonMethods : Enumerable.Empty <ICommonMethod>());
 }
コード例 #8
0
 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));
 }
コード例 #9
0
 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));
 }
コード例 #10
0
 public static ICommonMethod GetMethod(this IHasMethods hasMethods, string methodName, bool throwExceptionIfNotFound = false)
 {
     return(hasMethods.GetMethod(methodName, Type.EmptyTypes, throwExceptionIfNotFound));
 }
コード例 #11
0
 public static bool TryGetMethod(this IHasMethods hasMethods, string methodName, string[] methodParameterTypeFullNames, out ICommonMethod foundCommonMethod)
 {
     return((foundCommonMethod = hasMethods.GetMethod(methodName, methodParameterTypeFullNames)) != null);
 }
コード例 #12
0
 public static bool TryGetMethod(this IHasMethods hasMethods, string methodName, out ICommonMethod foundCommonMethod)
 {
     return((foundCommonMethod = hasMethods.GetMethod(methodName)) != null);
 }
コード例 #13
0
 public static IEnumerable <SyntaxNode> GetMethNodes(this SyntaxGenerator gen, IHasMethods holder)
 => holder.Methods.OfType <IHasSyntaxNodes>().SelectMany(n => n.GetNodes(gen));