es.regexp.constructor.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. var DESCRIPTORS = require('../internals/descriptors');
  2. var global = require('../internals/global');
  3. var isForced = require('../internals/is-forced');
  4. var inheritIfRequired = require('../internals/inherit-if-required');
  5. var defineProperty = require('../internals/object-define-property').f;
  6. var getOwnPropertyNames = require('../internals/object-get-own-property-names').f;
  7. var isRegExp = require('../internals/is-regexp');
  8. var getFlags = require('../internals/regexp-flags');
  9. var stickyHelpers = require('../internals/regexp-sticky-helpers');
  10. var redefine = require('../internals/redefine');
  11. var fails = require('../internals/fails');
  12. var setInternalState = require('../internals/internal-state').set;
  13. var setSpecies = require('../internals/set-species');
  14. var wellKnownSymbol = require('../internals/well-known-symbol');
  15. var MATCH = wellKnownSymbol('match');
  16. var NativeRegExp = global.RegExp;
  17. var RegExpPrototype = NativeRegExp.prototype;
  18. var re1 = /a/g;
  19. var re2 = /a/g;
  20. // "new" should create a new object, old webkit bug
  21. var CORRECT_NEW = new NativeRegExp(re1) !== re1;
  22. var UNSUPPORTED_Y = stickyHelpers.UNSUPPORTED_Y;
  23. var FORCED = DESCRIPTORS && isForced('RegExp', (!CORRECT_NEW || UNSUPPORTED_Y || fails(function () {
  24. re2[MATCH] = false;
  25. // RegExp constructor can alter flags and IsRegExp works correct with @@match
  26. return NativeRegExp(re1) != re1 || NativeRegExp(re2) == re2 || NativeRegExp(re1, 'i') != '/a/i';
  27. })));
  28. // `RegExp` constructor
  29. // https://tc39.github.io/ecma262/#sec-regexp-constructor
  30. if (FORCED) {
  31. var RegExpWrapper = function RegExp(pattern, flags) {
  32. var thisIsRegExp = this instanceof RegExpWrapper;
  33. var patternIsRegExp = isRegExp(pattern);
  34. var flagsAreUndefined = flags === undefined;
  35. var sticky;
  36. if (!thisIsRegExp && patternIsRegExp && pattern.constructor === RegExpWrapper && flagsAreUndefined) {
  37. return pattern;
  38. }
  39. if (CORRECT_NEW) {
  40. if (patternIsRegExp && !flagsAreUndefined) pattern = pattern.source;
  41. } else if (pattern instanceof RegExpWrapper) {
  42. if (flagsAreUndefined) flags = getFlags.call(pattern);
  43. pattern = pattern.source;
  44. }
  45. if (UNSUPPORTED_Y) {
  46. sticky = !!flags && flags.indexOf('y') > -1;
  47. if (sticky) flags = flags.replace(/y/g, '');
  48. }
  49. var result = inheritIfRequired(
  50. CORRECT_NEW ? new NativeRegExp(pattern, flags) : NativeRegExp(pattern, flags),
  51. thisIsRegExp ? this : RegExpPrototype,
  52. RegExpWrapper
  53. );
  54. if (UNSUPPORTED_Y && sticky) setInternalState(result, { sticky: sticky });
  55. return result;
  56. };
  57. var proxy = function (key) {
  58. key in RegExpWrapper || defineProperty(RegExpWrapper, key, {
  59. configurable: true,
  60. get: function () { return NativeRegExp[key]; },
  61. set: function (it) { NativeRegExp[key] = it; }
  62. });
  63. };
  64. var keys = getOwnPropertyNames(NativeRegExp);
  65. var index = 0;
  66. while (keys.length > index) proxy(keys[index++]);
  67. RegExpPrototype.constructor = RegExpWrapper;
  68. RegExpWrapper.prototype = RegExpPrototype;
  69. redefine(global, 'RegExp', RegExpWrapper);
  70. }
  71. // https://tc39.github.io/ecma262/#sec-get-regexp-@@species
  72. setSpecies('RegExp');