Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace deprecated ReportIssue in more locations #9423

Merged
merged 10 commits into from
Jun 14, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -49,28 +49,24 @@ public sealed class CollectionsShouldImplementGenericInterface : SonarDiagnostic
{
var typeDeclaration = (BaseTypeDeclarationSyntax)c.Node;
var implementedTypes = typeDeclaration.BaseList?.Types;
if (implementedTypes == null || c.IsRedundantPositionalRecordContext())
if (implementedTypes is null || c.IsRedundantPositionalRecordContext())
{
return;
}

List<Diagnostic> issues = null;
var containingType = (INamedTypeSymbol)c.ContainingSymbol;
foreach (var typeSymbol in containingType.Interfaces.Concat(new[] { containingType.BaseType }).WhereNotNull())
var typeSymbols = containingType.Interfaces.Concat([containingType.BaseType]).WhereNotNull().ToImmutableArray();
if (typeSymbols.Any(x => x.OriginalDefinition.IsAny(GenericTypes)))
{
return;
}
foreach (var typeSymbol in typeSymbols)
{
if (typeSymbol.OriginalDefinition.IsAny(GenericTypes))
{
return;
}

if (SuggestGenericCollectionType(typeSymbol) is { } suggestedGenericType)
{
issues ??= new();
issues.Add(Diagnostic.Create(Rule, typeDeclaration.Identifier.GetLocation(), suggestedGenericType));
c.ReportIssue(Rule, typeDeclaration.Identifier, suggestedGenericType);
}
}

issues?.ForEach(d => c.ReportIssue(d));
},
SyntaxKind.ClassDeclaration,
SyntaxKind.StructDeclaration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public sealed class DoNotDecreaseMemberVisibility : SonarDiagnosticAnalyzer
private const string MessageFormat = "This member hides '{0}'. Make it non-private or seal the class.";

private static readonly DiagnosticDescriptor Rule = DescriptorFactory.Create(DiagnosticId, MessageFormat);

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(Rule);

protected override void Initialize(SonarAnalysisContext context) =>
Expand All @@ -40,24 +41,24 @@ public sealed class DoNotDecreaseMemberVisibility : SonarDiagnosticAnalyzer
return;
}

var issueFinder = new IssueFinder(classSymbol, c.SemanticModel);
foreach (var diagnostic in classDeclaration.Members.Select(issueFinder.FindIssue).WhereNotNull())
var issueReporter = new IssueReporter(classSymbol, c);
foreach (var member in classDeclaration.Members)
{
c.ReportIssue(diagnostic);
issueReporter.ReportIssue(member);
}
},
SyntaxKind.ClassDeclaration,
SyntaxKindEx.RecordClassDeclaration);

