diff --git a/src/ErrorProne.NET.CoreAnalyzers.Tests/AsyncAnalyzers/NullConditionalOperatorAnalyzerTests.cs b/src/ErrorProne.NET.CoreAnalyzers.Tests/AsyncAnalyzers/NullConditionalOperatorAnalyzerTests.cs
index ab57af8..a4caa51 100644
--- a/src/ErrorProne.NET.CoreAnalyzers.Tests/AsyncAnalyzers/NullConditionalOperatorAnalyzerTests.cs
+++ b/src/ErrorProne.NET.CoreAnalyzers.Tests/AsyncAnalyzers/NullConditionalOperatorAnalyzerTests.cs
@@ -23,5 +23,22 @@ public async System.Threading.Tasks.Task Foo(MyClass m)
";
await VerifyCS.VerifyAsync(code);
}
- }
+
+ [Test]
+ public async Task No_Warn_When_Nullability_Is_Enabled()
+ {
+ // In this case the compiler will emit a warning.
+ string code = @"
+#nullable enable
+public class MyClass
+{
+ public async System.Threading.Tasks.Task Foo(MyClass? m)
+ {
+ await m?.Foo(null);
+ }
+}
+";
+ await VerifyCS.VerifyAsync(code);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/ErrorProne.NET.CoreAnalyzers/AsyncAnalyzers/NullConditionalOperatorAnalyzer.cs b/src/ErrorProne.NET.CoreAnalyzers/AsyncAnalyzers/NullConditionalOperatorAnalyzer.cs
index e4c23ec..ba88146 100644
--- a/src/ErrorProne.NET.CoreAnalyzers/AsyncAnalyzers/NullConditionalOperatorAnalyzer.cs
+++ b/src/ErrorProne.NET.CoreAnalyzers/AsyncAnalyzers/NullConditionalOperatorAnalyzer.cs
@@ -3,6 +3,7 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.CodeAnalysis.Operations;
namespace ErrorProne.NET.AsyncAnalyzers
{
@@ -24,7 +25,26 @@ public NullConditionalOperatorAnalyzer()
///
protected override void InitializeCore(AnalysisContext context)
{
- context.RegisterSyntaxNodeAction(AnalyzeAwaitExpression, SyntaxKind.AwaitExpression);
+ context.RegisterOperationAction(AnalyzeAwaitOperation, OperationKind.Await);
+ //context.RegisterSyntaxNodeAction(AnalyzeAwaitExpression, SyntaxKind.AwaitExpression);
+ }
+
+ private void AnalyzeAwaitOperation(OperationAnalysisContext context)
+ {
+ var operation = (IAwaitOperation) context.Operation;
+ // Check if the awaited operation is a conditional access operation
+ if (operation.Operation is IConditionalAccessOperation)
+ {
+ if (operation.Operation.Type?.NullableAnnotation == NullableAnnotation.Annotated)
+ {
+ // If the type is annotated, we don't report diagnostics.
+ return;
+ }
+
+ var location = operation.Syntax.GetLocation();
+ var diagnostic = Diagnostic.Create(Rule, location);
+ context.ReportDiagnostic(diagnostic);
+ }
}
private void AnalyzeAwaitExpression(SyntaxNodeAnalysisContext context)
diff --git a/src/ErrorProne.NET.CoreAnalyzers/DiagnosticDescriptors.cs b/src/ErrorProne.NET.CoreAnalyzers/DiagnosticDescriptors.cs
index b243ccc..a72879b 100644
--- a/src/ErrorProne.NET.CoreAnalyzers/DiagnosticDescriptors.cs
+++ b/src/ErrorProne.NET.CoreAnalyzers/DiagnosticDescriptors.cs
@@ -303,7 +303,7 @@ internal static class DiagnosticDescriptors
///
public static readonly DiagnosticDescriptor EPC37 = new DiagnosticDescriptor(
nameof(EPC37),
- title: "Do not validate arguments in async methods",
+ title: "Do not validate arguments in async methods eagerly",
messageFormat: "Argument validation in async method '{0}' will not fail eagerly. Consider using a wrapper method or Task.FromException.",
category: AsyncCategory,
// Info by default, since it might generate quite a bit of warnings for a codebase.