MethodDefinition FindEventInvokerMethodDefinition(TypeDefinition type) { var methodDefinition = type.Methods .Where(x => (x.IsFamily || x.IsFamilyAndAssembly || x.IsPublic || x.IsFamilyOrAssembly) && EventInvokerNames.Contains(x.Name)) .OrderByDescending(GetInvokerPriority) .FirstOrDefault(IsEventInvokerMethod); if (methodDefinition != null) { return(methodDefinition); } methodDefinition = type.Methods .Where(x => EventInvokerNames.Contains(x.Name)) .OrderByDescending(GetInvokerPriority) .FirstOrDefault(IsEventInvokerMethod); if (methodDefinition != null && methodDefinition.IsPrivate && methodDefinition.IsFinal && methodDefinition.IsVirtual && methodDefinition.Overrides.Count == 1) { // Explicitly implemented interfaces should call the interface method instead return(methodDefinition.Overrides[0].Resolve()); } return(methodDefinition); }
MethodReference FindExplicitImplementation(TypeDefinition type) { return(type.GetAllInterfaces() .Select(i => i.Resolve()) .Where(i => i != null && i.IsPublic) .SelectMany(i => i.Methods.Where(m => EventInvokerNames.Contains($"{i.FullName}.{m.Name}"))) .OrderByDescending(GetInvokerPriority) .FirstOrDefault(IsEventInvokerMethod)); }
OnChangedMethod CreateOnChangedMethod(TypeNode notifyNode, MethodDefinition methodDefinition, bool isDefaultMethod) { if (methodDefinition.IsStatic) { if (!SuppressOnPropertyNameChangedWarning) { EmitConditionalWarning(methodDefinition, $"The type {notifyNode.TypeDefinition.FullName} has a On_PropertyName_Changed method ({methodDefinition.Name}) which is static."); } return(null); } if (methodDefinition.ReturnType.FullName != "System.Void") { if (!SuppressOnPropertyNameChangedWarning) { EmitConditionalWarning(methodDefinition, $"The type {notifyNode.TypeDefinition.FullName} has a On_PropertyName_Changed method ({methodDefinition.Name}) that has a non void return value. Ensure the return type void."); } return(null); } var typeDefinitions = new Stack <TypeDefinition>(); typeDefinitions.Push(notifyNode.TypeDefinition); var onChangedType = OnChangedTypes.None; if (IsNoArgOnChangedMethod(methodDefinition)) { onChangedType = OnChangedTypes.NoArg; } else if (IsBeforeAfterOnChangedMethod(methodDefinition)) { onChangedType = OnChangedTypes.BeforeAfter; } if (onChangedType != OnChangedTypes.None) { ValidateOnChangedMethod(notifyNode, methodDefinition, isDefaultMethod); return(new OnChangedMethod { OnChangedType = onChangedType, MethodReference = GetMethodReference(typeDefinitions, methodDefinition), IsDefaultMethod = isDefaultMethod }); } if (!EventInvokerNames.Contains(methodDefinition.Name) && !SuppressOnPropertyNameChangedWarning) { EmitConditionalWarning(methodDefinition, $"Unsupported signature for a On_PropertyName_Changed method: {methodDefinition.Name} in {methodDefinition.DeclaringType.FullName}"); } return(null); }
IEnumerable <OnChangedMethod> GetOnChangedMethods(TypeNode notifyNode) { var methods = notifyNode.TypeDefinition.Methods; var onChangedMethods = methods.Where(x => x.Name.StartsWith("On") && x.Name.EndsWith("Changed") && x.Name != "OnChanged"); foreach (var methodDefinition in onChangedMethods) { if (methodDefinition.IsStatic) { var message = $"The type {notifyNode.TypeDefinition.FullName} has a On_PropertyName_Changed method ({methodDefinition.Name}) which is static."; throw new WeavingException(message); } if (methodDefinition.ReturnType.FullName != "System.Void") { var message = $"The type {notifyNode.TypeDefinition.FullName} has a On_PropertyName_Changed method ({methodDefinition.Name}) that has a non void return value. Ensure the return type void."; throw new WeavingException(message); } var typeDefinitions = new Stack <TypeDefinition>(); typeDefinitions.Push(notifyNode.TypeDefinition); if (IsNoArgOnChangedMethod(methodDefinition)) { ValidateOnChangedMethod(notifyNode, methodDefinition); yield return(new OnChangedMethod { OnChangedType = OnChangedTypes.NoArg, MethodReference = GetMethodReference(typeDefinitions, methodDefinition) }); } else if (IsBeforeAfterOnChangedMethod(methodDefinition)) { ValidateOnChangedMethod(notifyNode, methodDefinition); yield return(new OnChangedMethod { OnChangedType = OnChangedTypes.BeforeAfter, MethodReference = GetMethodReference(typeDefinitions, methodDefinition) }); } else if (!EventInvokerNames.Contains(methodDefinition.Name)) { EmitConditionalWarning(methodDefinition, $"Unsupported signature for a On_PropertyName_Changed method: {methodDefinition.Name} in {methodDefinition.DeclaringType.FullName}"); } } }
bool FindEventInvokerMethodDefinition(TypeDefinition type, out MethodDefinition methodDefinition) { methodDefinition = type.Methods .Where(x => (x.IsFamily || x.IsFamilyAndAssembly || x.IsPublic || x.IsFamilyOrAssembly) && EventInvokerNames.Contains(x.Name)) .OrderByDescending(definition => definition.Parameters.Count) .FirstOrDefault(x => IsBeforeAfterGenericMethod(x) || IsBeforeAfterMethod(x) || IsSingleStringMethod(x) || IsPropertyChangedArgMethod(x) || IsSenderPropertyChangedArgMethod(x)); if (methodDefinition == null) { methodDefinition = type.Methods .Where(x => EventInvokerNames.Contains(x.Name)) .OrderByDescending(definition => definition.Parameters.Count) .FirstOrDefault(x => IsBeforeAfterGenericMethod(x) || IsBeforeAfterMethod(x) || IsSingleStringMethod(x) || IsPropertyChangedArgMethod(x) || IsSenderPropertyChangedArgMethod(x)); } return(methodDefinition != null); }
bool FindEventInvokerMethodDefinition(TypeDefinition type, out MethodDefinition methodDefinition) { methodDefinition = type.Methods .Where(x => (x.IsFamily || x.IsFamilyAndAssembly || x.IsPublic || x.IsFamilyOrAssembly) && EventInvokerNames.Contains(x.Name)) .OrderByDescending(definition => definition.Parameters.Count) .FirstOrDefault(x => IsBeforeAfterMethod(x) || IsSingleStringMethod(x) || IsPropertyChangedArgMethod(x)); if (methodDefinition == null) { //TODO: when injecting calls to this method should check visibility methodDefinition = type.Methods .Where(x => EventInvokerNames.Contains(x.Name)) .OrderByDescending(definition => definition.Parameters.Count) .FirstOrDefault(x => IsBeforeAfterMethod(x) || IsSingleStringMethod(x) || IsPropertyChangedArgMethod(x)); } return(methodDefinition != null); }
MethodDefinition FindEventInvokerMethodDefinition(TypeDefinition type) { var methodDefinition = type.Methods .Where(x => (x.IsFamily || x.IsFamilyAndAssembly || x.IsPublic || x.IsFamilyOrAssembly) && EventInvokerNames.Contains(x.Name)) .OrderByDescending(GetInvokerPriority) .FirstOrDefault(IsEventInvokerMethod); if (methodDefinition == null) { methodDefinition = type.Methods .Where(x => EventInvokerNames.Contains(x.Name)) .OrderByDescending(GetInvokerPriority) .FirstOrDefault(IsEventInvokerMethod); } return(methodDefinition); }