private static List <SyntaxNodeSymbolSemanticModelTuple <SyntaxNode, ISymbol> > GetCandidateDeclarations(CSharpRemovableDeclarationCollector removableDeclarationCollector)
        {
            var candidateFields = removableDeclarationCollector.GetRemovableFieldLikeDeclarations(new HashSet <SyntaxKind> {
                SyntaxKind.FieldDeclaration
            }, MaxAccessibility)
                                  .Where(tuple => !IsInitializedOrFixed((VariableDeclaratorSyntax)tuple.SyntaxNode) &&
                                         !HasStructLayoutAttribute(tuple.Symbol.ContainingType));

            var candidateProperties = removableDeclarationCollector.GetRemovableDeclarations(new HashSet <SyntaxKind> {
                SyntaxKind.PropertyDeclaration
            }, MaxAccessibility)
                                      .Where(tuple => IsAutoPropertyWithNoInitializer((PropertyDeclarationSyntax)tuple.SyntaxNode) &&
                                             !HasStructLayoutAttribute(tuple.Symbol.ContainingType));

            return(candidateFields.Concat(candidateProperties).ToList());
        }
Beispiel #2
0
        private void RaiseOnUninvokedEventDeclaration(SymbolAnalysisContext context)
        {
            var namedType = (INamedTypeSymbol)context.Symbol;

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

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

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

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

            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);
        }
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterSymbolAction(
                c =>
            {
                var namedType = (INamedTypeSymbol)c.Symbol;
                if (!namedType.IsClassOrStruct() ||
                    namedType.GetAttributes(KnownType.System_Runtime_InteropServices_StructLayoutAttribute).Any() ||
                    namedType.ContainingType != null)
                {
                    return;
                }

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

                var candidateFields = removableDeclarationCollector.GetRemovableFieldLikeDeclarations(
                    new HashSet <SyntaxKind> {
                    SyntaxKind.FieldDeclaration
                }, maxAccessibility)
                                      .Where(tuple => !IsInitializedOrFixed(((VariableDeclaratorSyntax)tuple.SyntaxNode)));

                var candidateProperties = removableDeclarationCollector.GetRemovableDeclarations(
                    new HashSet <SyntaxKind> {
                    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);
        }