StringPrototype.js [plain text]
function match(regexp)
{
"use strict";
if (this == null)
@throwTypeError("String.prototype.match requires that |this| not be null or undefined");
if (regexp != null) {
var matcher = regexp.@matchSymbol;
if (matcher != @undefined)
return matcher.@call(regexp, this);
}
let thisString = @toString(this);
let createdRegExp = @regExpCreate(regexp, @undefined);
return createdRegExp.@matchSymbol(thisString);
}
@globalPrivate
function repeatSlowPath(string, count)
{
"use strict";
if (count === 0 || string.length === 0)
return "";
if (count === 1)
return string;
if (string.length * count > @MAX_STRING_LENGTH)
@throwOutOfMemoryError();
var result = "";
var operand = string;
while (true) {
if (count & 1)
result += operand;
count >>= 1;
if (!count)
return result;
operand += operand;
}
}
@globalPrivate
function repeatCharactersSlowPath(string, count)
{
"use strict";
var repeatCount = (count / string.length) | 0;
var remainingCharacters = count - repeatCount * string.length;
var result = "";
var operand = string;
while (true) {
if (repeatCount & 1)
result += operand;
repeatCount >>= 1;
if (!repeatCount)
break;
operand += operand;
}
if (remainingCharacters)
result += @stringSubstrInternal.@call(string, 0, remainingCharacters);
return result;
}
function repeat(count)
{
"use strict";
if (this == null)
@throwTypeError("String.prototype.repeat requires that |this| not be null or undefined");
var string = @toString(this);
count = @toInteger(count);
if (count < 0 || count === @Infinity)
@throwRangeError("String.prototype.repeat argument must be greater than or equal to 0 and not be Infinity");
if (string.length === 1)
return @repeatCharacter(string, count);
return @repeatSlowPath(string, count);
}
function padStart(maxLength)
{
"use strict";
if (this == null)
@throwTypeError("String.prototype.padStart requires that |this| not be null or undefined");
var string = @toString(this);
maxLength = @toLength(maxLength);
var stringLength = string.length;
if (maxLength <= stringLength)
return string;
var filler;
var fillString = @argument(1);
if (fillString === @undefined)
filler = " ";
else {
filler = @toString(fillString);
if (filler === "")
return string;
}
if (maxLength > @MAX_STRING_LENGTH)
@throwOutOfMemoryError();
var fillLength = maxLength - stringLength;
var truncatedStringFiller;
if (filler.length === 1)
truncatedStringFiller = @repeatCharacter(filler, fillLength);
else
truncatedStringFiller = @repeatCharactersSlowPath(filler, fillLength);
return truncatedStringFiller + string;
}
function padEnd(maxLength)
{
"use strict";
if (this == null)
@throwTypeError("String.prototype.padEnd requires that |this| not be null or undefined");
var string = @toString(this);
maxLength = @toLength(maxLength);
var stringLength = string.length;
if (maxLength <= stringLength)
return string;
var filler;
var fillString = @argument(1);
if (fillString === @undefined)
filler = " ";
else {
filler = @toString(fillString);
if (filler === "")
return string;
}
if (maxLength > @MAX_STRING_LENGTH)
@throwOutOfMemoryError();
var fillLength = maxLength - stringLength;
var truncatedStringFiller;
if (filler.length === 1)
truncatedStringFiller = @repeatCharacter(filler, fillLength);
else
truncatedStringFiller = @repeatCharactersSlowPath(filler, fillLength);
return string + truncatedStringFiller;
}
@globalPrivate
function hasObservableSideEffectsForStringReplace(regexp, replacer) {
if (replacer !== @regExpPrototypeSymbolReplace)
return true;
let regexpExec = @tryGetById(regexp, "exec");
if (regexpExec !== @regExpBuiltinExec)
return true;
let regexpGlobal = @tryGetById(regexp, "global");
if (regexpGlobal !== @regExpProtoGlobalGetter)
return true;
let regexpUnicode = @tryGetById(regexp, "unicode");
if (regexpUnicode !== @regExpProtoUnicodeGetter)
return true;
return !@isRegExpObject(regexp);
}
@intrinsic=StringPrototypeReplaceIntrinsic
function replace(search, replace)
{
"use strict";
if (this == null)
@throwTypeError("String.prototype.replace requires that |this| not be null or undefined");
if (search != null) {
let replacer = search.@replaceSymbol;
if (replacer !== @undefined) {
if (!@hasObservableSideEffectsForStringReplace(search, replacer))
return @toString(this).@replaceUsingRegExp(search, replace);
return replacer.@call(search, this, replace);
}
}
let thisString = @toString(this);
let searchString = @toString(search);
return thisString.@replaceUsingStringSearch(searchString, replace);
}
@globalPrivate
function getDefaultCollator()
{
return @getDefaultCollator.collator || (@getDefaultCollator.collator = new @Collator());
}
function localeCompare(that)
{
"use strict";
if (this == null)
@throwTypeError("String.prototype.localeCompare requires that |this| not be null or undefined");
var thisString = @toString(this);
var thatString = @toString(that);
var locales = @argument(1);
var options = @argument(2);
if (locales === @undefined && options === @undefined)
return @getDefaultCollator().compare(thisString, thatString);
var collator = new @Collator(locales, options);
return collator.compare(thisString, thatString);
}
function search(regexp)
{
"use strict";
if (this == null)
@throwTypeError("String.prototype.search requires that |this| not be null or undefined");
if (regexp != null) {
var searcher = regexp.@searchSymbol;
if (searcher != @undefined)
return searcher.@call(regexp, this);
}
var thisString = @toString(this);
var createdRegExp = @regExpCreate(regexp, @undefined);
return createdRegExp.@searchSymbol(thisString);
}
function split(separator, limit)
{
"use strict";
if (this == null)
@throwTypeError("String.prototype.split requires that |this| not be null or undefined");
if (separator != null) {
var splitter = separator.@splitSymbol;
if (splitter != @undefined)
return splitter.@call(separator, this, limit);
}
return @stringSplitFast.@call(this, separator, limit);
}
@globalPrivate
function stringConcatSlowPath()
{
"use strict";
var result = @toString(this);
for (var i = 0, length = arguments.length; i < length; ++i)
result += @toString(arguments[i]);
return result;
}
function concat(arg )
{
"use strict";
if (this == null)
@throwTypeError("String.prototype.concat requires that |this| not be null or undefined");
if (@argumentCount() === 1)
return @toString(this) + @toString(arg);
return @tailCallForwardArguments(@stringConcatSlowPath, this);
}
@globalPrivate
function createHTML(func, string, tag, attribute, value)
{
"use strict";
if (string == null)
@throwTypeError(`${func} requires that |this| not be null or undefined`);
let S = @toString(string);
let p1 = "<" + tag;
if (attribute) {
let V = @toString(value);
let escapedV = V.@replaceUsingRegExp(/"/g, '"');
p1 = p1 + " " + @toString(attribute) + '="' + escapedV + '"'
}
let p2 = p1 + ">"
let p3 = p2 + S;
let p4 = p3 + "</" + tag + ">";
return p4;
}
function anchor(url)
{
"use strict";
return @createHTML("String.prototype.link", this, "a", "name", url)
}
function big()
{
"use strict";
return @createHTML("String.prototype.big", this, "big", "", "");
}
function blink()
{
"use strict";
return @createHTML("String.prototype.blink", this, "blink", "", "");
}
function bold()
{
"use strict";
return @createHTML("String.prototype.bold", this, "b", "", "");
}
function fixed()
{
"use strict";
return @createHTML("String.prototype.fixed", this, "tt", "", "");
}
function fontcolor(color)
{
"use strict";
return @createHTML("String.prototype.fontcolor", this, "font", "color", color);
}
function fontsize(size)
{
"use strict";
return @createHTML("String.prototype.fontsize", this, "font", "size", size);
}
function italics()
{
"use strict";
return @createHTML("String.prototype.italics", this, "i", "", "");
}
function link(url)
{
"use strict";
return @createHTML("String.prototype.link", this, "a", "href", url)
}
function small()
{
"use strict";
return @createHTML("String.prototype.small", this, "small", "", "");
}
function strike()
{
"use strict";
return @createHTML("String.prototype.strike", this, "strike", "", "");
}
function sub()
{
"use strict";
return @createHTML("String.prototype.sub", this, "sub", "", "");
}
function sup()
{
"use strict";
return @createHTML("String.prototype.sup", this, "sup", "", "");
}