Browse Source

LibJS: Make PrimitiveString::deprecated_string() infallible

Work towards #20449.
Andreas Kling 1 year ago
parent
commit
09547ec975

+ 3 - 3
Tests/LibJS/test-js.cpp

@@ -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));

+ 8 - 8
Userland/Applications/Spreadsheet/JSIntegration.cpp

@@ -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());

+ 1 - 1
Userland/Libraries/LibJS/Contrib/Test262/IsHTMLDDA.cpp

@@ -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:

+ 2 - 2
Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp

@@ -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());
                 }
             }
         }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/DateConstructor.cpp

@@ -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 {

+ 1 - 1
Userland/Libraries/LibJS/Runtime/DatePrototype.cpp

@@ -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;

+ 5 - 5
Userland/Libraries/LibJS/Runtime/JSONObject.cpp

@@ -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()));
         }
     }
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Object.cpp

@@ -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));

+ 1 - 1
Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp

@@ -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));

+ 1 - 1
Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp

@@ -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);
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/PrimitiveString.h

@@ -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;

+ 1 - 1
Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp

@@ -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 {};
 }

+ 2 - 2
Userland/Libraries/LibJS/Runtime/ShadowRealmPrototype.cpp

@@ -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);
 }
 
 }

+ 3 - 3
Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp

@@ -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

+ 8 - 9
Userland/Libraries/LibJS/Runtime/Value.cpp

@@ -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())

+ 1 - 1
Userland/Libraries/LibJS/Runtime/ValueTraits.h

@@ -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())

+ 2 - 2
Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp

@@ -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