2015-11-05 13:08:39 +00:00
|
|
|
// Copyright 2015 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.
|
|
|
|
|
|
|
|
var r1 = /abc/gi;
|
|
|
|
assertEquals("abc", r1.source);
|
|
|
|
assertTrue(r1.global);
|
|
|
|
assertTrue(r1.ignoreCase);
|
|
|
|
assertFalse(r1.multiline);
|
|
|
|
assertFalse(r1.sticky);
|
|
|
|
assertFalse(r1.unicode);
|
|
|
|
|
|
|
|
// Internal slot of prototype is not read.
|
|
|
|
var r2 = { __proto__: r1 };
|
|
|
|
assertThrows(function() { r2.source; }, TypeError);
|
|
|
|
assertThrows(function() { r2.global; }, TypeError);
|
|
|
|
assertThrows(function() { r2.ignoreCase; }, TypeError);
|
|
|
|
assertThrows(function() { r2.multiline; }, TypeError);
|
|
|
|
assertThrows(function() { r2.sticky; }, TypeError);
|
|
|
|
assertThrows(function() { r2.unicode; }, TypeError);
|
|
|
|
|
|
|
|
var r3 = /I/;
|
|
|
|
var string = "iIiIi";
|
|
|
|
var expected = "iXiIi";
|
|
|
|
assertFalse(r3.global);
|
|
|
|
assertFalse(r3.ignoreCase);
|
|
|
|
assertEquals("", r3.flags);
|
|
|
|
assertEquals(expected, string.replace(r3, "X"));
|
|
|
|
|
|
|
|
var get_count = 0;
|
|
|
|
Object.defineProperty(r3, "global", {
|
|
|
|
get: function() { get_count++; return true; }
|
|
|
|
});
|
|
|
|
Object.defineProperty(r3, "ignoreCase", {
|
|
|
|
get: function() { get_count++; return true; }
|
|
|
|
});
|
|
|
|
|
|
|
|
assertTrue(r3.global);
|
|
|
|
assertEquals(1, get_count);
|
|
|
|
assertTrue(r3.ignoreCase);
|
|
|
|
assertEquals(2, get_count);
|
|
|
|
// Overridden flag getters affects the flags getter.
|
|
|
|
assertEquals("gi", r3.flags);
|
|
|
|
assertEquals(4, get_count);
|
2016-04-05 22:49:10 +00:00
|
|
|
// Overridden flag getters affect string.replace
|
|
|
|
// TODO(adamk): Add more tests here once we've switched
|
|
|
|
// to use [[OriginalFlags]] in more cases.
|
Revert of [regexp] Use consistent map checks for fast paths (patchset #7 id:120001 of https://chromiumcodereview.appspot.com/2434983002/ )
Reason for revert:
https://build.chromium.org/p/client.v8.fyi/builders/V8-Blink%20Linux%2064/builds/10853
Original issue's description:
> [regexp] Use consistent map checks for fast paths
>
> These map checks were implemented for TF code already. This CL makes
> sure that parts implemented in C++ follow the same logic, which is:
>
> An object is an unmodified regexp if:
> 1) it's a receiver,
> 2) its map is the initial regexp map,
> 3) its prototype is a receiver,
> 4) and its prototype's map is the initial prototype's initial map.
>
> We can now be smarter in @@replace and @@split since checking maps
> (unlike the previous check of RegExp.prototype.exec) is not observable,
> so we can perform fast-path checks at a time of our choosing.
>
> BUG=v8:5339,v8:5434,v8:5123
TBR=yangguo@chromium.org,jgruber@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:5339,v8:5434,v8:5123
Review-Url: https://chromiumcodereview.appspot.com/2438283002
Cr-Commit-Position: refs/heads/master@{#40499}
2016-10-21 11:14:59 +00:00
|
|
|
assertEquals(expected, string.replace(r3, "X"));
|
|
|
|
assertEquals(5, get_count);
|
2015-11-05 13:08:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
function testName(name) {
|
2016-04-04 07:05:47 +00:00
|
|
|
// Test for ES2017 RegExp web compatibility semantics
|
|
|
|
// https://github.com/tc39/ecma262/pull/511
|
|
|
|
assertEquals(name === "source" ? "(?:)" : undefined,
|
|
|
|
RegExp.prototype[name]);
|
2015-11-05 13:08:39 +00:00
|
|
|
assertEquals(
|
2015-11-10 06:58:04 +00:00
|
|
|
"get " + name,
|
2015-11-05 13:08:39 +00:00
|
|
|
Object.getOwnPropertyDescriptor(RegExp.prototype, name).get.name);
|
|
|
|
}
|
|
|
|
|
|
|
|
testName("global");
|
|
|
|
testName("ignoreCase");
|
|
|
|
testName("multiline");
|
|
|
|
testName("source");
|
|
|
|
testName("sticky");
|
|
|
|
testName("unicode");
|
2016-03-25 23:01:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
RegExp.prototype.flags = 'setter should be undefined';
|
|
|
|
|
|
|
|
assertEquals('', RegExp('').flags);
|
|
|
|
assertEquals('', /./.flags);
|
|
|
|
assertEquals('gimuy', RegExp('', 'yugmi').flags);
|
|
|
|
assertEquals('gimuy', /foo/yumig.flags);
|
|
|
|
|
|
|
|
var descriptor = Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags');
|
|
|
|
assertTrue(descriptor.configurable);
|
|
|
|
assertFalse(descriptor.enumerable);
|
|
|
|
assertInstanceof(descriptor.get, Function);
|
|
|
|
assertEquals(undefined, descriptor.set);
|
|
|
|
|
|
|
|
function testGenericFlags(object) {
|
|
|
|
return descriptor.get.call(object);
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals('', testGenericFlags({}));
|
|
|
|
assertEquals('i', testGenericFlags({ ignoreCase: true }));
|
|
|
|
assertEquals('uy', testGenericFlags({ global: 0, sticky: 1, unicode: 1 }));
|
|
|
|
assertEquals('m', testGenericFlags({ __proto__: { multiline: true } }));
|
|
|
|
assertThrows(function() { testGenericFlags(); }, TypeError);
|
|
|
|
assertThrows(function() { testGenericFlags(undefined); }, TypeError);
|
|
|
|
assertThrows(function() { testGenericFlags(null); }, TypeError);
|
|
|
|
assertThrows(function() { testGenericFlags(true); }, TypeError);
|
|
|
|
assertThrows(function() { testGenericFlags(false); }, TypeError);
|
|
|
|
assertThrows(function() { testGenericFlags(''); }, TypeError);
|
|
|
|
assertThrows(function() { testGenericFlags(42); }, TypeError);
|
|
|
|
|
|
|
|
var counter = 0;
|
|
|
|
var map = {};
|
|
|
|
var object = {
|
|
|
|
get global() {
|
|
|
|
map.g = counter++;
|
|
|
|
},
|
|
|
|
get ignoreCase() {
|
|
|
|
map.i = counter++;
|
|
|
|
},
|
|
|
|
get multiline() {
|
|
|
|
map.m = counter++;
|
|
|
|
},
|
|
|
|
get unicode() {
|
|
|
|
map.u = counter++;
|
|
|
|
},
|
|
|
|
get sticky() {
|
|
|
|
map.y = counter++;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
testGenericFlags(object);
|
|
|
|
assertEquals({ g: 0, i: 1, m: 2, u: 3, y: 4 }, map);
|