public void Generate_Sonar_Rules_Added()
        {
            // Arrange
            var generator = new RuleSetGenerator();

            var rules = new[]
            {
                CreateRule("csharpsquid", "active1", true, SonarQubeIssueSeverity.Major),
                // Even though this rule is for VB it will be added as C#, see NOTE below
                CreateRule("vbnet", "active2", true, SonarQubeIssueSeverity.Major),

                CreateRule("csharpsquid", "inactive1", false),
                // Even though this rule is for VB it will be added as C#, see NOTE below
                CreateRule("vbnet", "inactive2", false),
            };

            // Act
            var ruleSet = generator.Generate("cs", rules, ValidSonarCSharpProperties);

            // Assert
            ruleSet.Rules.Should().HaveCount(1);

            // NOTE: The RuleNamespace and AnalyzerId are taken from the language parameter of the
            // Generate method. The FetchArgumentsAndRulesets method will retrieve active/inactive
            // rules from SonarQube per language/quality profile and mixture of VB-C# rules is not
            // expected.
            ruleSet.Rules[0].RuleNamespace.Should().Be("SonarAnalyzer.CSharp");
            ruleSet.Rules[0].AnalyzerId.Should().Be("SonarAnalyzer.CSharp");
            ruleSet.Rules[0].RuleList.Should().HaveCount(4);
            ruleSet.Rules[0].RuleList.Select(r => r.Id).Should().BeEquivalentTo(
                "active1", "active2", "inactive1", "inactive2");
            ruleSet.Rules[0].RuleList.Select(r => r.Action).Should().BeEquivalentTo(
                "Warning", "Warning", "None", "None");
        }
Exemplo n.º 2
0
        public void TestGetRulesFor()
        {
            var generator = new RuleSetGenerator(pool);
            var ruleSet   = generator.GetRulesFor(
                new[]
            {
                new Job()
                {
                    Command     = JobCommand.Install,
                    PackageName = "unity",
                    Constraint  = new Constraint(">", "1.0"),
                },
            }, new Dictionary <int, IPackage>());

            var expected = new[]
            {
                "unity 1.6 requires bucket.helper >= 1.0 -> satisfiable by bucket.helper[1.6].",
                "bucket.helper 1.6 requires bucket.core >= 2.0 -> satisfiable by bucket.core[2.2, 3.6, 5.2].",
                "Can only install one of: bucket.core[3.6, 2.2].",
                "Can only install one of: bucket.core[5.2, 2.2].",
                "Can only install one of: bucket.core[5.2, 3.6].",
                "Install command rule (install unity 1.6)",
            };

            Assert.AreEqual(expected.Length, ruleSet.Count);

            for (var i = 0; i < ruleSet.Count; i++)
            {
                Assert.AreEqual(expected[i], ruleSet[i].GetPrettyString(pool));
            }
        }
        public void GetVSSeverity_Blocker_CorrectlyMapped(bool shouldTreatBlockerAsError, RuleAction expectedVsSeverity)
        {
            var envSettingsMock = new Mock <IEnvironmentSettings>();

            envSettingsMock.Setup(x => x.TreatBlockerSeverityAsError()).Returns(shouldTreatBlockerAsError);

            var testSubject = new RuleSetGenerator(envSettingsMock.Object);

            testSubject.GetVsSeverity(SonarQubeIssueSeverity.Blocker).Should().Be(expectedVsSeverity);
        }
        public void Generate_Common_Parameters()
        {
            // Arrange
            var generator = new RuleSetGenerator();

            // Act
            var ruleSet = generator.Generate("cs", EmptyRules, EmptyProperties);

            // Assert
            ruleSet.Description.Should().Be("This rule set was automatically generated from SonarQube");
            ruleSet.ToolsVersion.Should().Be("14.0");
            ruleSet.Name.Should().Be("Rules for SonarQube");
        }
        public void Generate_Rules_AreGroupAndSorted()
        {
            // Arrange
            var generator = new RuleSetGenerator();

            var properties = new Dictionary <string, string>
            {
                // The rules should be grouped by the analyzer id
                { "sonaranalyzer-cs.analyzerId", "SonarAnalyzer.CSharp" },
                { "wintellect.analyzerId", "AAA" },
                { "myanalyzer.analyzerId", "ZZZ" },

                // The namespace properties are required but shouldn't be used for sorting
                { "sonaranalyzer-cs.ruleNamespace", "SonarAnalyzer.CSharp" },
                { "wintellect.ruleNamespace", "XXX" },
                { "myanalyzer.ruleNamespace", "BBB" },
            };

            var rules = new[]
            {
                CreateRule("roslyn.myanalyzer", "my 1", true),

                CreateRule("roslyn.wintellect", "win2", true),
                CreateRule("roslyn.wintellect", "win1", true),
                CreateRule("roslyn.wintellect", "win0", false),

                CreateRule("csharpsquid", "S999", true),
                CreateRule("csharpsquid", "S111", false),
            };

            // Act
            var ruleSet = generator.Generate("cs", rules, properties);

            // Assert
            ruleSet.Rules.Should().HaveCount(3);

            // Expecting groups to be sorted alphabetically by analyzer id (not namespace)...
            ruleSet.Rules[0].AnalyzerId.Should().Be("AAA");
            ruleSet.Rules[1].AnalyzerId.Should().Be("SonarAnalyzer.CSharp");
            ruleSet.Rules[2].AnalyzerId.Should().Be("ZZZ");

            // ... and rules in groups to be sorted by rule key
            ruleSet.Rules[0].RuleList[0].Id.Should().Be("win0");
            ruleSet.Rules[0].RuleList[1].Id.Should().Be("win1");
            ruleSet.Rules[0].RuleList[2].Id.Should().Be("win2");

            ruleSet.Rules[1].RuleList[0].Id.Should().Be("S111");
            ruleSet.Rules[1].RuleList[1].Id.Should().Be("S999");

            ruleSet.Rules[2].RuleList[0].Id.Should().Be("my 1");
        }
