private static void WriteCodeFixProviders(IEnumerable <CodeFixProvider> fixers) { WriteLine(" CodeFixProviders:", Verbosity.Detailed); foreach (CodeFixProvider fixer in fixers.OrderBy(f => f.GetType(), TypeComparer.NamespaceThenName)) { Type type = fixer.GetType(); ExportCodeFixProviderAttribute attribute = type.GetCustomAttribute <ExportCodeFixProviderAttribute>(); WriteLine($" {type.FullName}", Verbosity.Detailed); if (ShouldWrite(Verbosity.Diagnostic)) { WriteLine($" Languages: {string.Join(", ", attribute.Languages.Select(f => GetShortLanguageName(f)).OrderBy(f => f))}", ConsoleColors.DarkGray, Verbosity.Diagnostic); WriteLine($" FixableDiagnosticIds: {string.Join(", ", fixer.FixableDiagnosticIds.Distinct().OrderBy(f => f))}", ConsoleColors.DarkGray, Verbosity.Diagnostic); Write(" FixAllProvider: ", ConsoleColors.DarkGray, Verbosity.Diagnostic); FixAllProvider fixAllProvider = fixer.GetFixAllProvider(); if (fixAllProvider != null) { WriteLine($"{fixAllProvider.GetType().FullName} ({string.Join(", ", fixAllProvider.GetSupportedFixAllScopes().Select(f => f.ToString()).OrderBy(f => f))})", ConsoleColors.DarkGray, Verbosity.Diagnostic); } else { WriteLine("-", ConsoleColors.DarkGray, Verbosity.Diagnostic); } } } }
internal CodeDiagnosticFixDescriptor(Type codeFixProviderType, ExportCodeFixProviderAttribute attribute) { if (codeFixProviderType == null) { throw new ArgumentNullException("codeFixProviderType"); } if (attribute == null) { throw new ArgumentNullException("attribute"); } this.codeFixProviderType = codeFixProviderType; this.attribute = attribute; }
/// <summary> /// Get all the <see cref="CodeFixProvider"/>s that are implemented in the given <see cref="AnalyzerFileReference"/> /// </summary> /// <returns>An array of <see cref="CodeFixProvider"/>s</returns> public static ImmutableArray <CodeFixProvider> GetFixers(this AnalyzerFileReference analyzerFileReference) { if (analyzerFileReference == null) { return(ImmutableArray <CodeFixProvider> .Empty); } IEnumerable <TypeInfo> typeInfos = null; ImmutableArray <CodeFixProvider> .Builder builder = null; try { Assembly analyzerAssembly = analyzerFileReference.GetAssembly(); typeInfos = analyzerAssembly.DefinedTypes; foreach (TypeInfo typeInfo in typeInfos) { if (typeInfo.IsSubclassOf(typeof(CodeFixProvider))) { try { ExportCodeFixProviderAttribute attribute = typeInfo.GetCustomAttribute <ExportCodeFixProviderAttribute>(); if (attribute != null) { builder = builder ?? ImmutableArray.CreateBuilder <CodeFixProvider>(); var fixer = (CodeFixProvider)Activator.CreateInstance(typeInfo.AsType()); if (HasImplementation(fixer)) { builder.Add(fixer); } } } catch { } } } } catch { } return(builder != null?builder.ToImmutable() : ImmutableArray <CodeFixProvider> .Empty); }
public static AnalyzerAssembly Load( Assembly analyzerAssembly, bool loadAnalyzers = true, bool loadFixers = true, string language = null) { Debug.Assert(loadAnalyzers || loadFixers); Dictionary <string, ImmutableArray <DiagnosticAnalyzer> .Builder> analyzers = null; Dictionary <string, ImmutableArray <CodeFixProvider> .Builder> fixers = null; try { foreach (TypeInfo typeInfo in analyzerAssembly.DefinedTypes) { if (loadAnalyzers && !typeInfo.IsAbstract && typeInfo.IsSubclassOf(typeof(DiagnosticAnalyzer))) { DiagnosticAnalyzerAttribute attribute = typeInfo.GetCustomAttribute <DiagnosticAnalyzerAttribute>(); if (attribute != null) { DiagnosticAnalyzer analyzer = CreateInstanceAndCatchIfThrows <DiagnosticAnalyzer>(typeInfo); if (analyzer != null) { if (analyzers == null) { analyzers = new Dictionary <string, ImmutableArray <DiagnosticAnalyzer> .Builder>(); } foreach (string language2 in attribute.Languages) { if (language == null || language == language2) { if (!analyzers.TryGetValue(language2, out ImmutableArray <DiagnosticAnalyzer> .Builder value)) { analyzers[language2] = ImmutableArray.CreateBuilder <DiagnosticAnalyzer>(); } analyzers[language2].Add(analyzer); } } } } } else if (loadFixers && !typeInfo.IsAbstract && typeInfo.IsSubclassOf(typeof(CodeFixProvider))) { ExportCodeFixProviderAttribute attribute = typeInfo.GetCustomAttribute <ExportCodeFixProviderAttribute>(); if (attribute != null) { CodeFixProvider fixer = CreateInstanceAndCatchIfThrows <CodeFixProvider>(typeInfo); if (fixer != null) { if (fixers == null) { fixers = new Dictionary <string, ImmutableArray <CodeFixProvider> .Builder>(); } foreach (string language2 in attribute.Languages) { if (language == null || language == language2) { if (!fixers.TryGetValue(language2, out ImmutableArray <CodeFixProvider> .Builder value)) { fixers[language2] = ImmutableArray.CreateBuilder <CodeFixProvider>(); } fixers[language2].Add(fixer); } } } } } } } catch (ReflectionTypeLoadException) { WriteLine($"Cannot load types from assembly '{analyzerAssembly.FullName}'", ConsoleColors.DarkGray, Verbosity.Diagnostic); } return(new AnalyzerAssembly( analyzerAssembly, analyzers?.ToImmutableDictionary(f => f.Key, f => f.Value.ToImmutableArray()) ?? ImmutableDictionary <string, ImmutableArray <DiagnosticAnalyzer> > .Empty, fixers?.ToImmutableDictionary(f => f.Key, f => f.Value.ToImmutableArray()) ?? ImmutableDictionary <string, ImmutableArray <CodeFixProvider> > .Empty)); }
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); }
public static AnalyzerFile Create(Assembly analyzerAssembly) { Dictionary <string, ImmutableArray <DiagnosticAnalyzer> .Builder> analyzers = null; Dictionary <string, ImmutableArray <CodeFixProvider> .Builder> fixers = null; try { foreach (TypeInfo typeInfo in analyzerAssembly.DefinedTypes) { if (typeInfo.IsSubclassOf(typeof(DiagnosticAnalyzer))) { DiagnosticAnalyzerAttribute attribute = typeInfo.GetCustomAttribute <DiagnosticAnalyzerAttribute>(); if (attribute != null) { var analyzer = (DiagnosticAnalyzer)Activator.CreateInstance(typeInfo.AsType()); if (analyzers == null) { analyzers = new Dictionary <string, ImmutableArray <DiagnosticAnalyzer> .Builder>(); } foreach (string language in attribute.Languages) { if (!analyzers.TryGetValue(language, out ImmutableArray <DiagnosticAnalyzer> .Builder value)) { analyzers[language] = ImmutableArray.CreateBuilder <DiagnosticAnalyzer>(); } analyzers[language].Add(analyzer); } } } else if (typeInfo.IsSubclassOf(typeof(CodeFixProvider))) { ExportCodeFixProviderAttribute attribute = typeInfo.GetCustomAttribute <ExportCodeFixProviderAttribute>(); if (attribute != null) { var fixer = (CodeFixProvider)Activator.CreateInstance(typeInfo.AsType()); if (fixers == null) { fixers = new Dictionary <string, ImmutableArray <CodeFixProvider> .Builder>(); } foreach (string language in attribute.Languages) { if (!fixers.TryGetValue(language, out ImmutableArray <CodeFixProvider> .Builder value)) { fixers[language] = ImmutableArray.CreateBuilder <CodeFixProvider>(); } fixers[language].Add(fixer); } } } } } catch (ReflectionTypeLoadException) { #if DEBUG WriteLine($"Cannot load types from assembly '{analyzerAssembly.Location}'", ConsoleColor.Yellow); #endif } return(new AnalyzerFile( analyzerAssembly, analyzers?.ToImmutableDictionary(f => f.Key, f => f.Value.ToImmutableArray()) ?? ImmutableDictionary <string, ImmutableArray <DiagnosticAnalyzer> > .Empty, fixers?.ToImmutableDictionary(f => f.Key, f => f.Value.ToImmutableArray()) ?? ImmutableDictionary <string, ImmutableArray <CodeFixProvider> > .Empty)); }
public static AnalyzerAssembly Load( Assembly analyzerAssembly, bool loadAnalyzers = true, bool loadFixers = true, string language = null) { Debug.Assert(loadAnalyzers || loadFixers); Dictionary <string, ImmutableArray <DiagnosticAnalyzer> .Builder> analyzers = null; Dictionary <string, ImmutableArray <CodeFixProvider> .Builder> fixers = null; TypeInfo[] types = null; try { types = analyzerAssembly.DefinedTypes.ToArray(); } catch (ReflectionTypeLoadException ex) { types = ex.Types.OfType <TypeInfo>().ToArray(); int count = ex.Types.Count(f => f == null); string message = $"Cannot load {count} type{((count == 1) ? "" : "s")} from assembly '{analyzerAssembly.FullName}'"; if (!string.IsNullOrEmpty(analyzerAssembly.Location)) { message += $" at '{analyzerAssembly.Location}'"; } WriteLine(message, ConsoleColors.DarkGray, Verbosity.Diagnostic); foreach (Exception loadeException in ex.LoaderExceptions) { WriteLine($" {loadeException.Message}", ConsoleColors.DarkGray, Verbosity.Diagnostic); } } foreach (TypeInfo typeInfo in types) { if (loadAnalyzers && !typeInfo.IsAbstract && typeInfo.IsSubclassOf(typeof(DiagnosticAnalyzer))) { DiagnosticAnalyzerAttribute attribute = typeInfo.GetCustomAttribute <DiagnosticAnalyzerAttribute>(); if (attribute != null) { DiagnosticAnalyzer analyzer = CreateInstanceAndCatchIfThrows <DiagnosticAnalyzer>(typeInfo); if (analyzer != null) { if (analyzers == null) { analyzers = new Dictionary <string, ImmutableArray <DiagnosticAnalyzer> .Builder>(); } foreach (string language2 in attribute.Languages) { if (language == null || language == language2) { if (!analyzers.TryGetValue(language2, out ImmutableArray <DiagnosticAnalyzer> .Builder value)) { analyzers[language2] = ImmutableArray.CreateBuilder <DiagnosticAnalyzer>(); } analyzers[language2].Add(analyzer); } } } } } else if (loadFixers && !typeInfo.IsAbstract && typeInfo.IsSubclassOf(typeof(CodeFixProvider))) { ExportCodeFixProviderAttribute attribute = typeInfo.GetCustomAttribute <ExportCodeFixProviderAttribute>(); if (attribute != null) { CodeFixProvider fixer = CreateInstanceAndCatchIfThrows <CodeFixProvider>(typeInfo); if (fixer != null) { if (fixers == null) { fixers = new Dictionary <string, ImmutableArray <CodeFixProvider> .Builder>(); } foreach (string language2 in attribute.Languages) { if (language == null || language == language2) { if (!fixers.TryGetValue(language2, out ImmutableArray <CodeFixProvider> .Builder value)) { fixers[language2] = ImmutableArray.CreateBuilder <CodeFixProvider>(); } fixers[language2].Add(fixer); } } } } } } return(new AnalyzerAssembly( analyzerAssembly, analyzers?.ToImmutableDictionary(f => f.Key, f => f.Value.ToImmutableArray()) ?? ImmutableDictionary <string, ImmutableArray <DiagnosticAnalyzer> > .Empty, fixers?.ToImmutableDictionary(f => f.Key, f => f.Value.ToImmutableArray()) ?? ImmutableDictionary <string, ImmutableArray <CodeFixProvider> > .Empty)); }