public static int Main(string[] args)
        {
            var options = new Options();
            if (!options.Parse())
            {
                PrintUsage(options);
                return -1;
            }

            var cts = new CancellationTokenSource();
            var ct = cts.Token;
            Console.CancelKeyPress += delegate { cts.Cancel(); };

            try
            {
                var engine = AnalysisEngine.FromFilePaths(
                    options.FilePaths,
                    symbolConfigurations: options.SymbolConfigurations,
                    alwaysDefinedSymbols: options.DefinedSymbols,
                    alwaysDisabledSymbols: options.DisabledSymbols,
                    alwaysIgnoredSymbols: options.IgnoredSymbols,
                    undefinedSymbolValue: options.UndefinedSymbolValue,
                    cancellationToken: ct).Result;

                engine.DocumentAnalyzed += (analysisEngine, info, cancellationToken) => OnDocumentAnalyzed(analysisEngine, options, info, cancellationToken);
                RunAsync(engine, options, ct).Wait(ct);
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine("Canceled.");
                return 1;
            }

            return 0;
        }
        private static async Task RunAsync(AnalysisEngine engine, Options options, CancellationToken cancellationToken)
        {
            var regionInfos = await engine.GetConditionalRegionInfo(cancellationToken);

            PrintConditionalRegionInfo(options, regionInfos);

            if (options.PrintSymbolInfo)
            {
                Console.WriteLine();
                PrintSymbolInfo(engine);
            }
        }
        private static void PrintUsage(Options options)
        {
            Console.WriteLine(
@"SYNTAX
  DeadRegions [<project> ...] [options]
  DeadRegions [<source file> ...] [options]
");

            Console.WriteLine(options.Usage);

            Console.WriteLine(
@"NOTES
  * The (possibly) environment dependent set of preprocessor symbols for a
    given project determined by MsBuild when loading an input project file will
    be ignored; only explicitly specified build configurations will be used in
    analysis.

  * When multiple projects are specified as input, the intersection of the
    files in all the projects will be analyzed.

  * <symbol list> is a comma or semi-colon separated list of preprocessor
    symbols.");
        }
예제 #4
0
        private static void PrintConditionalRegionInfo(Options options, IEnumerable <DocumentConditionalRegionInfo> regionInfos)
        {
            int disabledCount = 0;
            int enabledCount  = 0;
            int varyingCount  = 0;

            var originalForegroundColor = Console.ForegroundColor;

            foreach (var info in regionInfos)
            {
                foreach (var chain in info.Chains)
                {
                    foreach (var region in chain.Regions)
                    {
                        if (region.State == Tristate.False)
                        {
                            disabledCount++;
                            Console.ForegroundColor = ConsoleColor.Blue;
                            if (options.PrintDisabled)
                            {
                                Console.WriteLine(region);
                            }
                        }
                        else if (region.State == Tristate.True)
                        {
                            enabledCount++;
                            Console.ForegroundColor = ConsoleColor.Green;
                            if (options.PrintEnabled)
                            {
                                Console.WriteLine(region);
                            }
                        }
                        else
                        {
                            varyingCount++;
                            Console.ForegroundColor = ConsoleColor.DarkGray;
                            if (options.PrintVarying)
                            {
                                Console.WriteLine(region);
                            }
                        }
                    }
                }
            }

            Console.ForegroundColor = originalForegroundColor;

            // Print summary
            int totalRegionCount = disabledCount + enabledCount + varyingCount;

            if (totalRegionCount == 0)
            {
                Console.WriteLine("Did not find any conditional regions.");
            }
            else
            {
                Console.WriteLine("Conditional Regions");
                Console.WriteLine("  {0,5} found in total", totalRegionCount);

                if (disabledCount > 0)
                {
                    Console.WriteLine("  {0,5} always disabled", disabledCount);
                }

                if (enabledCount > 0)
                {
                    Console.WriteLine("  {0,5} always enabled", enabledCount);
                }

                if (varyingCount > 0)
                {
                    Console.WriteLine("  {0,5} varying", varyingCount);
                }
            }

            // TODO: Lines of disabled/enabled/varying code. This involves calculating unnecessary regions, converting those to line spans.
        }
        private static async Task OnDocumentAnalyzed(AnalysisEngine engine, Options options, DocumentConditionalRegionInfo info, CancellationToken cancellationToken)
        {
            if (options.Edit)
            {
                var fileInfo = new FileInfo(info.Document.FilePath);
                if (fileInfo.IsReadOnly || !fileInfo.Exists)
                {
                    Console.WriteLine("warning: skipping document '{0}' because it {1}.",
                        info.Document.FilePath, fileInfo.IsReadOnly ? "is read-only" : "does not exist");
                    return;
                }

                var document = await engine.RemoveUnnecessaryRegions(info, cancellationToken);
                document = await engine.SimplifyVaryingPreprocessorExpressions(document, cancellationToken);

                var text = await document.GetTextAsync(cancellationToken);
                using (var file = File.Open(document.FilePath, FileMode.Truncate, FileAccess.Write))
                {
                    var writer = new StreamWriter(file, text.Encoding);
                    text.Write(writer, cancellationToken);
                    await writer.FlushAsync();
                }
            }
        }
        private static void PrintConditionalRegionInfo(Options options, IEnumerable<DocumentConditionalRegionInfo> regionInfos)
        {
            int disabledCount = 0;
            int enabledCount = 0;
            int varyingCount = 0;

            var originalForegroundColor = Console.ForegroundColor;

            foreach (var info in regionInfos)
            {
                foreach (var chain in info.Chains)
                {
                    foreach (var region in chain.Regions)
                    {
                        if (region.State == Tristate.False)
                        {
                            disabledCount++;
                            Console.ForegroundColor = ConsoleColor.Blue;
                            if (options.PrintDisabled)
                            {
                                Console.WriteLine(region);
                            }
                        }
                        else if (region.State == Tristate.True)
                        {
                            enabledCount++;
                            Console.ForegroundColor = ConsoleColor.Green;
                            if (options.PrintEnabled)
                            {
                                Console.WriteLine(region);
                            }
                        }
                        else
                        {
                            varyingCount++;
                            Console.ForegroundColor = ConsoleColor.DarkGray;
                            if (options.PrintVarying)
                            {
                                Console.WriteLine(region);
                            }
                        }
                    }
                }
            }

            Console.ForegroundColor = originalForegroundColor;

            // Print summary
            int totalRegionCount = disabledCount + enabledCount + varyingCount;
            if (totalRegionCount == 0)
            {
                Console.WriteLine("Did not find any conditional regions.");
            }
            else
            {
                Console.WriteLine("Conditional Regions");
                Console.WriteLine("  {0,5} found in total", totalRegionCount);

                if (disabledCount > 0)
                {
                    Console.WriteLine("  {0,5} always disabled", disabledCount);
                }

                if (enabledCount > 0)
                {
                    Console.WriteLine("  {0,5} always enabled", enabledCount);
                }

                if (varyingCount > 0)
                {
                    Console.WriteLine("  {0,5} varying", varyingCount);
                }
            }

            // TODO: Lines of disabled/enabled/varying code. This involves calculating unnecessary regions, converting those to line spans.
        }