private static void ReportIssues(SymbolAnalysisContext context, HashSet <ISymbol> usedSymbols, HashSet <ISymbol> declaredPrivateSymbols, HashSet <ISymbol> emptyConstructors, BidirectionalDictionary <ISymbol, SyntaxNode> fieldLikeSymbols) { var unusedSymbols = declaredPrivateSymbols .Except(usedSymbols.Union(emptyConstructors)) .ToList(); var alreadyReportedFieldLikeSymbols = new HashSet <ISymbol>(); var unusedSymbolSyntaxPairs = unusedSymbols .SelectMany(unusedSymbol => unusedSymbol.DeclaringSyntaxReferences .Select(r => new { Syntax = r.GetSyntax(), Symbol = unusedSymbol })); foreach (var unused in unusedSymbolSyntaxPairs) { var location = unused.Syntax.GetLocation(); var canBeFieldLike = unused.Symbol is IFieldSymbol || unused.Symbol is IEventSymbol; if (canBeFieldLike) { if (alreadyReportedFieldLikeSymbols.Contains(unused.Symbol)) { continue; } var variableDeclaration = GetVariableDeclaration(unused.Syntax); if (variableDeclaration == null) { continue; } var declarations = variableDeclaration.Variables .Select(v => fieldLikeSymbols.GetByB(v)) .ToList(); if (declarations.All(d => unusedSymbols.Contains(d))) { location = unused.Syntax.Parent.Parent.GetLocation(); alreadyReportedFieldLikeSymbols.UnionWith(declarations); } } var memberKind = GetMemberType(unused.Symbol); var memberName = GetMemberName(unused.Symbol); context.ReportDiagnosticIfNonGenerated( Diagnostic.Create(rule, location, memberKind, memberName), context.Compilation); } }
private void ReportIssues(SymbolAnalysisContext context, HashSet <ISymbol> usedSymbols, HashSet <ISymbol> declaredPrivateSymbols, HashSet <ISymbol> emptyConstructors, BidirectionalDictionary <ISymbol, SyntaxNode> fieldLikeSymbols) { var unusedSymbols = declaredPrivateSymbols .Except(usedSymbols.Union(emptyConstructors)) .ToList(); var alreadyReportedFieldLikeSymbols = new HashSet <ISymbol>(); var unusedSymbolSyntaxPairs = unusedSymbols .SelectMany(unusedSymbol => unusedSymbol.DeclaringSyntaxReferences .Select(r => new { Syntax = r.GetSyntax(), Symbol = unusedSymbol })); foreach (var unused in unusedSymbolSyntaxPairs) { var location = unused.Syntax.GetLocation(); var canBeFieldLike = unused.Symbol is IFieldSymbol || unused.Symbol is IEventSymbol; if (canBeFieldLike) { if (alreadyReportedFieldLikeSymbols.Contains(unused.Symbol)) { continue; } var variableDeclaration = GetVariableDeclaration(unused.Syntax); if (variableDeclaration == null) { continue; } var declarations = variableDeclaration.Variables .Select(v => fieldLikeSymbols.GetByB(v)) .ToList(); if (declarations.All(d => unusedSymbols.Contains(d))) { location = unused.Syntax.Parent.Parent.GetLocation(); alreadyReportedFieldLikeSymbols.UnionWith(declarations); } } var memberKind = GetMemberType(unused.Symbol); var memberName = GetMemberName(unused.Symbol); var effectiveAccessibility = unused.Symbol.GetEffectiveAccessibility(); if (effectiveAccessibility == Accessibility.Internal) { // We can't report internal members directly because they might be used through another assembly. possibleUnusedInternalMembers.Add( Diagnostic.Create(rule, location, "internal", memberKind, memberName)); continue; } if (effectiveAccessibility == Accessibility.Private) { context.ReportDiagnosticIfNonGenerated( Diagnostic.Create(rule, location, "private", memberKind, memberName), context.Compilation); } } }
private static async Task<SyntaxNode> GetFixedDocumentAsync(FixAllContext fixAllContext, Document document) { var annotationKind = Guid.NewGuid().ToString(); var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false); var root = await document.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false); var elementDiagnosticPairs = diagnostics .Select(d => new KeyValuePair<SyntaxNodeOrToken, Diagnostic>(GetReportedElement(d, root), d)) .Where(n => !n.Key.IsMissing) .ToDictionary(kv => kv.Key, kv => kv.Value); var diagnosticAnnotationPairs = new BidirectionalDictionary<Diagnostic, SyntaxAnnotation>(); CreateAnnotationForDiagnostics(diagnostics, annotationKind, diagnosticAnnotationPairs); root = GetRootWithAnnotatedElements(root, elementDiagnosticPairs, diagnosticAnnotationPairs); var currentDocument = document.WithSyntaxRoot(root); var annotatedElements = root.GetAnnotatedNodesAndTokens(annotationKind).ToList(); while(annotatedElements.Any()) { var element = annotatedElements.First(); var annotation = element.GetAnnotations(annotationKind).First(); var diagnostic = diagnosticAnnotationPairs.GetByB(annotation); var location = root.GetAnnotatedNodesAndTokens(annotation).FirstOrDefault().GetLocation(); if (location == null) { //annotation is already removed from the tree continue; } var newDiagnostic = Diagnostic.Create( diagnostic.Descriptor, location, diagnostic.AdditionalLocations, diagnostic.Properties); var fixes = new List<CodeAction>(); var context = new CodeFixContext(currentDocument, newDiagnostic, (a, d) => { lock (fixes) { fixes.Add(a); } }, fixAllContext.CancellationToken); await fixAllContext.CodeFixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false); var action = fixes.FirstOrDefault(fix => fix.EquivalenceKey == fixAllContext.CodeActionEquivalenceKey); if (action != null) { var operations = await action.GetOperationsAsync(fixAllContext.CancellationToken); var solution = operations.OfType<ApplyChangesOperation>().Single().ChangedSolution; currentDocument = solution.GetDocument(document.Id); root = await currentDocument.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false); } root = RemoveAnnotationIfExists(root, annotation); currentDocument = document.WithSyntaxRoot(root); annotatedElements = root.GetAnnotatedNodesAndTokens(annotationKind).ToList(); } return await currentDocument.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false); }
private static void ReportIssues(SymbolAnalysisContext context, HashSet<ISymbol> usedSymbols, HashSet<ISymbol> declaredPrivateSymbols, HashSet<ISymbol> emptyConstructors, BidirectionalDictionary<ISymbol, SyntaxNode> fieldLikeSymbols) { var unusedSymbols = declaredPrivateSymbols .Except(usedSymbols.Union(emptyConstructors)) .ToList(); var alreadyReportedFieldLikeSymbols = new HashSet<ISymbol>(); var unusedSymbolSyntaxPairs = unusedSymbols .SelectMany(unusedSymbol => unusedSymbol.DeclaringSyntaxReferences .Select(r => new { Syntax = r.GetSyntax(), Symbol = unusedSymbol })); foreach (var unused in unusedSymbolSyntaxPairs) { var location = unused.Syntax.GetLocation(); var canBeFieldLike = unused.Symbol is IFieldSymbol || unused.Symbol is IEventSymbol; if (canBeFieldLike) { if (alreadyReportedFieldLikeSymbols.Contains(unused.Symbol)) { continue; } var variableDeclaration = GetVariableDeclaration(unused.Syntax); if (variableDeclaration == null) { continue; } var declarations = variableDeclaration.Variables .Select(v => fieldLikeSymbols.GetByB(v)) .ToList(); if (declarations.All(d => unusedSymbols.Contains(d))) { location = unused.Syntax.Parent.Parent.GetLocation(); alreadyReportedFieldLikeSymbols.UnionWith(declarations); } } context.ReportDiagnosticIfNonGenerated(Diagnostic.Create(Rule, location), context.Compilation); } }