LibJS: Make PrimitiveString::deprecated_string() infallible

Work towards #20449.
This commit is contained in:
Andreas Kling 2023-08-08 19:30:07 +02:00
parent c084269e5f
commit 09547ec975
Notes: sideshowbarker 2024-07-16 20:08:14 +09:00
17 changed files with 42 additions and 43 deletions

View File

@ -68,14 +68,14 @@ TESTJS_GLOBAL_FUNCTION(mark_as_garbage, markAsGarbage)
return execution_context->lexical_environment != nullptr;
});
if (!outer_environment.has_value())
return vm.throw_completion<JS::ReferenceError>(JS::ErrorType::UnknownIdentifier, TRY(variable_name.deprecated_string()));
return vm.throw_completion<JS::ReferenceError>(JS::ErrorType::UnknownIdentifier, variable_name.deprecated_string());
auto reference = TRY(vm.resolve_binding(TRY(variable_name.deprecated_string()), outer_environment.value()->lexical_environment));
auto reference = TRY(vm.resolve_binding(variable_name.deprecated_string(), outer_environment.value()->lexical_environment));
auto value = TRY(reference.get_value(vm));
if (!can_be_held_weakly(value))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::CannotBeHeldWeakly, DeprecatedString::formatted("Variable with name {}", TRY(variable_name.deprecated_string())));
return vm.throw_completion<JS::TypeError>(JS::ErrorType::CannotBeHeldWeakly, DeprecatedString::formatted("Variable with name {}", variable_name.deprecated_string()));
vm.heap().uproot_cell(&value.as_cell());
TRY(reference.delete_(vm));

View File

@ -196,7 +196,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_real_cell_contents)
auto name_value = vm.argument(0);
if (!name_value.is_string())
return vm.throw_completion<JS::TypeError>("Expected a String argument to get_real_cell_contents()"sv);
auto position = sheet_object.m_sheet.parse_cell_name(TRY(name_value.as_string().deprecated_string()));
auto position = sheet_object.m_sheet.parse_cell_name(name_value.as_string().deprecated_string());
if (!position.has_value())
return vm.throw_completion<JS::TypeError>("Invalid cell name"sv);
@ -225,7 +225,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::set_real_cell_contents)
auto name_value = vm.argument(0);
if (!name_value.is_string())
return vm.throw_completion<JS::TypeError>("Expected the first argument of set_real_cell_contents() to be a String"sv);
auto position = sheet_object.m_sheet.parse_cell_name(TRY(name_value.as_string().deprecated_string()));
auto position = sheet_object.m_sheet.parse_cell_name(name_value.as_string().deprecated_string());
if (!position.has_value())
return vm.throw_completion<JS::TypeError>("Invalid cell name"sv);
@ -234,7 +234,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::set_real_cell_contents)
return vm.throw_completion<JS::TypeError>("Expected the second argument of set_real_cell_contents() to be a String"sv);
auto& cell = sheet_object.m_sheet.ensure(position.value());
auto new_contents = TRY(new_contents_value.as_string().deprecated_string());
auto new_contents = new_contents_value.as_string().deprecated_string();
cell.set_data(new_contents);
return JS::js_null();
}
@ -255,7 +255,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::parse_cell_name)
auto name_value = vm.argument(0);
if (!name_value.is_string())
return vm.throw_completion<JS::TypeError>("Expected a String argument to parse_cell_name()"sv);
auto position = sheet_object.m_sheet.parse_cell_name(TRY(name_value.as_string().deprecated_string()));
auto position = sheet_object.m_sheet.parse_cell_name(name_value.as_string().deprecated_string());
if (!position.has_value())
return JS::js_undefined();
@ -301,7 +301,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_index)
if (!column_name.is_string())
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "String");
auto column_name_str = TRY(column_name.as_string().deprecated_string());
auto column_name_str = column_name.as_string().deprecated_string();
auto this_object = TRY(vm.this_value().to_object(vm));
@ -326,7 +326,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_arithmetic)
if (!column_name.is_string())
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "String");
auto column_name_str = TRY(column_name.as_string().deprecated_string());
auto column_name_str = column_name.as_string().deprecated_string();
auto offset = TRY(vm.argument(1).to_number(vm));
auto offset_number = static_cast<i32>(offset.as_double());
@ -354,7 +354,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_column_bound)
if (!column_name.is_string())
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "String");
auto column_name_str = TRY(column_name.as_string().deprecated_string());
auto column_name_str = column_name.as_string().deprecated_string();
auto this_object = TRY(vm.this_value().to_object(vm));
if (!is<SheetGlobalObject>(*this_object))
@ -406,7 +406,7 @@ JS_DEFINE_NATIVE_FUNCTION(WorkbookObject::sheet)
auto& workbook = workbook_object.m_workbook;
if (name_value.is_string()) {
auto name = TRY(name_value.as_string().deprecated_string());
auto name = name_value.as_string().deprecated_string();
for (auto& sheet : workbook.sheets()) {
if (sheet->name() == name)
return JS::Value(&sheet->global_object());

View File

@ -20,7 +20,7 @@ ThrowCompletionOr<Value> IsHTMLDDA::call()
auto& vm = this->vm();
if (vm.argument_count() == 0)
return js_null();
if (vm.argument(0).is_string() && TRY(vm.argument(0).as_string().deprecated_string()).is_empty())
if (vm.argument(0).is_string() && vm.argument(0).as_string().is_empty())
return js_null();
// Not sure if this really matters, INTERPRETING.md simply says:
// * IsHTMLDDA - (present only in implementations that can provide it) an object that:

View File

@ -595,7 +595,7 @@ ThrowCompletionOr<Value> perform_eval(VM& vm, Value x, CallerMode strict_caller,
.in_class_field_initializer = in_class_field_initializer,
};
Parser parser { Lexer { TRY(code_string.deprecated_string()) }, Program::Type::Script, move(initial_state) };
Parser parser { Lexer { code_string.deprecated_string() }, Program::Type::Script, move(initial_state) };
auto program = parser.parse_program(strict_caller == CallerMode::Strict);
// b. If script is a List of errors, throw a SyntaxError exception.
@ -1545,7 +1545,7 @@ ThrowCompletionOr<Value> perform_import_call(VM& vm, Value specifier, Value opti
// 4. If supportedAssertions contains key, then
if (supported_assertions.contains_slow(property_key.to_string())) {
// a. Append { [[Key]]: key, [[Value]]: value } to assertions.
assertions.empend(property_key.to_string(), TRY(value.as_string().deprecated_string()));
assertions.empend(property_key.to_string(), value.as_string().deprecated_string());
}
}
}

View File

@ -246,7 +246,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> DateConstructor::construct(FunctionObjec
if (primitive.is_string()) {
// 1. Assert: The next step never returns an abrupt completion because Type(v) is String.
// 2. Let tv be the result of parsing v as a date, in exactly the same manner as for the parse method (21.4.3.2).
time_value = parse_date_string(TRY(primitive.as_string().deprecated_string()));
time_value = parse_date_string(primitive.as_string().deprecated_string());
}
// iii. Else,
else {

View File

@ -1247,7 +1247,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::symbol_to_primitive)
auto hint_value = vm.argument(0);
if (!hint_value.is_string())
return vm.throw_completion<TypeError>(ErrorType::InvalidHint, TRY_OR_THROW_OOM(vm, hint_value.to_string_without_side_effects()));
auto hint = TRY(hint_value.as_string().deprecated_string());
auto hint = hint_value.as_string().deprecated_string();
Value::PreferredType try_first;
if (hint == "string" || hint == "default")
try_first = Value::PreferredType::String;

View File

@ -63,7 +63,7 @@ ThrowCompletionOr<DeprecatedString> JSONObject::stringify_impl(VM& vm, Value val
auto replacer_value = TRY(replacer_object.get(i));
DeprecatedString item;
if (replacer_value.is_string()) {
item = TRY(replacer_value.as_string().deprecated_string());
item = replacer_value.as_string().deprecated_string();
} else if (replacer_value.is_number()) {
item = MUST(replacer_value.to_deprecated_string(vm));
} else if (replacer_value.is_object()) {
@ -93,7 +93,7 @@ ThrowCompletionOr<DeprecatedString> JSONObject::stringify_impl(VM& vm, Value val
space_mv = min(10, space_mv);
state.gap = space_mv < 1 ? DeprecatedString::empty() : DeprecatedString::repeated(' ', space_mv);
} else if (space.is_string()) {
auto string = TRY(space.as_string().deprecated_string());
auto string = space.as_string().deprecated_string();
if (string.length() <= 10)
state.gap = string;
else
@ -185,7 +185,7 @@ ThrowCompletionOr<DeprecatedString> JSONObject::serialize_json_property(VM& vm,
// 8. If Type(value) is String, return QuoteJSONString(value).
if (value.is_string())
return quote_json_string(TRY(value.as_string().deprecated_string()));
return quote_json_string(value.as_string().deprecated_string());
// 9. If Type(value) is Number, then
if (value.is_number()) {
@ -250,7 +250,7 @@ ThrowCompletionOr<DeprecatedString> JSONObject::serialize_json_object(VM& vm, St
} else {
auto property_list = TRY(object.enumerable_own_property_names(PropertyKind::Key));
for (auto& property : property_list)
TRY(process_property(TRY(property.as_string().deprecated_string())));
TRY(process_property(property.as_string().deprecated_string()));
}
StringBuilder builder;
if (property_strings.is_empty()) {
@ -487,7 +487,7 @@ ThrowCompletionOr<Value> JSONObject::internalize_json_property(VM& vm, Object* h
} else {
auto property_list = TRY(value_object.enumerable_own_property_names(Object::PropertyKind::Key));
for (auto& property_key : property_list)
TRY(process_property(TRY(property_key.as_string().deprecated_string())));
TRY(process_property(property_key.as_string().deprecated_string()));
}
}

View File

@ -1335,7 +1335,7 @@ Optional<Completion> Object::enumerate_object_properties(Function<Optional<Compl
for (auto& key : own_keys) {
if (!key.is_string())
continue;
DeprecatedFlyString property_key = TRY(key.as_string().deprecated_string());
DeprecatedFlyString property_key = key.as_string().deprecated_string();
if (visited.contains(property_key))
continue;
auto descriptor = TRY(target->internal_get_own_property(property_key));

View File

@ -188,7 +188,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::to_string)
if (!to_string_tag.is_string())
tag = move(builtin_tag);
else
tag = TRY(to_string_tag.as_string().deprecated_string());
tag = to_string_tag.as_string().deprecated_string();
// 17. Return the string-concatenation of "[object ", tag, and "]".
return PrimitiveString::create(vm, DeprecatedString::formatted("[object {}]", tag));

View File

@ -96,7 +96,7 @@ StringView PrimitiveString::utf8_string_view() const
return m_utf8_string->bytes_as_string_view();
}
ThrowCompletionOr<DeprecatedString> PrimitiveString::deprecated_string() const
DeprecatedString PrimitiveString::deprecated_string() const
{
resolve_rope_if_needed(EncodingPreference::UTF8);

View File

@ -42,7 +42,7 @@ public:
[[nodiscard]] StringView utf8_string_view() const;
bool has_utf8_string() const { return m_utf8_string.has_value(); }
ThrowCompletionOr<DeprecatedString> deprecated_string() const;
[[nodiscard]] DeprecatedString deprecated_string() const;
bool has_deprecated_string() const { return m_deprecated_string.has_value(); }
[[nodiscard]] Utf16String utf16_string() const;

View File

@ -87,7 +87,7 @@ ThrowCompletionOr<void> copy_name_and_length(VM& vm, FunctionObject& function, F
target_name = PrimitiveString::create(vm, String {});
// 8. Perform SetFunctionName(F, targetName, prefix).
function.set_function_name({ TRY(target_name.as_string().deprecated_string()) }, move(prefix));
function.set_function_name({ target_name.as_string().deprecated_string() }, move(prefix));
return {};
}

View File

@ -49,7 +49,7 @@ JS_DEFINE_NATIVE_FUNCTION(ShadowRealmPrototype::evaluate)
auto& eval_realm = object->shadow_realm();
// 6. Return ? PerformShadowRealmEval(sourceText, callerRealm, evalRealm).
return perform_shadow_realm_eval(vm, TRY(source_text.as_string().deprecated_string()), *caller_realm, eval_realm);
return perform_shadow_realm_eval(vm, source_text.as_string().deprecated_string(), *caller_realm, eval_realm);
}
// 3.4.2 ShadowRealm.prototype.importValue ( specifier, exportName ), https://tc39.es/proposal-shadowrealm/#sec-shadowrealm.prototype.importvalue
@ -79,7 +79,7 @@ JS_DEFINE_NATIVE_FUNCTION(ShadowRealmPrototype::import_value)
auto& eval_context = object->execution_context();
// 8. Return ? ShadowRealmImportValue(specifierString, exportNameString, callerRealm, evalRealm, evalContext).
return shadow_realm_import_value(vm, move(specifier_string), TRY(export_name.as_string().deprecated_string()), *caller_realm, eval_realm, eval_context);
return shadow_realm_import_value(vm, move(specifier_string), export_name.as_string().deprecated_string(), *caller_realm, eval_realm, eval_context);
}
}

View File

@ -784,7 +784,7 @@ ThrowCompletionOr<double> resolve_iso_month(VM& vm, Object const& fields)
// 6. Assert: Type(monthCode) is String.
VERIFY(month_code.is_string());
auto month_code_string = TRY(month_code.as_string().deprecated_string());
auto month_code_string = month_code.as_string().deprecated_string();
// 7. If the length of monthCode is not 3, throw a RangeError exception.
auto month_length = month_code_string.length();
@ -960,7 +960,7 @@ ThrowCompletionOr<Object*> default_merge_calendar_fields(VM& vm, Object const& f
// 3. For each element key of fieldsKeys, do
for (auto& key : fields_keys) {
// a. If key is not "month" or "monthCode", then
if (!TRY(key.as_string().deprecated_string()).is_one_of(vm.names.month.as_string(), vm.names.monthCode.as_string())) {
if (!key.as_string().deprecated_string().is_one_of(vm.names.month.as_string(), vm.names.monthCode.as_string())) {
auto property_key = MUST(PropertyKey::from_value(vm, key));
// i. Let propValue be ? Get(fields, key).
@ -994,7 +994,7 @@ ThrowCompletionOr<Object*> default_merge_calendar_fields(VM& vm, Object const& f
}
// See comment above.
additional_fields_keys_contains_month_or_month_code_property |= TRY(key.as_string().deprecated_string()) == vm.names.month.as_string() || TRY(key.as_string().deprecated_string()) == vm.names.monthCode.as_string();
additional_fields_keys_contains_month_or_month_code_property |= key.as_string().deprecated_string() == vm.names.month.as_string() || key.as_string().deprecated_string() == vm.names.monthCode.as_string();
}
// 6. If additionalFieldsKeys does not contain either "month" or "monthCode", then

View File

@ -711,7 +711,7 @@ ThrowCompletionOr<Value> Value::to_number(VM& vm) const
return Value(as_bool() ? 1 : 0);
// 6. If argument is a String, return StringToNumber(argument).
case STRING_TAG:
return string_to_number(TRY(as_string().deprecated_string()));
return string_to_number(as_string().deprecated_string());
// 7. Assert: argument is an Object.
case OBJECT_TAG: {
// 8. Let primValue be ? ToPrimitive(argument, number).
@ -765,7 +765,7 @@ ThrowCompletionOr<NonnullGCPtr<BigInt>> Value::to_bigint(VM& vm) const
return primitive.as_bigint();
case STRING_TAG: {
// 1. Let n be ! StringToBigInt(prim).
auto bigint = string_to_bigint(vm, TRY(primitive.as_string().deprecated_string()));
auto bigint = string_to_bigint(vm, primitive.as_string().deprecated_string());
// 2. If n is undefined, throw a SyntaxError exception.
if (!bigint.has_value())
@ -2205,8 +2205,7 @@ bool same_value_non_number(Value lhs, Value rhs)
// 5. If x is a String, then
if (lhs.is_string()) {
// a. If x and y are exactly the same sequence of code units (same length and same code units at corresponding indices), return true; otherwise, return false.
// FIXME: Propagate this error.
return MUST(lhs.as_string().deprecated_string()) == MUST(rhs.as_string().deprecated_string());
return lhs.as_string().deprecated_string() == rhs.as_string().deprecated_string();
}
// 3. If x is undefined, return true.
@ -2287,7 +2286,7 @@ ThrowCompletionOr<bool> is_loosely_equal(VM& vm, Value lhs, Value rhs)
// 7. If Type(x) is BigInt and Type(y) is String, then
if (lhs.is_bigint() && rhs.is_string()) {
// a. Let n be StringToBigInt(y).
auto bigint = string_to_bigint(vm, TRY(rhs.as_string().deprecated_string()));
auto bigint = string_to_bigint(vm, rhs.as_string().deprecated_string());
// b. If n is undefined, return false.
if (!bigint.has_value())
@ -2368,8 +2367,8 @@ ThrowCompletionOr<TriState> is_less_than(VM& vm, Value lhs, Value rhs, bool left
// 3. If px is a String and py is a String, then
if (x_primitive.is_string() && y_primitive.is_string()) {
auto x_string = TRY(x_primitive.as_string().deprecated_string());
auto y_string = TRY(y_primitive.as_string().deprecated_string());
auto x_string = x_primitive.as_string().deprecated_string();
auto y_string = y_primitive.as_string().deprecated_string();
Utf8View x_code_points { x_string };
Utf8View y_code_points { y_string };
@ -2404,7 +2403,7 @@ ThrowCompletionOr<TriState> is_less_than(VM& vm, Value lhs, Value rhs, bool left
// a. If px is a BigInt and py is a String, then
if (x_primitive.is_bigint() && y_primitive.is_string()) {
// i. Let ny be StringToBigInt(py).
auto y_bigint = string_to_bigint(vm, TRY(y_primitive.as_string().deprecated_string()));
auto y_bigint = string_to_bigint(vm, y_primitive.as_string().deprecated_string());
// ii. If ny is undefined, return undefined.
if (!y_bigint.has_value())
@ -2419,7 +2418,7 @@ ThrowCompletionOr<TriState> is_less_than(VM& vm, Value lhs, Value rhs, bool left
// b. If px is a String and py is a BigInt, then
if (x_primitive.is_string() && y_primitive.is_bigint()) {
// i. Let nx be StringToBigInt(px).
auto x_bigint = string_to_bigint(vm, TRY(x_primitive.as_string().deprecated_string()));
auto x_bigint = string_to_bigint(vm, x_primitive.as_string().deprecated_string());
// ii. If nx is undefined, return undefined.
if (!x_bigint.has_value())

View File

@ -19,7 +19,7 @@ struct ValueTraits : public Traits<Value> {
VERIFY(!value.is_empty());
if (value.is_string()) {
// FIXME: Propagate this error.
return value.as_string().deprecated_string().release_value().hash();
return value.as_string().deprecated_string().hash();
}
if (value.is_bigint())

View File

@ -99,7 +99,7 @@ static ErrorOr<JsonValue, ExecuteScriptResultType> internal_json_clone_algorithm
if (value.is_number())
return JsonValue { value.as_double() };
if (value.is_string())
return JsonValue { TRY_OR_JS_ERROR(value.as_string().deprecated_string()) };
return JsonValue { value.as_string().deprecated_string() };
// NOTE: BigInt and Symbol not mentioned anywhere in the WebDriver spec, as it references ES5.
// It assumes that all primitives are handled above, and the value is an object for the remaining steps.
@ -130,7 +130,7 @@ static ErrorOr<JsonValue, ExecuteScriptResultType> internal_json_clone_algorithm
auto to_json_result = TRY_OR_JS_ERROR(to_json.as_function().internal_call(value, JS::MarkedVector<JS::Value> { vm.heap() }));
if (!to_json_result.is_string())
return ExecuteScriptResultType::JavaScriptError;
return TRY_OR_JS_ERROR(to_json_result.as_string().deprecated_string());
return to_json_result.as_string().deprecated_string();
}
// -> Otherwise