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)); } }
private static void Handle(SyntaxNodeAnalysisContext context) { if (!context.IsExcludedFromAnalysis() && context.Node is ArgumentSyntax { Parent : ArgumentListSyntax argumentList } argument) { if (argument.TryGetStringValue(context.SemanticModel, context.CancellationToken, out var text)) { if (text == ContainingSymbolName(context.ContainingSymbol) && context.SemanticModel.GetSymbolSafe(argumentList.Parent, context.CancellationToken) is IMethodSymbol method && method.TryFindParameter(argument, out var parameter)) { if (parameter.IsCallerMemberName()) { context.ReportDiagnostic(Diagnostic.Create(Descriptors.INPC004UseCallerMemberName, argument.GetLocation())); } else if (parameter.TrySingleDeclaration <SyntaxNode>(context.CancellationToken, out _) && OnPropertyChanged.IsMatch(method, context.SemanticModel, context.CancellationToken) == AnalysisResult.Yes) { context.ReportDiagnostic(Diagnostic.Create(Descriptors.INPC004UseCallerMemberName, argument.GetLocation())); } } if (SyntaxFacts.IsValidIdentifier(text)) { if (argumentList.Parent is InvocationExpressionSyntax onPropertyChangedCandidate && OnPropertyChanged.IsMatch(onPropertyChangedCandidate, context.SemanticModel, context.CancellationToken) != AnalysisResult.No && !context.ContainingSymbol.ContainingType.TryFindPropertyRecursive(text, out _)) { context.ReportDiagnostic(Diagnostic.Create(Descriptors.INPC009DoNotRaiseChangeForMissingProperty, argument.GetLocation())); } if (argumentList.Parent is ObjectCreationExpressionSyntax { Parent : ArgumentSyntax parentArg } objectCreation&& parentArg.FirstAncestor <InvocationExpressionSyntax>() is { } parentInvocation&& context.SemanticModel.TryGetSymbol(objectCreation, KnownSymbol.PropertyChangedEventArgs, context.CancellationToken, out _)) { if ((OnPropertyChanged.IsMatch(parentInvocation, context.SemanticModel, context.CancellationToken) != AnalysisResult.No || PropertyChangedEvent.IsInvoke(parentInvocation, context.SemanticModel, context.CancellationToken)) && !context.ContainingSymbol.ContainingType.TryFindPropertyRecursive(text, out _)) { context.ReportDiagnostic(Diagnostic.Create(Descriptors.INPC009DoNotRaiseChangeForMissingProperty, argument.GetLocation())); } } if (argument.Expression is LiteralExpressionSyntax literal && literal.IsKind(SyntaxKind.StringLiteralExpression)) { if (context.ContainingSymbol is IMethodSymbol containingMethod && containingMethod.Parameters.TrySingle(x => x.Name == literal.Token.ValueText, out _)) { context.ReportDiagnostic(Diagnostic.Create(Descriptors.INPC013UseNameof, argument.GetLocation())); } if (context.ContainingSymbol.ContainingType.TryFindPropertyRecursive(literal.Token.ValueText, out _)) { context.ReportDiagnostic(Diagnostic.Create(Descriptors.INPC013UseNameof, argument.GetLocation())); } } } } if (argument is { Expression : AnonymousFunctionExpressionSyntax lambda } &&