Skip to content

Commit

Permalink
some zloirock#453-related changes
Browse files Browse the repository at this point in the history
  • Loading branch information
zloirock committed Nov 18, 2018
1 parent 8a90bf6 commit 41a8b12
Show file tree
Hide file tree
Showing 10 changed files with 48 additions and 50 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
- Add triggering unhandled `Promise` rejection events (instead of only global handlers), [#205](https://github.com/zloirock/core-js/issues/205).
- Add support of `@@isConcatSpreadable` to `Array#concat`.
- Add support of `@@species` to `Array#{concat, filter, map, slice, splice}`.
- Add direct `.exec` calling to `RegExp#{@@replace, @@split, @@match, @@search}`, [#411](https://github.com/zloirock/core-js/issues/411).
- Add direct `.exec` calling to `RegExp#{@@replace, @@split, @@match, @@search}`. Also, added fixes for `RegExp#exec` method. [#411](https://github.com/zloirock/core-js/issues/411), [#434](https://github.com/zloirock/core-js/issues/434), [#453](https://github.com/zloirock/core-js/issues/453).
- Correct iterators prototypes chain, related [#261](https://github.com/zloirock/core-js/issues/261).
- Correct Typed Arrays prototypes chain, related [#378](https://github.com/zloirock/core-js/issues/378).
- Make the internal state of polyfilled features completely unobservable, [#146](https://github.com/zloirock/core-js/issues/146).
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ class String {

class RegExp {
constructor(pattern: RegExp | string, flags?: string): RegExp; // ES2015+ fix - can alter flags (IE9+)
exec(): Array<string | undefined> | null; // IE8- fixes
toString(): string; // ES2015+ fix - generic
@@match(string: string): Array | null;
@@replace(string: string, replaceValue: Function | string): string;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// empty
1 change: 1 addition & 0 deletions packages/core-js-pure/override/internals/regexp-exec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// empty
1 change: 1 addition & 0 deletions packages/core-js-pure/override/modules/es.regexp.exec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// empty
62 changes: 31 additions & 31 deletions packages/core-js/internals/fix-regexp-well-known-symbol-logic.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,39 @@ var regexpExec = require('../internals/regexp-exec');

var SPECIES = wellKnownSymbol('species');

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';
});

var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = (function () {
// Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
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) {
var SYMBOL = wellKnownSymbol(KEY);

var delegatesToSymbol = !fails(function () {
var DELEGATES_TO_SYMBOL = !fails(function () {
// String methods call symbol-named RegEp methods
var O = {};
O[SYMBOL] = function () { return 7; };
return ''[KEY](O) != 7;
});

var delegatesToExec = delegatesToSymbol ? !fails(function () {
var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL ? !fails(function () {
// Symbol-named RegExp methods call .exec
var execCalled = false;
var re = /a/;
Expand All @@ -35,42 +57,20 @@ module.exports = function (KEY, length, exec, sham) {
return !execCalled;
}) : undefined;

var replaceSupportsNamedGroups = KEY === 'replace' && !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';
});

var splitWorksWithOverwrittenExec = KEY === 'split' && (function () {
// Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
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';
})();

if (
!delegatesToSymbol ||
!delegatesToExec ||
(KEY === 'replace' && !replaceSupportsNamedGroups) ||
(KEY === 'split' && !splitWorksWithOverwrittenExec)
!DELEGATES_TO_SYMBOL ||
!DELEGATES_TO_EXEC ||
(KEY === 'replace' && !REPLACE_SUPPORTS_NAMED_GROUPS) ||
(KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)
) {
var nativeRegExpMethod = /./[SYMBOL];
var methods = exec(
requireObjectCoercible,
SYMBOL,
''[KEY],
function maybeCallNative(nativeMethod, regexp, str, arg2, forceStringMethod) {
if (regexp.exec === regexpExec.impl) {
if (delegatesToSymbol && !forceStringMethod) {
function (nativeMethod, regexp, str, arg2, forceStringMethod) {
if (regexp.exec === regexpExec) {
if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
// The native String method already delegates to @@method (this
// polyfilled function), leasing to infinite recursion.
// We avoid it by directly calling the native @@method method.
Expand Down
2 changes: 1 addition & 1 deletion packages/core-js/internals/regexp-exec-abstract.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ module.exports = function (R, S) {
throw new TypeError('RegExp#exec called on incompatible receiver');
}

return regexpExec.impl.call(R, S);
return regexpExec.call(R, S);
};

22 changes: 8 additions & 14 deletions packages/core-js/internals/regexp-exec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ var nativeReplace = String.prototype.replace;
var patchedExec = nativeExec;

var LAST_INDEX = 'lastIndex';
var LENGTH = 'length';

var UPDATES_LAST_INDEX_WRONG = (function () {
var re1 = /a/,
re2 = /b*/g;
var re1 = /a/;
var re2 = /b*/g;
nativeExec.call(re1, 'a');
nativeExec.call(re2, 'a');
return re1[LAST_INDEX] !== 0 || re2[LAST_INDEX] !== 0;
Expand All @@ -24,9 +23,9 @@ var UPDATES_LAST_INDEX_WRONG = (function () {
// nonparticipating capturing group, copied from es5-shim's String#split patch.
var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;

var patch = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED;
var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED;

if (patch) {
if (PATCH) {
patchedExec = function exec(str) {
var re = this;
var lastIndex, reCopy, match, i;
Expand All @@ -39,14 +38,13 @@ if (patch) {
match = nativeExec.call(re, str);

if (UPDATES_LAST_INDEX_WRONG && match) {
re[LAST_INDEX] = re.global ? match.index + match[0][LENGTH] : lastIndex;
re[LAST_INDEX] = re.global ? match.index + match[0].length : lastIndex;
}
if (NPCG_INCLUDED && match && match[LENGTH] > 1) {
if (NPCG_INCLUDED && match && match.length > 1) {
// Fix browsers whose `exec` methods don't consistently return `undefined`
// for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/
// eslint-disable-next-line no-loop-func
nativeReplace.call(match[0], reCopy, function () {
for (i = 1; i < arguments[LENGTH] - 2; i++) {
for (i = 1; i < arguments.length - 2; i++) {
if (arguments[i] === undefined) match[i] = undefined;
}
});
Expand All @@ -56,8 +54,4 @@ if (patch) {
};
}

module.exports = {
orig: nativeExec,
impl: patchedExec,
patched: patch
};
module.exports = patchedExec;
4 changes: 2 additions & 2 deletions packages/core-js/modules/es.regexp.exec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ var regexpExec = require('../internals/regexp-exec');
require('../internals/export')({
target: 'RegExp',
proto: true,
forced: regexpExec.patched
forced: regexpExec !== /./.exec
}, {
exec: regexpExec.impl
exec: regexpExec
});
2 changes: 1 addition & 1 deletion packages/core-js/modules/es.string.split.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ require('../internals/fix-regexp-well-known-symbol-logic')(
// Make `global` and avoid `lastIndex` issues by working with a copy
var separatorCopy = new RegExp(separator.source, flags + 'g');
var match, lastIndex, lastLength;
while (match = regexpExec.impl.call(separatorCopy, string)) {
while (match = regexpExec.call(separatorCopy, string)) {
lastIndex = separatorCopy.lastIndex;
if (lastIndex > lastLastIndex) {
output.push(string.slice(lastLastIndex, match.index));
Expand Down

0 comments on commit 41a8b12

Please sign in to comment.