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)); } } }
private static void AnalyzeTypeDeclaration(SyntaxNodeAnalysisContext context, TypeDeclarationSyntax typeDeclaration, INamedTypeSymbol debuggerDisplayAttribute) { 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.AddDelegate(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; } if (debuggerDisplayAttribute != null && walker.Nodes.Any(f => f.CanBeInDebuggerDisplayAttribute) && ShouldAnalyzeDebuggerDisplayAttribute()) { string value = context.SemanticModel .GetDeclaredSymbol(typeDeclaration, context.CancellationToken) .GetAttribute(debuggerDisplayAttribute)? .ConstructorArguments .SingleOrDefault(shouldThrow: false) .Value? .ToString(); if (value != null) { RemoveMethodsAndPropertiesThatAreInDebuggerDisplayAttributeValue(walker.Nodes, value); } if (walker.Nodes.Count == 0) { 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)); } } bool ShouldAnalyzeDebuggerDisplayAttribute() { if (typeDeclaration.Modifiers.Contains(SyntaxKind.PartialKeyword)) { return(true); } 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); } }