public static CompilationUnitSyntax Generate(AnalyzerDescriptor analyzer, string className) { string s = _sourceTemplate .Replace("$ClassName$", className) .Replace("$Identifier$", analyzer.Identifier); return(ParseCompilationUnit(s)); }
public static string CreateAnalyzerMarkdown(AnalyzerDescriptor analyzer) { var sb = new StringBuilder(); string title = analyzer.Title.TrimEnd('.'); sb.AppendHeader($"{((analyzer.IsObsolete) ? "[deprecated] " : "")}{analyzer.Id}: {title}"); sb.AppendLine(); sb.AppendTableHeader("Property", "Value"); sb.AppendTableRow("Id", analyzer.Id); sb.AppendTableRow("Category", analyzer.Category); sb.AppendTableRow("Default Severity", analyzer.DefaultSeverity); sb.AppendTableRow("Enabled by Default", GetBooleanAsText(analyzer.IsEnabledByDefault)); sb.AppendTableRow("Supports Fade-Out", GetBooleanAsText(analyzer.SupportsFadeOut)); sb.AppendTableRow("Supports Fade-Out Analyzer", GetBooleanAsText(analyzer.SupportsFadeOutAnalyzer)); ReadOnlyCollection <SampleDescriptor> samples = analyzer.Samples; if (samples.Count > 0) { sb.AppendLine(); sb.AppendHeader2((samples.Count == 1) ? "Example" : "Examples"); sb.AppendLine(); WriteSamples(sb, samples, new MarkdownHeader("Code with Diagnostic", 3), new MarkdownHeader("Code with Fix", 3)); } sb.AppendLine(); sb.AppendHeader2("How to Suppress"); sb.AppendLine(); sb.AppendHeader3("SuppressMessageAttribute"); sb.AppendLine(); sb.AppendCSharpCodeBlock($"[assembly: SuppressMessage(\"{analyzer.Category}\", \"{analyzer.Id}:{analyzer.Title}\", Justification = \"<Pending>\")]"); sb.AppendLine(); sb.AppendHeader3("#pragma"); sb.AppendLine(); sb.AppendCSharpCodeBlock($@"#pragma warning disable {analyzer.Id} // {analyzer.Title} #pragma warning restore {analyzer.Id} // {analyzer.Title}"); sb.AppendLine(); sb.AppendHeader3("Ruleset"); sb.AppendLine(); sb.AppendUnorderedListItem(); sb.AppendLink("How to configure rule set", "../HowToConfigureAnalyzers.md"); sb.AppendLine(); return(sb.ToString()); }
public static string CreateAnalyzersXml(IEnumerable <AnalyzerDescriptor> analyzers) { FieldInfo[] fieldInfos = typeof(DiagnosticDescriptors).GetFields(BindingFlags.Public | BindingFlags.Static); var doc = new XDocument(); var root = new XElement("Analyzers"); foreach (FieldInfo fieldInfo in fieldInfos.OrderBy(f => ((DiagnosticDescriptor)f.GetValue(null)).Id)) { if (fieldInfo.Name.EndsWith("FadeOut")) { continue; } var descriptor = (DiagnosticDescriptor)fieldInfo.GetValue(null); AnalyzerDescriptor analyzer = analyzers.FirstOrDefault(f => string.Equals(f.Id, descriptor.Id, StringComparison.CurrentCulture)); analyzer = new AnalyzerDescriptor( fieldInfo.Name, descriptor.Title.ToString(), descriptor.Id, descriptor.Category, descriptor.DefaultSeverity.ToString(), descriptor.IsEnabledByDefault, descriptor.CustomTags.Contains(WellKnownDiagnosticTags.Unnecessary), fieldInfos.Any(f => f.Name == fieldInfo.Name + "FadeOut")); root.Add(new XElement( "Analyzer", new XAttribute("Identifier", analyzer.Identifier), new XElement("Id", analyzer.Id), new XElement("Title", analyzer.Title), new XElement("Category", analyzer.Category), new XElement("DefaultSeverity", analyzer.DefaultSeverity), new XElement("IsEnabledByDefault", analyzer.IsEnabledByDefault), new XElement("SupportsFadeOut", analyzer.SupportsFadeOut), new XElement("SupportsFadeOutAnalyzer", analyzer.SupportsFadeOutAnalyzer) )); } doc.Add(root); using (var sw = new Utf8StringWriter()) { doc.Save(sw); return(sw.ToString()); } }
public static string CreateAnalyzerMarkDown(AnalyzerDescriptor analyzer) { using (var sw = new StringWriter()) { string title = analyzer.Title.TrimEnd('.').EscapeMarkdown(); sw.WriteLine($"#{((analyzer.IsObsolete) ? " [deprecated]" : "")} {analyzer.Id}: {title}"); sw.WriteLine(""); sw.WriteLine("Property | Value"); sw.WriteLine("--- | --- "); sw.WriteLine($"Id | {analyzer.Id}"); sw.WriteLine($"Category | {analyzer.Category}"); sw.WriteLine($"Default Severity | {analyzer.DefaultSeverity}"); sw.WriteLine($"Enabled by Default | {GetBooleanAsText(analyzer.IsEnabledByDefault)}"); sw.WriteLine($"Supports Fade-Out | {GetBooleanAsText(analyzer.SupportsFadeOut)}"); sw.WriteLine($"Supports Fade-Out Analyzer | {GetBooleanAsText(analyzer.SupportsFadeOutAnalyzer)}"); sw.WriteLine(); sw.WriteLine("## How to Suppress"); sw.WriteLine(); sw.WriteLine("### SuppressMessageAttribute"); sw.WriteLine(); sw.WriteLine("```csharp"); sw.WriteLine($"[assembly: SuppressMessage(\"{analyzer.Category}\", \"{analyzer.Id}:{analyzer.Title}\", Justification = \"<Pending>\")]"); sw.WriteLine("```"); sw.WriteLine(); sw.WriteLine(@"### \#pragma"); sw.WriteLine(); sw.WriteLine("```csharp"); sw.WriteLine($"#pragma warning disable {analyzer.Id} // {analyzer.Title}"); sw.WriteLine($"#pragma warning restore {analyzer.Id} // {analyzer.Title}"); sw.WriteLine("```"); sw.WriteLine(); sw.WriteLine("### Ruleset"); sw.WriteLine(); sw.Write("* [How to configure rule set](../HowToConfigureAnalyzers.md)"); sw.WriteLine(); return(sw.ToString()); } }
public static string CreateAnalyzerMarkdown(AnalyzerDescriptor analyzer) { var format = new MarkdownFormat(tableOptions: MarkdownFormat.Default.TableOptions | TableOptions.FormatContent); MDocument document = Document( Heading1($"{((analyzer.IsObsolete) ? "[deprecated] " : "")}{analyzer.Id}: {analyzer.Title.TrimEnd('.')}"), Table( TableRow("Property", "Value"), TableRow("Id", analyzer.Id), TableRow("Category", analyzer.Category), TableRow("Default Severity", analyzer.DefaultSeverity), TableRow("Enabled by Default", CheckboxOrHyphen(analyzer.IsEnabledByDefault)), TableRow("Supports Fade-Out", CheckboxOrHyphen(analyzer.SupportsFadeOut)), TableRow("Supports Fade-Out Analyzer", CheckboxOrHyphen(analyzer.SupportsFadeOutAnalyzer))), (!string.IsNullOrEmpty(analyzer.Summary)) ? Raw(analyzer.Summary) : null, Samples(), GetLinks(analyzer.Links), Heading2("How to Suppress"), Heading3("SuppressMessageAttribute"), FencedCodeBlock($"[assembly: SuppressMessage(\"{analyzer.Category}\", \"{analyzer.Id}:{analyzer.Title}\", Justification = \"<Pending>\")]", LanguageIdentifiers.CSharp), Heading3("#pragma"), FencedCodeBlock($"#pragma warning disable {analyzer.Id} // {analyzer.Title}\r\n#pragma warning restore {analyzer.Id} // {analyzer.Title}", LanguageIdentifiers.CSharp), Heading3("Ruleset"), BulletItem(Link("How to configure rule set", "../HowToConfigureAnalyzers.md"))); document.AddFootnote(); return(document.ToString(format)); IEnumerable <MElement> Samples() { IReadOnlyList <SampleDescriptor> samples = analyzer.Samples; if (samples.Count > 0) { yield return(Heading2((samples.Count == 1) ? "Example" : "Examples")); foreach (MElement item in GetSamples(samples, Heading3("Code with Diagnostic"), Heading3("Code with Fix"))) { yield return(item); } } } }
public static string CreateAnalyzerMarkdown(AnalyzerDescriptor analyzer) { var mb = new MarkdownBuilder(new MarkdownSettings(tableFormatting: TableFormatting.All)); mb.AppendHeader1($"{((analyzer.IsObsolete) ? "[deprecated] " : "")}{analyzer.Id}: {analyzer.Title.TrimEnd('.')}"); Table table = Table("Property", "Value") .AddRow("Id", analyzer.Id) .AddRow("Category", analyzer.Category) .AddRow("Default Severity", analyzer.DefaultSeverity) .AddRow("Enabled by Default", RawText(GetBooleanAsText(analyzer.IsEnabledByDefault))) .AddRow("Supports Fade-Out", RawText(GetBooleanAsText(analyzer.SupportsFadeOut))) .AddRow("Supports Fade-Out Analyzer", RawText(GetBooleanAsText(analyzer.SupportsFadeOutAnalyzer))); mb.Append(table); ReadOnlyCollection <SampleDescriptor> samples = analyzer.Samples; if (samples.Count > 0) { mb.AppendHeader2((samples.Count == 1) ? "Example" : "Examples"); AppendSamples(mb, samples, Header3("Code with Diagnostic"), Header3("Code with Fix")); } mb.AppendHeader2("How to Suppress"); mb.AppendHeader3("SuppressMessageAttribute"); mb.AppendCSharpCodeBlock($"[assembly: SuppressMessage(\"{analyzer.Category}\", \"{analyzer.Id}:{analyzer.Title}\", Justification = \"<Pending>\")]"); mb.AppendHeader3("#pragma"); mb.AppendCSharpCodeBlock($"#pragma warning disable {analyzer.Id} // {analyzer.Title}\r\n#pragma warning restore {analyzer.Id} // {analyzer.Title}"); mb.AppendHeader3("Ruleset"); mb.AppendListItem(Link("How to configure rule set", "../HowToConfigureAnalyzers.md")); return(mb.ToString()); }
private static void Main(string[] args) { if (args == null || args.Length == 0) { #if DEBUG args = new string[] { @"..\..\..\.." }; #else args = new string[] { Environment.CurrentDirectory }; #endif } string dirPath = args[0]; SortRefactoringsInFile(Path.Combine(dirPath, @"Refactorings\Refactorings.xml")); RefactoringDescriptor[] refactorings = RefactoringDescriptor .LoadFromFile(Path.Combine(dirPath, @"Refactorings\Refactorings.xml")) .OrderBy(f => f.Identifier, StringComparer.InvariantCulture) .ToArray(); Console.WriteLine($"number of refactorings: {refactorings.Length}"); AnalyzerDescriptor[] analyzers = AnalyzerDescriptor .LoadFromFile(Path.Combine(dirPath, @"Analyzers\Analyzers.xml")) .OrderBy(f => f.Id, StringComparer.InvariantCulture) .ToArray(); Console.WriteLine($"number of analyzers: {analyzers.Length}"); SaveFile( Path.Combine(dirPath, @"Analyzers\Analyzers.xml"), CreateAnalyzersXml(analyzers)); var htmlGenerator = new HtmlGenerator(); SaveFile( Path.Combine(dirPath, @"VisualStudio\description.txt"), File.ReadAllText(@"..\text\RoslynatorDescription.txt", Encoding.UTF8) + htmlGenerator.CreateRoslynatorDescription(analyzers, refactorings)); SaveFile( Path.Combine(dirPath, @"VisualStudio.Refactorings\description.txt"), File.ReadAllText(@"..\text\RoslynatorRefactoringsDescription.txt", Encoding.UTF8) + htmlGenerator.CreateRoslynatorRefactoringsDescription(refactorings)); var markdownGenerator = new MarkdownGenerator(); SaveFile( Path.Combine(Path.GetDirectoryName(dirPath), @"README.md"), markdownGenerator.CreateReadMeMarkDown(analyzers, refactorings)); foreach (string imagePath in MarkdownGenerator.FindMissingImages(refactorings, Path.Combine(Path.GetDirectoryName(dirPath), @"images\refactorings"))) { Console.WriteLine($"missing image: {imagePath}"); } SaveFile( Path.Combine(dirPath, @"Refactorings\Refactorings.md"), markdownGenerator.CreateRefactoringsMarkDown(refactorings)); SaveFile( Path.Combine(dirPath, @"Refactorings\README.md"), markdownGenerator.CreateRefactoringsReadMe(refactorings)); SaveFile( Path.Combine(dirPath, @"Analyzers\README.md"), markdownGenerator.CreateAnalyzersReadMe(analyzers)); SaveFile( Path.Combine(dirPath, @"Analyzers\AnalyzersByCategory.md"), markdownGenerator.CreateAnalyzersByCategoryMarkDown(analyzers)); #if DEBUG Console.WriteLine("DONE"); Console.ReadKey(); #endif }
private static void Main(string[] args) { string rootPath = args[0]; var metadata = new RoslynatorMetadata(rootPath); ImmutableArray <AnalyzerDescriptor> analyzers = metadata.Analyzers; ImmutableArray <RefactoringDescriptor> refactorings = metadata.Refactorings; ImmutableArray <CompilerDiagnosticDescriptor> compilerDiagnostics = metadata.CompilerDiagnostics; foreach (string id in args.Skip(1)) { if (_analyzerIdRegex.IsMatch(id)) { AnalyzerDescriptor analyzer = analyzers.FirstOrDefault(f => string.Equals(f.Id, id, StringComparison.OrdinalIgnoreCase)); if (analyzer == null) { Console.WriteLine($"Analyzer '{id}' not found"); continue; } string className = $"{analyzer.Id}{analyzer.Identifier}Tests"; WriteCompilationUnit( $@"Tests\Analyzers.Tests\{className}.cs", AnalyzerTestGenerator.Generate(analyzer, className), autoGenerated: false, normalizeWhitespace: false, fileMustExist: false, overwrite: false); } else if (_refactoringIdRegex.IsMatch(id)) { RefactoringDescriptor refactoring = refactorings.FirstOrDefault(f => string.Equals(f.Id, id, StringComparison.OrdinalIgnoreCase)); if (refactoring == null) { Console.WriteLine($"Refactoring '{id}' not found"); continue; } string className = $"{refactoring.Id}{refactoring.Identifier}Tests"; WriteCompilationUnit( $@"Tests\Refactorings.Tests\{className}.cs", RefactoringTestGenerator.Generate(refactoring, className), autoGenerated: false, normalizeWhitespace: false, fileMustExist: false, overwrite: false); } else if (_codeFixIdRegex.IsMatch(id)) { CompilerDiagnosticDescriptor compilerDiagnostic = compilerDiagnostics.FirstOrDefault(f => string.Equals(f.Id, id, StringComparison.OrdinalIgnoreCase)); if (compilerDiagnostic == null) { Console.WriteLine($"Compiler diagnostic '{id}' not found"); continue; } string className = $"{compilerDiagnostic.Id}{compilerDiagnostic.Identifier}Tests"; WriteCompilationUnit( $@"Tests\CodeFixes.Tests\{className}.cs", CodeFixTestGenerator.Generate(compilerDiagnostic, className), autoGenerated: false, normalizeWhitespace: false, fileMustExist: false, overwrite: false); } else { Console.WriteLine($"Id '{id}' not recognized"); } } void WriteCompilationUnit( string path, CompilationUnitSyntax compilationUnit, bool autoGenerated = true, bool normalizeWhitespace = true, bool fileMustExist = true, bool overwrite = true) { CodeGenerationHelpers.WriteCompilationUnit( path: Path.Combine(rootPath, path), compilationUnit: compilationUnit, banner: CodeGenerationHelpers.CopyrightBanner, autoGenerated: autoGenerated, normalizeWhitespace: normalizeWhitespace, fileMustExist: fileMustExist, overwrite: overwrite); } }
private static void WriteAnalyzer(XmlWriter writer, AnalyzerDescriptor analyzer) { writer.WriteElementString("li", $"{analyzer.Id} - {analyzer.Title}"); }