public override async Task<CommandResult> ExecuteAsync(ProjectOrSolution projectOrSolution, CancellationToken cancellationToken = default)
        {
            var codeMetricsOptions = new CodeMetricsOptions(
                includeGenerated: Options.IncludeGeneratedCode,
                includeWhitespace: Options.IncludeWhitespace,
                includeComments: Options.IncludeComments,
                includePreprocessorDirectives: Options.IncludePreprocessorDirectives,
                ignoreBlockBoundary: Options.IgnoreBlockBoundary);

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

                ICodeMetricsService service = MefWorkspaceServices.Default.GetService<ICodeMetricsService>(project.Language);

                if (service != null)
                {
                    await CountLinesAsync(project, service, codeMetricsOptions, cancellationToken);
                }
                else
                {
                    WriteLine($"Cannot count lines for '{project.FilePath}', language '{project.Language}' is not supported", ConsoleColor.Yellow, Verbosity.Minimal);
                }
            }
            else
            {
                CountLines(projectOrSolution.AsSolution(), codeMetricsOptions, cancellationToken);
            }

            return CommandResult.Success;
        }
        public override async Task <CommandResult> ExecuteAsync(ProjectOrSolution projectOrSolution, CancellationToken cancellationToken = default)
        {
            var codeMetricsOptions = new CodeMetricsOptions(includeGenerated: Options.IncludeGeneratedCode);

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

                ICodeMetricsService service = MefWorkspaceServices.Default.GetService <ICodeMetricsService>(project.Language);

                if (service != null)
                {
                    await CountLogicalLinesAsync(project, service, codeMetricsOptions, cancellationToken);
                }
                else
                {
                    WriteLine($"Cannot count logical lines for language '{project.Language}'", ConsoleColor.Yellow, Verbosity.Minimal);
                }
            }
            else
            {
                CountLines(projectOrSolution.AsSolution(), codeMetricsOptions, cancellationToken);
            }

            return(CommandResult.Success);
        }
        public static ImmutableDictionary <ProjectId, CodeMetricsInfo> CountLinesInParallel(
            IEnumerable <Project> projects,
            LinesOfCodeKind kind,
            CodeMetricsOptions options          = null,
            CancellationToken cancellationToken = default)
        {
            var codeMetrics = new ConcurrentBag <(ProjectId projectId, CodeMetricsInfo codeMetrics)>();

            Parallel.ForEach(projects, project =>
            {
                ICodeMetricsService service = MefWorkspaceServices.Default.GetService <ICodeMetricsService>(project.Language);

                CodeMetricsInfo projectMetrics = (service != null)
                    ? service.CountLinesAsync(project, kind, options, cancellationToken).Result
                    : CodeMetricsInfo.NotAvailable;

                codeMetrics.Add((project.Id, codeMetrics: projectMetrics));
            });
        private static async Task CountLogicalLinesAsync(Project project, ICodeMetricsService service, CodeMetricsOptions options, CancellationToken cancellationToken)
        {
            WriteLine($"Count logical lines for '{project.Name}'", ConsoleColor.Cyan, Verbosity.Minimal);

            Stopwatch stopwatch = Stopwatch.StartNew();

            CodeMetricsInfo codeMetrics = await service.CountLinesAsync(project, LinesOfCodeKind.Logical, options, cancellationToken);

            stopwatch.Stop();

            WriteLine(Verbosity.Minimal);

            WriteMetrics(
                codeMetrics.CodeLineCount,
                codeMetrics.WhitespaceLineCount,
                codeMetrics.CommentLineCount,
                codeMetrics.PreprocessorDirectiveLineCount,
                codeMetrics.TotalLineCount);

            WriteLine(Verbosity.Minimal);
            WriteLine($"Done counting logical lines for '{project.FilePath}' in {stopwatch.Elapsed:mm\\:ss\\.ff}", Verbosity.Normal);
        }