File: MetaAnalyzers\SymbolIsBannedInAnalyzersTests.cs
Web Access
Project: src\src\RoslynAnalyzers\Microsoft.CodeAnalysis.Analyzers\UnitTests\Microsoft.CodeAnalysis.Analyzers.UnitTests.csproj (Microsoft.CodeAnalysis.Analyzers.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable enable
 
using System.Collections.Immutable;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Testing;
using Test.Utilities;
using Xunit;
using VerifyCS = Test.Utilities.CSharpCodeFixVerifier<
    Microsoft.CodeAnalysis.CSharp.Analyzers.CSharpSymbolIsBannedInAnalyzersAnalyzer,
    Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>;
using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier<
    Microsoft.CodeAnalysis.VisualBasic.Analyzers.BasicSymbolIsBannedInAnalyzersAnalyzer,
    Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>;
 
namespace Microsoft.CodeAnalysis.Analyzers.UnitTests
{
    public class SymbolIsBannedInAnalyzersTests
    {
        [Fact]
        public async Task UseBannedApi_EnforcementEnabled_CSharp()
        {
            await new VerifyCS.Test
            {
                LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp9,
                TestCode = @"
using System.IO;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
 
[DiagnosticAnalyzer(LanguageNames.CSharp)]
class MyAnalyzer
{
}
 
class C
{
    void M()
    {
        _ = File.Exists(""something"");
    }
}
",
                ExpectedDiagnostics = {
                    // /0/Test0.cs(15,13): error RS1035: The symbol 'File' is banned for use by analyzers: Do not do file IO in analyzers
                    VerifyCS.Diagnostic("RS1035").WithSpan(15, 13, 15, 37).WithArguments("File", ": Do not do file IO in analyzers"),
                },
                TestState = {
                    AnalyzerConfigFiles = { ("/.editorconfig", $@"root = true
 
[*]
build_property.EnforceExtendedAnalyzerRules = true
"), },
                }
            }.RunAsync();
        }
 
        [Fact]
        public async Task UseBannedApi_EnforcementEnabled_Generator_CSharp()
        {
            await new VerifyCS.Test
            {
                LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp9,
                TestCode = @"
using System.IO;
using Microsoft.CodeAnalysis;
 
namespace Microsoft.CodeAnalysis
{
    public class GeneratorAttribute : System.Attribute { }
}
 
[Generator]
class MyAnalyzer
{
}
 
class C
{
    void M()
    {
        _ = File.Exists(""something"");
    }
}
",
                ExpectedDiagnostics = {
                    // /0/Test0.cs(19,13): error RS1035: The symbol 'File' is banned for use by analyzers: Do not do file IO in analyzers
                    VerifyCS.Diagnostic("RS1035").WithSpan(19, 13, 19, 37).WithArguments("File", ": Do not do file IO in analyzers"),
                },
                TestState = {
                    AnalyzerConfigFiles = { ("/.editorconfig", $@"root = true
 
[*]
build_property.EnforceExtendedAnalyzerRules = true
"), },
                }
            }.RunAsync();
        }
 
        [Fact]
        public async Task UseBannedApi_EnforcementNotSpecified_CSharp()
        {
            await new VerifyCS.Test
            {
                LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp9,
                TestCode = @"
using System.IO;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
 
[DiagnosticAnalyzer(LanguageNames.CSharp)]
class MyAnalyzer
{
}
 
class C
{
    void M()
    {
        _ = File.Exists(""something"");
    }
}
",
                ExpectedDiagnostics = {
                    // /0/Test0.cs(7,7): warning RS1036: 'MyAnalyzer': A project containing analyzers or source generators should specify the property '<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>'
                    VerifyCS.Diagnostic("RS1036").WithSpan(7, 7, 7, 17).WithArguments("MyAnalyzer"),
                }
            }.RunAsync();
        }
 
        [Fact]
        public async Task UseBannedApi_EnforcementDisabled_CSharp()
        {
            await new VerifyCS.Test
            {
                LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp9,
                TestCode = @"
using System.IO;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
 
[DiagnosticAnalyzer(LanguageNames.CSharp)]
class MyAnalyzer
{
}
 
class C
{
    void M()
    {
        _ = File.Exists(""something"");
    }
}
",
                TestState = {
                    AnalyzerConfigFiles = { ("/.editorconfig", $@"root = true
 
[*]
build_property.EnforceExtendedAnalyzerRules = false
"),
                    },
                }
            }.RunAsync();
        }
 
        [Fact]
        public async Task UseBannedApi_EnforcementEnabled_Basic()
        {
            await new VerifyVB.Test
            {
                LanguageVersion = Microsoft.CodeAnalysis.VisualBasic.LanguageVersion.Latest,
                TestCode = @"
Imports System.IO
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Diagnostics
 
<DiagnosticAnalyzer(LanguageNames.VisualBasic)>
Class MyDiagnosticAnalyzer
End Class
 
Class C
    Function M()
        File.Exists(""something"")
    End Function
End Class
",
                ExpectedDiagnostics =
                {
                    // /0/Test0.vb(12,9,12,33): error RS1035: The symbol 'File' is banned for use by analyzers: Do not do file IO in analyzers
                    VerifyVB.Diagnostic("RS1035").WithSpan(12, 9, 12, 33).WithArguments("File", ": Do not do file IO in analyzers"),
                },
                TestState = {
                    AnalyzerConfigFiles = { ("/.editorconfig", $@"root = true
 
[*]
build_property.EnforceExtendedAnalyzerRules = true
"),
                    },
                }
            }.RunAsync();
        }
 
        [Fact]
        public async Task UseBannedApi_EnforcementNotSpecified_Basic()
        {
            await new VerifyVB.Test
            {
                LanguageVersion = Microsoft.CodeAnalysis.VisualBasic.LanguageVersion.Latest,
                TestCode = @"
Imports System.IO
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Diagnostics
 
<DiagnosticAnalyzer(LanguageNames.VisualBasic)>
Class MyDiagnosticAnalyzer
End Class
 
Class C
    Function M()
        File.Exists(""something"")
    End Function
End Class
",
                ExpectedDiagnostics =
                {
                    // /0/Test0.vb(7,7): warning RS1036: 'MyDiagnosticAnalyzer': A project containing analyzers or source generators should specify the  property '<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>'
                    VerifyVB.Diagnostic("RS1036").WithSpan(7, 7, 7, 27).WithArguments("MyDiagnosticAnalyzer"),
                }
            }.RunAsync();
        }
 
        [Fact]
        public async Task UseBannedApi_EnforcementDisabled_Basic()
        {
            await new VerifyVB.Test
            {
                LanguageVersion = Microsoft.CodeAnalysis.VisualBasic.LanguageVersion.Latest,
                TestCode = @"
Imports System.IO
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Diagnostics
 
<DiagnosticAnalyzer(LanguageNames.VisualBasic)>
Class MyDiagnosticAnalyzer
End Class
 
Class C
    Function M()
        File.Exists(""something"")
    End Function
End Class
",
                TestState = {
                    AnalyzerConfigFiles = { ("/.editorconfig", $@"root = true
 
[*]
build_property.EnforceExtendedAnalyzerRules = false
"),
                    },
                }
            }.RunAsync();
        }
 
        [Fact]
        public async Task UseBannedApi_ISourceGenerator()
        {
            await new VerifyCS.Test
            {
                ReferenceAssemblies = AdditionalMetadataReferences.Default.WithPackages(ImmutableArray.Create(new PackageIdentity("Microsoft.CodeAnalysis.Common", "4.5.0"))),
                TestCode = """
                    using Microsoft.CodeAnalysis;
                    
                    [Generator]
                    class MyGenerator : ISourceGenerator
                    {
                        public void Initialize(GeneratorInitializationContext context)
                        {
                            {|#0:context.RegisterForPostInitialization(_ => { })|};
                        }
                        public void Execute(GeneratorExecutionContext context)
                        {
                            {|#1:context.AddSource("Generated.cs", "// <auto-generated/>")|};
                        }
                    }
                    """,
                TestState =
                {
                    AnalyzerConfigFiles =
                    {
                        ("/.editorconfig", """
                        root = true
 
                        [*]
                        build_property.EnforceExtendedAnalyzerRules = true
                        """),
                    },
                },
                ExpectedDiagnostics =
                {
                    // /0/Test0.cs(8,9): error RS1035: The symbol 'GeneratorInitializationContext' is banned for use by analyzers: Non-incremental source generators should not be used, implement IIncrementalGenerator instead
                    VerifyCS.Diagnostic("RS1035").WithLocation(0).WithArguments("GeneratorInitializationContext", ": Non-incremental source generators should not be used, implement IIncrementalGenerator instead"),
                    // /0/Test0.cs(14,9): error RS1035: The symbol 'GeneratorExecutionContext' is banned for use by analyzers: Non-incremental source generators should not be used, implement IIncrementalGenerator instead
                    VerifyCS.Diagnostic("RS1035").WithLocation(1).WithArguments("GeneratorExecutionContext", ": Non-incremental source generators should not be used, implement IIncrementalGenerator instead"),
                }
            }.RunAsync();
        }
    }
}