Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        public static AnalyzerAssembly LoadFile(
            string filePath,
            bool loadAnalyzers = true,
            bool loadFixers    = true,
            string language    = null)
        {
            Assembly assembly = Assembly.LoadFrom(filePath);

            return(AnalyzerAssembly.Load(assembly, loadAnalyzers: loadAnalyzers, loadFixers: loadFixers, language: language));
        }
Ejemplo n.º 4
0
        public static IEnumerable <AnalyzerAssemblyInfo> LoadFrom(
            string path,
            bool loadAnalyzers = true,
            bool loadFixers    = true,
            string language    = null)
        {
            if (File.Exists(path))
            {
                AnalyzerAssembly analyzerAssembly = Load(path);

                if (analyzerAssembly?.IsEmpty == false)
                {
                    yield return(new AnalyzerAssemblyInfo(analyzerAssembly, path));
                }
            }
            else if (Directory.Exists(path))
            {
                using (IEnumerator <string> en = Directory.EnumerateFiles(path, "*.dll", SearchOption.AllDirectories).GetEnumerator())
                {
                    while (true)
                    {
                        string           filePath         = null;
                        AnalyzerAssembly analyzerAssembly = null;

                        try
                        {
                            if (en.MoveNext())
                            {
                                filePath         = en.Current;
                                analyzerAssembly = Load(filePath);
                            }
                            else
                            {
                                break;
                            }
                        }
                        catch (Exception ex) when(ex is IOException ||
                                                  ex is SecurityException ||
                                                  ex is UnauthorizedAccessException)
                        {
                            WriteLine(ex.Message, ConsoleColor.DarkGray, Verbosity.Diagnostic);
                            continue;
                        }

                        if (analyzerAssembly?.IsEmpty == false)
                        {
                            yield return(new AnalyzerAssemblyInfo(analyzerAssembly, filePath));
                        }
                    }
                }
            }
            else
            {
                WriteLine($"File or directory not found: '{path}'", ConsoleColor.DarkGray, Verbosity.Normal);
            }

            AnalyzerAssembly Load(string filePath)
            {
                try
                {
                    return(LoadFile(filePath, loadAnalyzers, loadFixers, language));
                }
                catch (Exception ex) when(ex is FileLoadException ||
                                          ex is BadImageFormatException ||
                                          ex is SecurityException)
                {
                    WriteLine($"Cannot load assembly '{filePath}'", ConsoleColor.DarkGray, Verbosity.Diagnostic);

                    return(null);
                }
            }
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 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);
            }
        }
