protected sealed override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterSymbolAction(
                c =>
            {
                var namedType = (INamedTypeSymbol)c.Symbol;
                if (!namedType.IsClassOrStruct() ||
                    namedType.GetAttributes().Any(IsStructLayoutAttribute) ||
                    namedType.ContainingType != null)
                {
                    return;
                }

                var removableDeclarationCollector = new RemovableDeclarationCollector(namedType, c.Compilation);

                var candidateFields = removableDeclarationCollector.GetRemovableFieldLikeDeclarations(
                    ImmutableHashSet.Create(SyntaxKind.FieldDeclaration), maxAccessibility)
                                      .Where(tuple => !IsInitializedOrFixed(((VariableDeclaratorSyntax)tuple.SyntaxNode)));

                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);
        }
Esempio n. 2
0
        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));
        }
        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);
        }