internal static bool TryFind(ITypeSymbol type, SemanticModel semanticModel, CancellationToken cancellationToken, [NotNullWhen(true)] out IMethodSymbol?invoker) { if (PropertyChangedEvent.TryFind(type, out var propertyChangedEvent)) { return(TryFind(propertyChangedEvent, semanticModel, cancellationToken, out invoker)); } invoker = null; return(false); }
private static void Handle(SyntaxNodeAnalysisContext context) { if (!context.IsExcludedFromAnalysis() && context.ContainingSymbol is INamedTypeSymbol { IsStatic : false } type&& context.Node is ClassDeclarationSyntax classDeclaration && !IsExcludedType()) { if (classDeclaration.Members.TryFirstOfType(x => Property.ShouldNotify(x, context.SemanticModel, context.CancellationToken), out PropertyDeclarationSyntax _)) { var properties = string.Join( Environment.NewLine, classDeclaration.Members.OfType <PropertyDeclarationSyntax>() .Where(x => Property.ShouldNotify(x, context.SemanticModel, context.CancellationToken)) .Select(x => x.Identifier.ValueText)); context.ReportDiagnostic(Diagnostic.Create(Descriptors.INPC001ImplementINotifyPropertyChanged, classDeclaration.Identifier.GetLocation(), $"The class {type.Name} should notify for:{Environment.NewLine}{properties}")); } if (PropertyChangedEvent.TryFind(type, out var eventSymbol)) { if (eventSymbol.IsStatic) { return; } context.ReportDiagnostic(Diagnostic.Create(Descriptors.INPC001ImplementINotifyPropertyChanged, classDeclaration.Identifier.GetLocation(), $"The class {type.Name} has event PropertyChanged but does not implement INotifyPropertyChanged.")); } } bool IsExcludedType() { return(type.IsAssignableTo(KnownSymbol.INotifyPropertyChanged, context.Compilation) || type.IsAssignableTo(KnownSymbol.Attribute, context.Compilation) || type.IsAssignableTo(KnownSymbol.IEnumerator, context.Compilation) || type.IsAssignableTo(KnownSymbol.Stream, context.Compilation) || type.IsAssignableTo(KnownSymbol.MarkupExtension, context.Compilation) || type.IsAssignableTo(KnownSymbol.IValueConverter, context.Compilation) || type.IsAssignableTo(KnownSymbol.IMultiValueConverter, context.Compilation) || type.IsAssignableTo(KnownSymbol.DataTemplateSelector, context.Compilation) || type.IsAssignableTo(KnownSymbol.DependencyObject, context.Compilation)); } }