Exemplo n.º 6
0
        public void TestGetRulesReplaceRule()
        {
            var packageReplaceBucketHelper = Helper.MockPackage("bucket.replace.helper", "2.6",
                                                                replaces: new[] { new Link("bucket.replace.helper", "bucket.helper", new Constraint("==", "1.6"), "replaces") });

            var packageReplaceFoo = Helper.MockPackage("replace.foo", "2.8",
                                                       requires: new[] { new Link("replace.foo", "bucket.replace.helper", new Constraint(">=", "1.0"), "requires") });

            var repository = Helper.MockRepository(packageReplaceBucketHelper, packageReplaceFoo);

            pool.AddRepository(repository);
            var generator = new RuleSetGenerator(pool);

            var ruleSet = generator.GetRulesFor(
                new[]
            {
                new Job()
                {
                    Command     = JobCommand.Install,
                    PackageName = "unity",
                    Constraint  = new Constraint(">", "1.0"),
                },
                new Job()
                {
                    Command     = JobCommand.Install,
                    PackageName = "replace.foo",
                    Constraint  = new Constraint(">", "2.0"),
                },
            }, new Dictionary <int, IPackage>());

            var expected = new[]
            {
                "unity 1.6 requires bucket.helper >= 1.0 -> satisfiable by bucket.helper[1.6], bucket.replace.helper[2.6].",
                "bucket.helper 1.6 requires bucket.core >= 2.0 -> satisfiable by bucket.core[2.2, 3.6, 5.2].",
                "don't install bucket.replace.helper 2.6 | don't install bucket.helper 1.6",
                "Can only install one of: bucket.core[3.6, 2.2].",
                "Can only install one of: bucket.core[5.2, 2.2].",
                "Can only install one of: bucket.core[5.2, 3.6].",
                "Install command rule (install unity 1.6)",
                "replace.foo 2.8 requires bucket.replace.helper >= 1.0 -> satisfiable by bucket.replace.helper[2.6].",
                "Install command rule (install replace.foo 2.8)",
            };

            Assert.AreEqual(expected.Length, ruleSet.Count);

            for (var i = 0; i < ruleSet.Count; i++)
            {
                Assert.AreEqual(expected[i], ruleSet[i].GetPrettyString(pool));
            }
        }
Exemplo n.º 7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Solver"/> class.
 /// </summary>
 /// <param name="policy">The solver policy.</param>
 /// <param name="pool">The pool contains repositories that provide packages.</param>
 /// <param name="installed">The installed packages repository.</param>
 /// <param name="io">The input/output instance.</param>
 public Solver(IPolicy policy, Pool pool, IRepository installed, IIO io)
 {
     this.installed   = installed;
     this.io          = io;
     this.policy      = policy;
     this.pool        = pool;
     ruleSetGenerator = new RuleSetGenerator(pool);
     installedMap     = new Dictionary <int, IPackage>();
     updateMap        = new HashSet <int>();
     problems         = new List <Problem>();
     stopwatch        = new Stopwatch();
     learnedWhy       = new Dictionary <int, int>();
     learnedPool      = new List <LinkedList <Rule> >();
     branches         = new List <Branch>();
 }
        public void Generate_ArgumentChecks()
        {
            var          generator = new RuleSetGenerator();
            const string language  = "cs";

            Action act1 = () => generator.Generate(null, EmptyRules, EmptyProperties);

            act1.Should().ThrowExactly <ArgumentNullException>().And.ParamName.Should().Be("language");

            Action act3 = () => generator.Generate(language, null, EmptyProperties);

            act3.Should().ThrowExactly <ArgumentNullException>().And.ParamName.Should().Be("rules");

            Action act2 = () => generator.Generate(language, EmptyRules, null);

            act2.Should().ThrowExactly <ArgumentNullException>().And.ParamName.Should().Be("sonarProperties");
        }
        public void Generate_Unsupported_Rules_Ignored()
        {
            // Arrange
            var generator = new RuleSetGenerator();

            var rules = new[]
            {
                CreateRule("other.repo", "other.rule1", true),
                CreateRule("other.repo", "other.rule2", false),
            };

            // Act
            var ruleSet = generator.Generate("cs", rules, EmptyProperties);

            // Assert
            ruleSet.Rules.Should().BeEmpty();
        }