private sealed class IssueFinder
private sealed class IssueReporter
{
private readonly IList<IMethodSymbol> allBaseClassMethods;
private readonly IList<IPropertySymbol> allBaseClassProperties;
private readonly SemanticModel semanticModel;
private readonly SonarSyntaxNodeReportingContext context;

public IssueFinder(ITypeSymbol classSymbol, SemanticModel semanticModel)
public IssueReporter(ITypeSymbol classSymbol, SonarSyntaxNodeReportingContext context)
{
this.semanticModel = semanticModel;
this.context = context;
var allBaseClassMembers = classSymbol.BaseType
.GetSelfAndBaseTypes()
.SelectMany(t => t.GetMembers())
Expand All @@ -68,57 +69,39 @@ public IssueFinder(ITypeSymbol classSymbol, SemanticModel semanticModel)
allBaseClassProperties = allBaseClassMembers.OfType<IPropertySymbol>().ToList();
}

public Diagnostic FindIssue(MemberDeclarationSyntax memberDeclaration)
public void ReportIssue(MemberDeclarationSyntax memberDeclaration)
{
var memberSymbol = semanticModel.GetDeclaredSymbol(memberDeclaration);

if (memberSymbol is IMethodSymbol methodSymbol)
switch (context.SemanticModel.GetDeclaredSymbol(memberDeclaration))
{
return FindMethodIssue(memberDeclaration, methodSymbol);
case IMethodSymbol methodSymbol:
ReportMethodIssue(memberDeclaration, methodSymbol);
break;
case IPropertySymbol propertySymbol:
ReportPropertyIssue(memberDeclaration, propertySymbol);
break;
}

return memberSymbol is IPropertySymbol propertySymbol ? FindPropertyIssue(memberDeclaration, propertySymbol) : null;
}

private Diagnostic FindMethodIssue(MemberDeclarationSyntax memberDeclaration, IMethodSymbol methodSymbol)
private void ReportMethodIssue(MemberDeclarationSyntax memberDeclaration, IMethodSymbol methodSymbol)
{
if (memberDeclaration is not MethodDeclarationSyntax methodDeclaration
|| methodDeclaration.Modifiers.Any(SyntaxKind.NewKeyword))
{
return null;
}

var hidingMethod = allBaseClassMethods.FirstOrDefault(m => IsDecreasingAccess(m.DeclaredAccessibility, methodSymbol.DeclaredAccessibility, false)
&& IsMatchingSignature(m, methodSymbol));

if (hidingMethod != null)
if (memberDeclaration is MethodDeclarationSyntax methodDeclaration
&& !methodDeclaration.Modifiers.Any(SyntaxKind.NewKeyword)
&& allBaseClassMethods.FirstOrDefault(x =>
IsDecreasingAccess(x.DeclaredAccessibility, methodSymbol.DeclaredAccessibility, false)
&& IsMatchingSignature(x, methodSymbol)) is { } hidingMethod)
{
var location = methodDeclaration.Identifier.GetLocation();
if (location != null)
{
return Diagnostic.Create(Rule, location, hidingMethod);
}
context.ReportIssue(Rule, methodDeclaration.Identifier, hidingMethod.ToDisplayString());
}

return null;
}

private Diagnostic FindPropertyIssue(MemberDeclarationSyntax memberDeclaration, IPropertySymbol propertySymbol)
private void ReportPropertyIssue(MemberDeclarationSyntax memberDeclaration, IPropertySymbol propertySymbol)
{
if (memberDeclaration is not PropertyDeclarationSyntax propertyDeclaration
|| propertyDeclaration.Modifiers.Any(SyntaxKind.NewKeyword))
if (memberDeclaration is PropertyDeclarationSyntax propertyDeclaration
&& !propertyDeclaration.Modifiers.Any(SyntaxKind.NewKeyword)
&& allBaseClassProperties.FirstOrDefault(x => IsDecreasingPropertyAccess(x, propertySymbol, propertySymbol.IsOverride)) is { } hidingProperty)
{
return null;
context.ReportIssue(Rule, propertyDeclaration.Identifier, hidingProperty.ToDisplayString());
}

var hidingProperty = allBaseClassProperties.FirstOrDefault(p => IsDecreasingPropertyAccess(p, propertySymbol, propertySymbol.IsOverride));
if (hidingProperty != null)
{
var location = propertyDeclaration.Identifier.GetLocation();
return Diagnostic.Create(Rule, location, hidingProperty);
}

return null;
}

private static bool IsSymbolVisibleFromNamespace(ISymbol symbol, INamespaceSymbol ns) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,21 @@ public sealed class DoNotHideBaseClassMethods : SonarDiagnosticAnalyzer
var declarationSyntax = (TypeDeclarationSyntax)c.Node;
if (declarationSyntax.Identifier.IsMissing
|| c.IsRedundantPositionalRecordContext()
|| !(c.SemanticModel.GetDeclaredSymbol(declarationSyntax) is {} declaredSymbol))
|| !(c.SemanticModel.GetDeclaredSymbol(declarationSyntax) is { } declaredSymbol))
{
return;
}

var issueFinder = new IssueFinder(declaredSymbol, c.SemanticModel);
foreach (var diagnostic in declarationSyntax.Members.Select(issueFinder.FindIssue).WhereNotNull())
var issueReporter = new IssueReporter(declaredSymbol, c);
foreach (var member in declarationSyntax.Members)
{
c.ReportIssue(diagnostic);
issueReporter.ReportIssue(member);
}
},
SyntaxKind.ClassDeclaration,
SyntaxKindEx.RecordClassDeclaration);

private sealed class IssueFinder
private sealed class IssueReporter
{
private enum Match
{
Expand All @@ -59,25 +59,22 @@ private enum Match
}

private readonly IList<IMethodSymbol> allBaseTypeMethods;
private readonly SemanticModel semanticModel;
private readonly SonarSyntaxNodeReportingContext context;

public IssueFinder(ITypeSymbol typeSymbol, SemanticModel semanticModel)
public IssueReporter(ITypeSymbol typeSymbol, SonarSyntaxNodeReportingContext context)
{
this.semanticModel = semanticModel;
this.context = context;
allBaseTypeMethods = GetAllBaseMethods(typeSymbol);
}

public Diagnostic FindIssue(MemberDeclarationSyntax memberDeclaration)
public void ReportIssue(MemberDeclarationSyntax memberDeclaration)
{
var issueLocation = (memberDeclaration as MethodDeclarationSyntax)?.Identifier.GetLocation();

if (semanticModel.GetDeclaredSymbol(memberDeclaration) is not IMethodSymbol methodSymbol || issueLocation == null)
if (memberDeclaration is MethodDeclarationSyntax { Identifier: { } identifier }
&& context.SemanticModel.GetDeclaredSymbol(memberDeclaration) is IMethodSymbol methodSymbol
&& FindBaseMethodHiddenByMethod(methodSymbol) is { } baseMethodHidden)
{
return null;
context.ReportIssue(Rule, identifier, baseMethodHidden.ToDisplayString());
}

var baseMethodHidden = FindBaseMethodHiddenByMethod(methodSymbol);
return baseMethodHidden != null ? Diagnostic.Create(Rule, issueLocation, baseMethodHidden) : null;
}

private static List<IMethodSymbol> GetAllBaseMethods(ITypeSymbol typeSymbol) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,16 @@ private enum Shift
}

linesWithShiftOperations.Add(shift.Line);
if (shift.Diagnostic != null)
if (shift.Node is not null)
{
c.ReportIssue(shift.Diagnostic);
c.ReportIssue(Rule, shift.Node, shift.Description);
}
}

zeroShiftIssues
.Where(sh => !ContainsShiftExpressionWithinTwoLines(linesWithShiftOperations, sh.Line))
.ToList()
.ForEach(sh => c.ReportIssue(sh.Diagnostic));
foreach (var shift in zeroShiftIssues.Where(x => !ContainsShiftExpressionWithinTwoLines(linesWithShiftOperations, x.Line)))
{
c.ReportIssue(Rule, shift.Node, shift.Description);
}
},
SyntaxKind.MethodDeclaration,
SyntaxKind.PropertyDeclaration);
Expand Down Expand Up @@ -196,18 +196,20 @@ private static string FindProblemDescription(int typeSizeInBits, int shiftBy, Sh

private sealed class ShiftInstance
{
public Diagnostic Diagnostic { get; }
public string Description { get; }
public SyntaxNode Node { get; }
public bool IsLiteralZero { get; }
public int Line { get; }

public ShiftInstance(SyntaxNode node) =>
Line = node.GetLineNumberToReport();

public ShiftInstance(string description, bool isLieralZero, SyntaxNode node)
public ShiftInstance(string description, bool isLiteralZero, SyntaxNode node)
: this(node)
{
Diagnostic = Diagnostic.Create(Rule, node.GetLocation(), description);
IsLiteralZero = isLieralZero;
Description = description;
IsLiteralZero = isLiteralZero;
Node = node;
}
}
}
Expand Down
Loading