Пример #1
0
        public static CompilationUnitSyntax Generate(AnalyzerDescriptor analyzer, string className)
        {
            string s = _sourceTemplate
                       .Replace("$ClassName$", className)
                       .Replace("$Identifier$", analyzer.Identifier);

            return(ParseCompilationUnit(s));
        }
Пример #2
0
        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());
        }
Пример #3
0
        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());
            }
        }
Пример #4
0
        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());
            }
        }
Пример #5
0
        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);
                    }
                }
            }
        }
Пример #6
0
        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());
        }
Пример #7
0
        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
        }
Пример #8
0
        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);
            }
        }
Пример #9
0
 private static void WriteAnalyzer(XmlWriter writer, AnalyzerDescriptor analyzer)
 {
     writer.WriteElementString("li", $"{analyzer.Id} - {analyzer.Title}");
 }