OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |