protected override void Initialize(SonarAnalysisContext context) { context.RegisterSymbolAction( c => { var namedType = (INamedTypeSymbol)c.Symbol; if (!namedType.IsClassOrStruct() || namedType.ContainingType != null) { return; } var removableDeclarationCollector = new RemovableDeclarationCollector(namedType, c.Compilation); var candidateFields = removableDeclarationCollector.GetRemovableFieldLikeDeclarations( ImmutableHashSet.Create(SyntaxKind.FieldDeclaration), maxAccessibility) .Where(tuple => ((VariableDeclaratorSyntax)tuple.SyntaxNode).Initializer == null); var candidateProperties = removableDeclarationCollector.GetRemovableDeclarations( ImmutableHashSet.Create(SyntaxKind.PropertyDeclaration), maxAccessibility) .Where(tuple => IsAutoPropertyWithNoInitializer((PropertyDeclarationSyntax)tuple.SyntaxNode)); var allCandidateMembers = candidateFields.Concat(candidateProperties).ToList(); if (!allCandidateMembers.Any()) { return; } var usedMembers = GetMemberUsages(removableDeclarationCollector, new HashSet<ISymbol>(allCandidateMembers.Select(t => t.Symbol))); var usedMemberSymbols = new HashSet<ISymbol>(usedMembers.Select(tuple => tuple.Symbol)); var assignedMemberSymbols = GetAssignedMemberSymbols(usedMembers); foreach (var candidateMember in allCandidateMembers) { if (!usedMemberSymbols.Contains(candidateMember.Symbol)) { /// reported by <see cref="UnusedPrivateMember"/> continue; } if (!assignedMemberSymbols.Contains(candidateMember.Symbol)) { var field = candidateMember.SyntaxNode as VariableDeclaratorSyntax; var property = candidateMember.SyntaxNode as PropertyDeclarationSyntax; var memberType = field != null ? "field" : "auto-property"; var location = field != null ? field.Identifier.GetLocation() : property.Identifier.GetLocation(); c.ReportDiagnosticIfNonGenerated(Diagnostic.Create(Rule, location, memberType, candidateMember.Symbol.Name)); } } }, SymbolKind.NamedType); }
protected override void Initialize(SonarAnalysisContext context) { context.RegisterSymbolAction( c => { var namedType = (INamedTypeSymbol)c.Symbol; if (!namedType.IsClassOrStruct() || namedType.ContainingType != null) { return; } var removableDeclarationCollector = new RemovableDeclarationCollector(namedType, c.Compilation); var removableEvents = removableDeclarationCollector.GetRemovableDeclarations( ImmutableHashSet.Create(SyntaxKind.EventDeclaration), maxAccessibility); var removableEventFields = removableDeclarationCollector.GetRemovableFieldLikeDeclarations( ImmutableHashSet.Create(SyntaxKind.EventFieldDeclaration), maxAccessibility); var allRemovableEvents = removableEvents.Concat(removableEventFields).ToList(); if (!allRemovableEvents.Any()) { return; } var symbolNames = allRemovableEvents.Select(t => t.Symbol.Name).ToImmutableHashSet(); var usedSymbols = GetReferencedSymbolsWithMatchingNames(removableDeclarationCollector, symbolNames); var invokedSymbols = GetInvokedEventSymbols(removableDeclarationCollector); var possiblyCopiedSymbols = GetPossiblyCopiedSymbols(removableDeclarationCollector); foreach (var removableEvent in allRemovableEvents) { if (!usedSymbols.Contains(removableEvent.Symbol)) { /// reported by <see cref="UnusedPrivateMember"/> continue; } if (!invokedSymbols.Contains(removableEvent.Symbol) && !possiblyCopiedSymbols.Contains(removableEvent.Symbol)) { var eventField = removableEvent.SyntaxNode as VariableDeclaratorSyntax; var location = eventField != null ? eventField.Identifier.GetLocation() : ((EventDeclarationSyntax)removableEvent.SyntaxNode).Identifier.GetLocation(); c.ReportDiagnosticIfNonGenerated(Diagnostic.Create(Rule, location)); } } }, SymbolKind.NamedType); }
private static void CollectRemovableEventsAndProperties(RemovableDeclarationCollector helper, HashSet<ISymbol> declaredPrivateSymbols) { var declarationKinds = ImmutableHashSet.Create(SyntaxKind.EventDeclaration, SyntaxKind.PropertyDeclaration, SyntaxKind.IndexerDeclaration); var declarations = helper.GetRemovableDeclarations(declarationKinds, maxAccessibility); declaredPrivateSymbols.UnionWith(declarations.Select(d => d.Symbol)); }