public CommandResult Execute(AnalyzeAssemblyCommandLineOptions options)
        {
            var assemblies = new HashSet <Assembly>();

            AnalyzerAssemblyInfo[] analyzerAssemblies = options.GetPaths()
                                                        .SelectMany(path => AnalyzerAssemblyLoader.LoadFrom(
                                                                        path: path,
                                                                        loadAnalyzers: !options.NoAnalyzers,
                                                                        loadFixers: !options.NoFixers,
                                                                        language: Language))
                                                        .OrderBy(f => f.AnalyzerAssembly.Assembly.GetName().Name)
                                                        .ThenBy(f => f.FilePath)
                                                        .ToArray();

            for (int i = 0; i < analyzerAssemblies.Length; i++)
            {
                AnalyzerAssembly analyzerAssembly = analyzerAssemblies[i].AnalyzerAssembly;

                if (assemblies.Add(analyzerAssembly.Assembly))
                {
                    WriteLine(analyzerAssembly.FullName, ConsoleColor.Cyan, Verbosity.Minimal);

                    if (ShouldWrite(Verbosity.Normal))
                    {
                        WriteAnalyzerAssembly(analyzerAssemblies[i], DiagnosticMap.Create(analyzerAssembly));

                        if (i < analyzerAssemblies.Length - 1)
                        {
                            WriteLine(Verbosity.Normal);
                        }
                    }
                }
                else
                {
                    Write(analyzerAssembly.FullName, ConsoleColor.DarkGray, Verbosity.Minimal);
                    WriteLine($" [{analyzerAssemblies[i].FilePath}]", ConsoleColor.DarkGray, Verbosity.Minimal);
                }
            }

            if (ShouldWrite(Verbosity.Detailed) &&
                analyzerAssemblies.Length > 1)
            {
                DiagnosticMap map = DiagnosticMap.Create(analyzerAssemblies.Select(f => f.AnalyzerAssembly));

                WriteLine(Verbosity.Detailed);
                WriteDiagnostics(map, allProperties: true, useAssemblyQualifiedName: true);
            }

            WriteLine(Verbosity.Minimal);
            WriteLine($"{assemblies.Count} analyzer {((assemblies.Count == 1) ? "assembly" : "assemblies")} found", ConsoleColor.Green, Verbosity.Minimal);
            WriteLine(Verbosity.Minimal);

            if (options.Output != null &&
                analyzerAssemblies.Length > 0)
            {
                AnalyzerAssemblyXmlSerializer.Serialize(analyzerAssemblies, options.Output);
            }

            return(CommandResult.Success);
        }
