in src/EditorFeatures/CSharpTest/Diagnostics/Suppression/SuppressionTests.cs [33:595]
protected override TestWorkspace CreateWorkspaceFromFile(string initialMarkup, TestParameters parameters)
=> TestWorkspace.CreateCSharp(initialMarkup, parameters.parseOptions, parameters.compilationOptions);
#region "Pragma disable tests"
public abstract partial class CSharpPragmaWarningDisableSuppressionTests : CSharpSuppressionTests
{
protected sealed override int CodeActionIndex
{
get { return 0; }
}
public class CompilerDiagnosticSuppressionTests : CSharpPragmaWarningDisableSuppressionTests
{
internal override Tuple<DiagnosticAnalyzer, ISuppressionFixProvider> CreateDiagnosticProviderAndFixer(Workspace workspace)
{
return Tuple.Create<DiagnosticAnalyzer, ISuppressionFixProvider>(null, new CSharpSuppressionCodeFixProvider());
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestPragmaWarningDirective()
{
await TestAsync(
@"
class Class
{
void Method()
{
[|int x = 0;|]
}
}",
$@"
class Class
{{
void Method()
{{
#pragma warning disable CS0219 // {CSharpResources.WRN_UnreferencedVarAssg_Title}
int x = 0;
#pragma warning restore CS0219 // {CSharpResources.WRN_UnreferencedVarAssg_Title}
}}
}}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestMultilineStatementPragmaWarningDirective()
{
await TestAsync(
@"
class Class
{
void Method()
{
[|int x = 0
+ 1;|]
}
}",
$@"
class Class
{{
void Method()
{{
#pragma warning disable CS0219 // {CSharpResources.WRN_UnreferencedVarAssg_Title}
int x = 0
#pragma warning restore CS0219 // {CSharpResources.WRN_UnreferencedVarAssg_Title}
+ 1;
}}
}}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestPragmaWarningDirectiveWithExistingTrivia()
{
await TestAsync(
@"
class Class
{
void Method()
{
// Start comment previous line
/* Start comment same line */ [|int x = 0;|] // End comment same line
/* End comment next line */
}
}",
$@"
class Class
{{
void Method()
{{
// Start comment previous line
#pragma warning disable CS0219 // {CSharpResources.WRN_UnreferencedVarAssg_Title}
/* Start comment same line */
int x = 0; // End comment same line
#pragma warning restore CS0219 // {CSharpResources.WRN_UnreferencedVarAssg_Title}
/* End comment next line */
}}
}}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestMultipleInstancesOfPragmaWarningDirective()
{
await TestAsync(
@"
class Class
{
void Method()
{
[|int x = 0, y = 0;|]
}
}",
$@"
class Class
{{
void Method()
{{
#pragma warning disable CS0219 // {CSharpResources.WRN_UnreferencedVarAssg_Title}
int x = 0, y = 0;
#pragma warning restore CS0219 // {CSharpResources.WRN_UnreferencedVarAssg_Title}
}}
}}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
[WorkItem(3311, "https://github.com/dotnet/roslyn/issues/3311")]
public async Task TestNoDuplicateSuppressionCodeFixes()
{
var source = @"
class Class
{
void Method()
{
[|int x = 0, y = 0; string s;|]
}
}";
var parameters = new TestParameters();
using (var workspace = CreateWorkspaceFromOptions(source, parameters))
{
var diagnosticService = new TestDiagnosticAnalyzerService(LanguageNames.CSharp, new CSharpCompilerDiagnosticAnalyzer());
var incrementalAnalyzer = diagnosticService.CreateIncrementalAnalyzer(workspace);
var suppressionProvider = CreateDiagnosticProviderAndFixer(workspace).Item2;
var suppressionProviderFactory = new Lazy<ISuppressionFixProvider, CodeChangeProviderMetadata>(() => suppressionProvider,
new CodeChangeProviderMetadata("SuppressionProvider", languages: new[] { LanguageNames.CSharp }));
var fixService = new CodeFixService(diagnosticService,
SpecializedCollections.EmptyEnumerable<Lazy<IErrorLoggerService>>(),
SpecializedCollections.EmptyEnumerable<Lazy<CodeFixProvider, CodeChangeProviderMetadata>>(),
SpecializedCollections.SingletonEnumerable(suppressionProviderFactory));
var document = GetDocumentAndSelectSpan(workspace, out var span);
var diagnostics = await diagnosticService.GetDiagnosticsForSpanAsync(document, span);
Assert.Equal(2, diagnostics.Where(d => d.Id == "CS0219").Count());
var allFixes = (await fixService.GetFixesAsync(document, span, includeSuppressionFixes: true, cancellationToken: CancellationToken.None))
.SelectMany(fixCollection => fixCollection.Fixes);
var cs0219Fixes = allFixes.Where(fix => fix.PrimaryDiagnostic.Id == "CS0219");
// Ensure that both the fixes have identical equivalence key, and hence get de-duplicated in LB menu.
Assert.Equal(2, cs0219Fixes.Count());
var cs0219EquivalenceKey = cs0219Fixes.First().Action.EquivalenceKey;
Assert.NotNull(cs0219EquivalenceKey);
Assert.Equal(cs0219EquivalenceKey, cs0219Fixes.Last().Action.EquivalenceKey);
// Ensure that there *is* a fix for the other warning and that it has a *different*
// equivalence key so that it *doesn't* get de-duplicated
Assert.Equal(1, diagnostics.Where(d => d.Id == "CS0168").Count());
var cs0168Fixes = allFixes.Where(fix => fix.PrimaryDiagnostic.Id == "CS0168");
var cs0168EquivalenceKey = cs0168Fixes.Single().Action.EquivalenceKey;
Assert.NotNull(cs0168EquivalenceKey);
Assert.NotEqual(cs0219EquivalenceKey, cs0168EquivalenceKey);
}
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestErrorAndWarningScenario()
{
await TestAsync(
@"
class Class
{
void Method()
{
return 0;
[|int x = ""0"";|]
}
}",
$@"
class Class
{{
void Method()
{{
return 0;
#pragma warning disable CS0162 // {CSharpResources.WRN_UnreachableCode_Title}
int x = ""0"";
#pragma warning restore CS0162 // {CSharpResources.WRN_UnreachableCode_Title}
}}
}}");
}
[WorkItem(956453, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/956453")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestWholeFilePragmaWarningDirective()
{
await TestAsync(
@"class Class { void Method() { [|int x = 0;|] } }",
$@"#pragma warning disable CS0219 // {CSharpResources.WRN_UnreferencedVarAssg_Title}
class Class {{ void Method() {{ int x = 0; }} }}
#pragma warning restore CS0219 // {CSharpResources.WRN_UnreferencedVarAssg_Title}");
}
[WorkItem(970129, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/970129")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestSuppressionAroundSingleToken()
{
await TestAsync(
@"
using System;
[Obsolete]
class Session { }
class Program
{
static void Main()
{
[|Session|]
}
}",
$@"
using System;
[Obsolete]
class Session {{ }}
class Program
{{
static void Main()
{{
#pragma warning disable CS0612 // {CSharpResources.WRN_DeprecatedSymbol_Title}
Session
#pragma warning restore CS0612 // {CSharpResources.WRN_DeprecatedSymbol_Title}
}}
}}");
}
[WorkItem(1066576, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1066576")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestPragmaWarningDirectiveAroundTrivia1()
{
await TestAsync(
@"
class Class
{
void Method()
{
// Comment
// Comment
[|#pragma abcde|]
} // Comment
}",
$@"
class Class
{{
void Method()
{{
// Comment
// Comment
#pragma warning disable CS1633 // {CSharpResources.WRN_IllegalPragma_Title}
#pragma abcde
}} // Comment
#pragma warning restore CS1633 // {CSharpResources.WRN_IllegalPragma_Title}
}}");
}
[WorkItem(1066576, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1066576")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestPragmaWarningDirectiveAroundTrivia2()
{
await TestAsync(
@"[|#pragma abcde|]",
$@"#pragma warning disable CS1633 // {CSharpResources.WRN_IllegalPragma_Title}
#pragma abcde
#pragma warning restore CS1633 // {CSharpResources.WRN_IllegalPragma_Title}");
}
[WorkItem(1066576, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1066576")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestPragmaWarningDirectiveAroundTrivia3()
{
await TestAsync(
@"[|#pragma abcde|] ",
$@"#pragma warning disable CS1633 // {CSharpResources.WRN_IllegalPragma_Title}
#pragma abcde
#pragma warning restore CS1633 // {CSharpResources.WRN_IllegalPragma_Title}");
}
[WorkItem(1066576, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1066576")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestPragmaWarningDirectiveAroundTrivia4()
{
await TestAsync(
@"
[|#pragma abc|]
class C { }
",
$@"
#pragma warning disable CS1633 // {CSharpResources.WRN_IllegalPragma_Title}
#pragma abc
class C {{ }}
#pragma warning restore CS1633 // {CSharpResources.WRN_IllegalPragma_Title}
");
}
[WorkItem(1066576, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1066576")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestPragmaWarningDirectiveAroundTrivia5()
{
await TestAsync(
@"class C1 { }
[|#pragma abc|]
class C2 { }
class C3 { }",
$@"class C1 {{ }}
#pragma warning disable CS1633 // {CSharpResources.WRN_IllegalPragma_Title}
#pragma abc
class C2 {{ }}
#pragma warning restore CS1633 // {CSharpResources.WRN_IllegalPragma_Title}
class C3 {{ }}");
}
[WorkItem(1066576, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1066576")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestPragmaWarningDirectiveAroundTrivia6()
{
await TestAsync(
@"class C1 { }
class C2 { } /// <summary><see [|cref=""abc""|]/></summary>
class C3 { } // comment
// comment
// comment",
$@"class C1 {{ }}
#pragma warning disable CS1574 // {CSharpResources.WRN_BadXMLRef_Title}
class C2 {{ }} /// <summary><see cref=""abc""/></summary>
class
#pragma warning restore CS1574 // {CSharpResources.WRN_BadXMLRef_Title}
C3 {{ }} // comment
// comment
// comment", CSharpParseOptions.Default.WithDocumentationMode(DocumentationMode.Diagnose));
}
}
public class UserHiddenDiagnosticSuppressionTests : CSharpPragmaWarningDisableSuppressionTests
{
internal override Tuple<DiagnosticAnalyzer, ISuppressionFixProvider> CreateDiagnosticProviderAndFixer(Workspace workspace)
{
return new Tuple<DiagnosticAnalyzer, ISuppressionFixProvider>(
new CSharpSimplifyTypeNamesDiagnosticAnalyzer(), new CSharpSuppressionCodeFixProvider());
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestHiddenDiagnosticCannotBeSuppressed()
{
await TestMissingAsync(
@"
using System;
class Class
{
int Method()
{
[|System.Int32 x = 0;|]
return x;
}
}");
}
}
public partial class UserInfoDiagnosticSuppressionTests : CSharpPragmaWarningDisableSuppressionTests
{
private class UserDiagnosticAnalyzer : DiagnosticAnalyzer
{
public static readonly DiagnosticDescriptor Decsciptor =
new DiagnosticDescriptor("InfoDiagnostic", "InfoDiagnostic Title", "InfoDiagnostic", "InfoDiagnostic", DiagnosticSeverity.Info, isEnabledByDefault: true);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
{
get
{
return ImmutableArray.Create(Decsciptor);
}
}
public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.ClassDeclaration);
}
public void AnalyzeNode(SyntaxNodeAnalysisContext context)
{
var classDecl = (ClassDeclarationSyntax)context.Node;
context.ReportDiagnostic(Diagnostic.Create(Decsciptor, classDecl.Identifier.GetLocation()));
}
}
internal override Tuple<DiagnosticAnalyzer, ISuppressionFixProvider> CreateDiagnosticProviderAndFixer(Workspace workspace)
{
return new Tuple<DiagnosticAnalyzer, ISuppressionFixProvider>(
new UserDiagnosticAnalyzer(), new CSharpSuppressionCodeFixProvider());
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestInfoDiagnosticSuppressed()
{
await TestAsync(
@"
using System;
[|class Class|]
{
int Method()
{
int x = 0;
}
}",
@"
using System;
#pragma warning disable InfoDiagnostic // InfoDiagnostic Title
class Class
#pragma warning restore InfoDiagnostic // InfoDiagnostic Title
{
int Method()
{
int x = 0;
}
}");
}
}
public class UserErrorDiagnosticSuppressionTests : CSharpPragmaWarningDisableSuppressionTests
{
private class UserDiagnosticAnalyzer : DiagnosticAnalyzer
{
private DiagnosticDescriptor _descriptor =
new DiagnosticDescriptor("ErrorDiagnostic", "ErrorDiagnostic", "ErrorDiagnostic", "ErrorDiagnostic", DiagnosticSeverity.Error, isEnabledByDefault: true);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
{
get
{
return ImmutableArray.Create(_descriptor);
}
}
public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.ClassDeclaration);
}
public void AnalyzeNode(SyntaxNodeAnalysisContext context)
{
var classDecl = (ClassDeclarationSyntax)context.Node;
context.ReportDiagnostic(Diagnostic.Create(_descriptor, classDecl.Identifier.GetLocation()));
}
}
internal override Tuple<DiagnosticAnalyzer, ISuppressionFixProvider> CreateDiagnosticProviderAndFixer(Workspace workspace)
{
return new Tuple<DiagnosticAnalyzer, ISuppressionFixProvider>(
new UserDiagnosticAnalyzer(), new CSharpSuppressionCodeFixProvider());
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestErrorDiagnosticCanBeSuppressed()
{
await TestAsync(
@"
using System;
[|class Class|]
{
int Method()
{
int x = 0;
}
}",
@"
using System;
#pragma warning disable ErrorDiagnostic // ErrorDiagnostic
class Class
#pragma warning restore ErrorDiagnostic // ErrorDiagnostic
{
int Method()
{
int x = 0;
}
}");
}
}
public class DiagnosticWithBadIdSuppressionTests : CSharpPragmaWarningDisableSuppressionTests
{
// Analyzer driver generates a no-location analyzer exception diagnostic, which we don't intend to test here.
protected override bool IncludeNoLocationDiagnostics => false;
private class UserDiagnosticAnalyzer : DiagnosticAnalyzer
{
private DiagnosticDescriptor _descriptor =
new DiagnosticDescriptor("@~DiagnosticWithBadId", "DiagnosticWithBadId", "DiagnosticWithBadId", "DiagnosticWithBadId", DiagnosticSeverity.Info, isEnabledByDefault: true);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
{
get
{
return ImmutableArray.Create(_descriptor);
}
}
public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.ClassDeclaration);
}
public void AnalyzeNode(SyntaxNodeAnalysisContext context)
{
var classDecl = (ClassDeclarationSyntax)context.Node;
context.ReportDiagnostic(Diagnostic.Create(_descriptor, classDecl.Identifier.GetLocation()));
}
}
internal override Tuple<DiagnosticAnalyzer, ISuppressionFixProvider> CreateDiagnosticProviderAndFixer(Workspace workspace)
{
return new Tuple<DiagnosticAnalyzer, ISuppressionFixProvider>(
new UserDiagnosticAnalyzer(), new CSharpSuppressionCodeFixProvider());
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSuppression)]
public async Task TestDiagnosticWithBadIdSuppressed()
{
// Diagnostics with bad/invalid ID are not reported.
await TestMissingAsync(
@"
using System;
[|class Class|]
{
int Method()
{
int x = 0;
}
}");
}
}
}