Skip to content

Commit

Permalink
untangle fix-regexp-well-known-symbol-logic by moving feature detec…
Browse files Browse the repository at this point in the history
…tion to related modules
  • Loading branch information
zloirock committed Jun 20, 2021
1 parent 1a510ac commit 3f5640c
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 55 deletions.
52 changes: 2 additions & 50 deletions packages/core-js/internals/fix-regexp-well-known-symbol-logic.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,47 +10,7 @@ var createNonEnumerableProperty = require('../internals/create-non-enumerable-pr
var SPECIES = wellKnownSymbol('species');
var RegExpPrototype = RegExp.prototype;

var REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {
// #replace needs built-in support for named groups.
// #match works fine because it just return the exec results, even if it has
// a "grops" property.
var re = /./;
re.exec = function () {
var result = [];
result.groups = { a: '7' };
return result;
};
return ''.replace(re, '$<a>') !== '7';
});

// IE <= 11 replaces $0 with the whole match, as if it was $&
// https://stackoverflow.com/questions/6024666/getting-ie-to-replace-a-regex-with-the-literal-string-0
var REPLACE_KEEPS_$0 = (function () {
// eslint-disable-next-line regexp/prefer-escape-replacement-dollar-char -- required for testing
return 'a'.replace(/./, '$0') === '$0';
})();

var REPLACE = wellKnownSymbol('replace');
// Safari <= 13.0.3(?) substitutes nth capture where n>m with an empty string
var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = (function () {
if (/./[REPLACE]) {
return /./[REPLACE]('a', '$0') === '';
}
return false;
})();

// Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
// Weex JS has frozen built-in prototypes, so use try / catch wrapper
var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails(function () {
// eslint-disable-next-line regexp/no-empty-group -- required for testing
var re = /(?:)/;
var originalExec = re.exec;
re.exec = function () { return originalExec.apply(this, arguments); };
var result = 'ab'.split(re);
return result.length !== 2 || result[0] !== 'a' || result[1] !== 'b';
});

module.exports = function (KEY, length, exec, sham) {
module.exports = function (KEY, length, exec, FORCED, sham) {
var SYMBOL = wellKnownSymbol(KEY);

var DELEGATES_TO_SYMBOL = !fails(function () {
Expand Down Expand Up @@ -87,12 +47,7 @@ module.exports = function (KEY, length, exec, sham) {
if (
!DELEGATES_TO_SYMBOL ||
!DELEGATES_TO_EXEC ||
(KEY === 'replace' && !(
REPLACE_SUPPORTS_NAMED_GROUPS &&
REPLACE_KEEPS_$0 &&
!REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE
)) ||
(KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)
FORCED
) {
var nativeRegExpMethod = /./[SYMBOL];
var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) {
Expand All @@ -107,9 +62,6 @@ module.exports = function (KEY, length, exec, sham) {
return { done: true, value: nativeMethod.call(str, regexp, arg2) };
}
return { done: false };
}, {
REPLACE_KEEPS_$0: REPLACE_KEEPS_$0,
REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE: REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE
});
var stringMethod = methods[0];
var regexMethod = methods[1];
Expand Down
37 changes: 33 additions & 4 deletions packages/core-js/modules/es.string.replace.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,47 @@ var requireObjectCoercible = require('../internals/require-object-coercible');
var advanceStringIndex = require('../internals/advance-string-index');
var getSubstitution = require('../internals/get-substitution');
var regExpExec = require('../internals/regexp-exec-abstract');
var fails = require('../internals/fails');
var wellKnownSymbol = require('../internals/well-known-symbol');

var REPLACE = wellKnownSymbol('replace');
var max = Math.max;
var min = Math.min;

var maybeToString = function (it) {
return it === undefined ? it : String(it);
};

var REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {
// #replace needs built-in support for named groups.
// #match works fine because it just return the exec results, even if it has
// a "groups" property.
var re = /./;
re.exec = function () {
var result = [];
result.groups = { a: '7' };
return result;
};
return ''.replace(re, '$<a>') !== '7';
});

// IE <= 11 replaces $0 with the whole match, as if it was $&
// https://stackoverflow.com/questions/6024666/getting-ie-to-replace-a-regex-with-the-literal-string-0
var REPLACE_KEEPS_$0 = (function () {
// eslint-disable-next-line regexp/prefer-escape-replacement-dollar-char -- required for testing
return 'a'.replace(/./, '$0') === '$0';
})();

// Safari <= 13.0.3(?) substitutes nth capture where n>m with an empty string
var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = (function () {
if (/./[REPLACE]) {
return /./[REPLACE]('a', '$0') === '';
}
return false;
})();

// @@replace logic
fixRegExpWellKnownSymbolLogic('replace', 2, function (REPLACE, nativeReplace, maybeCallNative, reason) {
var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = reason.REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE;
var REPLACE_KEEPS_$0 = reason.REPLACE_KEEPS_$0;
fixRegExpWellKnownSymbolLogic('replace', 2, function (_, nativeReplace, maybeCallNative) {
var UNSAFE_SUBSTITUTE = REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE ? '$' : '$0';

return [
Expand Down Expand Up @@ -95,4 +124,4 @@ fixRegExpWellKnownSymbolLogic('replace', 2, function (REPLACE, nativeReplace, ma
return accumulatedResult + S.slice(nextSourcePosition);
}
];
});
}, !REPLACE_SUPPORTS_NAMED_GROUPS || !REPLACE_KEEPS_$0 || REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE);
14 changes: 13 additions & 1 deletion packages/core-js/modules/es.string.split.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,24 @@ var toLength = require('../internals/to-length');
var callRegExpExec = require('../internals/regexp-exec-abstract');
var regexpExec = require('../internals/regexp-exec');
var stickyHelpers = require('../internals/regexp-sticky-helpers');
var fails = require('../internals/fails');

var UNSUPPORTED_Y = stickyHelpers.UNSUPPORTED_Y;
var arrayPush = [].push;
var min = Math.min;
var MAX_UINT32 = 0xFFFFFFFF;

// Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
// Weex JS has frozen built-in prototypes, so use try / catch wrapper
var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails(function () {
// eslint-disable-next-line regexp/no-empty-group -- required for testing
var re = /(?:)/;
var originalExec = re.exec;
re.exec = function () { return originalExec.apply(this, arguments); };
var result = 'ab'.split(re);
return result.length !== 2 || result[0] !== 'a' || result[1] !== 'b';
});

// @@split logic
fixRegExpWellKnownSymbolLogic('split', 2, function (SPLIT, nativeSplit, maybeCallNative) {
var internalSplit;
Expand Down Expand Up @@ -131,4 +143,4 @@ fixRegExpWellKnownSymbolLogic('split', 2, function (SPLIT, nativeSplit, maybeCal
return A;
}
];
}, UNSUPPORTED_Y);
}, !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC, UNSUPPORTED_Y);

0 comments on commit 3f5640c

Please sign in to comment.