diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/CSharpCodeFixVerifier`2.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/CSharpCodeFixVerifier`2.cs index 471c02d564d311..e0202a38cf94d2 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/CSharpCodeFixVerifier`2.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/CSharpCodeFixVerifier`2.cs @@ -20,62 +20,26 @@ public static class CSharpCodeFixVerifier where TAnalyzer : DiagnosticAnalyzer, new() where TCodeFix : CodeFixProvider, new() { - /// - public static DiagnosticResult Diagnostic() - => CSharpCodeFixVerifier.Diagnostic(); - - /// - public static DiagnosticResult Diagnostic(string diagnosticId) - => CSharpCodeFixVerifier.Diagnostic(diagnosticId); - - /// - public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) - => CSharpCodeFixVerifier.Diagnostic(descriptor); - - /// - public static async Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected) - => await VerifyAnalyzerAsync(source, null, usePreviewLanguageVersion: true, expected); - - /// - public static async Task VerifyAnalyzerAsync(string source, ReferenceAssemblies? references, bool usePreviewLanguageVersion, params DiagnosticResult[] expected) + public static async Task VerifyAnalyzerAsync(string source, ReferenceAssemblies? references = null) { - Test test = new Test(references, usePreviewLanguageVersion, numberOfIterations: 1) - { - TestCode = source, - }; - - test.ExpectedDiagnostics.AddRange(expected); - await test.RunAsync(CancellationToken.None); + await VerifyCodeFixAsync(source, source, references); } - /// - public static async Task VerifyCodeFixAsync(string source, string fixedSource) - => await VerifyCodeFixAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource); - - /// - public static async Task VerifyCodeFixAsync(string source, DiagnosticResult expected, string fixedSource) - => await VerifyCodeFixAsync(source, new[] { expected }, fixedSource); - - /// - public static async Task VerifyCodeFixAsync(string source, DiagnosticResult[] expected, string fixedSource, int numberOfIterations = 1) + public static async Task VerifyCodeFixAsync(string source, string fixedSource, ReferenceAssemblies? references = null) { - Test test = new Test(null, usePreviewLanguageVersion: true, numberOfIterations) + Test test = new Test(references) { TestCode = source, FixedCode = fixedSource, }; - test.ExpectedDiagnostics.AddRange(expected); await test.RunAsync(CancellationToken.None); } public class Test : CSharpCodeFixTest { - public Test(ReferenceAssemblies? references, bool usePreviewLanguageVersion, int numberOfIterations) + public Test(ReferenceAssemblies? references = null) { - // Code Fixer generates partial methods that will need to use the source generator to be filled. - this.CompilerDiagnostics = CompilerDiagnostics.None; - if (references != null) { ReferenceAssemblies = references; @@ -87,21 +51,17 @@ public Test(ReferenceAssemblies? references, bool usePreviewLanguageVersion, int ReferenceAssemblies = new ReferenceAssemblies(string.Empty); TestState.AdditionalReferences.AddRange(RegexGeneratorHelper.References); } + } - NumberOfFixAllIterations = numberOfIterations; - - SolutionTransforms.Add((solution, projectId) => - { - if (usePreviewLanguageVersion) - { - CSharpParseOptions parseOptions = solution.GetProject(projectId).ParseOptions as CSharpParseOptions; - parseOptions = parseOptions.WithLanguageVersion(LanguageVersion.Preview); - solution = solution.WithProjectParseOptions(projectId, parseOptions); - } + public LanguageVersion LanguageVersion { get; set; } = LanguageVersion.Preview; - return solution; - }); + protected override ParseOptions CreateParseOptions() + { + return ((CSharpParseOptions)base.CreateParseOptions()).WithLanguageVersion(LanguageVersion); } + + // CS8795: Partial method '{0}' must have an implementation part because it has accessibility modifiers. + protected override bool IsCompilerDiagnosticIncluded(Diagnostic diagnostic, CompilerDiagnostics compilerDiagnostics) => base.IsCompilerDiagnosticIncluded(diagnostic, compilerDiagnostics) && diagnostic.Id != "CS8795"; } } } diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/UpgradeToRegexGeneratorAnalyzerTests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/UpgradeToRegexGeneratorAnalyzerTests.cs index 1a278912c62cc6..5c18259ef93eb9 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/UpgradeToRegexGeneratorAnalyzerTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/UpgradeToRegexGeneratorAnalyzerTests.cs @@ -7,7 +7,10 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions.Generator; +using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Testing; using Xunit; using VerifyCS = System.Text.RegularExpressions.Tests.CSharpCodeFixVerifier< @@ -45,7 +48,7 @@ public class Program { public static void Main(string[] args) { - var regex = new Regex("""", timeout: TimeSpan.FromSeconds(10)); + var regex = new Regex("""", matchTimeout: TimeSpan.FromSeconds(10), options: RegexOptions.None); } }" }; @@ -56,7 +59,18 @@ public class Program { public static void Main(string[] args) { - var regex = new Regex(timeout: TimeSpan.FromSeconds(10), pattern: """"); + var regex = new Regex(matchTimeout: TimeSpan.FromSeconds(10), pattern: """", options: RegexOptions.None); + } +}" }; + + yield return new object[] { @"using System; +using System.Text.RegularExpressions; + +public class Program +{ + public static void Main(string[] args) + { + var regex = new Regex(matchTimeout: TimeSpan.FromSeconds(10), options: RegexOptions.None, pattern: """"); } }" }; } @@ -83,7 +97,12 @@ partial class Program [RegexGenerator("""")] private static partial Regex MyRegex(); }"; - await VerifyCS.VerifyCodeFixAsync(test, fixedCode); + await new VerifyCS.Test + { + TestCode = test, + FixedCode = fixedCode, + TestState = { OutputKind = OutputKind.ConsoleApplication }, + }.RunAsync(); } public static IEnumerable StaticInvocationWithTimeoutTestData() @@ -136,7 +155,7 @@ public static void Main(string[] args) } }"; - await VerifyCS.VerifyAnalyzerAsync(test, ReferenceAssemblies.Net.Net60, usePreviewLanguageVersion: true); + await VerifyCS.VerifyAnalyzerAsync(test, ReferenceAssemblies.Net.Net60); } [Theory] @@ -154,8 +173,12 @@ public static void Main(string[] args) var isMatch = " + ConstructRegexInvocation(invocationType, "\"\"") + isMatchInvocation + @"; } }"; - - await VerifyCS.VerifyAnalyzerAsync(test, null, usePreviewLanguageVersion: false); + await new VerifyCS.Test + { + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp10, + }.RunAsync(); } public static IEnumerable ConstantPatternTestData() @@ -171,7 +194,7 @@ public class Program { public static void Main(string[] args) { - var isMatch = {|#0:" + ConstructRegexInvocation(invocationType, "\"\"") + @"|}" + isMatchInvocation + @"; + var isMatch = [|" + ConstructRegexInvocation(invocationType, "\"\"") + @"|]" + isMatchInvocation + @"; } }", @"using System.Text; using System.Text.RegularExpressions; @@ -196,7 +219,7 @@ public class Program public static void Main(string[] args) { const string pattern = @""""; - var isMatch = {|#0:" + ConstructRegexInvocation(invocationType, "\"\"") + @"|}" + isMatchInvocation + @"; + var isMatch = [|" + ConstructRegexInvocation(invocationType, "\"\"") + @"|]" + isMatchInvocation + @"; } }", @"using System.Text; using System.Text.RegularExpressions; @@ -223,7 +246,7 @@ public class Program public static void Main(string[] args) { - var isMatch = {|#0:" + ConstructRegexInvocation(invocationType, "\"\"") + @"|}" + isMatchInvocation + @"; + var isMatch = [|" + ConstructRegexInvocation(invocationType, "\"\"") + @"|]" + isMatchInvocation + @"; } }", @"using System.Text; using System.Text.RegularExpressions; @@ -247,8 +270,7 @@ public static void Main(string[] args) [MemberData(nameof(ConstantPatternTestData))] public async Task DiagnosticEmittedForConstantPattern(string test, string fixedSource) { - DiagnosticResult expectedDiagnostic = VerifyCS.Diagnostic(UseRegexSourceGeneratorDiagnosticId).WithLocation(0); - await VerifyCS.VerifyCodeFixAsync(test, expectedDiagnostic, fixedSource); + await VerifyCS.VerifyCodeFixAsync(test, fixedSource); } public static IEnumerable VariablePatternTestData() @@ -339,7 +361,7 @@ public class Program { public static void Main(string[] args) { - var isMatch = {|#0:" + ConstructRegexInvocation(invocationType, "\"\"", "RegexOptions.None") + @"|}" + isMatchInvocation + @"; + var isMatch = [|" + ConstructRegexInvocation(invocationType, "\"\"", "RegexOptions.None") + @"|]" + isMatchInvocation + @"; } }", @"using System.Text.RegularExpressions; @@ -362,7 +384,7 @@ public class Program public static void Main(string[] args) { const RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.CultureInvariant; - var isMatch = {|#0:" + ConstructRegexInvocation(invocationType, "\"\"", "options") + @"|}" + isMatchInvocation + @"; + var isMatch = [|" + ConstructRegexInvocation(invocationType, "\"\"", "options") + @"|]" + isMatchInvocation + @"; } }", @"using System.Text.RegularExpressions; @@ -387,7 +409,7 @@ public class Program public static void Main(string[] args) { - var isMatch = {|#0:" + ConstructRegexInvocation(invocationType, "\"\"", "Options") + @"|}" + isMatchInvocation + @"; + var isMatch = [|" + ConstructRegexInvocation(invocationType, "\"\"", "Options") + @"|]" + isMatchInvocation + @"; } }", @"using System.Text.RegularExpressions; @@ -410,8 +432,7 @@ public static void Main(string[] args) [MemberData(nameof(ConstantOptionsTestData))] public async Task DiagnosticEmittedForConstantOptions(string test, string fixedSource) { - DiagnosticResult expected = VerifyCS.Diagnostic(UseRegexSourceGeneratorDiagnosticId).WithLocation(0); - await VerifyCS.VerifyCodeFixAsync(test, expected, fixedSource); + await VerifyCS.VerifyCodeFixAsync(test, fixedSource); } public static IEnumerable VariableOptionsTestData() @@ -498,7 +519,7 @@ public class Program { public static void Main(string[] args) { - {|#0:Regex.@@Method@@(""input"", ""a|b"", RegexOptions.None)|}; + [|Regex.@@Method@@(""input"", ""a|b"", RegexOptions.None)|]; } }"; const string fixedSourceWithOptions = @"using System.Text.RegularExpressions; @@ -513,7 +534,6 @@ public static void Main(string[] args) [RegexGenerator(""a|b"", RegexOptions.None)] private static partial Regex MyRegex(); }"; - DiagnosticResult expectedDiagnostic = VerifyCS.Diagnostic(UseRegexSourceGeneratorDiagnosticId).WithLocation(0); const string testTemplateWithoutOptions = @"using System.Text.RegularExpressions; @@ -521,7 +541,7 @@ public class Program { public static void Main(string[] args) { - {|#0:Regex.@@Method@@(""input"", ""a|b"")|}; + [|Regex.@@Method@@(""input"", ""a|b"")|]; } }"; const string fixedSourceWithoutOptions = @"using System.Text.RegularExpressions; @@ -543,11 +563,11 @@ public static void Main(string[] args) { if (includeRegexOptions) { - yield return new object[] { testTemplateWithOptions.Replace("@@Method@@", methodName), expectedDiagnostic, fixedSourceWithOptions.Replace("@@Method@@", methodName) }; + yield return new object[] { testTemplateWithOptions.Replace("@@Method@@", methodName), fixedSourceWithOptions.Replace("@@Method@@", methodName) }; } else { - yield return new object[] { testTemplateWithoutOptions.Replace("@@Method@@", methodName), expectedDiagnostic, fixedSourceWithoutOptions.Replace("@@Method@@", methodName) }; + yield return new object[] { testTemplateWithoutOptions.Replace("@@Method@@", methodName), fixedSourceWithoutOptions.Replace("@@Method@@", methodName) }; } } @@ -561,10 +581,10 @@ public class Program { public static void Main(string[] args) { - {|#0:Regex.Replace(""input"", ""a[b|c]*"", ""replacement"", RegexOptions.CultureInvariant)|}; + [|Regex.Replace(""input"", ""a[b|c]*"", ""replacement"", RegexOptions.CultureInvariant)|]; } } -", expectedDiagnostic, @"using System.Text.RegularExpressions; +", @"using System.Text.RegularExpressions; public partial class Program { @@ -584,10 +604,10 @@ public class Program { public static void Main(string[] args) { - {|#0:Regex.Replace(""input"", ""a[b|c]*"", ""replacement"")|}; + [|Regex.Replace(""input"", ""a[b|c]*"", ""replacement"")|]; } } -", expectedDiagnostic, @"using System.Text.RegularExpressions; +", @"using System.Text.RegularExpressions; public partial class Program { @@ -604,13 +624,12 @@ public static void Main(string[] args) [Theory] [MemberData(nameof(StaticInvocationsAndFixedSourceTestData))] - public async Task DiagnosticAndCodeFixForAllStaticMethods(string test, DiagnosticResult expectedDiagnostic, string fixedSource) - => await VerifyCS.VerifyCodeFixAsync(test, expectedDiagnostic, fixedSource); + public async Task DiagnosticAndCodeFixForAllStaticMethods(string test, string fixedSource) + => await VerifyCS.VerifyCodeFixAsync(test, fixedSource); [Fact] public async Task CodeFixSupportsNesting() { - DiagnosticResult expectedDiagnostic = VerifyCS.Diagnostic(UseRegexSourceGeneratorDiagnosticId).WithLocation(0); string test = @"using System.Text.RegularExpressions; public class A @@ -623,7 +642,7 @@ public partial class D { public void Foo() { - Regex regex = {|#0:new Regex(""pattern"", RegexOptions.IgnorePatternWhitespace)|}; + Regex regex = [|new Regex(""pattern"", RegexOptions.IgnorePatternWhitespace)|]; } } } @@ -653,7 +672,7 @@ public void Foo() } "; - await VerifyCS.VerifyCodeFixAsync(test, expectedDiagnostic, fixedSource); + await VerifyCS.VerifyCodeFixAsync(test, fixedSource); } [Theory] @@ -683,17 +702,11 @@ public class Program { public static void Main() { - Regex regex1 = {|#0:new Regex(""a|b"")|}; - Regex regex2 = {|#1:new Regex(""c|d"", RegexOptions.CultureInvariant)|}; + Regex regex1 = [|new Regex(""a|b"")|]; + Regex regex2 = [|new Regex(""c|d"", RegexOptions.CultureInvariant)|]; } } "; - DiagnosticResult[] expectedDiagnostics = new[] - { - VerifyCS.Diagnostic(UseRegexSourceGeneratorDiagnosticId).WithLocation(0), - VerifyCS.Diagnostic(UseRegexSourceGeneratorDiagnosticId).WithLocation(1) - }; - string fixedSource = @"using System.Text.RegularExpressions; public partial class Program @@ -710,8 +723,12 @@ public static void Main() private static partial Regex MyRegex1(); } "; - - await VerifyCS.VerifyCodeFixAsync(test, expectedDiagnostics, fixedSource, 2); + await new VerifyCS.Test + { + TestCode = test, + FixedCode = fixedSource, + NumberOfFixAllIterations = 2, + }.RunAsync(); } [Fact] @@ -723,10 +740,9 @@ class Program { static void Main(string[] args) { - Regex r = {|#0:new Regex(options: RegexOptions.None, pattern: ""a|b"")|}; + Regex r = [|new Regex(options: RegexOptions.None, pattern: ""a|b"")|]; } }"; - DiagnosticResult expectedDiagnostic = VerifyCS.Diagnostic(UseRegexSourceGeneratorDiagnosticId).WithLocation(0); string fixedSource = @"using System.Text.RegularExpressions; @@ -741,17 +757,18 @@ static void Main(string[] args) private static partial Regex MyRegex(); }"; - await VerifyCS.VerifyCodeFixAsync(test, expectedDiagnostic, fixedSource); + await VerifyCS.VerifyCodeFixAsync(test, fixedSource); } [Fact] public async Task TopLevelStatements_MultipleSourceFiles() { - await new VerifyCS.Test(references: null, usePreviewLanguageVersion: true, numberOfIterations: 1) + await new VerifyCS.Test { TestState = { Sources = { "public class C { }", @"var r = [|new System.Text.RegularExpressions.Regex("""")|];" }, + OutputKind = OutputKind.ConsoleApplication, }, FixedState = { @@ -762,7 +779,7 @@ partial class Program [System.Text.RegularExpressions.RegexGenerator("""")] private static partial System.Text.RegularExpressions.Regex MyRegex(); }" } - } + }, }.RunAsync(); } @@ -774,10 +791,9 @@ public async Task LeadingAndTrailingTriviaIsPreservedByFixer() static class Class { public static string CollapseWhitespace(this string text) => - {|#0:Regex.Replace(text, @"" \s+"" , "" "")|}; + [|Regex.Replace(text, @"" \s+"" , "" "")|]; }"; - DiagnosticResult expectedDiagnostic = VerifyCS.Diagnostic(UseRegexSourceGeneratorDiagnosticId).WithLocation(0); string expectedFixedCode = @"using System.Text.RegularExpressions; static partial class Class @@ -788,7 +804,7 @@ public static string CollapseWhitespace(this string text) => private static partial Regex MyRegex(); }"; - await VerifyCS.VerifyCodeFixAsync(test, expectedDiagnostic, expectedFixedCode); + await VerifyCS.VerifyCodeFixAsync(test, expectedFixedCode); } [Fact]