diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/StreamReadStatement.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/StreamReadStatement.cs index 3f776fc7238..c44a0c1d9f9 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/StreamReadStatement.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/StreamReadStatement.cs @@ -20,45 +20,45 @@ using System.IO; -namespace SonarAnalyzer.Rules.CSharp +namespace SonarAnalyzer.Rules.CSharp; + +[DiagnosticAnalyzer(LanguageNames.CSharp)] +public sealed class StreamReadStatement : SonarDiagnosticAnalyzer { - [DiagnosticAnalyzer(LanguageNames.CSharp)] - public sealed class StreamReadStatement : SonarDiagnosticAnalyzer - { - private const string DiagnosticId = "S2674"; - private const string MessageFormat = "Check the return value of the '{0}' call to see how many bytes were read."; + private const string DiagnosticId = "S2674"; + private const string MessageFormat = "Check the return value of the '{0}' call to see how many bytes were read."; - private static readonly DiagnosticDescriptor Rule = DescriptorFactory.Create(DiagnosticId, MessageFormat); - private static readonly ISet ReadMethodNames = new HashSet - { - nameof(Stream.Read), - nameof(Stream.ReadAsync), - "ReadAtLeast", // Net7: https://learn.microsoft.com/dotnet/api/system.io.stream.readatleast#applies-to - "ReadAtLeastAsync", - }; + private static readonly DiagnosticDescriptor Rule = DescriptorFactory.Create(DiagnosticId, MessageFormat); - public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(Rule); + private static readonly ISet ReadMethodNames = new HashSet(StringComparer.Ordinal) + { + nameof(Stream.Read), + nameof(Stream.ReadAsync), + "ReadAtLeast", // Net7: https://learn.microsoft.com/dotnet/api/system.io.stream.readatleast#applies-to + "ReadAtLeastAsync", + }; - protected override void Initialize(SonarAnalysisContext context) => - context.RegisterNodeAction(c => + public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(Rule); + + protected override void Initialize(SonarAnalysisContext context) => + context.RegisterNodeAction(c => + { + var statement = (ExpressionStatementSyntax)c.Node; + var expression = statement.Expression switch + { + AwaitExpressionSyntax awaitExpression => awaitExpression.AwaitedExpressionWithoutConfigureAwait(), + var x => x, + }; + expression = expression.RemoveConditionalAccess(); + if (expression is InvocationExpressionSyntax invocation + && invocation.GetMethodCallIdentifier() is { } methodIdentifier + && ReadMethodNames.Contains(methodIdentifier.Text) + && c.SemanticModel.GetSymbolInfo(expression).Symbol is IMethodSymbol method + && (method.ContainingType.Is(KnownType.System_IO_Stream) + || (method.IsOverride && method.ContainingType.DerivesOrImplements(KnownType.System_IO_Stream)))) { - var statement = (ExpressionStatementSyntax)c.Node; - var expression = statement.Expression switch - { - AwaitExpressionSyntax awaitExpression => awaitExpression.AwaitedExpressionWithoutConfigureAwait(), - var x => x, - }; - expression = expression.RemoveConditionalAccess(); - if (expression is InvocationExpressionSyntax invocation - && invocation.GetMethodCallIdentifier() is { } methodIdentifier - && ReadMethodNames.Contains(methodIdentifier.Text, StringComparer.Ordinal) - && c.SemanticModel.GetSymbolInfo(expression).Symbol is IMethodSymbol method - && (method.ContainingType.Is(KnownType.System_IO_Stream) - || (method.IsOverride && method.ContainingType.DerivesOrImplements(KnownType.System_IO_Stream)))) - { - c.ReportIssue(Rule, expression, method.Name); - } - }, - SyntaxKind.ExpressionStatement); - } + c.ReportIssue(Rule, expression, method.Name); + } + }, + SyntaxKind.ExpressionStatement); }