Title: [254195] trunk
Revision
254195
Author
[email protected]
Date
2020-01-08 05:48:20 -0800 (Wed, 08 Jan 2020)

Log Message

RegExp.prototype[Symbol.replace] does not support named capture groups
https://bugs.webkit.org/show_bug.cgi?id=205783

Reviewed by Ross Kirsling.

JSTests:

* test262/expectations.yaml: Mark 6 test cases as passing.

Source/_javascript_Core:

This patch adds named capture groups support to RegExp.prototype[Symbol.replace],
for both functional and string pattern replacement.
(steps 14.j-l of https://tc39.es/ecma262/#sec-regexp.prototype-@@replace)

This method is used in slow path of String.prototype.replace (RegExp subclass handling),
yet it also can be invoked directly in user code.

* builtins/RegExpPrototype.js:
(getSubstitution):
(Symbol.replace):

Modified Paths

Diff

Modified: trunk/JSTests/ChangeLog (254194 => 254195)


--- trunk/JSTests/ChangeLog	2020-01-08 12:45:03 UTC (rev 254194)
+++ trunk/JSTests/ChangeLog	2020-01-08 13:48:20 UTC (rev 254195)
@@ -1,3 +1,12 @@
+2020-01-08  Alexey Shvayka  <[email protected]>
+
+        RegExp.prototype[Symbol.replace] does not support named capture groups
+        https://bugs.webkit.org/show_bug.cgi?id=205783
+
+        Reviewed by Ross Kirsling.
+
+        * test262/expectations.yaml: Mark 6 test cases as passing.
+
 2020-01-07  Saam Barati  <[email protected]>
 
         AI rule for ValueMod/ValueDiv produce constants with the wrong format when the result can be an int32

Modified: trunk/JSTests/test262/expectations.yaml (254194 => 254195)


--- trunk/JSTests/test262/expectations.yaml	2020-01-08 12:45:03 UTC (rev 254194)
+++ trunk/JSTests/test262/expectations.yaml	2020-01-08 13:48:20 UTC (rev 254195)
@@ -1264,12 +1264,6 @@
 test/built-ins/Proxy/construct/trap-is-not-callable-realm.js:
   default: 'Test262Error: Expected a TypeError but got a TypeError'
   strict mode: 'Test262Error: Expected a TypeError but got a TypeError'
-test/built-ins/RegExp/named-groups/groups-object-subclass-sans.js:
-  default: 'Test262Error: Expected SameValue(«b», «$<a>») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«b», «$<a>») to be true'
-test/built-ins/RegExp/named-groups/groups-object-subclass.js:
-  default: 'Test262Error: Expected SameValue(«b», «$<a>») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«b», «$<a>») to be true'
 test/built-ins/RegExp/named-groups/unicode-property-names.js:
   default: 'SyntaxError: Invalid regular _expression_: invalid group specifier name'
   strict mode: 'SyntaxError: Invalid regular _expression_: invalid group specifier name'
@@ -1669,9 +1663,6 @@
 test/built-ins/String/proto-from-ctor-realm.js:
   default: 'Test262Error: Expected SameValue(«», «») to be true'
   strict mode: 'Test262Error: Expected SameValue(«», «») to be true'
-test/built-ins/String/prototype/replaceAll/searchValue-replacer-RegExp-call.js:
-  default: "Test262Error: sample 11: 'abcba'.replaceAll(/(?<named>b)/g, '($<named>)') Expected SameValue(«a($<named>)c($<named>)a», «a(b)c(b)a») to be true"
-  strict mode: "Test262Error: sample 11: 'abcba'.replaceAll(/(?<named>b)/g, '($<named>)') Expected SameValue(«a($<named>)c($<named>)a», «a(b)c(b)a») to be true"
 test/built-ins/ThrowTypeError/extensible.js:
   default: 'Test262Error: Expected SameValue(«true», «false») to be true'
   strict mode: 'Test262Error: Expected SameValue(«true», «false») to be true'

Modified: trunk/Source/_javascript_Core/ChangeLog (254194 => 254195)


--- trunk/Source/_javascript_Core/ChangeLog	2020-01-08 12:45:03 UTC (rev 254194)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-01-08 13:48:20 UTC (rev 254195)
@@ -1,3 +1,21 @@
+2020-01-08  Alexey Shvayka  <[email protected]>
+
+        RegExp.prototype[Symbol.replace] does not support named capture groups
+        https://bugs.webkit.org/show_bug.cgi?id=205783
+
+        Reviewed by Ross Kirsling.
+
+        This patch adds named capture groups support to RegExp.prototype[Symbol.replace],
+        for both functional and string pattern replacement.
+        (steps 14.j-l of https://tc39.es/ecma262/#sec-regexp.prototype-@@replace)
+
+        This method is used in slow path of String.prototype.replace (RegExp subclass handling),
+        yet it also can be invoked directly in user code.
+
+        * builtins/RegExpPrototype.js:
+        (getSubstitution):
+        (Symbol.replace):
+
 2020-01-07  Saam Barati  <[email protected]>
 
         AI rule for ValueMod/ValueDiv produce constants with the wrong format when the result can be an int32

Modified: trunk/Source/_javascript_Core/builtins/RegExpPrototype.js (254194 => 254195)


--- trunk/Source/_javascript_Core/builtins/RegExpPrototype.js	2020-01-08 12:45:03 UTC (rev 254194)
+++ trunk/Source/_javascript_Core/builtins/RegExpPrototype.js	2020-01-08 13:48:20 UTC (rev 254195)
@@ -179,7 +179,7 @@
 {
     "use strict";
 
-    function getSubstitution(matched, str, position, captures, replacement)
+    function getSubstitution(matched, str, position, captures, namedCaptures, replacement)
     {
         "use strict";
 
@@ -219,6 +219,24 @@
                         result = result + str.substring(tailPos);
                     start++;
                     break;
+                case "<":
+                    if (namedCaptures !== @undefined) {
+                        let groupNameStartIndex = start + 1;
+                        let groupNameEndIndex = replacement.indexOf(">", groupNameStartIndex);
+                        if (groupNameEndIndex !== -1) {
+                            let groupName = replacement.substring(groupNameStartIndex, groupNameEndIndex);
+                            let capture = namedCaptures[groupName];
+                            if (capture !== @undefined)
+                                result = result + @toString(capture);
+
+                            start = groupNameEndIndex + 1;
+                            break;
+                        }
+                    }
+
+                    result = result + "$<";
+                    start++;
+                    break;
                 default:
                     let chCode = ch.charCodeAt(0);
                     if (chCode >= 0x30 && chCode <= 0x39) {
@@ -325,6 +343,7 @@
         }
 
         let replacement;
+        let namedCaptures = result.groups;
 
         if (functionalReplace) {
             let replacerArgs = [ matched ].concat(captures);
@@ -331,11 +350,18 @@
             replacerArgs.@push(position);
             replacerArgs.@push(str);
 
+            if (namedCaptures !== @undefined)
+                replacerArgs.@push(namedCaptures);
+
             let replValue = replace.@apply(@undefined, replacerArgs);
             replacement = @toString(replValue);
-        } else
-            replacement = getSubstitution(matched, str, position, captures, replace);
+        } else {
+            if (namedCaptures !== @undefined)
+                namedCaptures = @toObject(namedCaptures, "RegExp.prototype[Symbol.replace] requires 'groups' property of a match not be null");
 
+            replacement = getSubstitution(matched, str, position, captures, namedCaptures, replace);
+        }
+
         if (position >= nextSourcePosition && position >= lastPosition) {
             accumulatedResult = accumulatedResult + str.substring(nextSourcePosition, position) + replacement;
             nextSourcePosition = position + matchLength;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to