| Index: src/js/string.js
|
| diff --git a/src/js/string.js b/src/js/string.js
|
| index c0587350cd6d4730183398c094c1db517c3c5e3e..1da5c5f766b979353a5e053518f31f41cf7fe635 100644
|
| --- a/src/js/string.js
|
| +++ b/src/js/string.js
|
| @@ -9,21 +9,9 @@
|
| // -------------------------------------------------------------------
|
| // Imports
|
|
|
| -var ArrayJoin;
|
| -var GlobalRegExp = global.RegExp;
|
| var GlobalString = global.String;
|
| -var MaxSimple;
|
| -var MinSimple;
|
| var matchSymbol = utils.ImportNow("match_symbol");
|
| -var replaceSymbol = utils.ImportNow("replace_symbol");
|
| var searchSymbol = utils.ImportNow("search_symbol");
|
| -var splitSymbol = utils.ImportNow("split_symbol");
|
| -
|
| -utils.Import(function(from) {
|
| - ArrayJoin = from.ArrayJoin;
|
| - MaxSimple = from.MaxSimple;
|
| - MinSimple = from.MinSimple;
|
| -});
|
|
|
| //-------------------------------------------------------------------
|
|
|
| @@ -58,154 +46,6 @@ function StringMatchJS(pattern) {
|
| return regexp[matchSymbol](subject);
|
| }
|
|
|
| -// ES#sec-getsubstitution
|
| -// GetSubstitution(matched, str, position, captures, replacement)
|
| -// Expand the $-expressions in the string and return a new string with
|
| -// the result.
|
| -function GetSubstitution(matched, string, position, captures, replacement) {
|
| - var matchLength = matched.length;
|
| - var stringLength = string.length;
|
| - var capturesLength = captures.length;
|
| - var tailPos = position + matchLength;
|
| - var result = "";
|
| - var pos, expansion, peek, next, scaledIndex, advance, newScaledIndex;
|
| -
|
| - var next = %StringIndexOf(replacement, '$', 0);
|
| - if (next < 0) {
|
| - result += replacement;
|
| - return result;
|
| - }
|
| -
|
| - if (next > 0) result += %_SubString(replacement, 0, next);
|
| -
|
| - while (true) {
|
| - expansion = '$';
|
| - pos = next + 1;
|
| - if (pos < replacement.length) {
|
| - peek = %_StringCharCodeAt(replacement, pos);
|
| - if (peek == 36) { // $$
|
| - ++pos;
|
| - result += '$';
|
| - } else if (peek == 38) { // $& - match
|
| - ++pos;
|
| - result += matched;
|
| - } else if (peek == 96) { // $` - prefix
|
| - ++pos;
|
| - result += %_SubString(string, 0, position);
|
| - } else if (peek == 39) { // $' - suffix
|
| - ++pos;
|
| - result += %_SubString(string, tailPos, stringLength);
|
| - } else if (peek >= 48 && peek <= 57) {
|
| - // Valid indices are $1 .. $9, $01 .. $09 and $10 .. $99
|
| - scaledIndex = (peek - 48);
|
| - advance = 1;
|
| - if (pos + 1 < replacement.length) {
|
| - next = %_StringCharCodeAt(replacement, pos + 1);
|
| - if (next >= 48 && next <= 57) {
|
| - newScaledIndex = scaledIndex * 10 + ((next - 48));
|
| - if (newScaledIndex < capturesLength) {
|
| - scaledIndex = newScaledIndex;
|
| - advance = 2;
|
| - }
|
| - }
|
| - }
|
| - if (scaledIndex != 0 && scaledIndex < capturesLength) {
|
| - var capture = captures.at(scaledIndex);
|
| - if (!IS_UNDEFINED(capture)) result += capture;
|
| - pos += advance;
|
| - } else {
|
| - result += '$';
|
| - }
|
| - } else {
|
| - result += '$';
|
| - }
|
| - } else {
|
| - result += '$';
|
| - }
|
| -
|
| - // Go the the next $ in the replacement.
|
| - next = %StringIndexOf(replacement, '$', pos);
|
| -
|
| - // Return if there are no more $ characters in the replacement. If we
|
| - // haven't reached the end, we need to append the suffix.
|
| - if (next < 0) {
|
| - if (pos < replacement.length) {
|
| - result += %_SubString(replacement, pos, replacement.length);
|
| - }
|
| - return result;
|
| - }
|
| -
|
| - // Append substring between the previous and the next $ character.
|
| - if (next > pos) {
|
| - result += %_SubString(replacement, pos, next);
|
| - }
|
| - }
|
| - return result;
|
| -}
|
| -
|
| -// ES6, section 21.1.3.14
|
| -function StringReplace(search, replace) {
|
| - CHECK_OBJECT_COERCIBLE(this, "String.prototype.replace");
|
| -
|
| - // Decision tree for dispatch
|
| - // .. regexp search (in src/js/regexp.js, RegExpReplace)
|
| - // .... string replace
|
| - // ...... non-global search
|
| - // ........ empty string replace
|
| - // ........ non-empty string replace (with $-expansion)
|
| - // ...... global search
|
| - // ........ no need to circumvent last match info override
|
| - // ........ need to circument last match info override
|
| - // .... function replace
|
| - // ...... global search
|
| - // ...... non-global search
|
| - // .. string search
|
| - // .... special case that replaces with one single character
|
| - // ...... function replace
|
| - // ...... string replace (with $-expansion)
|
| -
|
| - if (!IS_NULL_OR_UNDEFINED(search)) {
|
| - var replacer = search[replaceSymbol];
|
| - if (!IS_UNDEFINED(replacer)) {
|
| - return %_Call(replacer, search, this, replace);
|
| - }
|
| - }
|
| -
|
| - var subject = TO_STRING(this);
|
| -
|
| - search = TO_STRING(search);
|
| -
|
| - if (search.length == 1 &&
|
| - subject.length > 0xFF &&
|
| - IS_STRING(replace) &&
|
| - %StringIndexOf(replace, '$', 0) < 0) {
|
| - // Searching by traversing a cons string tree and replace with cons of
|
| - // slices works only when the replaced string is a single character, being
|
| - // replaced by a simple string and only pays off for long strings.
|
| - return %StringReplaceOneCharWithString(subject, search, replace);
|
| - }
|
| - var start = %StringIndexOf(subject, search, 0);
|
| - if (start < 0) return subject;
|
| - var end = start + search.length;
|
| -
|
| - var result = %_SubString(subject, 0, start);
|
| -
|
| - // Compute the string to replace with.
|
| - if (IS_CALLABLE(replace)) {
|
| - result += replace(search, start, subject);
|
| - } else {
|
| - // In this case, we don't have any capture groups and can get away with
|
| - // faking the captures object by simply setting its length to 1.
|
| - const captures = { length: 1 };
|
| - const matched = %_SubString(subject, start, end);
|
| - result += GetSubstitution(matched, subject, start, captures,
|
| - TO_STRING(replace));
|
| - }
|
| -
|
| - return result + %_SubString(subject, end, subject.length);
|
| -}
|
| -
|
| -
|
| // ES6 21.1.3.15.
|
| function StringSearch(pattern) {
|
| CHECK_OBJECT_COERCIBLE(this, "String.prototype.search");
|
| @@ -266,39 +106,6 @@ function StringSlice(start, end) {
|
| return %_SubString(s, start_i, end_i);
|
| }
|
|
|
| -
|
| -// ES6 21.1.3.17.
|
| -function StringSplitJS(separator, limit) {
|
| - CHECK_OBJECT_COERCIBLE(this, "String.prototype.split");
|
| -
|
| - if (!IS_NULL_OR_UNDEFINED(separator)) {
|
| - var splitter = separator[splitSymbol];
|
| - if (!IS_UNDEFINED(splitter)) {
|
| - return %_Call(splitter, separator, this, limit);
|
| - }
|
| - }
|
| -
|
| - var subject = TO_STRING(this);
|
| - limit = (IS_UNDEFINED(limit)) ? kMaxUint32 : TO_UINT32(limit);
|
| -
|
| - var length = subject.length;
|
| - var separator_string = TO_STRING(separator);
|
| -
|
| - if (limit === 0) return [];
|
| -
|
| - // ECMA-262 says that if separator is undefined, the result should
|
| - // be an array of size 1 containing the entire string.
|
| - if (IS_UNDEFINED(separator)) return [subject];
|
| -
|
| - var separator_length = separator_string.length;
|
| -
|
| - // If the separator string is empty then return the elements in the subject.
|
| - if (separator_length === 0) return %StringToArray(subject, limit);
|
| -
|
| - return %StringSplit(subject, separator_string, limit);
|
| -}
|
| -
|
| -
|
| // ECMA-262, 15.5.4.16
|
| function StringToLowerCaseJS() {
|
| CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLowerCase");
|
| @@ -515,10 +322,8 @@ utils.InstallFunctions(GlobalString.prototype, DONT_ENUM, [
|
| "concat", StringConcat,
|
| "match", StringMatchJS,
|
| "repeat", StringRepeat,
|
| - "replace", StringReplace,
|
| "search", StringSearch,
|
| "slice", StringSlice,
|
| - "split", StringSplitJS,
|
| "toLowerCase", StringToLowerCaseJS,
|
| "toLocaleLowerCase", StringToLocaleLowerCase,
|
| "toUpperCase", StringToUpperCaseJS,
|
| @@ -539,14 +344,4 @@ utils.InstallFunctions(GlobalString.prototype, DONT_ENUM, [
|
| "sup", StringSup
|
| ]);
|
|
|
| -// -------------------------------------------------------------------
|
| -// Exports
|
| -
|
| -utils.Export(function(to) {
|
| - to.StringMatch = StringMatchJS;
|
| - to.StringReplace = StringReplace;
|
| - to.StringSlice = StringSlice;
|
| - to.StringSplit = StringSplitJS;
|
| -});
|
| -
|
| })
|
|
|