v8/test/mjsunit/harmony/regexp-match-indices.js
Joshua Litt 8c79beadbf Reland "[regexp] Implement the match indices proposal"
Implements match indices for regexp, as specified by
https://github.com/tc39/proposal-regexp-match-indices,
a stage 3 TC39 proposal. This implementation is hidden
behind the '--harmony-regexp-match-indices' flag.

Regexp match indices extends the JSRegExpResult object
with an array of indices of matches, as well as a
dictionary of capture names to match indices.

Bug: v8:9548
Change-Id: Ia9efcee00d997dda6158539b8d0f4c4e5965e5e7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1771379
Commit-Queue: Joshua Litt <joshualitt@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63581}
2019-09-05 15:13:39 +00:00

106 lines
2.1 KiB
JavaScript

// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Flags: --harmony-regexp-match-indices
// Sanity test.
{
const re = /a+(?<Z>z)?/;
const m = re.exec("xaaaz");
assertEquals(m.indices, [[1, 5], [4, 5]]);
assertEquals(m.indices.groups, {'Z': [4, 5]})
}
// Capture groups that are not matched return `undefined`.
{
const re = /a+(?<Z>z)?/;
const m = re.exec("xaaay");
assertEquals(m.indices, [[1, 4], undefined]);
assertEquals(m.indices.groups, {'Z': undefined});
}
// Two capture groups.
{
const re = /a+(?<A>zz)?(?<B>ii)?/;
const m = re.exec("xaaazzii");
assertEquals(m.indices, [[1, 8], [4, 6], [6, 8]]);
assertEquals(m.indices.groups, {'A': [4, 6], 'B': [6, 8]});
}
// No capture groups.
{
const re = /a+/;
const m = re.exec("xaaazzii");
assertEquals(m.indices [[1, 4]]);
assertEquals(m.indices.groups, undefined);
}
// No match.
{
const re = /a+/;
const m = re.exec("xzzii");
assertEquals(null, m);
}
// Unnamed capture groups.
{
const re = /a+(z)?/;
const m = re.exec("xaaaz")
assertEquals(m.indices, [[1, 5], [4, 5]]);
assertEquals(m.indices.groups, undefined)
}
// Named and unnamed capture groups.
{
const re = /a+(z)?(?<Y>y)?/;
const m = re.exec("xaaazyy")
assertEquals(m.indices, [[1, 6], [4, 5], [5, 6]]);
assertEquals(m.indices.groups, {'Y': [5, 6]})
}
// Verify property overwrite.
{
const re = /a+(?<Z>z)?/;
const m = re.exec("xaaaz");
m.indices = null;
assertEquals(null, m.indices);
}
// Mess with array prototype, we should still do the right thing.
{
Object.defineProperty(Array.prototype, "groups", {
get: () => {
assertUnreachable();
return null;
},
set: (x) => {
assertUnreachable();
}
});
Object.defineProperty(Array.prototype, "0", {
get: () => {
assertUnreachable();
return null;
},
set: (x) => {
assertUnreachable();
}
});
const re = /a+(?<Z>z)?/;
const m = re.exec("xaaaz");
assertEquals(m.indices.groups, {'Z': [4, 5]})
}