string GetMethodWarning(TypeNode notifyNode, OnChangedMethod onChangedMethod) { var method = onChangedMethod.MethodDefinition; var methodRef = onChangedMethod.MethodReference; var propertyName = method.Name.Substring("On".Length, method.Name.Length - "On".Length - "Changed".Length); var baseMessage = $"Type {method.DeclaringType.FullName} contains a method {method.Name} which will not be called"; var foundProperty = GetProperty(methodRef, propertyName); if (foundProperty == null) { return($"{baseMessage} as {propertyName} is not found."); } if (foundProperty.DeclaringType != method.DeclaringType) { return($"{baseMessage} as {propertyName} is declared on base class {foundProperty.DeclaringType.Name}."); } if (foundProperty.CustomAttributes.ContainsAttribute("PropertyChanged.DoNotNotifyAttribute")) { return($"{baseMessage} as {propertyName} is attributed with [DoNotNotify]."); } if (foundProperty.CustomAttributes.ContainsAttribute("PropertyChanged.OnChangedMethodAttribute")) { return($"{baseMessage} as {propertyName} is attributed with an alternative [OnChangedMethod]."); } return($"{baseMessage}."); }
OnChangedMethod FindOnChangedMethod(TypeNode notifyNode, string methodName) { OnChangedMethod foundMethod = null; foreach (var methodDefinition in notifyNode.TypeDefinition.Methods) { if (methodDefinition.Name != methodName) { continue; } var method = CreateOnChangedMethod(notifyNode, methodDefinition, false); if (method == null) { continue; } if (foundMethod != null) { throw new WeavingException($"The type {notifyNode.TypeDefinition.FullName} has multiple valid overloads of a On_PropertyName_Changed method named {methodName})."); } foundMethod = method; } if (foundMethod == null) { throw new WeavingException($"The type {notifyNode.TypeDefinition.FullName} does not have a valid On_PropertyName_Changed method named {methodName})."); } return(foundMethod); }
void ValidateOnChangedMethod(TypeNode notifyNode, OnChangedMethod onChangedMethod) { var method = onChangedMethod.MethodDefinition; if (method.IsVirtual && !method.IsNewSlot) { return; } if (!onChangedMethod.IsDefaultMethod) { return; } bool PropertyWillBeNotified(PropertyDefinition p) { return(notifyNode.PropertyDatas .Any(pd => pd.PropertyDefinition == p || pd.AlsoNotifyFor.Contains(p))); } if (onChangedMethod.Properties.Any(PropertyWillBeNotified)) { return; } if (!SuppressOnPropertyNameChangedWarning) { EmitConditionalWarning(method, GetMethodWarning(notifyNode, onChangedMethod)); } }