From 94afcb54de07499d15fe8e601127148bba022f96 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Thu, 2 Apr 2020 21:16:13 +0100 Subject: [PATCH] LibJS: Implement Error.prototype.toString() --- Libraries/LibJS/Runtime/ErrorPrototype.cpp | 24 +++++++++++++++++++ Libraries/LibJS/Runtime/ErrorPrototype.h | 2 ++ .../LibJS/Tests/Error.prototype.toString.js | 13 ++++++++++ 3 files changed, 39 insertions(+) create mode 100644 Libraries/LibJS/Tests/Error.prototype.toString.js diff --git a/Libraries/LibJS/Runtime/ErrorPrototype.cpp b/Libraries/LibJS/Runtime/ErrorPrototype.cpp index a15707c0da..da59c5a07c 100644 --- a/Libraries/LibJS/Runtime/ErrorPrototype.cpp +++ b/Libraries/LibJS/Runtime/ErrorPrototype.cpp @@ -38,6 +38,7 @@ ErrorPrototype::ErrorPrototype() { put_native_property("name", name_getter, nullptr); put_native_property("message", message_getter, nullptr); + put_native_function("toString", to_string); } ErrorPrototype::~ErrorPrototype() @@ -64,4 +65,27 @@ Value ErrorPrototype::message_getter(Interpreter& interpreter) return js_string(interpreter.heap(), static_cast(this_object)->message()); } +Value ErrorPrototype::to_string(Interpreter& interpreter) +{ + if (!interpreter.this_value().is_object()) + return interpreter.throw_exception("TypeError", "Not an object"); + auto& this_object = interpreter.this_value().as_object(); + + String name = "Error"; + auto object_name_property = this_object.get("name"); + if (object_name_property.has_value() && !object_name_property.value().is_undefined()) + name = object_name_property.value().to_string(); + + String message = ""; + auto object_message_property = this_object.get("message"); + if (object_message_property.has_value() && !object_message_property.value().is_undefined()) + message = object_message_property.value().to_string(); + + if (name.length() == 0) + return js_string(interpreter.heap(), message); + if (message.length() == 0) + return js_string(interpreter.heap(), name); + return js_string(interpreter.heap(), String::format("%s: %s", name.characters(), message.characters())); +} + } diff --git a/Libraries/LibJS/Runtime/ErrorPrototype.h b/Libraries/LibJS/Runtime/ErrorPrototype.h index dd334f1cc4..58c97c6370 100644 --- a/Libraries/LibJS/Runtime/ErrorPrototype.h +++ b/Libraries/LibJS/Runtime/ErrorPrototype.h @@ -38,6 +38,8 @@ public: private: virtual const char* class_name() const override { return "ErrorPrototype"; } + static Value to_string(Interpreter&); + static Value name_getter(Interpreter&); static Value message_getter(Interpreter&); }; diff --git a/Libraries/LibJS/Tests/Error.prototype.toString.js b/Libraries/LibJS/Tests/Error.prototype.toString.js new file mode 100644 index 0000000000..cc0b8185c0 --- /dev/null +++ b/Libraries/LibJS/Tests/Error.prototype.toString.js @@ -0,0 +1,13 @@ +function assert(x) { if (!x) throw 1; } + +try { + assert(Error().toString() === "Error"); + assert(Error(undefined).toString() === "Error"); + assert(Error(null).toString() === "Error: null"); + assert(Error("test").toString() === "Error: test"); + assert(Error(42).toString() === "Error: 42"); + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +}