Beispiel #1
0
        private static void AnalyzeTypeDeclaration(SyntaxNodeAnalysisContext context, TypeDeclarationSyntax typeDeclaration)
        {
            if (typeDeclaration.Modifiers.Contains(SyntaxKind.PartialKeyword))
            {
                return;
            }

            SyntaxList <MemberDeclarationSyntax> members = typeDeclaration.Members;

            UnusedMemberWalker walker            = null;
            SemanticModel      semanticModel     = context.SemanticModel;
            CancellationToken  cancellationToken = context.CancellationToken;

            foreach (MemberDeclarationSyntax member in members)
            {
                if (member.ContainsDiagnostics)
                {
                    continue;
                }

                if (member.ContainsUnbalancedIfElseDirectives(member.Span))
                {
                    continue;
                }

                switch (member.Kind())
                {
                case SyntaxKind.DelegateDeclaration:
                {
                    var declaration = (DelegateDeclarationSyntax)member;

                    if (SyntaxAccessibility <DelegateDeclarationSyntax> .Instance.GetAccessibility(declaration) == Accessibility.Private)
                    {
                        if (walker == null)
                        {
                            walker = UnusedMemberWalkerCache.GetInstance();
                        }

                        walker.AddDelegate(declaration.Identifier.ValueText, declaration);
                    }

                    break;
                }

                case SyntaxKind.EventDeclaration:
                {
                    var declaration = (EventDeclarationSyntax)member;

                    if (declaration.ExplicitInterfaceSpecifier == null &&
                        SyntaxAccessibility <EventDeclarationSyntax> .Instance.GetAccessibility(declaration) == Accessibility.Private)
                    {
                        if (walker == null)
                        {
                            walker = UnusedMemberWalkerCache.GetInstance();
                        }

                        walker.AddNode(declaration.Identifier.ValueText, declaration);
                    }

                    break;
                }

                case SyntaxKind.EventFieldDeclaration:
                {
                    var declaration = (EventFieldDeclarationSyntax)member;

                    if (SyntaxAccessibility <EventFieldDeclarationSyntax> .Instance.GetAccessibility(declaration) == Accessibility.Private)
                    {
                        if (walker == null)
                        {
                            walker = UnusedMemberWalkerCache.GetInstance();
                        }

                        walker.AddNodes(declaration.Declaration);
                    }

                    break;
                }

                case SyntaxKind.FieldDeclaration:
                {
                    var             declaration = (FieldDeclarationSyntax)member;
                    SyntaxTokenList modifiers   = declaration.Modifiers;

                    if (SyntaxAccessibility <FieldDeclarationSyntax> .Instance.GetAccessibility(declaration) == Accessibility.Private)
                    {
                        if (walker == null)
                        {
                            walker = UnusedMemberWalkerCache.GetInstance();
                        }

                        walker.AddNodes(declaration.Declaration, isConst: modifiers.Contains(SyntaxKind.ConstKeyword));
                    }

                    break;
                }

                case SyntaxKind.MethodDeclaration:
                {
                    var declaration = (MethodDeclarationSyntax)member;

                    SyntaxTokenList modifiers = declaration.Modifiers;

                    if (declaration.ExplicitInterfaceSpecifier == null &&
                        !declaration.AttributeLists.Any() &&
                        SyntaxAccessibility <MethodDeclarationSyntax> .Instance.GetAccessibility(declaration) == Accessibility.Private)
                    {
                        string methodName = declaration.Identifier.ValueText;

                        if (!IsMainMethod(declaration, modifiers, methodName))
                        {
                            if (walker == null)
                            {
                                walker = UnusedMemberWalkerCache.GetInstance();
                            }

                            walker.AddNode(methodName, declaration);
                        }
                    }

                    break;
                }

                case SyntaxKind.PropertyDeclaration:
                {
                    var declaration = (PropertyDeclarationSyntax)member;

                    if (declaration.ExplicitInterfaceSpecifier == null &&
                        SyntaxAccessibility <PropertyDeclarationSyntax> .Instance.GetAccessibility(declaration) == Accessibility.Private)
                    {
                        if (walker == null)
                        {
                            walker = UnusedMemberWalkerCache.GetInstance();
                        }

                        walker.AddNode(declaration.Identifier.ValueText, declaration);
                    }

                    break;
                }
                }
            }

            if (walker == null)
            {
                return;
            }

            Collection <NodeSymbolInfo> nodes = walker.Nodes;

            if (ShouldAnalyzeDebuggerDisplayAttribute() &&
                nodes.Any(f => f.CanBeInDebuggerDisplayAttribute))
            {
                string value = semanticModel
                               .GetDeclaredSymbol(typeDeclaration, cancellationToken)
                               .GetAttribute(MetadataNames.System_Diagnostics_DebuggerDisplayAttribute)?
                               .ConstructorArguments
                               .SingleOrDefault(shouldThrow: false)
                               .Value?
                               .ToString();

                if (value != null)
                {
                    RemoveMethodsAndPropertiesThatAreInDebuggerDisplayAttributeValue(value, ref nodes);
                }

                if (nodes.Count == 0)
                {
                    UnusedMemberWalkerCache.Free(walker);
                    return;
                }
            }

            walker.SemanticModel     = semanticModel;
            walker.CancellationToken = cancellationToken;

            walker.Visit(typeDeclaration);

            foreach (NodeSymbolInfo info in nodes)
            {
                SyntaxNode node = info.Node;

                if (node is VariableDeclaratorSyntax variableDeclarator)
                {
                    var variableDeclaration = (VariableDeclarationSyntax)variableDeclarator.Parent;

                    if (variableDeclaration.Variables.Count == 1)
                    {
                        ReportDiagnostic(context, variableDeclaration.Parent, CSharpFacts.GetTitle(variableDeclaration.Parent));
                    }
                    else
                    {
                        ReportDiagnostic(context, variableDeclarator, CSharpFacts.GetTitle(variableDeclaration.Parent));
                    }
                }
                else
                {
                    ReportDiagnostic(context, node, CSharpFacts.GetTitle(node));
                }
            }

            UnusedMemberWalkerCache.Free(walker);

            bool ShouldAnalyzeDebuggerDisplayAttribute()
            {
                foreach (AttributeListSyntax attributeList in typeDeclaration.AttributeLists)
                {
                    foreach (AttributeSyntax attribute in attributeList.Attributes)
                    {
                        if (attribute.ArgumentList?.Arguments.Count(f => f.NameEquals == null) == 1)
                        {
                            return(true);
                        }
                    }
                }

                return(false);
            }
        }
Beispiel #2
0
        private static void AnalyzeTypeDeclaration(SyntaxNodeAnalysisContext context, TypeDeclarationSyntax typeDeclaration)
        {
            if (typeDeclaration.Modifiers.Contains(SyntaxKind.PartialKeyword))
            {
                return;
            }

            SyntaxList <MemberDeclarationSyntax> members = typeDeclaration.Members;

            UnusedMemberWalker walker = null;

            foreach (MemberDeclarationSyntax member in members)
            {
                if (member.ContainsDiagnostics)
                {
                    continue;
                }

                if (member.ContainsDirectives)
                {
                    continue;
                }

                switch (member.Kind())
                {
                case SyntaxKind.DelegateDeclaration:
                {
                    var declaration = (DelegateDeclarationSyntax)member;

                    if (SyntaxAccessibility.GetAccessibility(declaration) == Accessibility.Private)
                    {
                        if (walker == null)
                        {
                            walker = UnusedMemberWalkerCache.GetInstance(context.SemanticModel, context.CancellationToken);
                        }

                        walker.AddNode(declaration.Identifier.ValueText, declaration);
                    }

                    break;
                }

                case SyntaxKind.EventDeclaration:
                {
                    var declaration = (EventDeclarationSyntax)member;

                    if (declaration.ExplicitInterfaceSpecifier == null &&
                        SyntaxAccessibility.GetAccessibility(declaration) == Accessibility.Private)
                    {
                        if (walker == null)
                        {
                            walker = UnusedMemberWalkerCache.GetInstance(context.SemanticModel, context.CancellationToken);
                        }

                        walker.AddNode(declaration.Identifier.ValueText, declaration);
                    }

                    break;
                }

                case SyntaxKind.EventFieldDeclaration:
                {
                    var declaration = (EventFieldDeclarationSyntax)member;

                    if (SyntaxAccessibility.GetAccessibility(declaration) == Accessibility.Private)
                    {
                        if (walker == null)
                        {
                            walker = UnusedMemberWalkerCache.GetInstance(context.SemanticModel, context.CancellationToken);
                        }

                        walker.AddNodes(declaration.Declaration);
                    }

                    break;
                }

                case SyntaxKind.FieldDeclaration:
                {
                    var             declaration = (FieldDeclarationSyntax)member;
                    SyntaxTokenList modifiers   = declaration.Modifiers;

                    if (SyntaxAccessibility.GetAccessibility(declaration) == Accessibility.Private)
                    {
                        if (walker == null)
                        {
                            walker = UnusedMemberWalkerCache.GetInstance(context.SemanticModel, context.CancellationToken);
                        }

                        walker.AddNodes(declaration.Declaration, isConst: modifiers.Contains(SyntaxKind.ConstKeyword));
                    }

                    break;
                }

                case SyntaxKind.MethodDeclaration:
                {
                    var declaration = (MethodDeclarationSyntax)member;

                    SyntaxTokenList modifiers = declaration.Modifiers;

                    if (declaration.ExplicitInterfaceSpecifier == null &&
                        !declaration.AttributeLists.Any() &&
                        SyntaxAccessibility.GetAccessibility(declaration) == Accessibility.Private)
                    {
                        string methodName = declaration.Identifier.ValueText;

                        if (!IsMainMethod(declaration, modifiers, methodName))
                        {
                            if (walker == null)
                            {
                                walker = UnusedMemberWalkerCache.GetInstance(context.SemanticModel, context.CancellationToken);
                            }

                            walker.AddNode(methodName, declaration);
                        }
                    }

                    break;
                }

                case SyntaxKind.PropertyDeclaration:
                {
                    var declaration = (PropertyDeclarationSyntax)member;

                    if (declaration.ExplicitInterfaceSpecifier == null &&
                        SyntaxAccessibility.GetAccessibility(declaration) == Accessibility.Private)
                    {
                        if (walker == null)
                        {
                            walker = UnusedMemberWalkerCache.GetInstance(context.SemanticModel, context.CancellationToken);
                        }

                        walker.AddNode(declaration.Identifier.ValueText, declaration);
                    }

                    break;
                }
                }
            }

            if (walker == null)
            {
                return;
            }

            walker.Visit(typeDeclaration);

            foreach (NodeSymbolInfo info in UnusedMemberWalkerCache.GetNodesAndFree(walker))
            {
                SyntaxNode node = info.Node;

                if (node is VariableDeclaratorSyntax variableDeclarator)
                {
                    var variableDeclaration = (VariableDeclarationSyntax)variableDeclarator.Parent;

                    if (variableDeclaration.Variables.Count == 1)
                    {
                        ReportDiagnostic(context, variableDeclaration.Parent, CSharpFacts.GetTitle(variableDeclaration.Parent));
                    }
                    else
                    {
                        ReportDiagnostic(context, variableDeclarator, CSharpFacts.GetTitle(variableDeclaration.Parent));
                    }
                }
                else
                {
                    ReportDiagnostic(context, node, CSharpFacts.GetTitle(node));
                }
            }
        }