Ejemplo n.º 7
0
        private static XElement SerializeAnalyzerAssembly(AnalyzerAssemblyInfo analyzerAssemblyInfo, IFormatProvider formatProvider)
        {
            AnalyzerAssembly analyzerAssembly = analyzerAssemblyInfo.AnalyzerAssembly;

            DiagnosticMap map = DiagnosticMap.Create(analyzerAssembly);

            return(new XElement(
                       "AnalyzerAssembly",
                       new XAttribute("Name", analyzerAssembly.FullName),
                       new XElement("Location", analyzerAssemblyInfo.FilePath),
                       new XElement("Summary", SerializeSummary()),
                       new XElement("Analyzers", SerializeDiagnosticAnalyzers()),
                       new XElement("Fixers", SerializeCodeFixProviders()),
                       SerializeDiagnostics(map, allProperties: false, useAssemblyQualifiedName: false, formatProvider: formatProvider)));

            IEnumerable <XElement> SerializeSummary()
            {
                if (analyzerAssembly.HasAnalyzers)
                {
                    yield return(new XElement("Analyzers",
                                              new XAttribute("Count", map.Analyzers.Length),
                                              new XElement("Languages",
                                                           analyzerAssembly.AnalyzersByLanguage
                                                           .OrderBy(f => f.Key)
                                                           .Select(f => new XElement("Language", new XAttribute("Name", f.Key), new XAttribute("Count", f.Value.Length)))),
                                              new XElement("SupportedDiagnostics",
                                                           new XAttribute("Count", map.SupportedDiagnostics.Length),
                                                           new XElement("Prefixes",
                                                                        map.SupportedDiagnosticsByPrefix
                                                                        .OrderBy(f => f.Key)
                                                                        .Select(f => new XElement("Prefix", new XAttribute("Value", f.Key), new XAttribute("Count", f.Value.Length)))))));
                }

                if (analyzerAssembly.HasFixers)
                {
                    yield return(new XElement("Fixers",
                                              new XAttribute("Count", map.Fixers.Length),
                                              new XElement("Languages",
                                                           analyzerAssembly.FixersByLanguage
                                                           .OrderBy(f => f.Key)
                                                           .Select(f => new XElement("Language", new XAttribute("Name", f.Key), new XAttribute("Count", f.Value.Length)))),
                                              new XElement("FixableDiagnostics",
                                                           new XAttribute("Count", map.FixableDiagnosticIds.Length),
                                                           new XElement("Prefixes",
                                                                        map.FixableDiagnosticIdsByPrefix
                                                                        .OrderBy(f => f.Key)
                                                                        .Select(f => new XElement("Prefix", new XAttribute("Value", f.Key), new XAttribute("Count", f.Value.Length)))))));
                }
            }

            IEnumerable <XElement> SerializeDiagnosticAnalyzers()
            {
                foreach (DiagnosticAnalyzer analyzer in map.Analyzers.OrderBy(f => f.GetType(), TypeComparer.NamespaceThenName))
                {
                    Type type = analyzer.GetType();

                    DiagnosticAnalyzerAttribute attribute = type.GetCustomAttribute <DiagnosticAnalyzerAttribute>();

                    yield return(new XElement("Analyzer",
                                              new XAttribute("Name", type.FullName),
                                              new XElement("Languages", attribute.Languages.Select(f => new XElement("Language", f))),
                                              new XElement("SupportedDiagnostics",
                                                           analyzer.SupportedDiagnostics
                                                           .Select(f => f.Id)
                                                           .Distinct()
                                                           .OrderBy(f => f)
                                                           .Select(f => new XElement("Id", f)))));
                }
            }

            IEnumerable <XElement> SerializeCodeFixProviders()
            {
                foreach (CodeFixProvider fixer in map.Fixers.OrderBy(f => f.GetType(), TypeComparer.NamespaceThenName))
                {
                    Type type = fixer.GetType();

                    ExportCodeFixProviderAttribute attribute = type.GetCustomAttribute <ExportCodeFixProviderAttribute>();

                    yield return(new XElement("Fixer",
                                              new XAttribute("Name", type.FullName),
                                              new XElement("Languages", attribute.Languages.Select(f => new XElement("Language", f))),
                                              new XElement("FixableDiagnostics", fixer.FixableDiagnosticIds
                                                           .Distinct()
                                                           .OrderBy(f => f)
                                                           .Select(f => new XElement("Id", f))),
                                              CreateFixAllProviderElement(fixer)));
                }

                XElement CreateFixAllProviderElement(CodeFixProvider fixer)
                {
                    FixAllProvider fixAllProvider = fixer.GetFixAllProvider();

                    if (fixAllProvider != null)
                    {
                        return(new XElement("FixAllProvider", new XAttribute("Name", fixAllProvider.GetType().FullName)));
                    }

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

            foreach ((string filePath, AnalyzerAssembly analyzerAssembly) in options.GetPaths()
                     .SelectMany(path => AnalyzerAssembly.LoadFrom(
                                     path: path,
                                     loadAnalyzers: !options.NoAnalyzers,
                                     loadFixers: !options.NoFixers,
                                     language: Language))
                     .OrderBy(f => f.analyzerAssembly.GetName().Name)
                     .ThenBy(f => f.filePath))
            {
                if (assemblies.Add(analyzerAssembly.Assembly))
                {
                    Write($"{analyzerAssembly.FullName}", ConsoleColor.Cyan, Verbosity.Minimal);
                    WriteLine($" [{filePath}]", Verbosity.Minimal);
                }
                else
                {
                    Write($"{analyzerAssembly.FullName}", ConsoleColor.DarkGray, Verbosity.Minimal);
                    WriteLine($" [{filePath}]", ConsoleColor.DarkGray, Verbosity.Minimal);
                    continue;
                }

                DiagnosticAnalyzer[] analyzers = analyzerAssembly
                                                 .Analyzers
                                                 .SelectMany(f => f.Value)
                                                 .Distinct()
                                                 .ToArray();

                if (analyzers.Length > 0)
                {
                    Write($"  {analyzers.Length} DiagnosticAnalyzers (", Verbosity.Normal);

                    using (IEnumerator <KeyValuePair <string, ImmutableArray <DiagnosticAnalyzer> > > en = analyzerAssembly.Analyzers.OrderBy(f => f.Key).GetEnumerator())
                    {
                        if (en.MoveNext())
                        {
                            while (true)
                            {
                                Write($"{en.Current.Value.Length} {Utilities.GetShortLanguageName(en.Current.Key)}", Verbosity.Normal);

                                if (en.MoveNext())
                                {
                                    Write(", ");
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }

                    WriteLine(")", Verbosity.Normal);

                    foreach (DiagnosticAnalyzer analyzer in analyzers.OrderBy(f => f.GetType().FullName))
                    {
                        Type type = analyzer.GetType();

                        DiagnosticAnalyzerAttribute attribute = type.GetCustomAttribute <DiagnosticAnalyzerAttribute>();

                        WriteLine($"    {type.FullName}", Verbosity.Detailed);
                        WriteLine($"      Supported Languages:   {string.Join(", ", attribute.Languages.Select(f => Utilities.GetShortLanguageName(f)).OrderBy(f => f))}", ConsoleColor.DarkGray, Verbosity.Detailed);
                        WriteLine($"      Supported Diagnostics: {string.Join(", ", analyzer.SupportedDiagnostics.Select(f => f.Id).OrderBy(f => f))}", ConsoleColor.DarkGray, Verbosity.Detailed);
                    }
                }

                CodeFixProvider[] fixers = analyzerAssembly
                                           .Fixers
                                           .SelectMany(f => f.Value)
                                           .Distinct()
                                           .ToArray();

                if (fixers.Length > 0)
                {
                    Write($"  {fixers.Length} CodeFixProviders (", Verbosity.Normal);

                    using (IEnumerator <KeyValuePair <string, ImmutableArray <CodeFixProvider> > > en = analyzerAssembly.Fixers.OrderBy(f => f.Key).GetEnumerator())
                    {
                        if (en.MoveNext())
                        {
                            while (true)
                            {
                                Write($"{en.Current.Value.Length} {Utilities.GetShortLanguageName(en.Current.Key)}", Verbosity.Normal);

                                if (en.MoveNext())
                                {
                                    Write(", ");
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }

                    WriteLine(")", Verbosity.Normal);

                    foreach (CodeFixProvider fixer in fixers.OrderBy(f => f.GetType().FullName))
                    {
                        Type type = fixer.GetType();

                        ExportCodeFixProviderAttribute attribute = type.GetCustomAttribute <ExportCodeFixProviderAttribute>();

                        WriteLine($"    {type.FullName}", Verbosity.Detailed);
                        WriteLine($"      Supported Languages: {string.Join(", ", attribute.Languages.Select(f => Utilities.GetShortLanguageName(f)).OrderBy(f => f))}", ConsoleColor.DarkGray, Verbosity.Detailed);
                        WriteLine($"      Fixable Diagnostics: {string.Join(", ", fixer.FixableDiagnosticIds.OrderBy(f => f))}", ConsoleColor.DarkGray, Verbosity.Detailed);

                        Write("      FixAllProvider:      ", ConsoleColor.DarkGray, Verbosity.Detailed);

                        FixAllProvider fixAllProvider = fixer.GetFixAllProvider();

                        if (fixAllProvider != null)
                        {
                            WriteLine($"{fixAllProvider.GetType().FullName} ({string.Join(", ", fixAllProvider.GetSupportedFixAllScopes().Select(f => f.ToString()).OrderBy(f => f))})", ConsoleColor.DarkGray, Verbosity.Detailed);
                        }
                        else
                        {
                            WriteLine("-", ConsoleColor.DarkGray, Verbosity.Detailed);
                        }
                    }
                }
            }

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

            return(CommandResult.Success);
        }
Ejemplo n.º 9
0
 public static DiagnosticMap Create(AnalyzerAssembly analyzerAssembly)
 {
     return(Create(analyzerAssembly.GetAnalyzers(), analyzerAssembly.GetFixers()));
 }
Ejemplo n.º 10
0
 public AnalyzerAssemblyInfo(AnalyzerAssembly analyzerAssembly, string filePath)
 {
     AnalyzerAssembly = analyzerAssembly;
     FilePath         = filePath;
 }