Skip to content

Commit 00aa651

Browse files
authored
Add initial regex source generator (dotnet#59186)
* Add RegexGeneratorAttribute Adds the new RegexGenerator attribute that's a signal to the regex generator to generate code for the specified regex. * Implement RegexGenerator Add a source generator for generating C# code for Regex. This is primarily a port of RegexCompiler.cs, generating C# code instead of MSIL. * Add generator test project Adds tests dedicated to the mechanics of the source generator, e.g. that appropriate diagnostics are issued for improper use of RegexGenerator. * Integrate source generator into many regex tests Start integrating the source generator into the regex test suite, so that many existing tests also validate the generated code. * Address PR feedback * Improve cachability of source generator Changing the generator to not collect all regexes together means we don't need to reprocess/regenerate all regexes every time any one of them is changed. * Use closest matching ctor from GetRegexAsync To better test the appropriate ctor usage. * Improve a few of the polyfills * Address PR feedback * Fully qualify types and remove unnecessary $s Also fixed one place where the IL we were generating wasn't as good as the reflection emit code. * Suppress a couple more warnings * Fix stray ! * Fix TODO about unrolling multi comparisons Also clean up generated code in a few places to make it more readable / concise. * Update resources per PR feedback * Add more tests, clean up parser code, and allow instance/interface methods * Fix test suppression on mobile
1 parent 072cbae commit 00aa651

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+10017
-975
lines changed

docs/project/list-of-diagnostics.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,13 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL
138138
| __`SYSLIB1037`__ | *_`SYSLIB1032`-`SYSLIB1039` reserved for System.Text.Json.SourceGeneration._* |
139139
| __`SYSLIB1038`__ | *_`SYSLIB1032`-`SYSLIB1039` reserved for System.Text.Json.SourceGeneration._* |
140140
| __`SYSLIB1039`__ | *_`SYSLIB1032`-`SYSLIB1039` reserved for System.Text.Json.SourceGeneration._* |
141+
| __`SYSLIB1040`__ | Invalid RegexGenerator attribute |
142+
| __`SYSLIB1041`__ | Multiple RegexGenerator attribute |
143+
| __`SYSLIB1042`__ | Invalid RegexGenerator arguments |
144+
| __`SYSLIB1043`__ | RegexGenerator method must have a valid signature |
145+
| __`SYSLIB1044`__ | RegexGenerator only supports C# 10 and newer |
146+
| __`SYSLIB1045`__ | *_`SYSLIB1045`-`SYSLIB1049` reserved for System.Text.RegularExpressions.Generator._* |
147+
| __`SYSLIB1046`__ | *_`SYSLIB1045`-`SYSLIB1049` reserved for System.Text.RegularExpressions.Generator._* |
148+
| __`SYSLIB1047`__ | *_`SYSLIB1045`-`SYSLIB1049` reserved for System.Text.RegularExpressions.Generator._* |
149+
| __`SYSLIB1048`__ | *_`SYSLIB1045`-`SYSLIB1049` reserved for System.Text.RegularExpressions.Generator._* |
150+
| __`SYSLIB1049`__ | *_`SYSLIB1045`-`SYSLIB1049` reserved for System.Text.RegularExpressions.Generator._* |

src/libraries/System.Text.RegularExpressions/System.Text.RegularExpressions.sln

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
Microsoft Visual Studio Solution File, Format Version 12.00
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.0.31709.452
5+
MinimumVisualStudioVersion = 10.0.40219.1
26
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{63551298-BFD4-43FC-8465-AC454228B83C}"
37
EndProject
48
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{84AABEC1-5CDA-4AB8-819E-9CA508DB6F39}"
@@ -17,6 +21,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{15319A22-BC9
1721
EndProject
1822
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D8FD137E-6961-4629-A71A-53394897FE6B}"
1923
EndProject
24+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gen", "gen", "{7A5AF59C-5114-4788-B5AA-80C977766060}"
25+
EndProject
26+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.RegularExpressions.Generator", "gen\System.Text.RegularExpressions.Generator.csproj", "{3699C8E2-C354-4AED-81DC-ECBAC3EFEB4B}"
27+
EndProject
28+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.RegularExpressions.Generators.Tests", "tests\System.Text.RegularExpressions.Generators.Tests\System.Text.RegularExpressions.Generators.Tests.csproj", "{32ABFCDA-10FD-4A98-A429-145C28021EBE}"
29+
EndProject
2030
Global
2131
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2232
Debug|Any CPU = Debug|Any CPU
@@ -47,17 +57,27 @@ Global
4757
{8EE1A7C4-3630-4900-8976-9B3ADAFF10DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
4858
{8EE1A7C4-3630-4900-8976-9B3ADAFF10DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
4959
{8EE1A7C4-3630-4900-8976-9B3ADAFF10DC}.Release|Any CPU.Build.0 = Release|Any CPU
60+
{3699C8E2-C354-4AED-81DC-ECBAC3EFEB4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
61+
{3699C8E2-C354-4AED-81DC-ECBAC3EFEB4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
62+
{3699C8E2-C354-4AED-81DC-ECBAC3EFEB4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
63+
{3699C8E2-C354-4AED-81DC-ECBAC3EFEB4B}.Release|Any CPU.Build.0 = Release|Any CPU
64+
{32ABFCDA-10FD-4A98-A429-145C28021EBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
65+
{32ABFCDA-10FD-4A98-A429-145C28021EBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
66+
{32ABFCDA-10FD-4A98-A429-145C28021EBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
67+
{32ABFCDA-10FD-4A98-A429-145C28021EBE}.Release|Any CPU.Build.0 = Release|Any CPU
5068
EndGlobalSection
5169
GlobalSection(SolutionProperties) = preSolution
5270
HideSolutionNode = FALSE
5371
EndGlobalSection
5472
GlobalSection(NestedProjects) = preSolution
5573
{63551298-BFD4-43FC-8465-AC454228B83C} = {2ACCCAAB-F0CE-4839-82BD-F174861DEA78}
56-
{8EE1A7C4-3630-4900-8976-9B3ADAFF10DC} = {2ACCCAAB-F0CE-4839-82BD-F174861DEA78}
5774
{84AABEC1-5CDA-4AB8-819E-9CA508DB6F39} = {15319A22-BC91-407B-A795-334DD05C82A0}
58-
{C043B00D-8662-43E4-9E87-8BB317059111} = {15319A22-BC91-407B-A795-334DD05C82A0}
5975
{B7E3B087-583F-49B0-8820-787CD98E54C7} = {D8FD137E-6961-4629-A71A-53394897FE6B}
76+
{C043B00D-8662-43E4-9E87-8BB317059111} = {15319A22-BC91-407B-A795-334DD05C82A0}
6077
{0409C086-D7CC-43F8-9762-C94FB1E47F5B} = {D8FD137E-6961-4629-A71A-53394897FE6B}
78+
{8EE1A7C4-3630-4900-8976-9B3ADAFF10DC} = {2ACCCAAB-F0CE-4839-82BD-F174861DEA78}
79+
{3699C8E2-C354-4AED-81DC-ECBAC3EFEB4B} = {7A5AF59C-5114-4788-B5AA-80C977766060}
80+
{32ABFCDA-10FD-4A98-A429-145C28021EBE} = {2ACCCAAB-F0CE-4839-82BD-F174861DEA78}
6181
EndGlobalSection
6282
GlobalSection(ExtensibilityGlobals) = postSolution
6383
SolutionGuid = {1ED4AB32-B7AA-478F-A96B-F725ACD0AABB}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using Microsoft.CodeAnalysis;
6+
7+
namespace System.Text.RegularExpressions.Generator
8+
{
9+
internal static class DiagnosticDescriptors
10+
{
11+
public static DiagnosticDescriptor InvalidRegexGeneratorAttribute { get; } = new DiagnosticDescriptor(
12+
id: "SYSLIB1040",
13+
title: new LocalizableResourceString(nameof(SR.InvalidRegexGeneratorAttributeTitle), SR.ResourceManager, typeof(FxResources.System.Text.RegularExpressions.Generator.SR)),
14+
messageFormat: new LocalizableResourceString(nameof(SR.InvalidRegexGeneratorAttributeMessage), SR.ResourceManager, typeof(FxResources.System.Text.RegularExpressions.Generator.SR)),
15+
category: "RegexGenerator",
16+
DiagnosticSeverity.Error,
17+
isEnabledByDefault: true,
18+
customTags: WellKnownDiagnosticTags.NotConfigurable);
19+
20+
public static DiagnosticDescriptor MultipleRegexGeneratorAttributes { get; } = new DiagnosticDescriptor(
21+
id: "SYSLIB1041",
22+
title: new LocalizableResourceString(nameof(SR.InvalidRegexGeneratorAttributeTitle), SR.ResourceManager, typeof(FxResources.System.Text.RegularExpressions.Generator.SR)),
23+
messageFormat: new LocalizableResourceString(nameof(SR.MultipleRegexGeneratorAttributesMessage), SR.ResourceManager, typeof(FxResources.System.Text.RegularExpressions.Generator.SR)),
24+
category: "RegexGenerator",
25+
DiagnosticSeverity.Error,
26+
isEnabledByDefault: true,
27+
customTags: WellKnownDiagnosticTags.NotConfigurable);
28+
29+
public static DiagnosticDescriptor InvalidRegexArguments { get; } = new DiagnosticDescriptor(
30+
id: "SYSLIB1042",
31+
title: new LocalizableResourceString(nameof(SR.InvalidRegexGeneratorAttributeTitle), SR.ResourceManager, typeof(FxResources.System.Text.RegularExpressions.Generator.SR)),
32+
messageFormat: new LocalizableResourceString(nameof(SR.InvalidRegexArgumentsMessage), SR.ResourceManager, typeof(FxResources.System.Text.RegularExpressions.Generator.SR)),
33+
category: "RegexGenerator",
34+
DiagnosticSeverity.Error,
35+
isEnabledByDefault: true,
36+
customTags: WellKnownDiagnosticTags.NotConfigurable);
37+
38+
public static DiagnosticDescriptor RegexMethodMustHaveValidSignature { get; } = new DiagnosticDescriptor(
39+
id: "SYSLIB1043",
40+
title: new LocalizableResourceString(nameof(SR.InvalidRegexGeneratorAttributeTitle), SR.ResourceManager, typeof(FxResources.System.Text.RegularExpressions.Generator.SR)),
41+
messageFormat: new LocalizableResourceString(nameof(SR.RegexMethodMustHaveValidSignatureMessage), SR.ResourceManager, typeof(FxResources.System.Text.RegularExpressions.Generator.SR)),
42+
category: "RegexGenerator",
43+
DiagnosticSeverity.Error,
44+
isEnabledByDefault: true,
45+
customTags: WellKnownDiagnosticTags.NotConfigurable);
46+
47+
public static DiagnosticDescriptor InvalidLangVersion { get; } = new DiagnosticDescriptor(
48+
id: "SYSLIB1044",
49+
title: new LocalizableResourceString(nameof(SR.InvalidRegexGeneratorAttributeTitle), SR.ResourceManager, typeof(FxResources.System.Text.RegularExpressions.Generator.SR)),
50+
messageFormat: new LocalizableResourceString(nameof(SR.InvalidLangVersionMessage), SR.ResourceManager, typeof(FxResources.System.Text.RegularExpressions.Generator.SR)),
51+
category: "RegexGenerator",
52+
DiagnosticSeverity.Error,
53+
isEnabledByDefault: true,
54+
customTags: WellKnownDiagnosticTags.NotConfigurable);
55+
}
56+
}

0 commit comments

Comments
 (0)