예제 #1
0
        public override async Task <CommandResult> ExecuteAsync(ProjectOrSolution projectOrSolution, CancellationToken cancellationToken = default)
        {
            AssemblyResolver.Register();

            ImmutableArray <UnusedSymbolInfo> allUnusedSymbols;

            if (projectOrSolution.IsProject)
            {
                Project project = projectOrSolution.AsProject();

                allUnusedSymbols = await AnalyzeProject(project, cancellationToken);
            }
            else
            {
                Solution solution = projectOrSolution.AsSolution();

                ImmutableArray <UnusedSymbolInfo> .Builder unusedSymbols = null;

                foreach (Project project in FilterProjects(solution, Options, s => s
                                                           .GetProjectDependencyGraph()
                                                           .GetTopologicallySortedProjects(cancellationToken)
                                                           .ToImmutableArray()))
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    ImmutableArray <UnusedSymbolInfo> unusedSymbols2 = await AnalyzeProject(project, cancellationToken);

                    if (unusedSymbols2.Any())
                    {
                        (unusedSymbols ?? (unusedSymbols = ImmutableArray.CreateBuilder <UnusedSymbolInfo>())).AddRange(unusedSymbols2);
                    }
                }

                allUnusedSymbols = unusedSymbols?.ToImmutableArray() ?? ImmutableArray <UnusedSymbolInfo> .Empty;
            }

            if (allUnusedSymbols.Any())
            {
                WriteLine(Verbosity.Normal);

                Dictionary <UnusedSymbolKind, int> countByKind = allUnusedSymbols
                                                                 .GroupBy(f => UnusedSymbolFinder.GetUnusedSymbolKind(f.Symbol))
                                                                 .OrderByDescending(f => f.Count())
                                                                 .ThenBy(f => f.Key)
                                                                 .ToDictionary(f => f.Key, f => f.Count());

                int maxCountLength = countByKind.Sum(f => f.Value.ToString().Length);

                foreach (KeyValuePair <UnusedSymbolKind, int> kvp in countByKind)
                {
                    WriteLine($"{kvp.Value.ToString().PadLeft(maxCountLength)} {kvp.Key.ToString().ToLowerInvariant()} symbols", Verbosity.Normal);
                }
            }

            WriteLine(Verbosity.Minimal);
            WriteLine($"{allUnusedSymbols.Length} unused {((allUnusedSymbols.Length == 1) ? "symbol" : "symbols")} found", ConsoleColor.Green, Verbosity.Minimal);
            WriteLine(Verbosity.Minimal);

            return(CommandResult.Success);
        }
예제 #2
0
        private async Task <ImmutableArray <UnusedSymbolInfo> > AnalyzeProject(Project project, CancellationToken cancellationToken)
        {
            WriteLine($"Analyze '{project.Name}'", Verbosity.Minimal);

            Compilation compilation = await project.GetCompilationAsync(cancellationToken);

            INamedTypeSymbol generatedCodeAttribute = compilation.GetTypeByMetadataName("System.CodeDom.Compiler.GeneratedCodeAttribute");

            ImmutableHashSet <ISymbol> ignoredSymbols = Options.IgnoredSymbols
                                                        .Select(f => DocumentationCommentId.GetFirstSymbolForDeclarationId(f, compilation))
                                                        .Where(f => f != null)
                                                        .ToImmutableHashSet();

            return(await UnusedSymbolFinder.FindUnusedSymbolsAsync(project, compilation, Predicate, ignoredSymbols, cancellationToken : cancellationToken).ConfigureAwait(false));

            bool Predicate(ISymbol symbol)
            {
                return((UnusedSymbolKinds & GetUnusedSymbolKinds(symbol)) != 0 &&
                       IsVisible(symbol) &&
                       (!Options.IgnoreObsolete ||
                        !symbol.HasAttribute(MetadataNames.System_ObsoleteAttribute)) &&
                       (Options.IncludeGeneratedCode ||
                        !GeneratedCodeUtility.IsGeneratedCode(symbol, generatedCodeAttribute, MefWorkspaceServices.Default.GetService <ISyntaxFactsService>(project.Language).IsComment, cancellationToken)));
            }
        }