Exemplo n.º 10
0
        public void TestGetRulesWithConflictRule()
        {
            var packageConflict = Helper.MockPackage("bucket.conflict", "2.2",
                                                     conflict: new[] { new Link("bucket.conflict", "bucket.core", new Constraint("<", "5.0"), "conflict") });
            var repository = Helper.MockRepository(packageConflict);

            pool.AddRepository(repository);
            var generator = new RuleSetGenerator(pool);

            var ruleSet = generator.GetRulesFor(
                new[]
            {
                new Job()
                {
                    Command     = JobCommand.Install,
                    PackageName = "unity",
                    Constraint  = new Constraint(">", "1.0"),
                },
                new Job()
                {
                    Command     = JobCommand.Install,
                    PackageName = "bucket.conflict",
                    Constraint  = new Constraint(">", "2.0"),
                },
            }, new Dictionary <int, IPackage>());

            var expected = new[]
            {
                "unity 1.6 requires bucket.helper >= 1.0 -> satisfiable by bucket.helper[1.6].",
                "bucket.helper 1.6 requires bucket.core >= 2.0 -> satisfiable by bucket.core[2.2, 3.6, 5.2].",
                "Can only install one of: bucket.core[3.6, 2.2].",
                "Can only install one of: bucket.core[5.2, 2.2].",
                "Can only install one of: bucket.core[5.2, 3.6].",
                "Install command rule (install unity 1.6)",
                "Install command rule (install bucket.conflict 2.2)",
                "bucket.conflict 2.2 conflicts with bucket.core[2.2].",
                "bucket.conflict 2.2 conflicts with bucket.core[3.6].",
            };

            Assert.AreEqual(expected.Length, ruleSet.Count);

            for (var i = 0; i < ruleSet.Count; i++)
            {
                Assert.AreEqual(expected[i], ruleSet[i].GetPrettyString(pool));
            }
        }
        public void Generate_RuleNamespace_Property_Missing()
        {
            // Arrange
            var generator = new RuleSetGenerator();

            var properties = new Dictionary <string, string>
            {
                { "sonaranalyzer-cs.analyzerId", "SonarAnalyzer.CSharp" },
            };

            // Act & Assert
            var action = new Action(() => generator.Generate("cs", ValidSonarCSharpRules, properties));

            action.Should().ThrowExactly <InvalidOperationException>().And
            .Message.Should().StartWith(
                "Property does not exist: sonaranalyzer-cs.ruleNamespace. This property should be set by the plugin in SonarQube.");
        }
        public void Generate_ActiveRules_VsSeverity_IsCorrectlyMapped()
        {
            // Arrange
            var generator = new RuleSetGenerator();

            var activeRules = new List <SonarQubeRule>
            {
                CreateSonarCSharpRule("rule1", isActive: true, sqSeverity: SonarQubeIssueSeverity.Info),
                CreateSonarCSharpRule("rule2", isActive: true, sqSeverity: SonarQubeIssueSeverity.Critical)
            };

            // Act
            var ruleSet = generator.Generate("cs", activeRules, ValidSonarCSharpProperties);

            // Assert
            ruleSet.Rules.Should().HaveCount(1);
            ruleSet.Rules[0].RuleList.Select(r => r.Action).Should().BeEquivalentTo("Info", "Warning");
        }
        public void Generate_EmptyProperties()
        {
            // Arrange
            var generator = new RuleSetGenerator();
            var rules     = new List <SonarQubeRule>
            {
                CreateRule("repo", "key"),
            };

            // Act
            var ruleSet = generator.Generate("cs", rules, EmptyProperties);

            // Assert
            ruleSet.Rules.Should().BeEmpty(); // No analyzers
            ruleSet.Description.Should().Be("This rule set was automatically generated from SonarQube");
            ruleSet.ToolsVersion.Should().Be("14.0");
            ruleSet.Name.Should().Be("Rules for SonarQube");
        }
        public void Generate_InactiveRules_VSseverity_IsAlwaysNone()
        {
            // Arrange
            var generator = new RuleSetGenerator();

            var inactiveRules = new List <SonarQubeRule>
            {
                CreateSonarCSharpRule("rule1", isActive: false, sqSeverity: SonarQubeIssueSeverity.Major),
                CreateSonarCSharpRule("rule2", isActive: false, sqSeverity: SonarQubeIssueSeverity.Info),
            };

            // Act
            var ruleSet = generator.Generate("cs", inactiveRules, ValidSonarCSharpProperties);

            // Assert
            ruleSet.Rules.Should().HaveCount(1);
            ruleSet.Rules[0].RuleList.Select(r => r.Action).Should().BeEquivalentTo("None", "None");
        }
        public void Generate_RoslynSDK_Rules_Added()
        {
            // Arrange
            var generator = new RuleSetGenerator();

            var properties = new Dictionary <string, string>
            {
                ["custom1.analyzerId"]    = "CustomAnalyzer1",
                ["custom1.ruleNamespace"] = "CustomNamespace1",
                ["custom2.analyzerId"]    = "CustomAnalyzer2",
                ["custom2.ruleNamespace"] = "CustomNamespace2",
            };

            var rules = new[]
            {
                CreateRule("roslyn.custom1", "active1", true, SonarQubeIssueSeverity.Info),
                CreateRule("roslyn.custom2", "active2", true, SonarQubeIssueSeverity.Critical),
                CreateRule("roslyn.custom1", "inactive1", false),
                CreateRule("roslyn.custom2", "inactive2", false),
            };

            // Act
            var ruleSet = generator.Generate("cs", rules, properties);

            // Assert
            ruleSet.Rules.Should().HaveCount(2);

            ruleSet.Rules[0].RuleNamespace.Should().Be("CustomNamespace1");
            ruleSet.Rules[0].AnalyzerId.Should().Be("CustomAnalyzer1");
            ruleSet.Rules[0].RuleList.Should().HaveCount(2);
            ruleSet.Rules[0].RuleList.Select(r => r.Id).Should().BeEquivalentTo("active1", "inactive1");
            ruleSet.Rules[0].RuleList.Select(r => r.Action).Should().BeEquivalentTo("Info", "None");

            ruleSet.Rules[1].RuleNamespace.Should().Be("CustomNamespace2");
            ruleSet.Rules[1].AnalyzerId.Should().Be("CustomAnalyzer2");
            ruleSet.Rules[1].RuleList.Should().HaveCount(2);
            ruleSet.Rules[1].RuleList.Select(r => r.Id).Should().BeEquivalentTo("active2", "inactive2");
            ruleSet.Rules[1].RuleList.Select(r => r.Action).Should().BeEquivalentTo("Warning", "None");
        }
 public void GetActionText_Valid(RuleAction action, string expected)
 {
     RuleSetGenerator.GetActionText(action).Should().Be(expected);
 }
        public void GetVSSeverity_NotBlocker_CorrectlyMapped(SonarQubeIssueSeverity sqSeverity, RuleAction expectedVsSeverity)
        {
            var testSubject = new RuleSetGenerator();

            testSubject.GetVsSeverity(sqSeverity).Should().Be(expectedVsSeverity);
        }
