From fad8aefa7c9d971d14f927cdf67c8b3400c6eb05 Mon Sep 17 00:00:00 2001 From: Pavel Mikula Date: Wed, 29 May 2024 16:02:21 +0200 Subject: [PATCH] ReportIssue: Remove obsolete overloads from SonarAnalysisContextExtensions --- .../SonarAnalysisContextExtensions.cs | 34 ++----- .../Rules/AspNet/UseAspNetModelBinding.cs | 2 +- ...lyWithNeutralResourcesLanguageAttribute.cs | 2 +- .../Rules/UninvokedEventDeclaration.cs | 9 +- .../Rules/UnusedPrivateMember.cs | 92 +++++++++---------- .../SonarAnalysisContextExtensions.cs | 9 +- .../Rules/OptionExplicitOn.cs | 2 +- .../Rules/OptionStrictOn.cs | 2 +- 8 files changed, 60 insertions(+), 92 deletions(-) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Extensions/SonarAnalysisContextExtensions.cs b/analyzers/src/SonarAnalyzer.CSharp/Extensions/SonarAnalysisContextExtensions.cs index a2636368584..227d37369ed 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Extensions/SonarAnalysisContextExtensions.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Extensions/SonarAnalysisContextExtensions.cs @@ -46,37 +46,19 @@ public static void RegisterSemanticModelAction(this SonarAnalysisContext context public static void RegisterCodeBlockStartAction(this SonarAnalysisContext context, Action> action) => context.RegisterCodeBlockStartAction(CSharpGeneratedCodeRecognizer.Instance, action); - [Obsolete("Use another overload of ReportIssue, without calling Diagnostic.Create")] - public static void ReportIssue(this SonarCompilationReportingContext context, Diagnostic diagnostic) => - context.ReportIssue(CSharpGeneratedCodeRecognizer.Instance, diagnostic); - - public static void ReportIssue(this SonarCompilationReportingContext context, - DiagnosticDescriptor rule, - Location primaryLocation, - IEnumerable secondaryLocations, - params string[] messageArgs) => - context.ReportIssue(CSharpGeneratedCodeRecognizer.Instance, rule, primaryLocation, secondaryLocations, messageArgs); - - public static void ReportIssue(this SonarCompilationReportingContext context, DiagnosticDescriptor rule, Location location, params string[] messageArgs) => - context.ReportIssue(CSharpGeneratedCodeRecognizer.Instance, rule, location, messageArgs); - - [Obsolete("Use another overload of ReportIssue, without calling Diagnostic.Create")] - public static void ReportIssue(this SonarSymbolReportingContext context, Diagnostic diagnostic) => - context.ReportIssue(CSharpGeneratedCodeRecognizer.Instance, diagnostic); - - public static void ReportIssue(this SonarSymbolReportingContext context, DiagnosticDescriptor rule, SyntaxNode locationSyntax, params string[] messageArgs) => + public static void ReportIssue(this SonarCompilationReportingContextBase context, DiagnosticDescriptor rule, SyntaxNode locationSyntax, params string[] messageArgs) => context.ReportIssue(CSharpGeneratedCodeRecognizer.Instance, rule, locationSyntax, messageArgs); - public static void ReportIssue(this SonarSymbolReportingContext context, DiagnosticDescriptor rule, SyntaxToken locationToken, params string[] messageArgs) => + public static void ReportIssue(this SonarCompilationReportingContextBase context, DiagnosticDescriptor rule, SyntaxToken locationToken, params string[] messageArgs) => context.ReportIssue(CSharpGeneratedCodeRecognizer.Instance, rule, locationToken, messageArgs); - public static void ReportIssue(this SonarSymbolReportingContext context, DiagnosticDescriptor rule, Location location, params string[] messageArgs) => + public static void ReportIssue(this SonarCompilationReportingContextBase context, DiagnosticDescriptor rule, Location location, params string[] messageArgs) => context.ReportIssue(CSharpGeneratedCodeRecognizer.Instance, rule, location, messageArgs); - public static void ReportIssue(this SonarSymbolReportingContext context, - DiagnosticDescriptor rule, - Location primaryLocation, - IEnumerable secondaryLocations, - params string[] messageArgs) => + public static void ReportIssue(this SonarCompilationReportingContextBase context, + DiagnosticDescriptor rule, + Location primaryLocation, + IEnumerable secondaryLocations, + params string[] messageArgs) => context.ReportIssue(CSharpGeneratedCodeRecognizer.Instance, rule, primaryLocation, secondaryLocations, messageArgs); } diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/AspNet/UseAspNetModelBinding.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/AspNet/UseAspNetModelBinding.cs index f03540a0fa0..11e94182093 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/AspNet/UseAspNetModelBinding.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/AspNet/UseAspNetModelBinding.cs @@ -77,7 +77,7 @@ private void RegisterForSymbols(SonarCompilationStartAnalysisContext compilation { foreach (var candidate in candidates.Where(x => !(hasActionFiltersOverrides && x.OriginatesFromParameter))) { - symbolEnd.ReportIssue(Diagnostic.Create(Rule, candidate.Location, candidate.Message)); + symbolEnd.ReportIssue(Rule, candidate.Location, candidate.Message); } }); }, SymbolKind.NamedType); diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/MarkAssemblyWithNeutralResourcesLanguageAttribute.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/MarkAssemblyWithNeutralResourcesLanguageAttribute.cs index 7f05482929e..bc2b216d34b 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/MarkAssemblyWithNeutralResourcesLanguageAttribute.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/MarkAssemblyWithNeutralResourcesLanguageAttribute.cs @@ -42,7 +42,7 @@ protected override void Initialize(SonarAnalysisContext context) => { if (hasResx && !HasNeutralResourcesLanguageAttribute(cc.Compilation.Assembly)) { - cc.ReportIssue(Rule, null, cc.Compilation.AssemblyName); + cc.ReportIssue(Rule, (Location)null, cc.Compilation.AssemblyName); } }); }); diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/UninvokedEventDeclaration.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/UninvokedEventDeclaration.cs index 56f627034ea..275c9ee7b41 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/UninvokedEventDeclaration.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/UninvokedEventDeclaration.cs @@ -60,11 +60,10 @@ private void RaiseOnUninvokedEventDeclaration(SonarSymbolReportingContext contex var usedSymbols = GetInvokedEventSymbols(removableDeclarationCollector) .Concat(GetPossiblyCopiedSymbols(removableDeclarationCollector)) .ToHashSet(); - - removableEventFields - .Where(x => !usedSymbols.Contains(x.Symbol)) - .ToList() - .ForEach(x => context.ReportIssue(Diagnostic.Create(Rule, GetLocation(x.Node), x.Symbol.Name))); + foreach (var field in removableEventFields.Where(x => !usedSymbols.Contains(x.Symbol))) + { + context.ReportIssue(Rule, GetLocation(field.Node), field.Symbol.Name); + } Location GetLocation(SyntaxNode node) => node is VariableDeclaratorSyntax variableDeclarator diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs index f6964883606..9c8617113b3 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/UnusedPrivateMember.cs @@ -70,10 +70,7 @@ protected override void Initialize(SonarAnalysisContext context) => { usageCollector.SafeVisit(syntaxTree.GetRoot()); } - foreach (var diagnostic in DiagnosticsForUnusedPrivateMembers(usageCollector, removableInternalTypes, SyntaxConstants.Internal, new())) - { - cc.ReportIssue(diagnostic); - } + ReportUnusedPrivateMembers(cc, usageCollector, removableInternalTypes, SyntaxConstants.Internal, new()); }); }); @@ -87,14 +84,8 @@ private static void NamedSymbolAction(SonarSymbolReportingContext context, HashS && new CSharpSymbolUsageCollector(context.Compilation, AssociatedSymbols(privateSymbols)) is var usageCollector && VisitDeclaringReferences(namedType, usageCollector, context, includeGeneratedFile: true)) { - foreach (var diagnostic in DiagnosticsForUnusedPrivateMembers(usageCollector, privateSymbols, SyntaxConstants.Private, fieldLikeSymbols)) - { - context.ReportIssue(diagnostic); - } - foreach (var diagnostic in DiagnosticsForUsedButUnreadFields(usageCollector, privateSymbols)) - { - context.ReportIssue(diagnostic); - } + ReportUnusedPrivateMembers(context, usageCollector, privateSymbols, SyntaxConstants.Private, fieldLikeSymbols); + ReportUsedButUnreadFields(context, usageCollector, privateSymbols); } } @@ -140,10 +131,11 @@ static IEnumerable PrivateNestedMembersFromNonGenerat .SelectMany(x => x.GetSyntax().ChildNodes().OfType()); } - private static IEnumerable DiagnosticsForUnusedPrivateMembers(CSharpSymbolUsageCollector usageCollector, - ISet removableSymbols, - string accessibility, - BidirectionalDictionary fieldLikeSymbols) + private static void ReportUnusedPrivateMembers(SonarCompilationReportingContextBase context, + CSharpSymbolUsageCollector usageCollector, + ISet removableSymbols, + string accessibility, + BidirectionalDictionary fieldLikeSymbols) { var unusedSymbols = GetUnusedSymbols(usageCollector, removableSymbols); @@ -151,17 +143,18 @@ private static IEnumerable DiagnosticsForUnusedPrivateMembers(CSharp .Intersect(usageCollector.UsedSymbols) .OfType() .Where(usageCollector.PropertyAccess.ContainsKey) - .Where(x => !IsMentionedInDebuggerDisplay(x, usageCollector)) - .Select(x => GetDiagnosticsForProperty(x, usageCollector.PropertyAccess)) - .WhereNotNull(); - - return GetDiagnosticsForMembers(unusedSymbols, accessibility, fieldLikeSymbols).Concat(propertiesWithUnusedAccessor); + .Where(x => !IsMentionedInDebuggerDisplay(x, usageCollector)); + foreach (var property in propertiesWithUnusedAccessor) + { + ReportProperty(context, property, usageCollector.PropertyAccess); + } + ReportDiagnosticsForMembers(context, unusedSymbols, accessibility, fieldLikeSymbols); } private static bool IsMentionedInDebuggerDisplay(ISymbol symbol, CSharpSymbolUsageCollector usageCollector) => usageCollector.DebuggerDisplayValues.Any(x => x.Contains(symbol.Name)); - private static IEnumerable DiagnosticsForUsedButUnreadFields(CSharpSymbolUsageCollector usageCollector, IEnumerable removableSymbols) + private static void ReportUsedButUnreadFields(SonarSymbolReportingContext context, CSharpSymbolUsageCollector usageCollector, IEnumerable removableSymbols) { var unusedSymbols = GetUnusedSymbols(usageCollector, removableSymbols); @@ -171,7 +164,10 @@ private static IEnumerable DiagnosticsForUsedButUnreadFields(CSharpS .Where(x => !unusedSymbols.Contains(x.Symbol) && !IsMentionedInDebuggerDisplay(x.Symbol, usageCollector)) .Where(x => x.Declaration is not null && !x.Readings.Any()); - return GetDiagnosticsForUnreadFields(usedButUnreadFields); + foreach (var usage in usedButUnreadFields) + { + context.ReportIssue(RuleS4487, usage.Declaration.GetLocation(), GetFieldAccessibilityForMessage(usage.Symbol), usage.Symbol.Name); + } } private static HashSet GetUnusedSymbols(CSharpSymbolUsageCollector usageCollector, IEnumerable removableSymbols) => @@ -180,9 +176,6 @@ private static HashSet GetUnusedSymbols(CSharpSymbolUsageCollector usag .Where(x => !IsMentionedInDebuggerDisplay(x, usageCollector) && !IsAccessorUsed(x, usageCollector)) .ToHashSet(); - private static IEnumerable GetDiagnosticsForUnreadFields(IEnumerable unreadFields) => - unreadFields.Select(x => Diagnostic.Create(RuleS4487, x.Declaration.GetLocation(), GetFieldAccessibilityForMessage(x.Symbol), x.Symbol.Name)); - private static bool IsAccessorUsed(ISymbol symbol, CSharpSymbolUsageCollector usageCollector) => symbol is IMethodSymbol { } accessor && accessor.AssociatedSymbol is IPropertySymbol { } property @@ -193,11 +186,11 @@ symbol is IMethodSymbol { } accessor private static string GetFieldAccessibilityForMessage(ISymbol symbol) => symbol.DeclaredAccessibility == Accessibility.Private ? SyntaxConstants.Private : "private class"; - private static IEnumerable GetDiagnosticsForMembers(ICollection unusedSymbols, - string accessibility, - BidirectionalDictionary fieldLikeSymbols) + private static void ReportDiagnosticsForMembers(SonarCompilationReportingContextBase context, + ICollection unusedSymbols, + string accessibility, + BidirectionalDictionary fieldLikeSymbols) { - var diagnostics = new List(); var alreadyReportedFieldLikeSymbols = new HashSet(); var unusedSymbolSyntaxPairs = unusedSymbols.SelectMany(x => x.DeclaringSyntaxReferences.Select(syntax => new NodeAndSymbol(syntax.GetSyntax(), x))); @@ -221,11 +214,16 @@ private static IEnumerable GetDiagnosticsForMembers(ICollection GetSiblingDeclarators(SyntaxNode variableDeclarator) => variableDeclarator.Parent.Parent switch { @@ -234,38 +232,30 @@ static IEnumerable GetSiblingDeclarators(SyntaxNode va _ => Enumerable.Empty(), }; - Diagnostic CreateS1144Diagnostic(SyntaxNode syntaxNode, ISymbol symbol) => - symbol.IsConstructor() && !syntaxNode.GetModifiers().Any(SyntaxKind.PrivateKeyword) - ? Diagnostic.Create(RuleS1144ForPublicCtor, syntaxNode.GetLocation(), accessibility, symbol.ContainingType.Name) - : Diagnostic.Create(RuleS1144, GetIdentifierLocation(syntaxNode), accessibility, symbol.GetClassification(), GetMemberName(symbol)); - static Location GetIdentifierLocation(SyntaxNode syntaxNode) => syntaxNode.GetIdentifier() is { } identifier ? identifier.GetLocation() : syntaxNode.GetLocation(); } - private static Diagnostic GetDiagnosticsForProperty(IPropertySymbol property, IReadOnlyDictionary propertyAccessorAccess) + private static void ReportProperty(SonarCompilationReportingContextBase context, + IPropertySymbol property, + IReadOnlyDictionary propertyAccessorAccess) { var access = propertyAccessorAccess[property]; if (access == AccessorAccess.Get - && property.SetMethod is { } + && property.SetMethod is not null && GetAccessorSyntax(property.SetMethod) is { } setter) { - return Diagnostic.Create(RuleS1144, setter.Keyword.GetLocation(), SyntaxConstants.Private, "set accessor in property", property.Name); + context.ReportIssue(RuleS1144, setter.Keyword.GetLocation(), SyntaxConstants.Private, "set accessor in property", property.Name); } else if (access == AccessorAccess.Set - && property.GetMethod is { } - && GetAccessorSyntax(property.GetMethod) is { } getter - && getter.HasBodyOrExpressionBody()) + && property.GetMethod is not null + && GetAccessorSyntax(property.GetMethod) is { } getter + && getter.HasBodyOrExpressionBody()) { - return Diagnostic.Create(RuleS1144, getter.Keyword.GetLocation(), SyntaxConstants.Private, "get accessor in property", property.Name); + context.ReportIssue(RuleS1144, getter.Keyword.GetLocation(), SyntaxConstants.Private, "get accessor in property", property.Name); } - else - { - return null; - } - static AccessorDeclarationSyntax GetAccessorSyntax(ISymbol symbol) => symbol?.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax() as AccessorDeclarationSyntax; } @@ -534,7 +524,7 @@ private static bool IsRemovable(ISymbol symbol) => private static bool HasAttributes(ISymbol symbol) { IEnumerable attributes = symbol.GetAttributes(); - if (symbol is IMethodSymbol { MethodKind: MethodKind.PropertyGet or MethodKind.PropertySet} method + if (symbol is IMethodSymbol { MethodKind: MethodKind.PropertyGet or MethodKind.PropertySet } method && method.AssociatedSymbol is { } property) { attributes = attributes.Union(property.GetAttributes()); diff --git a/analyzers/src/SonarAnalyzer.VisualBasic/Extensions/SonarAnalysisContextExtensions.cs b/analyzers/src/SonarAnalyzer.VisualBasic/Extensions/SonarAnalysisContextExtensions.cs index a5a5b74f341..4894334f048 100644 --- a/analyzers/src/SonarAnalyzer.VisualBasic/Extensions/SonarAnalysisContextExtensions.cs +++ b/analyzers/src/SonarAnalyzer.VisualBasic/Extensions/SonarAnalysisContextExtensions.cs @@ -46,15 +46,12 @@ public static void RegisterSemanticModelAction(this SonarParametrizedAnalysisCon public static void RegisterCodeBlockStartAction(this SonarAnalysisContext context, Action> action) => context.RegisterCodeBlockStartAction(VisualBasicGeneratedCodeRecognizer.Instance, action); - public static void ReportIssue(this SonarCompilationReportingContext context, DiagnosticDescriptor rule, Location location, params string[] messageArgs) => - context.ReportIssue(VisualBasicGeneratedCodeRecognizer.Instance, rule, location, messageArgs); - - public static void ReportIssue(this SonarSymbolReportingContext context, DiagnosticDescriptor rule, SyntaxNode locationSyntax, params string[] messageArgs) => + public static void ReportIssue(this SonarCompilationReportingContextBase context, DiagnosticDescriptor rule, SyntaxNode locationSyntax, params string[] messageArgs) => context.ReportIssue(VisualBasicGeneratedCodeRecognizer.Instance, rule, locationSyntax, messageArgs); - public static void ReportIssue(this SonarSymbolReportingContext context, DiagnosticDescriptor rule, SyntaxToken locationToken, params string[] messageArgs) => + public static void ReportIssue(this SonarCompilationReportingContextBase context, DiagnosticDescriptor rule, SyntaxToken locationToken, params string[] messageArgs) => context.ReportIssue(VisualBasicGeneratedCodeRecognizer.Instance, rule, locationToken, messageArgs); - public static void ReportIssue(this SonarSymbolReportingContext context, DiagnosticDescriptor rule, Location location, params string[] messageArgs) => + public static void ReportIssue(this SonarCompilationReportingContextBase context, DiagnosticDescriptor rule, Location location, params string[] messageArgs) => context.ReportIssue(VisualBasicGeneratedCodeRecognizer.Instance, rule, location, messageArgs); } diff --git a/analyzers/src/SonarAnalyzer.VisualBasic/Rules/OptionExplicitOn.cs b/analyzers/src/SonarAnalyzer.VisualBasic/Rules/OptionExplicitOn.cs index c45e5d3f950..85df92d0a25 100644 --- a/analyzers/src/SonarAnalyzer.VisualBasic/Rules/OptionExplicitOn.cs +++ b/analyzers/src/SonarAnalyzer.VisualBasic/Rules/OptionExplicitOn.cs @@ -49,7 +49,7 @@ protected override void Initialize(SonarAnalysisContext context) { if (!c.Compilation.VB().Options.OptionExplicit) { - c.ReportIssue(Rule, null, string.Format(AssemblyMessageFormat, c.Compilation.AssemblyName)); + c.ReportIssue(Rule, (Location)null, string.Format(AssemblyMessageFormat, c.Compilation.AssemblyName)); } })); } diff --git a/analyzers/src/SonarAnalyzer.VisualBasic/Rules/OptionStrictOn.cs b/analyzers/src/SonarAnalyzer.VisualBasic/Rules/OptionStrictOn.cs index e8eaf17f59e..e55070ce198 100644 --- a/analyzers/src/SonarAnalyzer.VisualBasic/Rules/OptionStrictOn.cs +++ b/analyzers/src/SonarAnalyzer.VisualBasic/Rules/OptionStrictOn.cs @@ -49,7 +49,7 @@ protected override void Initialize(SonarAnalysisContext context) { if (c.Compilation.VB().Options.OptionStrict != OptionStrict.On) { - c.ReportIssue(Rule, null, string.Format(AssemblyMessageFormat, c.Compilation.AssemblyName)); + c.ReportIssue(Rule, (Location)null, string.Format(AssemblyMessageFormat, c.Compilation.AssemblyName)); } })); }