Delete old code generation approach from RegexCompiler / source generator (#62318)
authorStephen Toub <stoub@microsoft.com>
Fri, 3 Dec 2021 22:09:51 +0000 (17:09 -0500)
committerGitHub <noreply@github.com>
Fri, 3 Dec 2021 22:09:51 +0000 (17:09 -0500)
commit80ba698a41cafa092a12a18119ae4a1c57347d64
tree838b43c02f961545ab584b4555dd3ead40845b69
parentf2c8f7c0bde8b9d389ce491b34bc0b0d9edf6a7e
Delete old code generation approach from RegexCompiler / source generator (#62318)

* Delete old code generation approach from RegexCompiler / source generator

In .NET Framework and up through .NET Core 3.1, the code generated for RegexOptions.Compiler was effectively an unrolled version of what RegexInterpreter would process.  The RegexNode tree would be turned into a series of opcodes via RegexWriter; the interpreter would then sit in a loop processing those opcodes, and the RegexCompiler iterates through the opcodes generating code for each equivalent to what the interpreter would do but with some decisions made at compile-time rather than at run-time.  This approach, however, leads to complicated code that's not pay-for-play (e.g. a big backtracking jump table that all compilations go through even if there's no backtracking), that doesn't factor in the shape of the tree (e.g. it's difficult to add optimizations based on interactions between nodes in the graph), and that doesn't read well when emitted as C# instead of IL as part of the source generator.  In .NET 5, we started adding an alternative implementation that processed the RegexNode tree directly, addressing all of those cited issues; however, it only worked for a subset of expressions, namely those with little-to-no backtracking (e.g. non-atomic loops and alternations weren't supported).  Since then, we've improved it to the point where everything other than RegexOptions.RightToLeft (which implicitly means lookbehinds as well) is supported, and we've agreed it's ok to drop compilation for those constructs; if they ever become an issue, we can add support for them via the new compilation scheme.

As such, this PR:
- Deletes all of the code associated with the older code generation scheme
- Updates the Regex ctor to fall back to selecting the interpreter if the expression can't be compiled
- Updates the source generator to fall back to just emitting a cached use of Regex if the expression can't be compiled (and issuing a diagnostic in that case)
- Adds several tests that now pass with the new scheme that didn't with the old (and that still don't with the interpreter)

* Make the addition of more declarations a bit more robust

* Reduce backtracking code gen when nodes are atomic

Also added some comments and renamed a few methods for consistency between RegexCompiler and RegexGenerator.Emitter

* Fix tests on mono interpreter
25 files changed:
src/libraries/System.Text.RegularExpressions/gen/DiagnosticDescriptors.cs
src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs
src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Parser.cs
src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.cs
src/libraries/System.Text.RegularExpressions/gen/Resources/Strings.resx
src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.cs.xlf
src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.de.xlf
src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.es.xlf
src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.fr.xlf
src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.it.xlf
src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.ja.xlf
src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.ko.xlf
src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.pl.xlf
src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.pt-BR.xlf
src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.ru.xlf
src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.tr.xlf
src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.zh-Hans.xlf
src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.zh-Hant.xlf
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.cs
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCompiler.cs
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexLWCGCompiler.cs
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexNode.cs
src/libraries/System.Text.RegularExpressions/tests/Regex.MultipleMatches.Tests.cs
src/libraries/System.Text.RegularExpressions/tests/RegexGeneratorHelper.netcoreapp.cs
src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Generators.Tests/RegexGeneratorParserTests.cs