1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved.
2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file.
4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar r1 = /abc/gi;
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals("abc", r1.source);
7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertTrue(r1.global);
8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertTrue(r1.ignoreCase);
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertFalse(r1.multiline);
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertFalse(r1.sticky);
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertFalse(r1.unicode);
12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Internal slot of prototype is not read.
14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar r2 = { __proto__: r1 };
15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertThrows(function() { r2.source; }, TypeError);
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertThrows(function() { r2.global; }, TypeError);
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertThrows(function() { r2.ignoreCase; }, TypeError);
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertThrows(function() { r2.multiline; }, TypeError);
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertThrows(function() { r2.sticky; }, TypeError);
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertThrows(function() { r2.unicode; }, TypeError);
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar r3 = /I/;
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar string = "iIiIi";
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar expected = "iXiIi";
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertFalse(r3.global);
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertFalse(r3.ignoreCase);
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals("", r3.flags);
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals(expected, string.replace(r3, "X"));
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar get_count = 0;
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochObject.defineProperty(r3, "global", {
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  get: function() { get_count++; return true; }
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch});
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochObject.defineProperty(r3, "ignoreCase", {
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  get: function() { get_count++; return true; }
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch});
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertTrue(r3.global);
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals(1, get_count);
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertTrue(r3.ignoreCase);
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals(2, get_count);
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Overridden flag getters affects the flags getter.
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals("gi", r3.flags);
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals(4, get_count);
451b268ca467c924004286c97bac133db489cf43d0Ben Murdoch// Overridden flag getters affect string.replace
461b268ca467c924004286c97bac133db489cf43d0Ben Murdoch// TODO(adamk): Add more tests here once we've switched
471b268ca467c924004286c97bac133db489cf43d0Ben Murdoch// to use [[OriginalFlags]] in more cases.
48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals(expected, string.replace(r3, "X"));
491b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertEquals(5, get_count);
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction testName(name) {
531b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  // Test for ES2017 RegExp web compatibility semantics
541b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  // https://github.com/tc39/ecma262/pull/511
551b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  assertEquals(name === "source" ? "(?:)" : undefined,
561b268ca467c924004286c97bac133db489cf43d0Ben Murdoch               RegExp.prototype[name]);
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      "get " + name,
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Object.getOwnPropertyDescriptor(RegExp.prototype, name).get.name);
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochtestName("global");
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochtestName("ignoreCase");
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochtestName("multiline");
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochtestName("source");
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochtestName("sticky");
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochtestName("unicode");
681b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
691b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
701b268ca467c924004286c97bac133db489cf43d0Ben MurdochRegExp.prototype.flags = 'setter should be undefined';
711b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
721b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertEquals('', RegExp('').flags);
731b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertEquals('', /./.flags);
741b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertEquals('gimuy', RegExp('', 'yugmi').flags);
751b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertEquals('gimuy', /foo/yumig.flags);
761b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
771b268ca467c924004286c97bac133db489cf43d0Ben Murdochvar descriptor = Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags');
781b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertTrue(descriptor.configurable);
791b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertFalse(descriptor.enumerable);
801b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertInstanceof(descriptor.get, Function);
811b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertEquals(undefined, descriptor.set);
821b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
831b268ca467c924004286c97bac133db489cf43d0Ben Murdochfunction testGenericFlags(object) {
841b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  return descriptor.get.call(object);
851b268ca467c924004286c97bac133db489cf43d0Ben Murdoch}
861b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
871b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertEquals('', testGenericFlags({}));
881b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertEquals('i', testGenericFlags({ ignoreCase: true }));
891b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertEquals('uy', testGenericFlags({ global: 0, sticky: 1, unicode: 1 }));
901b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertEquals('m', testGenericFlags({ __proto__: { multiline: true } }));
911b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertThrows(function() { testGenericFlags(); }, TypeError);
921b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertThrows(function() { testGenericFlags(undefined); }, TypeError);
931b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertThrows(function() { testGenericFlags(null); }, TypeError);
941b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertThrows(function() { testGenericFlags(true); }, TypeError);
951b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertThrows(function() { testGenericFlags(false); }, TypeError);
961b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertThrows(function() { testGenericFlags(''); }, TypeError);
971b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertThrows(function() { testGenericFlags(42); }, TypeError);
981b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
991b268ca467c924004286c97bac133db489cf43d0Ben Murdochvar counter = 0;
1001b268ca467c924004286c97bac133db489cf43d0Ben Murdochvar map = {};
1011b268ca467c924004286c97bac133db489cf43d0Ben Murdochvar object = {
1021b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  get global() {
1031b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    map.g = counter++;
1041b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  },
1051b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  get ignoreCase() {
1061b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    map.i = counter++;
1071b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  },
1081b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  get multiline() {
1091b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    map.m = counter++;
1101b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  },
1111b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  get unicode() {
1121b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    map.u = counter++;
1131b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  },
1141b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  get sticky() {
1151b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    map.y = counter++;
1161b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  }
1171b268ca467c924004286c97bac133db489cf43d0Ben Murdoch};
1181b268ca467c924004286c97bac133db489cf43d0Ben MurdochtestGenericFlags(object);
1191b268ca467c924004286c97bac133db489cf43d0Ben MurdochassertEquals({ g: 0, i: 1, m: 2, u: 3, y: 4 }, map);
120