public override void Initialize(AnalysisContext context) { context.RegisterCompilationStartAction(analysisContext => { analysisContext.RegisterSyntaxNodeAction( c => { var methodDeclaration = c.Node as MethodDeclarationSyntax; var classDeclaration = c.Node as ClassDeclarationSyntax; if (methodDeclaration != null && (methodDeclaration.Modifiers.Any(modifier => ModifiersToSkip.Contains(modifier.Kind())) || methodDeclaration.Body == null)) { return; } var declarationSymbol = c.SemanticModel.GetDeclaredSymbol(c.Node); if (declarationSymbol == null) { return; } TypeParameterListSyntax typeParameterList; string typeOfContainer; if (classDeclaration == null) { typeParameterList = methodDeclaration.TypeParameterList; typeOfContainer = "method"; } else { typeParameterList = classDeclaration.TypeParameterList; typeOfContainer = "class"; } if (typeParameterList == null || typeParameterList.Parameters.Count == 0) { return; } var typeParameters = typeParameterList.Parameters .Select(typeParameter => typeParameter.Identifier.Text) .ToList(); var declarations = declarationSymbol.DeclaringSyntaxReferences .Select(reference => reference.GetSyntax()); var usedTypeParameters = GetUsedTypeParameters(declarations, c, analysisContext.Compilation); foreach (var typeParameter in typeParameters.Where(typeParameter => !usedTypeParameters.Contains(typeParameter))) { c.ReportDiagnostic(Diagnostic.Create(Rule, typeParameterList.Parameters.First(tp => tp.Identifier.Text == typeParameter) .GetLocation(), typeParameter, typeOfContainer)); } }, SyntaxKind.MethodDeclaration, SyntaxKind.ClassDeclaration); }); }
public override void Initialize(AnalysisContext context) { context.RegisterSyntaxNodeAction( c => { var methodDeclaration = c.Node as MethodDeclarationSyntax; var classDeclaration = c.Node as ClassDeclarationSyntax; if (methodDeclaration == null && classDeclaration == null) { return; } if (methodDeclaration != null && methodDeclaration.Modifiers.Any(modifier => ModifiersToSkip.Contains(modifier.Kind()))) { return; } var declarationSymbol = c.SemanticModel.GetDeclaredSymbol(c.Node); if (declarationSymbol == null) { return; } TypeParameterListSyntax typeParameterList; string typeOfContainer; if (classDeclaration == null) { typeParameterList = methodDeclaration.TypeParameterList; typeOfContainer = "method"; } else { typeParameterList = classDeclaration.TypeParameterList; typeOfContainer = "class"; } if (typeParameterList == null || typeParameterList.Parameters.Count == 0) { return; } var typeParameters = typeParameterList.Parameters .Select(typeParameter => typeParameter.Identifier.Text) .ToList(); var declarations = declarationSymbol.DeclaringSyntaxReferences.Select(reference => reference.GetSyntax()); var usedTypeParameters = declarations.SelectMany(declaration => declaration.DescendantNodes()) .OfType <IdentifierNameSyntax>() .Select(identifier => c.SemanticModel.GetSymbolInfo(identifier).Symbol) .Where(symbol => symbol != null && symbol.Kind == SymbolKind.TypeParameter) .Select(symbol => symbol.Name) .ToList(); foreach (var typeParameter in typeParameters.Where(typeParameter => !usedTypeParameters.Contains(typeParameter))) { c.ReportDiagnostic(Diagnostic.Create(Rule, typeParameterList.Parameters.First(tp => tp.Identifier.Text == typeParameter) .GetLocation(), typeParameter, typeOfContainer)); } }, SyntaxKind.MethodDeclaration, SyntaxKind.ClassDeclaration); }