fix-regexp-well-known-symbol-logic.js 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. 'use strict';
  2. // TODO: Remove from `core-js@4` since it's moved to entry points
  3. require('../modules/es.regexp.exec');
  4. var call = require('../internals/function-call');
  5. var defineBuiltIn = require('../internals/define-built-in');
  6. var regexpExec = require('../internals/regexp-exec');
  7. var fails = require('../internals/fails');
  8. var wellKnownSymbol = require('../internals/well-known-symbol');
  9. var createNonEnumerableProperty = require('../internals/create-non-enumerable-property');
  10. var SPECIES = wellKnownSymbol('species');
  11. var RegExpPrototype = RegExp.prototype;
  12. module.exports = function (KEY, exec, FORCED, SHAM) {
  13. var SYMBOL = wellKnownSymbol(KEY);
  14. var DELEGATES_TO_SYMBOL = !fails(function () {
  15. // String methods call symbol-named RegExp methods
  16. var O = {};
  17. // eslint-disable-next-line unicorn/no-immediate-mutation -- ES3 syntax limitation
  18. O[SYMBOL] = function () { return 7; };
  19. return ''[KEY](O) !== 7;
  20. });
  21. var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails(function () {
  22. // Symbol-named RegExp methods call .exec
  23. var execCalled = false;
  24. var re = /a/;
  25. if (KEY === 'split') {
  26. // We can't use real regex here since it causes deoptimization
  27. // and serious performance degradation in V8
  28. // https://github.com/zloirock/core-js/issues/306
  29. // RegExp[@@split] doesn't call the regex's exec method, but first creates
  30. // a new one. We need to return the patched regex when creating the new one.
  31. var constructor = {};
  32. // eslint-disable-next-line unicorn/no-immediate-mutation -- ES3 syntax limitation
  33. constructor[SPECIES] = function () { return re; };
  34. re = { constructor: constructor, flags: '' };
  35. // eslint-disable-next-line unicorn/no-immediate-mutation -- ES3 syntax limitation
  36. re[SYMBOL] = /./[SYMBOL];
  37. }
  38. re.exec = function () {
  39. execCalled = true;
  40. return null;
  41. };
  42. re[SYMBOL]('');
  43. return !execCalled;
  44. });
  45. if (
  46. !DELEGATES_TO_SYMBOL ||
  47. !DELEGATES_TO_EXEC ||
  48. FORCED
  49. ) {
  50. var nativeRegExpMethod = /./[SYMBOL];
  51. var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) {
  52. var $exec = regexp.exec;
  53. if ($exec === regexpExec || $exec === RegExpPrototype.exec) {
  54. if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
  55. // The native String method already delegates to @@method (this
  56. // polyfilled function), leasing to infinite recursion.
  57. // We avoid it by directly calling the native @@method method.
  58. return { done: true, value: call(nativeRegExpMethod, regexp, str, arg2) };
  59. }
  60. return { done: true, value: call(nativeMethod, str, regexp, arg2) };
  61. }
  62. return { done: false };
  63. });
  64. defineBuiltIn(String.prototype, KEY, methods[0]);
  65. defineBuiltIn(RegExpPrototype, SYMBOL, methods[1]);
  66. }
  67. if (SHAM) createNonEnumerableProperty(RegExpPrototype[SYMBOL], 'sham', true);
  68. };