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 CollectRemovableFieldLikeDeclarations(RemovableDeclarationCollector declarationCollector,
                                                                  HashSet <ISymbol> declaredPrivateSymbols, BidirectionalDictionary <ISymbol, SyntaxNode> fieldLikeSymbols)
        {
            var declarationKinds           = ImmutableHashSet.Create(SyntaxKind.FieldDeclaration, SyntaxKind.EventFieldDeclaration);
            var removableFieldsDefinitions = declarationCollector.GetRemovableFieldLikeDeclarations(declarationKinds, maxAccessibility);

            foreach (var fieldsDefinitions in removableFieldsDefinitions)
            {
                declaredPrivateSymbols.Add(fieldsDefinitions.Symbol);
                fieldLikeSymbols.Add(fieldsDefinitions.Symbol, fieldsDefinitions.SyntaxNode);
            }
        }
        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);
        }
Esempio n. 4
0
        private void RaiseOnUninvokedEventDeclaration(SymbolAnalysisContext context)
        {
            var namedType = (INamedTypeSymbol)context.Symbol;

            if (!namedType.IsClassOrStruct() ||
                namedType.ContainingType != null)
            {
                return;
            }

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

            var removableEventFields = removableDeclarationCollector
                                       .GetRemovableFieldLikeDeclarations(eventSyntax, maxAccessibility)
                                       .ToList();

            if (!removableEventFields.Any())
            {
                return;
            }

            var symbolNames           = removableEventFields.Select(t => t.Symbol.Name).ToHashSet();
            var usedSymbols           = GetReferencedSymbolsWithMatchingNames(removableDeclarationCollector, symbolNames);
            var invokedSymbols        = GetInvokedEventSymbols(removableDeclarationCollector);
            var possiblyCopiedSymbols = GetPossiblyCopiedSymbols(removableDeclarationCollector);

            removableEventFields
            .Where(IsNotInvoked)
            .Where(IsNotCopied)
            .ToList()
            .ForEach(x => context.ReportDiagnosticIfNonGenerated(
                         Diagnostic.Create(rule, GetLocation(x.SyntaxNode), x.Symbol.Name)));

            Location GetLocation(SyntaxNode node) =>
            node is VariableDeclaratorSyntax variableDeclarator
                    ? variableDeclarator.Identifier.GetLocation()
                    : ((EventDeclarationSyntax)node).Identifier.GetLocation();

            bool IsNotInvoked(SyntaxNodeSymbolSemanticModelTuple <SyntaxNode, ISymbol> tuple) =>
            !invokedSymbols.Contains(tuple.Symbol);

            bool IsNotCopied(SyntaxNodeSymbolSemanticModelTuple <SyntaxNode, ISymbol> tuple) =>
            !possiblyCopiedSymbols.Contains(tuple.Symbol);

            bool IsUsed(SyntaxNodeSymbolSemanticModelTuple <SyntaxNode, ISymbol> tuple) =>
            usedSymbols.Contains(tuple.Symbol);
        }