diff --git a/WpfAnalyzers.Test/WPF0042AvoidSideEffectsInClrAccessorsTests/Valid.cs b/WpfAnalyzers.Test/WPF0042AvoidSideEffectsInClrAccessorsTests/Valid.cs index ffba000f..6c6e004c 100644 --- a/WpfAnalyzers.Test/WPF0042AvoidSideEffectsInClrAccessorsTests/Valid.cs +++ b/WpfAnalyzers.Test/WPF0042AvoidSideEffectsInClrAccessorsTests/Valid.cs @@ -359,6 +359,51 @@ public static void SetText(DependencyObject element, string? value) RoslynAssert.Valid(Analyzer, code); } + + [Test] + public static void AttachedPropertyWithNewNullChecks() + { + var code = @" +namespace N +{ + using System; + using System.Windows; + + public static class WithNullChecks + { + public static readonly DependencyProperty TextProperty = DependencyProperty.RegisterAttached( + ""Text"", + typeof(string), + typeof(WithNullChecks), + new PropertyMetadata(default(string))); + + /// Helper for setting on . + /// to set on. + /// Text property value. + public static void SetText(DependencyObject element, string? value) + { + ArgumentNullException.ThrowIfNull(element); + + element.SetValue(TextProperty, value); + } + + /// Helper for getting from . + /// to read from. + /// Text property value. + [AttachedPropertyBrowsableForType(typeof(DependencyObject))] + public static string? GetText(DependencyObject element) + { + ArgumentNullException.ThrowIfNull(element); + + return (string?)element.GetValue(TextProperty); + } + } +}"; + + RoslynAssert.Valid(Analyzer, code); + } + + [Test] public static void AttachedPropertyWithEmptyIfs() { diff --git a/WpfAnalyzers/Analyzers/ClrMethodDeclarationAnalyzer.cs b/WpfAnalyzers/Analyzers/ClrMethodDeclarationAnalyzer.cs index 7768bcf7..7d9b861d 100644 --- a/WpfAnalyzers/Analyzers/ClrMethodDeclarationAnalyzer.cs +++ b/WpfAnalyzers/Analyzers/ClrMethodDeclarationAnalyzer.cs @@ -240,6 +240,13 @@ private static bool TryGetSideEffect(BlockSyntax body, InvocationExpressionSynta { switch (statement) { + case ExpressionStatementSyntax { Expression: { } expression } + when NullCheck.IsNullCheck(expression, null, CancellationToken.None, out _): + continue; + case ExpressionStatementSyntax { Expression: InvocationExpressionSyntax { Expression: MemberAccessExpressionSyntax { Expression: IdentifierNameSyntax { } name } expression } } + when name.ToString() == nameof(System.ArgumentNullException) && + expression.Name.ToString() == "ThrowIfNull": + continue; case ExpressionStatementSyntax { Expression: { } expression } when expression == getOrSet: continue;