Allow using non-backtracking code gen for captures in atomic groups (#2327)
authorStephen Toub <stoub@microsoft.com>
Thu, 30 Jan 2020 16:05:39 +0000 (11:05 -0500)
committerGitHub <noreply@github.com>
Thu, 30 Jan 2020 16:05:39 +0000 (11:05 -0500)
I think it was an oversight that I didn't include Atomic in this list previously.  This lets our better non-backtracking code gen be used even when captures are inside of atomic groups.

src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCompiler.cs

index 00e97cb..c8ee603 100644 (file)
@@ -1826,21 +1826,25 @@ namespace System.Text.RegularExpressions
                             supported = node.N == -1;
                             if (supported)
                             {
-                                // And we only support them in certain places in the tree, e.g. we don't support
-                                // them inside of lookaheads.
+                                // And we only support them in certain places in the tree.
                                 RegexNode? parent = node.Next;
                                 while (parent != null)
                                 {
-                                    if (parent.Type != RegexNode.Concatenate &&
-                                        parent.Type != RegexNode.Alternate &&
-                                        parent.Type != RegexNode.Capture &&
-                                        parent.Type != RegexNode.Require) // a positive look* node is already checked to ensure it's lookahead rather than lookbehind
+                                    switch (parent.Type)
                                     {
-                                        supported = false;
-                                        break;
-                                    }
+                                        case RegexNode.Alternate:
+                                        case RegexNode.Atomic:
+                                        case RegexNode.Capture:
+                                        case RegexNode.Concatenate:
+                                        case RegexNode.Require:
+                                            parent = parent.Next;
+                                            break;
 
-                                    parent = parent.Next;
+                                        default:
+                                            parent = null;
+                                            supported = false;
+                                            break;
+                                    }
                                 }
 
                                 if (supported)