Beispiel #2
0
        public static void WriteXml(
            XmlWriter writer,
            IEnumerable <AnalyzerAssembly> analyzerAssemblies,
            string name,
            Version toolsVersion,
            string description             = null,
            IFormatProvider formatProvider = null)
        {
            writer.WriteStartDocument();

            writer.WriteStartElement("RuleSet");
            writer.WriteAttributeString("Name", name);
            writer.WriteAttributeString("ToolsVersion", toolsVersion.ToString(2));

            if (!string.IsNullOrEmpty(description))
            {
                writer.WriteAttributeString("Description", description);
            }

            foreach (AnalyzerAssembly analyzerAssembly in analyzerAssemblies.OrderBy(f => f.Name))
            {
                using (IEnumerator <DiagnosticDescriptor> en = DiagnosticMap.Create(analyzerAssembly).SupportedDiagnostics
                                                               .Where(f => !f.CustomTags.Contains(WellKnownDiagnosticTags.NotConfigurable) &&
                                                                      !f.IsAnalyzerExceptionDescriptor())
                                                               .OrderBy(f => f.Id)
                                                               .GetEnumerator())
                {
                    if (en.MoveNext())
                    {
                        writer.WriteStartElement("Rules");
                        writer.WriteAttributeString("AnalyzerId", analyzerAssembly.Name);
                        writer.WriteAttributeString("RuleNamespace", analyzerAssembly.Name);

                        do
                        {
                            writer.WriteWhitespace(writer.Settings.NewLineChars);
                            writer.WriteWhitespace(writer.Settings.IndentChars);
                            writer.WriteWhitespace(writer.Settings.IndentChars);
                            writer.WriteStartElement("Rule");
                            DiagnosticDescriptor current = en.Current;
                            writer.WriteAttributeString("Id", current.Id);
                            writer.WriteAttributeString("Action", GetAction(current));
                            writer.WriteEndElement();

                            string title = current.Title.ToString(formatProvider);

                            if (!string.IsNullOrEmpty(title))
                            {
                                writer.WriteWhitespace(" ");
                                writer.WriteComment($" {title} ");
                            }
                        }while (en.MoveNext());

                        writer.WriteWhitespace(writer.Settings.NewLineChars);
                        writer.WriteWhitespace(writer.Settings.IndentChars);
                        writer.WriteEndElement();
                    }
                }
            }
Beispiel #3
0
        public CommandStatus Execute(AnalyzeAssemblyCommandLineOptions options)
        {
            var assemblies = new HashSet <Assembly>();

            AnalyzerAssemblyInfo[] analyzerAssemblies = options.GetPaths()
                                                        .SelectMany(path => AnalyzerAssemblyLoader.LoadFrom(
                                                                        path: path,
                                                                        searchPattern: options.FileNamePattern ?? AnalyzerAssemblyLoader.DefaultSearchPattern,
                                                                        loadAnalyzers: !options.NoAnalyzers,
                                                                        loadFixers: !options.NoFixers,
                                                                        language: Language))
                                                        .OrderBy(f => f.AnalyzerAssembly.Assembly.GetName().Name)
                                                        .ThenBy(f => f.FilePath)
                                                        .ToArray();

            for (int i = 0; i < analyzerAssemblies.Length; i++)
            {
                AnalyzerAssembly analyzerAssembly = analyzerAssemblies[i].AnalyzerAssembly;

                if (assemblies.Add(analyzerAssembly.Assembly))
                {
                    WriteLine(analyzerAssembly.FullName, ConsoleColors.Cyan, Verbosity.Minimal);

                    if (ShouldWrite(Verbosity.Normal))
                    {
                        WriteAnalyzerAssembly(analyzerAssemblies[i], DiagnosticMap.Create(analyzerAssembly));

                        if (i < analyzerAssemblies.Length - 1)
                        {
                            WriteLine(Verbosity.Normal);
                        }
                    }
                }
                else
                {
                    Write(analyzerAssembly.FullName, ConsoleColors.DarkGray, Verbosity.Minimal);
                    WriteLine($" [{analyzerAssemblies[i].FilePath}]", ConsoleColors.DarkGray, Verbosity.Minimal);
                }
            }

            if (ShouldWrite(Verbosity.Detailed) &&
                analyzerAssemblies.Length > 1)
            {
                DiagnosticMap map = DiagnosticMap.Create(analyzerAssemblies.Select(f => f.AnalyzerAssembly));

                WriteLine(Verbosity.Detailed);
                WriteDiagnostics(map, allProperties: true, useAssemblyQualifiedName: true);
            }

            WriteLine(Verbosity.Minimal);
            WriteLine($"{assemblies.Count} analyzer {((assemblies.Count == 1) ? "assembly" : "assemblies")} found", ConsoleColors.Green, Verbosity.Minimal);

            if (analyzerAssemblies.Length > 0)
            {
                CultureInfo culture = (options.Culture != null) ? CultureInfo.GetCultureInfo(options.Culture) : null;

                foreach (string path in options.Output)
                {
                    WriteLine($"Save '{path}'", ConsoleColors.DarkGray, Verbosity.Diagnostic);

                    string extension = Path.GetExtension(path);

                    if (string.Equals(extension, ".xml", StringComparison.OrdinalIgnoreCase))
                    {
                        AnalyzerAssemblyXmlSerializer.Serialize(path, analyzerAssemblies, culture);
                    }
                    else if (string.Equals(extension, ".ruleset", StringComparison.OrdinalIgnoreCase))
                    {
                        WriteLine($"Save ruleset to '{path}'", ConsoleColors.DarkGray, Verbosity.Diagnostic);

                        using (var fileStream = new FileStream(path, FileMode.Create))
                            using (XmlWriter xmlWriter = XmlWriter.Create(fileStream, new XmlWriterSettings()
                            {
                                Indent = true, IndentChars = "  ", CloseOutput = false
                            }))
                            {
                                RuleSetUtility.WriteXml(
                                    writer: xmlWriter,
                                    analyzerAssemblies: analyzerAssemblies.Select(f => f.AnalyzerAssembly),
                                    name: "",
                                    toolsVersion: new Version(15, 0),
                                    description: null,
                                    formatProvider: culture);
                            }
                    }
                }
            }

            return((analyzerAssemblies.Length > 0) ? CommandStatus.Success : CommandStatus.NotSuccess);
        }
Beispiel #4
0
        private static void WriteDiagnostics(
            DiagnosticMap map,
            bool allProperties            = true,
            bool useAssemblyQualifiedName = false)
        {
            WriteLine("  Diagnostics:", Verbosity.Detailed);

            foreach (KeyValuePair <string, DiagnosticDescriptor> kvp in map.DiagnosticsById.OrderBy(f => f.Key))
            {
                WriteDiagnostic(kvp.Key, kvp.Value);
            }

            void WriteDiagnostic(string diagnosticId, DiagnosticDescriptor descriptor)
            {
                if (descriptor == null)
                {
                    WriteLine($"    {diagnosticId}", Verbosity.Detailed);
                }
                else
                {
                    string title         = descriptor.Title?.ToString();
                    string messageFormat = descriptor.MessageFormat?.ToString();

                    if (string.IsNullOrEmpty(title))
                    {
                        title = messageFormat;
                    }

                    WriteLine($"    {diagnosticId} {title}", Verbosity.Detailed);

                    if (allProperties &&
                        ShouldWrite(Verbosity.Diagnostic))
                    {
                        if (title != messageFormat)
                        {
                            WriteLine($"      MessageFormat:       {messageFormat}", ConsoleColors.DarkGray, Verbosity.Diagnostic);
                        }

                        WriteLine($"      Category:            {descriptor.Category}", ConsoleColors.DarkGray, Verbosity.Diagnostic);
                        WriteLine($"      DefaultSeverity:     {descriptor.DefaultSeverity}", ConsoleColors.DarkGray, Verbosity.Diagnostic);
                        WriteLine($"      IsEnabledByDefault:  {descriptor.IsEnabledByDefault}", ConsoleColors.DarkGray, Verbosity.Diagnostic);

                        string description = descriptor.Description?.ToString();

                        if (!string.IsNullOrEmpty(description))
                        {
                            WriteLine($"      Description:         {description}", ConsoleColors.DarkGray, Verbosity.Diagnostic);
                        }

                        if (!string.IsNullOrEmpty(descriptor.HelpLinkUri))
                        {
                            WriteLine($"      HelpLinkUri:         {descriptor.HelpLinkUri}", ConsoleColors.DarkGray, Verbosity.Diagnostic);
                        }

                        string customTags = string.Join(", ", descriptor.CustomTags.OrderBy(f => f));

                        if (!string.IsNullOrEmpty(customTags))
                        {
                            WriteLine($"      CustomTags:          {customTags}", ConsoleColors.DarkGray, Verbosity.Diagnostic);
                        }
                    }
                }

                if (ShouldWrite(Verbosity.Diagnostic))
                {
                    if (map.AnalyzersById.TryGetValue(diagnosticId, out IEnumerable <DiagnosticAnalyzer> analyzers2))
                    {
                        Write("      DiagnosticAnalyzers: ", ConsoleColors.DarkGray, Verbosity.Diagnostic);

                        WriteTypes(analyzers2.Select(f => f.GetType()));
                    }

                    if (map.FixersById.TryGetValue(diagnosticId, out IEnumerable <CodeFixProvider> fixers2))
                    {
                        Write("      CodeFixProviders:    ", ConsoleColors.DarkGray, Verbosity.Diagnostic);

                        WriteTypes(fixers2.Select(f => f.GetType()));
                    }
                }
            }

            void WriteTypes(IEnumerable <Type> types)
            {
                using (IEnumerator <Type> en = types.OrderBy(f => f, TypeComparer.NamespaceThenName).GetEnumerator())
                {
                    if (en.MoveNext())
                    {
                        while (true)
                        {
                            string name = (useAssemblyQualifiedName) ? en.Current.AssemblyQualifiedName : en.Current.FullName;

                            WriteLine(name, ConsoleColors.DarkGray, Verbosity.Diagnostic);

                            if (en.MoveNext())
                            {
                                Write("                           ", ConsoleColors.DarkGray, Verbosity.Diagnostic);
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }
Beispiel #5
0
        private static (int maxLength, int maxDigitLength) CalculateMaxLength(AnalyzerAssembly analyzerAssembly, DiagnosticMap map)
        {
            int maxLength      = 22;
            int maxDigitLength = 0;

            if (analyzerAssembly.HasAnalyzers)
            {
                maxLength = Math.Max(maxLength, analyzerAssembly.AnalyzersByLanguage.Max(f => GetShortLanguageName(f.Key).Length + 3));
                maxLength = Math.Max(maxLength, map.SupportedDiagnosticsByPrefix.Max(f => f.Key.Length + 3));

                maxDigitLength = Math.Max(maxDigitLength, map.Analyzers.Length.ToString().Length);
                maxDigitLength = Math.Max(maxDigitLength, map.SupportedDiagnostics.Length.ToString().Length);
            }

            if (analyzerAssembly.HasFixers)
            {
                maxLength = Math.Max(maxLength, analyzerAssembly.FixersByLanguage.Max(f => GetShortLanguageName(f.Key).Length + 3));
                maxLength = Math.Max(maxLength, map.FixableDiagnosticIdsByPrefix.Max(f => f.Key.Length + 3));

                maxDigitLength = Math.Max(maxDigitLength, map.Fixers.Length.ToString().Length);
                maxDigitLength = Math.Max(maxDigitLength, map.FixableDiagnosticIds.Length.ToString().Length);
            }

            return(maxLength, maxDigitLength);
        }
Beispiel #6
0
        private static void WriteAnalyzerAssembly(AnalyzerAssemblyInfo analyzerAssemblyInfo, DiagnosticMap map)
        {
            AnalyzerAssembly analyzerAssembly = analyzerAssemblyInfo.AnalyzerAssembly;

            WriteLine(Verbosity.Normal);
            WriteLine($"  Location:             {analyzerAssemblyInfo.FilePath}", Verbosity.Normal);

            (int maxLength, int maxDigitLength) = CalculateMaxLength(analyzerAssembly, map);

            if (analyzerAssembly.HasAnalyzers)
            {
                WriteLine($"  DiagnosticAnalyzers:  {map.Analyzers.Length.ToString().PadLeft(maxDigitLength)}", Verbosity.Normal);

                foreach (KeyValuePair <string, ImmutableArray <DiagnosticAnalyzer> > kvp in analyzerAssembly.AnalyzersByLanguage.OrderBy(f => f.Key))
                {
                    WriteLine($"    {GetShortLanguageName(kvp.Key).PadRight(maxLength - 2)}{kvp.Value.Length.ToString().PadLeft(maxDigitLength)}", Verbosity.Normal);
                }

                WriteLine($"  SupportedDiagnostics: {map.SupportedDiagnostics.Length.ToString().PadLeft(maxDigitLength)}", Verbosity.Normal);

                foreach (KeyValuePair <string, ImmutableArray <DiagnosticDescriptor> > kvp in map.SupportedDiagnosticsByPrefix
                         .OrderBy(f => f.Key))
                {
                    WriteLine($"    {kvp.Key.PadRight(maxLength - 2)}{kvp.Value.Length.ToString().PadLeft(maxDigitLength)}", Verbosity.Normal);
                }
            }

            if (analyzerAssembly.HasFixers)
            {
                WriteLine($"  CodeFixProviders:     {map.Fixers.Length.ToString().PadLeft(maxDigitLength)}", Verbosity.Normal);

                foreach (KeyValuePair <string, ImmutableArray <CodeFixProvider> > kvp in analyzerAssembly.FixersByLanguage.OrderBy(f => f.Key))
                {
                    WriteLine($"    {GetShortLanguageName(kvp.Key).PadRight(maxLength - 2)}{kvp.Value.Length.ToString().PadLeft(maxDigitLength)}", Verbosity.Normal);
                }

                WriteLine($"  FixableDiagnosticIds: {map.FixableDiagnosticIds.Length}", Verbosity.Normal);

                foreach (KeyValuePair <string, ImmutableArray <string> > kvp in map.FixableDiagnosticIdsByPrefix
                         .OrderBy(f => f.Key))
                {
                    WriteLine($"    {kvp.Key.PadRight(maxLength - 2)}{kvp.Value.Length.ToString().PadLeft(maxDigitLength)}", Verbosity.Normal);
                }
            }

            if (ShouldWrite(Verbosity.Detailed))
            {
                if (analyzerAssembly.HasAnalyzers)
                {
                    WriteLine(Verbosity.Detailed);
                    WriteDiagnosticAnalyzers(map.Analyzers);
                }

                if (analyzerAssembly.HasFixers)
                {
                    WriteLine(Verbosity.Detailed);
                    WriteCodeFixProviders(map.Fixers);
                }

                WriteLine(Verbosity.Detailed);
                WriteDiagnostics(map, allProperties: false, useAssemblyQualifiedName: false);
            }
        }