Skip to content

Commit

Permalink
removed significant redundant code from String#split polyfill
Browse files Browse the repository at this point in the history
  • Loading branch information
zloirock committed Jan 5, 2024
1 parent 809e11c commit 3c592f0
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 65 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## Changelog
##### Unreleased
- Fixed internal `ToLength` operation with bigints, [#1318](https://github.com/zloirock/core-js/issues/1318)
- Removed significant redundant code from `String#split` polyfill

##### [3.35.0 - 2023.12.29](https://github.com/zloirock/core-js/releases/tag/v3.35.0)
- [`{ Map, Set, WeakMap, WeakSet }.{ from, of }`](https://github.com/tc39/proposal-setmap-offrom) became non-generic, following [this](https://github.com/tc39/proposal-setmap-offrom/issues/16#issuecomment-1843346541) and some other notes. Now they can be invoked without `this`, but no longer return subclass instances
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
// TODO: Remove from `core-js@4` since it's moved to entry points
require('../modules/es.regexp.exec');
var uncurryThis = require('../internals/function-uncurry-this-clause');
var call = require('../internals/function-call');
var defineBuiltIn = require('../internals/define-built-in');
var regexpExec = require('../internals/regexp-exec');
var fails = require('../internals/fails');
Expand Down Expand Up @@ -53,18 +53,17 @@ module.exports = function (KEY, exec, FORCED, SHAM) {
!DELEGATES_TO_EXEC ||
FORCED
) {
var uncurriedNativeRegExpMethod = uncurryThis(/./[SYMBOL]);
var nativeRegExpMethod = /./[SYMBOL];
var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) {
var uncurriedNativeMethod = uncurryThis(nativeMethod);
var $exec = regexp.exec;
if ($exec === regexpExec || $exec === RegExpPrototype.exec) {
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.
return { done: true, value: uncurriedNativeRegExpMethod(regexp, str, arg2) };
return { done: true, value: call(nativeRegExpMethod, regexp, str, arg2) };
}
return { done: true, value: uncurriedNativeMethod(str, regexp, arg2) };
return { done: true, value: call(nativeMethod, str, regexp, arg2) };
}
return { done: false };
});
Expand Down
74 changes: 14 additions & 60 deletions packages/core-js/modules/es.string.split.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
'use strict';
var apply = require('../internals/function-apply');
var call = require('../internals/function-call');
var uncurryThis = require('../internals/function-uncurry-this');
var fixRegExpWellKnownSymbolLogic = require('../internals/fix-regexp-well-known-symbol-logic');
var anObject = require('../internals/an-object');
var isNullOrUndefined = require('../internals/is-null-or-undefined');
var isRegExp = require('../internals/is-regexp');
var requireObjectCoercible = require('../internals/require-object-coercible');
var speciesConstructor = require('../internals/species-constructor');
var advanceStringIndex = require('../internals/advance-string-index');
var toLength = require('../internals/to-length');
var toString = require('../internals/to-string');
var getMethod = require('../internals/get-method');
var arraySlice = require('../internals/array-slice');
var callRegExpExec = require('../internals/regexp-exec-abstract');
var regexpExec = require('../internals/regexp-exec');
var regExpExec = require('../internals/regexp-exec-abstract');
var stickyHelpers = require('../internals/regexp-sticky-helpers');
var fails = require('../internals/fails');

var UNSUPPORTED_Y = stickyHelpers.UNSUPPORTED_Y;
var MAX_UINT32 = 0xFFFFFFFF;
var min = Math.min;
var $push = [].push;
var exec = uncurryThis(/./.exec);
var push = uncurryThis($push);
var push = uncurryThis([].push);
var stringSlice = uncurryThis(''.slice);

// Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
Expand All @@ -39,58 +33,18 @@ var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails(function () {

// @@split logic
fixRegExpWellKnownSymbolLogic('split', function (SPLIT, nativeSplit, maybeCallNative) {
var internalSplit;
if (
'abbc'.split(/(b)*/)[1] === 'c' ||
var BUGGY = 'abbc'.split(/(b)*/)[1] === 'c' ||
// eslint-disable-next-line regexp/no-empty-group -- required for testing
'test'.split(/(?:)/, -1).length !== 4 ||
'ab'.split(/(?:ab)*/).length !== 2 ||
'.'.split(/(.?)(.?)/).length !== 4 ||
// eslint-disable-next-line regexp/no-empty-capturing-group, regexp/no-empty-group -- required for testing
'.'.split(/()()/).length > 1 ||
''.split(/.?/).length
) {
// based on es5-shim implementation, need to rework it
internalSplit = function (separator, limit) {
var string = toString(requireObjectCoercible(this));
var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
if (lim === 0) return [];
if (separator === undefined) return [string];
// If `separator` is not a regex, use native split
if (!isRegExp(separator)) {
return call(nativeSplit, string, separator, lim);
}
var output = [];
var flags = (separator.ignoreCase ? 'i' : '') +
(separator.multiline ? 'm' : '') +
(separator.unicode ? 'u' : '') +
(separator.sticky ? 'y' : '');
var lastLastIndex = 0;
// 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 = call(regexpExec, separatorCopy, string)) {
lastIndex = separatorCopy.lastIndex;
if (lastIndex > lastLastIndex) {
push(output, stringSlice(string, lastLastIndex, match.index));
if (match.length > 1 && match.index < string.length) apply($push, output, arraySlice(match, 1));
lastLength = match[0].length;
lastLastIndex = lastIndex;
if (output.length >= lim) break;
}
if (separatorCopy.lastIndex === match.index) separatorCopy.lastIndex++; // Avoid an infinite loop
}
if (lastLastIndex === string.length) {
if (lastLength || !exec(separatorCopy, '')) push(output, '');
} else push(output, stringSlice(string, lastLastIndex));
return output.length > lim ? arraySlice(output, 0, lim) : output;
};
// Chakra, V8
} else if ('0'.split(undefined, 0).length) {
internalSplit = function (separator, limit) {
return separator === undefined && limit === 0 ? [] : call(nativeSplit, this, separator, limit);
};
} else internalSplit = nativeSplit;
''.split(/.?/).length;

var internalSplit = '0'.split(undefined, 0).length ? function (separator, limit) {
return separator === undefined && limit === 0 ? [] : call(nativeSplit, this, separator, limit);
} : nativeSplit;

return [
// `String.prototype.split` method
Expand All @@ -110,30 +64,30 @@ fixRegExpWellKnownSymbolLogic('split', function (SPLIT, nativeSplit, maybeCallNa
function (string, limit) {
var rx = anObject(this);
var S = toString(string);
var res = maybeCallNative(internalSplit, rx, S, limit, internalSplit !== nativeSplit);

if (res.done) return res.value;
if (!BUGGY) {
var res = maybeCallNative(internalSplit, rx, S, limit, internalSplit !== nativeSplit);
if (res.done) return res.value;
}

var C = speciesConstructor(rx, RegExp);

var unicodeMatching = rx.unicode;
var flags = (rx.ignoreCase ? 'i' : '') +
(rx.multiline ? 'm' : '') +
(rx.unicode ? 'u' : '') +
(UNSUPPORTED_Y ? 'g' : 'y');

// ^(? + rx + ) is needed, in combination with some S slicing, to
// simulate the 'y' flag.
var splitter = new C(UNSUPPORTED_Y ? '^(?:' + rx.source + ')' : rx, flags);
var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
if (lim === 0) return [];
if (S.length === 0) return callRegExpExec(splitter, S) === null ? [S] : [];
if (S.length === 0) return regExpExec(splitter, S) === null ? [S] : [];
var p = 0;
var q = 0;
var A = [];
while (q < S.length) {
splitter.lastIndex = UNSUPPORTED_Y ? 0 : q;
var z = callRegExpExec(splitter, UNSUPPORTED_Y ? stringSlice(S, q) : S);
var z = regExpExec(splitter, UNSUPPORTED_Y ? stringSlice(S, q) : S);
var e;
if (
z === null ||
Expand Down

0 comments on commit 3c592f0

Please sign in to comment.