LibJS: Use Optional<String> in StringPrototype

This commit is contained in:
Andreas Kling 2021-06-15 13:54:41 +02:00
parent bbf653c425
commit f20c5e1872
Notes: sideshowbarker 2024-07-18 12:13:45 +09:00

View file

@ -22,7 +22,7 @@
namespace JS {
static String ak_string_from(VM& vm, GlobalObject& global_object)
static Optional<String> ak_string_from(VM& vm, GlobalObject& global_object)
{
auto this_value = require_object_coercible(global_object, vm.this_value(global_object));
if (vm.exception())
@ -115,7 +115,7 @@ static Value this_string_value(GlobalObject& global_object, Value value)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::char_at)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
i32 index = 0;
if (vm.argument_count()) {
@ -123,17 +123,17 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::char_at)
if (vm.exception())
return {};
}
if (index < 0 || index >= static_cast<i32>(string.length()))
if (index < 0 || index >= static_cast<i32>(string->length()))
return js_string(vm, String::empty());
// FIXME: This should return a character corresponding to the i'th UTF-16 code point.
return js_string(vm, string.substring(index, 1));
return js_string(vm, string->substring(index, 1));
}
// 22.1.3.2 String.prototype.charCodeAt ( pos ), https://tc39.es/ecma262/#sec-string.prototype.charcodeat
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::char_code_at)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
i32 index = 0;
if (vm.argument_count()) {
@ -141,17 +141,17 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::char_code_at)
if (vm.exception())
return {};
}
if (index < 0 || index >= static_cast<i32>(string.length()))
if (index < 0 || index >= static_cast<i32>(string->length()))
return js_nan();
// FIXME: This should return the i'th UTF-16 code point.
return Value((i32)string[index]);
return Value((i32)(*string)[index]);
}
// 22.1.3.16 String.prototype.repeat ( count ), https://tc39.es/ecma262/#sec-string.prototype.repeat
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::repeat)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
if (!vm.argument_count())
return js_string(vm, String::empty());
@ -168,7 +168,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::repeat)
}
StringBuilder builder;
for (size_t i = 0; i < count; ++i)
builder.append(string);
builder.append(*string);
return js_string(vm, builder.to_string());
}
@ -176,7 +176,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::repeat)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::starts_with)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
auto search_string_value = vm.argument(0);
@ -193,7 +193,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::starts_with)
if (vm.exception())
return {};
auto string_length = string.length();
auto string_length = string->length();
auto search_string_length = search_string.length();
size_t start = 0;
if (!vm.argument(1).is_undefined()) {
@ -206,14 +206,14 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::starts_with)
return Value(false);
if (search_string_length == 0)
return Value(true);
return Value(string.substring(start, search_string_length) == search_string);
return Value(string->substring(start, search_string_length) == search_string);
}
// 22.1.3.6 String.prototype.endsWith ( searchString [ , endPosition ] ), https://tc39.es/ecma262/#sec-string.prototype.endswith
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::ends_with)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
auto search_string_value = vm.argument(0);
@ -230,7 +230,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::ends_with)
if (vm.exception())
return {};
auto string_length = string.length();
auto string_length = string->length();
auto search_string_length = search_string.length();
size_t pos = string_length;
@ -249,37 +249,37 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::ends_with)
return Value(false);
auto start = pos - search_string_length;
return Value(string.substring(start, search_string_length) == search_string);
return Value(string->substring(start, search_string_length) == search_string);
}
// 22.1.3.8 String.prototype.indexOf ( searchString [ , position ] ), https://tc39.es/ecma262/#sec-string.prototype.indexof
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::index_of)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
auto needle = vm.argument(0).to_string(global_object);
if (vm.exception())
return {};
return Value((i32)string.find(needle).value_or(-1));
return Value((i32)string->find(needle).value_or(-1));
}
// 22.1.3.26 String.prototype.toLowerCase ( ), https://tc39.es/ecma262/#sec-string.prototype.tolowercase
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::to_lowercase)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
return js_string(vm, string.to_lowercase());
return js_string(vm, string->to_lowercase());
}
// 22.1.3.28 String.prototype.toUpperCase ( ), https://tc39.es/ecma262/#sec-string.prototype.touppercase
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::to_uppercase)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
return js_string(vm, string.to_uppercase());
return js_string(vm, string->to_uppercase());
}
// 22.1.3.27 String.prototype.toString ( ), https://tc39.es/ecma262/#sec-string.prototype.tostring
@ -335,55 +335,55 @@ static Value pad_string(GlobalObject& global_object, const String& string, PadPl
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::pad_start)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
return pad_string(global_object, string, PadPlacement::Start);
return pad_string(global_object, *string, PadPlacement::Start);
}
// 22.1.3.14 String.prototype.padEnd ( maxLength [ , fillString ] ), https://tc39.es/ecma262/#sec-string.prototype.padend
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::pad_end)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
return pad_string(global_object, string, PadPlacement::End);
return pad_string(global_object, *string, PadPlacement::End);
}
// 22.1.3.29 String.prototype.trim ( ), https://tc39.es/ecma262/#sec-string.prototype.trim
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
return js_string(vm, string.trim_whitespace(TrimMode::Both));
return js_string(vm, string->trim_whitespace(TrimMode::Both));
}
// 22.1.3.31 String.prototype.trimStart ( ), https://tc39.es/ecma262/#sec-string.prototype.trimstart
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim_start)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
return js_string(vm, string.trim_whitespace(TrimMode::Left));
return js_string(vm, string->trim_whitespace(TrimMode::Left));
}
// 22.1.3.30 String.prototype.trimEnd ( ), https://tc39.es/ecma262/#sec-string.prototype.trimend
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim_end)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
return js_string(vm, string.trim_whitespace(TrimMode::Right));
return js_string(vm, string->trim_whitespace(TrimMode::Right));
}
// 22.1.3.23 String.prototype.substring ( start, end ), https://tc39.es/ecma262/#sec-string.prototype.substring
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::concat)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
StringBuilder builder;
builder.append(string);
builder.append(*string);
for (size_t i = 0; i < vm.argument_count(); ++i) {
auto string_argument = vm.argument(i).to_string(global_object);
if (vm.exception())
@ -397,13 +397,13 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::concat)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substring)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
if (vm.argument_count() == 0)
return js_string(vm, string);
return js_string(vm, *string);
// FIXME: index_start and index_end should index a UTF-16 code_point view of the string.
auto string_length = string.length();
auto string_length = string->length();
auto start = vm.argument(0).to_integer_or_infinity(global_object);
if (vm.exception())
return {};
@ -428,7 +428,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substring)
}
auto part_length = index_end - index_start;
auto string_part = string.substring(index_start, part_length);
auto string_part = string->substring(index_start, part_length);
return js_string(vm, string_part);
}
@ -436,13 +436,13 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substring)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substr)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
if (vm.argument_count() == 0)
return js_string(vm, string);
return js_string(vm, *string);
// FIXME: this should index a UTF-16 code_point view of the string.
auto size = (i32)string.length();
auto size = (i32)string->length();
auto int_start = vm.argument(0).to_integer_or_infinity(global_object);
if (vm.exception())
@ -466,7 +466,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substr)
if (int_start >= int_end)
return js_string(vm, String(""));
auto string_part = string.substring(int_start, int_end - int_start);
auto string_part = string->substring(int_start, int_end - int_start);
return js_string(vm, string_part);
}
@ -474,12 +474,12 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substr)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::includes)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
auto search_string = vm.argument(0).to_string(global_object);
if (vm.exception())
return {};
auto string_length = string.length();
auto string_length = string->length();
// FIXME: start should index a UTF-16 code_point view of the string.
size_t start = 0;
if (!vm.argument(1).is_undefined()) {
@ -489,9 +489,9 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::includes)
start = clamp(position, static_cast<double>(0), static_cast<double>(string_length));
}
if (start == 0)
return Value(string.contains(search_string));
return Value(string->contains(search_string));
auto substring_length = string_length - start;
auto substring_search = string.substring(start, substring_length);
auto substring_search = string->substring(start, substring_length);
return Value(substring_search.contains(search_string));
}
@ -499,14 +499,14 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::includes)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::slice)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
if (vm.argument_count() == 0)
return js_string(vm, string);
return js_string(vm, *string);
// FIXME: index_start and index_end should index a UTF-16 code_point view of the string.
auto string_length = static_cast<i32>(string.length());
auto string_length = static_cast<i32>(string->length());
auto index_start = vm.argument(0).to_i32(global_object);
if (vm.exception())
return {};
@ -536,7 +536,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::slice)
return js_string(vm, String::empty());
auto part_length = index_end - index_start;
auto string_part = string.substring(index_start, part_length);
auto string_part = string->substring(index_start, part_length);
return js_string(vm, string_part);
}
@ -546,7 +546,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::split)
// FIXME Implement the @@split part
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
auto* result = Array::create(global_object);
@ -567,15 +567,15 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::split)
return result;
if (vm.argument(0).is_undefined()) {
result->define_property(0, js_string(vm, string));
result->define_property(0, js_string(vm, *string));
return result;
}
auto len = string.length();
auto len = string->length();
auto separator_len = separator.length();
if (len == 0) {
if (separator_len > 0)
result->define_property(0, js_string(vm, string));
result->define_property(0, js_string(vm, *string));
return result;
}
@ -583,18 +583,18 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::split)
auto pos = start;
if (separator_len == 0) {
for (pos = 0; pos < len; pos++)
result->define_property(pos, js_string(vm, string.substring(pos, 1)));
result->define_property(pos, js_string(vm, string->substring(pos, 1)));
return result;
}
while (pos != len) {
auto e = split_match(string, pos, separator);
auto e = split_match(*string, pos, separator);
if (!e.has_value()) {
pos += 1;
continue;
}
auto segment = string.substring_view(start, pos - start);
auto segment = string->substring_view(start, pos - start);
result->define_property(result_len, js_string(vm, segment));
result_len++;
if (result_len == limit)
@ -603,7 +603,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::split)
pos = start;
}
auto rest = string.substring(start, len - start);
auto rest = string->substring(start, len - start);
result->define_property(result_len, js_string(vm, rest));
return result;
@ -613,7 +613,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::split)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::last_index_of)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
auto search_string = vm.argument(0).to_string(global_object);
if (vm.exception())
@ -621,9 +621,9 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::last_index_of)
auto position = vm.argument(1).to_number(global_object);
if (vm.exception())
return {};
if (search_string.length() > string.length())
if (search_string.length() > string->length())
return Value(-1);
auto max_index = string.length() - search_string.length();
auto max_index = string->length() - search_string.length();
auto from_index = max_index;
if (!position.is_nan()) {
// FIXME: from_index should index a UTF-16 code_point view of the string.
@ -634,7 +634,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::last_index_of)
}
for (i32 i = from_index; i >= 0; --i) {
auto part_view = string.substring_view(i, search_string.length());
auto part_view = string->substring_view(i, search_string.length());
if (part_view == search_string)
return Value(i);
}
@ -646,9 +646,9 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::last_index_of)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::at)
{
auto string = ak_string_from(vm, global_object);
if (string.is_null())
if (!string.has_value())
return {};
auto length = string.length();
auto length = string->length();
auto relative_index = vm.argument(0).to_integer_or_infinity(global_object);
if (vm.exception())
return {};
@ -663,7 +663,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::at)
}
if (index.has_overflow() || index.value() >= length)
return js_undefined();
return js_string(vm, String::formatted("{}", string[index.value()]));
return js_string(vm, String::formatted("{}", (*string)[index.value()]));
}
// 22.1.3.33 String.prototype [ @@iterator ] ( ), https://tc39.es/ecma262/#sec-string.prototype-@@iterator