Exemplo n.º 18
0
        private static void Main(string[] args)
        {
            if (args == null || args.Length == 0)
            {
#if DEBUG
                args = new[] { @"..\..\..\..\.." };
#else
                args = new string[] { Environment.CurrentDirectory };
#endif
            }

            string rootPath = args[0];

            StringComparer comparer = StringComparer.InvariantCulture;

            var metadata = new RoslynatorMetadata(rootPath);

            ImmutableArray <AnalyzerMetadata>           analyzers             = metadata.Analyzers;
            ImmutableArray <AnalyzerMetadata>           codeAnalysisAnalyzers = metadata.CodeAnalysisAnalyzers;
            ImmutableArray <AnalyzerMetadata>           formattingAnalyzers   = metadata.FormattingAnalyzers;
            ImmutableArray <RefactoringMetadata>        refactorings          = metadata.Refactorings;
            ImmutableArray <CodeFixMetadata>            codeFixes             = metadata.CodeFixes;
            ImmutableArray <CompilerDiagnosticMetadata> compilerDiagnostics   = metadata.CompilerDiagnostics;

            WriteCompilationUnit(
                @"Refactorings\CSharp\RefactoringIdentifiers.Generated.cs",
                RefactoringIdentifiersGenerator.Generate(refactorings, obsolete: false, comparer: comparer));

            WriteCompilationUnit(
                @"Refactorings\CSharp\RefactoringIdentifiers.Deprecated.Generated.cs",
                RefactoringIdentifiersGenerator.Generate(refactorings, obsolete: true, comparer: comparer));

            WriteCompilationUnit(
                @"VisualStudio.Common\RefactoringsOptionsPage.Generated.cs",
                RefactoringsOptionsPageGenerator.Generate(refactorings.Where(f => !f.IsObsolete), comparer));

            WriteDiagnostics(@"Analyzers\CSharp", analyzers, @namespace: "Roslynator.CSharp");

            WriteDiagnostics(@"CodeAnalysis.Analyzers\CSharp", codeAnalysisAnalyzers, @namespace: "Roslynator.CodeAnalysis.CSharp");

            WriteDiagnostics(@"Formatting.Analyzers\CSharp", formattingAnalyzers, @namespace: "Roslynator.Formatting.CSharp");

            WriteCompilationUnit(
                @"CodeFixes\CSharp\CompilerDiagnosticDescriptors.Generated.cs",
                CompilerDiagnosticDescriptorsGenerator.Generate(compilerDiagnostics, comparer: comparer, @namespace: "Roslynator.CSharp"),
                normalizeWhitespace: false);

            WriteCompilationUnit(
                @"CodeFixes\CSharp\CodeFixDescriptors.Generated.cs",
                CodeFixDescriptorsGenerator.Generate(codeFixes.Where(f => !f.IsObsolete), comparer: comparer, @namespace: "Roslynator.CSharp"),
                normalizeWhitespace: false);

            WriteCompilationUnit(
                @"CodeFixes\CSharp\CodeFixIdentifiers.Generated.cs",
                CodeFixIdentifiersGenerator.Generate(codeFixes, comparer));

            WriteCompilationUnit(
                @"VisualStudio.Common\CodeFixesOptionsPage.Generated.cs",
                CodeFixesOptionsPageGenerator.Generate(codeFixes, comparer));

            WriteCompilationUnit(
                @"CSharp\CSharp\CompilerDiagnosticIdentifiers.Generated.cs",
                CompilerDiagnosticIdentifiersGenerator.Generate(compilerDiagnostics, comparer));

            WriteCompilationUnit(
                @"Tools\CodeGeneration\CSharp\Symbols.Generated.cs",
                SymbolsGetKindsGenerator.Generate());

            WriteCompilationUnit(
                @"CSharp\CSharp\SyntaxWalkers\CSharpSyntaxNodeWalker.cs",
                CSharpSyntaxNodeWalkerGenerator.Generate());

            string ruleSetXml = File.ReadAllText(Path.Combine(rootPath, @"Tools\CodeGeneration\DefaultRuleSet.xml"));

            WriteCompilationUnit(
                @"VisualStudio.Common\RuleSetHelpers.Generated.cs",
                RuleSetGenerator.Generate(ruleSetXml));

            File.WriteAllText(
                Path.Combine(rootPath, @"VisualStudioCode\package\src\configurationFiles.generated.ts"),
                @"export const configurationFileContent = {
	ruleset: `"
                + ruleSetXml
                + @"`,
	config: `<?xml version=""1.0"" encoding=""utf-8""?>
<Roslynator>
  <Settings>
    <General>
      <!-- <PrefixFieldIdentifierWithUnderscore>true</PrefixFieldIdentifierWithUnderscore> -->
    </General>
    <Refactorings>
      <!-- <Refactoring Id=""RRxxxx"" IsEnabled=""false"" /> -->
    </Refactorings>
    <CodeFixes>
      <!-- <CodeFix Id=""CSxxxx.RCFxxxx"" IsEnabled=""false"" /> -->
      <!-- <CodeFix Id=""CSxxxx"" IsEnabled=""false"" /> -->
      <!-- <CodeFix Id=""RCFxxxx"" IsEnabled=""false"" /> -->
    </CodeFixes>
  </Settings>
</Roslynator>`
};",
                new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));

            Console.WriteLine($"number of analyzers: {analyzers.Count(f => !f.IsObsolete)}");
            Console.WriteLine($"number of code analysis analyzers: {codeAnalysisAnalyzers.Count(f => !f.IsObsolete)}");
            Console.WriteLine($"number of formatting analyzers: {formattingAnalyzers.Count(f => !f.IsObsolete)}");
            Console.WriteLine($"number of refactorings: {refactorings.Length}");
            Console.WriteLine($"number of code fixes: {codeFixes.Length}");
            Console.WriteLine($"number of fixable compiler diagnostics: {codeFixes.SelectMany(f => f.FixableDiagnosticIds).Distinct().Count()}");

            void WriteDiagnostics(
                string dirPath,
                ImmutableArray <AnalyzerMetadata> analyzers,
                string @namespace,
                string descriptorsClassName = "DiagnosticDescriptors",
                string identifiersClassName = "DiagnosticIdentifiers")
            {
                WriteCompilationUnit(
                    Path.Combine(dirPath, $"{descriptorsClassName}.Generated.cs"),
                    DiagnosticDescriptorsGenerator.Generate(analyzers, obsolete: false, comparer: comparer, @namespace: @namespace, className: descriptorsClassName, identifiersClassName: identifiersClassName),
                    normalizeWhitespace: false);

                WriteCompilationUnit(
                    Path.Combine(dirPath, $"{descriptorsClassName}.Deprecated.Generated.cs"),
                    DiagnosticDescriptorsGenerator.Generate(analyzers, obsolete: true, comparer: comparer, @namespace: @namespace, className: descriptorsClassName, identifiersClassName: identifiersClassName),
                    normalizeWhitespace: false);

                WriteCompilationUnit(
                    Path.Combine(dirPath, $"{identifiersClassName}.Generated.cs"),
                    DiagnosticIdentifiersGenerator.Generate(analyzers, obsolete: false, comparer: comparer, @namespace: @namespace, className: identifiersClassName));

                WriteCompilationUnit(
                    Path.Combine(dirPath, $"{identifiersClassName}.Deprecated.Generated.cs"),
                    DiagnosticIdentifiersGenerator.Generate(analyzers, obsolete: true, comparer: comparer, @namespace: @namespace, className: identifiersClassName));

                IEnumerable <AnalyzerMetadata> optionAnalyzers = analyzers.SelectMany(f => f.OptionAnalyzers);

                if (optionAnalyzers.Any())
                {
                    WriteCompilationUnit(
                        Path.Combine(dirPath, "AnalyzerOptions.Generated.cs"),
                        DiagnosticDescriptorsGenerator.Generate(optionAnalyzers, obsolete: false, comparer: comparer, @namespace: @namespace, className: "AnalyzerOptions", identifiersClassName: "AnalyzerOptionIdentifiers"),
                        normalizeWhitespace: false,
                        fileMustExist: false);

                    WriteCompilationUnit(
                        Path.Combine(dirPath, "AnalyzerOptionIdentifiers.Generated.cs"),
                        DiagnosticIdentifiersGenerator.Generate(optionAnalyzers, obsolete: false, comparer: comparer, @namespace: @namespace, className: "AnalyzerOptionIdentifiers"),
                        fileMustExist: false);
                }

                IEnumerable <string> analyzerOptionIdentifiers = analyzers
                                                                 .SelectMany(f => f.OptionAnalyzers)
                                                                 .Select(f => f.Identifier);

                WriteCompilationUnit(
                    Path.Combine(dirPath, "AnalyzerOptionsAnalyzer.Generated.cs"),
                    AnalyzerOptionsAnalyzerGenerator.Generate(analyzerOptionIdentifiers, @namespace: @namespace),
                    fileMustExist: false);
            }

            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: "Copyright (c) Josef Pihrt. All rights reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.",
                    autoGenerated: autoGenerated,
                    normalizeWhitespace: normalizeWhitespace,
                    fileMustExist: fileMustExist,
                    overwrite: overwrite);
            }
        }
        public void GetActionText_Invalid()
        {
            Action act = () => RuleSetGenerator.GetActionText((RuleAction)(-1));

            act.Should().Throw <NotSupportedException>();
        }