Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: test/mjsunit/harmony/regexp-named-captures.js

Issue 2788873002: [regexp] Allow named captures and back-references in non-unicode patterns (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/regexp/regexp-parser.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2017 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Flags: --harmony-regexp-named-captures --harmony-regexp-lookbehind 5 // Flags: --harmony-regexp-named-captures --harmony-regexp-lookbehind
6 6
7 // Malformed named captures. 7 // Malformed named captures.
8 assertThrows("/(?<>a)/u"); // Empty name. 8 assertThrows("/(?<>a)/u", SyntaxError); // Empty name.
9 assertThrows("/(?<aa)/u"); // Unterminated name. 9 assertThrows("/(?<aa)/u", SyntaxError); // Unterminated name.
10 assertThrows("/(?<42a>a)/u"); // Name starting with digits. 10 assertThrows("/(?<42a>a)/u", SyntaxError); // Name starting with digits.
11 assertThrows("/(?<:a>a)/u"); // Name starting with invalid char. 11 assertThrows("/(?<:a>a)/u", SyntaxError); // Name starting with invalid char.
12 assertThrows("/(?<a:>a)/u"); // Name containing with invalid char. 12 assertThrows("/(?<a:>a)/u", SyntaxError); // Name containing with invalid char.
13 assertThrows("/(?<a>a)(?<a>a)/u"); // Duplicate name. 13 assertThrows("/(?<a>a)(?<a>a)/u", SyntaxError); // Duplicate name.
14 assertThrows("/(?<a>a)(?<b>b)(?<a>a)/u"); // Duplicate name. 14 assertThrows("/(?<a>a)(?<b>b)(?<a>a)/u", SyntaxError); // Duplicate name.
15 assertThrows("/\\k<a>/u"); // Invalid reference. 15 assertThrows("/\\k<a>/u", SyntaxError); // Invalid reference.
16 assertThrows("/(?<a>a)\\k<ab>/u"); // Invalid reference. 16 assertThrows("/\\k<a/u", SyntaxError); // Unterminated reference.
17 assertThrows("/(?<ab>a)\\k<a>/u"); // Invalid reference. 17 assertThrows("/\\k/u", SyntaxError); // Lone \k.
18 assertThrows("/\\k<a>(?<ab>a)/u"); // Invalid reference. 18 assertThrows("/(?<a>.)\\k/u", SyntaxError); // Lone \k.
19 assertThrows("/(?<a>.)\\k<a/u", SyntaxError); // Unterminated reference.
20 assertThrows("/(?<a>.)\\k<b>/u", SyntaxError); // Invalid reference.
21 assertThrows("/(?<a>a)\\k<ab>/u", SyntaxError); // Invalid reference.
22 assertThrows("/(?<ab>a)\\k<a>/u", SyntaxError); // Invalid reference.
23 assertThrows("/\\k<a>(?<ab>a)/u", SyntaxError); // Invalid reference.
24 assertThrows("/(?<a>\\a)/u", SyntaxError); // Identity escape in capture.
19 25
20 // Fallback behavior in non-unicode mode. 26 // Behavior in non-unicode mode.
21 assertThrows("/(?<>a)/", SyntaxError); 27 assertThrows("/(?<>a)/", SyntaxError);
22 assertThrows("/(?<aa)/", SyntaxError); 28 assertThrows("/(?<aa)/", SyntaxError);
23 assertThrows("/(?<42a>a)/", SyntaxError); 29 assertThrows("/(?<42a>a)/", SyntaxError);
24 assertThrows("/(?<:a>a)/", SyntaxError); 30 assertThrows("/(?<:a>a)/", SyntaxError);
25 assertThrows("/(?<a:>a)/", SyntaxError); 31 assertThrows("/(?<a:>a)/", SyntaxError);
26 assertThrows("/(?<a>a)(?<a>a)/", SyntaxError); 32 assertThrows("/(?<a>a)(?<a>a)/", SyntaxError);
27 assertThrows("/(?<a>a)(?<b>b)(?<a>a)/", SyntaxError); 33 assertThrows("/(?<a>a)(?<b>b)(?<a>a)/", SyntaxError);
34 assertTrue(/\k<a>/.test("k<a>"));
35 assertTrue(/\k<4>/.test("k<4>"));
36 assertTrue(/\k<a/.test("k<a"));
37 assertTrue(/\k/.test("k"));
38 assertThrows("/(?<a>.)\\k/", SyntaxError);
39 assertThrows("/(?<a>.)\\k<a/", SyntaxError);
40 assertThrows("/(?<a>.)\\k<b>/", SyntaxError);
28 assertThrows("/(?<a>a)\\k<ab>/", SyntaxError); 41 assertThrows("/(?<a>a)\\k<ab>/", SyntaxError);
29 assertThrows("/(?<ab>a)\\k<a>/", SyntaxError); 42 assertThrows("/(?<ab>a)\\k<a>/", SyntaxError);
43 assertThrows("/\\k<a>(?<ab>a)/", SyntaxError);
44 assertThrows("/\\k<a(?<a>a)/", SyntaxError);
45 assertTrue(/(?<a>\a)/.test("a"));
30 46
31 assertEquals(["k<a>"], "xxxk<a>xxx".match(/\k<a>/)); 47 assertEquals(["k<a>"], "xxxk<a>xxx".match(/\k<a>/));
32 assertEquals(["k<a"], "xxxk<a>xxx".match(/\k<a/)); 48 assertEquals(["k<a"], "xxxk<a>xxx".match(/\k<a/));
33 49
50 assertEquals({a: "a", b: "b", c: "c"},
51 /(?<a>.)(?<b>.)(?<c>.)\k<c>\k<b>\k<a>/.exec("abccba").groups);
52
53 // A couple of corner cases around '\k' as named back-references vs. identity
54 // escapes.
55 assertTrue(/\k<a>(?<=>)a/.test("k<a>a"));
56 assertTrue(/\k<a>(?<!a)a/.test("k<a>a"));
57 assertTrue(/\k<a>(<a>x)/.test("k<a><a>x"));
58 assertTrue(/\k<a>(?<a>x)/.test("x"));
59 assertThrows("/\\k<a>(?<b>x)/", SyntaxError);
60 assertThrows("/\\k<a(?<a>.)/", SyntaxError);
61 assertThrows("/\\k(?<a>.)/", SyntaxError);
62
34 // Basic named groups. 63 // Basic named groups.
35 assertEquals(["a", "a"], "bab".match(/(?<a>a)/u)); 64 assertEquals(["a", "a"], "bab".match(/(?<a>a)/u));
36 assertEquals(["a", "a"], "bab".match(/(?<a42>a)/u)); 65 assertEquals(["a", "a"], "bab".match(/(?<a42>a)/u));
37 assertEquals(["a", "a"], "bab".match(/(?<_>a)/u)); 66 assertEquals(["a", "a"], "bab".match(/(?<_>a)/u));
38 assertEquals(["a", "a"], "bab".match(/(?<$>a)/u)); 67 assertEquals(["a", "a"], "bab".match(/(?<$>a)/u));
39 assertEquals(["bab", "a"], "bab".match(/.(?<$>a)./u)); 68 assertEquals(["bab", "a"], "bab".match(/.(?<$>a)./u));
40 assertEquals(["bab", "a", "b"], "bab".match(/.(?<a>a)(.)/u)); 69 assertEquals(["bab", "a", "b"], "bab".match(/.(?<a>a)(.)/u));
41 assertEquals(["bab", "a", "b"], "bab".match(/.(?<a>a)(?<b>.)/u)); 70 assertEquals(["bab", "a", "b"], "bab".match(/.(?<a>a)(?<b>.)/u));
42 assertEquals(["bab", "ab"], "bab".match(/.(?<a>\w\w)/u)); 71 assertEquals(["bab", "ab"], "bab".match(/.(?<a>\w\w)/u));
43 assertEquals(["bab", "bab"], "bab".match(/(?<a>\w\w\w)/u)); 72 assertEquals(["bab", "bab"], "bab".match(/(?<a>\w\w\w)/u));
44 assertEquals(["bab", "ba", "b"], "bab".match(/(?<a>\w\w)(?<b>\w)/u)); 73 assertEquals(["bab", "ba", "b"], "bab".match(/(?<a>\w\w)(?<b>\w)/u));
45 74
75 assertEquals(["a", "a"], "bab".match(/(?<a>a)/));
76 assertEquals(["a", "a"], "bab".match(/(?<a42>a)/));
77 assertEquals(["a", "a"], "bab".match(/(?<_>a)/));
78 assertEquals(["a", "a"], "bab".match(/(?<$>a)/));
79 assertEquals(["bab", "a"], "bab".match(/.(?<$>a)./));
80 assertEquals(["bab", "a", "b"], "bab".match(/.(?<a>a)(.)/));
81 assertEquals(["bab", "a", "b"], "bab".match(/.(?<a>a)(?<b>.)/));
82 assertEquals(["bab", "ab"], "bab".match(/.(?<a>\w\w)/));
83 assertEquals(["bab", "bab"], "bab".match(/(?<a>\w\w\w)/));
84 assertEquals(["bab", "ba", "b"], "bab".match(/(?<a>\w\w)(?<b>\w)/));
85
46 assertEquals("bab".match(/(a)/u), "bab".match(/(?<a>a)/u)); 86 assertEquals("bab".match(/(a)/u), "bab".match(/(?<a>a)/u));
47 assertEquals("bab".match(/(a)/u), "bab".match(/(?<a42>a)/u)); 87 assertEquals("bab".match(/(a)/u), "bab".match(/(?<a42>a)/u));
48 assertEquals("bab".match(/(a)/u), "bab".match(/(?<_>a)/u)); 88 assertEquals("bab".match(/(a)/u), "bab".match(/(?<_>a)/u));
49 assertEquals("bab".match(/(a)/u), "bab".match(/(?<$>a)/u)); 89 assertEquals("bab".match(/(a)/u), "bab".match(/(?<$>a)/u));
50 assertEquals("bab".match(/.(a)./u), "bab".match(/.(?<$>a)./u)); 90 assertEquals("bab".match(/.(a)./u), "bab".match(/.(?<$>a)./u));
51 assertEquals("bab".match(/.(a)(.)/u), "bab".match(/.(?<a>a)(.)/u)); 91 assertEquals("bab".match(/.(a)(.)/u), "bab".match(/.(?<a>a)(.)/u));
52 assertEquals("bab".match(/.(a)(.)/u), "bab".match(/.(?<a>a)(?<b>.)/u)); 92 assertEquals("bab".match(/.(a)(.)/u), "bab".match(/.(?<a>a)(?<b>.)/u));
53 assertEquals("bab".match(/.(\w\w)/u), "bab".match(/.(?<a>\w\w)/u)); 93 assertEquals("bab".match(/.(\w\w)/u), "bab".match(/.(?<a>\w\w)/u));
54 assertEquals("bab".match(/(\w\w\w)/u), "bab".match(/(?<a>\w\w\w)/u)); 94 assertEquals("bab".match(/(\w\w\w)/u), "bab".match(/(?<a>\w\w\w)/u));
55 assertEquals("bab".match(/(\w\w)(\w)/u), "bab".match(/(?<a>\w\w)(?<b>\w)/u)); 95 assertEquals("bab".match(/(\w\w)(\w)/u), "bab".match(/(?<a>\w\w)(?<b>\w)/u));
(...skipping 18 matching lines...) Expand all
74 assertEquals(["bab", "b"], "bab".match(/(?<a>\k<a>\w)../u)); 114 assertEquals(["bab", "b"], "bab".match(/(?<a>\k<a>\w)../u));
75 assertEquals({a: "b"}, "bab".match(/(?<a>\k<a>\w)../u).groups); 115 assertEquals({a: "b"}, "bab".match(/(?<a>\k<a>\w)../u).groups);
76 116
77 // Reference before group. 117 // Reference before group.
78 assertEquals(["bab", "b"], "bab".match(/\k<a>(?<a>b)\w\k<a>/u)); 118 assertEquals(["bab", "b"], "bab".match(/\k<a>(?<a>b)\w\k<a>/u));
79 assertEquals({a: "b"}, "bab".match(/\k<a>(?<a>b)\w\k<a>/u).groups); 119 assertEquals({a: "b"}, "bab".match(/\k<a>(?<a>b)\w\k<a>/u).groups);
80 assertEquals(["bab", "b", "a"], "bab".match(/(?<b>b)\k<a>(?<a>a)\k<b>/u)); 120 assertEquals(["bab", "b", "a"], "bab".match(/(?<b>b)\k<a>(?<a>a)\k<b>/u));
81 assertEquals({a: "a", b: "b"}, 121 assertEquals({a: "a", b: "b"},
82 "bab".match(/(?<b>b)\k<a>(?<a>a)\k<b>/u).groups); 122 "bab".match(/(?<b>b)\k<a>(?<a>a)\k<b>/u).groups);
83 123
124 assertEquals(["bab", "b"], "bab".match(/\k<a>(?<a>b)\w\k<a>/));
125 assertEquals(["bab", "b", "a"], "bab".match(/(?<b>b)\k<a>(?<a>a)\k<b>/));
126
84 // Reference properties. 127 // Reference properties.
85 assertEquals("a", /(?<a>a)(?<b>b)\k<a>/u.exec("aba").groups.a); 128 assertEquals("a", /(?<a>a)(?<b>b)\k<a>/u.exec("aba").groups.a);
86 assertEquals("b", /(?<a>a)(?<b>b)\k<a>/u.exec("aba").groups.b); 129 assertEquals("b", /(?<a>a)(?<b>b)\k<a>/u.exec("aba").groups.b);
87 assertEquals(undefined, /(?<a>a)(?<b>b)\k<a>/u.exec("aba").groups.c); 130 assertEquals(undefined, /(?<a>a)(?<b>b)\k<a>/u.exec("aba").groups.c);
88 assertEquals(undefined, /(?<a>a)(?<b>b)\k<a>|(?<c>c)/u.exec("aba").groups.c); 131 assertEquals(undefined, /(?<a>a)(?<b>b)\k<a>|(?<c>c)/u.exec("aba").groups.c);
89 132
90 // Unicode names. 133 // Unicode names.
91 assertEquals("a", /(?<π>a)/u.exec("bab").groups.π); 134 assertEquals("a", /(?<π>a)/u.exec("bab").groups.π);
135 assertEquals("a", /(?<\u{03C0}>a)/u.exec("bab").groups.π);
136 assertEquals("a", /(?<π>a)/u.exec("bab").groups.\u03C0);
92 assertEquals("a", /(?<\u{03C0}>a)/u.exec("bab").groups.\u03C0); 137 assertEquals("a", /(?<\u{03C0}>a)/u.exec("bab").groups.\u03C0);
93 assertEquals("a", /(?<$>a)/u.exec("bab").groups.$); 138 assertEquals("a", /(?<$>a)/u.exec("bab").groups.$);
94 assertEquals("a", /(?<_>a)/u.exec("bab").groups._); 139 assertEquals("a", /(?<_>a)/u.exec("bab").groups._);
95 assertEquals("a", /(?<$𐒤>a)/u.exec("bab").groups.$𐒤); 140 assertEquals("a", /(?<$𐒤>a)/u.exec("bab").groups.$𐒤);
96 assertEquals("a", /(?<_\u200C>a)/u.exec("bab").groups._\u200C); 141 assertEquals("a", /(?<_\u200C>a)/u.exec("bab").groups._\u200C);
97 assertEquals("a", /(?<_\u200D>a)/u.exec("bab").groups._\u200D); 142 assertEquals("a", /(?<_\u200D>a)/u.exec("bab").groups._\u200D);
98 assertEquals("a", /(?<ಠ_ಠ>a)/u.exec("bab").groups.ಠ_ಠ); 143 assertEquals("a", /(?<ಠ_ಠ>a)/u.exec("bab").groups.ಠ_ಠ);
99 assertThrows('/(?<❤>a)/u', SyntaxError); 144 assertThrows('/(?<❤>a)/u', SyntaxError);
100 assertThrows('/(?<𐒤>a)/u', SyntaxError); // ID_Continue but not ID_Start. 145 assertThrows('/(?<𐒤>a)/u', SyntaxError); // ID_Continue but not ID_Start.
101 146
147 assertEquals("a", /(?<π>a)/.exec("bab").groups.π);
148 assertEquals("a", /(?<$>a)/.exec("bab").groups.$);
149 assertEquals("a", /(?<_>a)/.exec("bab").groups._);
150 assertThrows("/(?<$𐒤>a)/", SyntaxError);
jgruber 2017/03/31 11:53:01 This one may be an issue. The regexp parser doesn'
151 assertEquals("a", /(?<ಠ_ಠ>a)/.exec("bab").groups.ಠ_ಠ);
152 assertThrows('/(?<❤>a)/', SyntaxError);
153 assertThrows('/(?<𐒤>a)/', SyntaxError); // ID_Continue but not ID_Start.
154
102 // Interaction with lookbehind assertions. 155 // Interaction with lookbehind assertions.
103 assertEquals(["f", "c"], "abcdef".match(/(?<=(?<a>\w){3})f/u)); 156 assertEquals(["f", "c"], "abcdef".match(/(?<=(?<a>\w){3})f/u));
104 assertEquals({a: "c"}, "abcdef".match(/(?<=(?<a>\w){3})f/u).groups); 157 assertEquals({a: "c"}, "abcdef".match(/(?<=(?<a>\w){3})f/u).groups);
105 assertEquals({a: "b"}, "abcdef".match(/(?<=(?<a>\w){4})f/u).groups); 158 assertEquals({a: "b"}, "abcdef".match(/(?<=(?<a>\w){4})f/u).groups);
106 assertEquals({a: "a"}, "abcdef".match(/(?<=(?<a>\w)+)f/u).groups); 159 assertEquals({a: "a"}, "abcdef".match(/(?<=(?<a>\w)+)f/u).groups);
107 assertNull("abcdef".match(/(?<=(?<a>\w){6})f/u)); 160 assertNull("abcdef".match(/(?<=(?<a>\w){6})f/u));
108 161
109 assertEquals(["f", ""], "abcdef".match(/((?<=\w{3}))f/u)); 162 assertEquals(["f", ""], "abcdef".match(/((?<=\w{3}))f/u));
110 assertEquals(["f", ""], "abcdef".match(/(?<a>(?<=\w{3}))f/u)); 163 assertEquals(["f", ""], "abcdef".match(/(?<a>(?<=\w{3}))f/u));
111 164
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 // named captures). 362 // named captures).
310 { 363 {
311 let re = toSlowMode(/(?<fst>.)(?<snd>.)/u); 364 let re = toSlowMode(/(?<fst>.)(?<snd>.)/u);
312 assertEquals("bacd", "abcd".replace(re, "$<snd>$<fst>")); 365 assertEquals("bacd", "abcd".replace(re, "$<snd>$<fst>"));
313 assertEquals("bacd", "abcd".replace(re, "$2$1")); 366 assertEquals("bacd", "abcd".replace(re, "$2$1"));
314 assertThrows(() => "abcd".replace(re, "$<snd"), SyntaxError); 367 assertThrows(() => "abcd".replace(re, "$<snd"), SyntaxError);
315 assertEquals("cd", "abcd".replace(re, "$<42$1>")); 368 assertEquals("cd", "abcd".replace(re, "$<42$1>"));
316 assertEquals("cd", "abcd".replace(re, "$<thd>")); 369 assertEquals("cd", "abcd".replace(re, "$<thd>"));
317 assertEquals("cd", "abcd".replace(re, "$<$1>")); 370 assertEquals("cd", "abcd".replace(re, "$<$1>"));
318 } 371 }
OLDNEW
« no previous file with comments | « src/regexp/regexp-parser.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698