summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2023-02-10 11:40:52 -0500
committerLinus Groh <mail@linusgroh.de>2023-02-10 17:26:20 +0000
commit3b4879d29b3b0c6e44ce175c9738b3ca6c1f86ab (patch)
treec7b92ecd992f8d6eca6067d894ed83c4cd0c672e /Userland/Libraries/LibJS
parent8f9659a5495e598dec542b529efd90ca4d737c60 (diff)
downloadserenity-3b4879d29b3b0c6e44ce175c9738b3ca6c1f86ab.zip
LibJS+Userland: Port the JS Console object and direct callers to String
Diffstat (limited to 'Userland/Libraries/LibJS')
-rw-r--r--Userland/Libraries/LibJS/Console.cpp126
-rw-r--r--Userland/Libraries/LibJS/Console.h21
2 files changed, 88 insertions, 59 deletions
diff --git a/Userland/Libraries/LibJS/Console.cpp b/Userland/Libraries/LibJS/Console.cpp
index c7749704fa..37f1e80e74 100644
--- a/Userland/Libraries/LibJS/Console.cpp
+++ b/Userland/Libraries/LibJS/Console.cpp
@@ -10,6 +10,7 @@
#include <LibJS/Runtime/AbstractOperations.h>
#include <LibJS/Runtime/StringConstructor.h>
#include <LibJS/Runtime/Temporal/Duration.h>
+#include <LibJS/Runtime/ThrowableStringBuilder.h>
namespace JS {
@@ -98,29 +99,37 @@ ThrowCompletionOr<Value> Console::trace()
auto& execution_context_stack = vm.execution_context_stack();
// NOTE: -2 to skip the console.trace() execution context
for (ssize_t i = execution_context_stack.size() - 2; i >= 0; --i) {
- auto& function_name = execution_context_stack[i]->function_name;
- trace.stack.append(function_name.is_empty() ? "<anonymous>" : function_name);
+ auto const& function_name = execution_context_stack[i]->function_name;
+ trace.stack.append(function_name.is_empty()
+ ? TRY_OR_THROW_OOM(vm, String::from_utf8("<anonymous>"sv))
+ : TRY_OR_THROW_OOM(vm, String::from_deprecated_string(function_name)));
}
// 2. Optionally, let formattedData be the result of Formatter(data), and incorporate formattedData as a label for trace.
if (vm.argument_count() > 0) {
- StringBuilder builder;
auto data = vm_arguments();
auto formatted_data = TRY(m_client->formatter(data));
- trace.label = TRY(value_vector_to_deprecated_string(formatted_data));
+ trace.label = TRY(value_vector_to_string(formatted_data));
}
// 3. Perform Printer("trace", « trace »).
return m_client->printer(Console::LogLevel::Trace, trace);
}
+static ThrowCompletionOr<String> label_or_fallback(VM& vm, StringView fallback)
+{
+ return vm.argument_count() > 0
+ ? vm.argument(0).to_string(vm)
+ : TRY_OR_THROW_OOM(vm, String::from_utf8(fallback));
+}
+
// 1.2.1. count(label), https://console.spec.whatwg.org/#count
ThrowCompletionOr<Value> Console::count()
{
auto& vm = realm().vm();
// NOTE: "default" is the default value in the IDL. https://console.spec.whatwg.org/#ref-for-count
- auto label = vm.argument_count() ? TRY(vm.argument(0).to_deprecated_string(vm)) : "default";
+ auto label = TRY(label_or_fallback(vm, "default"sv));
// 1. Let map be the associated count map.
auto& map = m_counters;
@@ -135,11 +144,11 @@ ThrowCompletionOr<Value> Console::count()
}
// 4. Let concat be the concatenation of label, U+003A (:), U+0020 SPACE, and ToString(map[label]).
- DeprecatedString concat = DeprecatedString::formatted("{}: {}", label, map.get(label).value());
+ auto concat = TRY_OR_THROW_OOM(vm, String::formatted("{}: {}", label, map.get(label).value()));
// 5. Perform Logger("count", « concat »).
MarkedVector<Value> concat_as_vector { vm.heap() };
- concat_as_vector.append(PrimitiveString::create(vm, concat));
+ concat_as_vector.append(PrimitiveString::create(vm, move(concat)));
if (m_client)
TRY(m_client->logger(LogLevel::Count, concat_as_vector));
return js_undefined();
@@ -151,7 +160,7 @@ ThrowCompletionOr<Value> Console::count_reset()
auto& vm = realm().vm();
// NOTE: "default" is the default value in the IDL. https://console.spec.whatwg.org/#ref-for-countreset
- auto label = vm.argument_count() ? TRY(vm.argument(0).to_deprecated_string(vm)) : "default";
+ auto label = TRY(label_or_fallback(vm, "default"sv));
// 1. Let map be the associated count map.
auto& map = m_counters;
@@ -164,10 +173,10 @@ ThrowCompletionOr<Value> Console::count_reset()
else {
// 1. Let message be a string without any formatting specifiers indicating generically
// that the given label does not have an associated count.
- auto message = DeprecatedString::formatted("\"{}\" doesn't have a count", label);
+ auto message = TRY_OR_THROW_OOM(vm, String::formatted("\"{}\" doesn't have a count", label));
// 2. Perform Logger("countReset", « message »);
MarkedVector<Value> message_as_vector { vm.heap() };
- message_as_vector.append(PrimitiveString::create(vm, message));
+ message_as_vector.append(PrimitiveString::create(vm, move(message)));
if (m_client)
TRY(m_client->logger(LogLevel::CountReset, message_as_vector));
}
@@ -212,9 +221,9 @@ ThrowCompletionOr<Value> Console::assert_()
// 3. Otherwise:
else {
// 1. Let concat be the concatenation of message, U+003A (:), U+0020 SPACE, and first.
- auto concat = PrimitiveString::create(vm, DeprecatedString::formatted("{}: {}", TRY(message->deprecated_string()), first.to_deprecated_string(vm).value()));
+ auto concat = TRY_OR_THROW_OOM(vm, String::formatted("{}: {}", TRY(message->utf8_string()), MUST(first.to_string(vm))));
// 2. Set data[0] to concat.
- data[0] = concat;
+ data[0] = PrimitiveString::create(vm, move(concat));
}
}
@@ -227,19 +236,21 @@ ThrowCompletionOr<Value> Console::assert_()
// 1.3.1. group(...data), https://console.spec.whatwg.org/#group
ThrowCompletionOr<Value> Console::group()
{
+ auto& vm = realm().vm();
+
// 1. Let group be a new group.
Group group;
// 2. If data is not empty, let groupLabel be the result of Formatter(data).
- DeprecatedString group_label;
+ String group_label {};
auto data = vm_arguments();
if (!data.is_empty()) {
auto formatted_data = TRY(m_client->formatter(data));
- group_label = TRY(value_vector_to_deprecated_string(formatted_data));
+ group_label = TRY(value_vector_to_string(formatted_data));
}
// ... Otherwise, let groupLabel be an implementation-chosen label representing a group.
else {
- group_label = "Group";
+ group_label = TRY_OR_THROW_OOM(vm, String::from_utf8("Group"sv));
}
// 3. Incorporate groupLabel as a label for group.
@@ -261,19 +272,21 @@ ThrowCompletionOr<Value> Console::group()
// 1.3.2. groupCollapsed(...data), https://console.spec.whatwg.org/#groupcollapsed
ThrowCompletionOr<Value> Console::group_collapsed()
{
+ auto& vm = realm().vm();
+
// 1. Let group be a new group.
Group group;
// 2. If data is not empty, let groupLabel be the result of Formatter(data).
- DeprecatedString group_label;
+ String group_label {};
auto data = vm_arguments();
if (!data.is_empty()) {
auto formatted_data = TRY(m_client->formatter(data));
- group_label = TRY(value_vector_to_deprecated_string(formatted_data));
+ group_label = TRY(value_vector_to_string(formatted_data));
}
// ... Otherwise, let groupLabel be an implementation-chosen label representing a group.
else {
- group_label = "Group";
+ group_label = TRY_OR_THROW_OOM(vm, String::from_utf8("Group"sv));
}
// 3. Incorporate groupLabel as a label for group.
@@ -312,14 +325,17 @@ ThrowCompletionOr<Value> Console::time()
auto& vm = realm().vm();
// NOTE: "default" is the default value in the IDL. https://console.spec.whatwg.org/#ref-for-time
- auto label = vm.argument_count() ? TRY(vm.argument(0).to_deprecated_string(vm)) : "default";
+ auto label = TRY(label_or_fallback(vm, "default"sv));
// 1. If the associated timer table contains an entry with key label, return, optionally reporting
- // a warning to the console indicating that a timer with label `label` has already been started.
+ // a warning to the console indicating that a timer with label `label` has already been started.
if (m_timer_table.contains(label)) {
if (m_client) {
MarkedVector<Value> timer_already_exists_warning_message_as_vector { vm.heap() };
- timer_already_exists_warning_message_as_vector.append(PrimitiveString::create(vm, DeprecatedString::formatted("Timer '{}' already exists.", label)));
+
+ auto message = TRY_OR_THROW_OOM(vm, String::formatted("Timer '{}' already exists.", label));
+ timer_already_exists_warning_message_as_vector.append(PrimitiveString::create(vm, move(message)));
+
TRY(m_client->printer(LogLevel::Warn, move(timer_already_exists_warning_message_as_vector)));
}
return js_undefined();
@@ -336,7 +352,7 @@ ThrowCompletionOr<Value> Console::time_log()
auto& vm = realm().vm();
// NOTE: "default" is the default value in the IDL. https://console.spec.whatwg.org/#ref-for-timelog
- auto label = vm.argument_count() ? TRY(vm.argument(0).to_deprecated_string(vm)) : "default";
+ auto label = TRY(label_or_fallback(vm, "default"sv));
// 1. Let timerTable be the associated timer table.
@@ -347,7 +363,10 @@ ThrowCompletionOr<Value> Console::time_log()
if (maybe_start_time == m_timer_table.end()) {
if (m_client) {
MarkedVector<Value> timer_does_not_exist_warning_message_as_vector { vm.heap() };
- timer_does_not_exist_warning_message_as_vector.append(PrimitiveString::create(vm, DeprecatedString::formatted("Timer '{}' does not exist.", label)));
+
+ auto message = TRY_OR_THROW_OOM(vm, String::formatted("Timer '{}' does not exist.", label));
+ timer_does_not_exist_warning_message_as_vector.append(PrimitiveString::create(vm, move(message)));
+
TRY(m_client->printer(LogLevel::Warn, move(timer_does_not_exist_warning_message_as_vector)));
}
return js_undefined();
@@ -358,12 +377,12 @@ ThrowCompletionOr<Value> Console::time_log()
auto duration = TRY(format_time_since(start_time));
// 4. Let concat be the concatenation of label, U+003A (:), U+0020 SPACE, and duration.
- auto concat = DeprecatedString::formatted("{}: {}", label, duration);
+ auto concat = TRY_OR_THROW_OOM(vm, String::formatted("{}: {}", label, duration));
// 5. Prepend concat to data.
MarkedVector<Value> data { vm.heap() };
data.ensure_capacity(vm.argument_count());
- data.append(PrimitiveString::create(vm, concat));
+ data.append(PrimitiveString::create(vm, move(concat)));
for (size_t i = 1; i < vm.argument_count(); ++i)
data.append(vm.argument(i));
@@ -379,7 +398,7 @@ ThrowCompletionOr<Value> Console::time_end()
auto& vm = realm().vm();
// NOTE: "default" is the default value in the IDL. https://console.spec.whatwg.org/#ref-for-timeend
- auto label = vm.argument_count() ? TRY(vm.argument(0).to_deprecated_string(vm)) : "default";
+ auto label = TRY(label_or_fallback(vm, "default"sv));
// 1. Let timerTable be the associated timer table.
@@ -390,7 +409,10 @@ ThrowCompletionOr<Value> Console::time_end()
if (maybe_start_time == m_timer_table.end()) {
if (m_client) {
MarkedVector<Value> timer_does_not_exist_warning_message_as_vector { vm.heap() };
- timer_does_not_exist_warning_message_as_vector.append(PrimitiveString::create(vm, DeprecatedString::formatted("Timer '{}' does not exist.", label)));
+
+ auto message = TRY_OR_THROW_OOM(vm, String::formatted("Timer '{}' does not exist.", label));
+ timer_does_not_exist_warning_message_as_vector.append(PrimitiveString::create(vm, move(message)));
+
TRY(m_client->printer(LogLevel::Warn, move(timer_does_not_exist_warning_message_as_vector)));
}
return js_undefined();
@@ -404,12 +426,12 @@ ThrowCompletionOr<Value> Console::time_end()
auto duration = TRY(format_time_since(start_time));
// 5. Let concat be the concatenation of label, U+003A (:), U+0020 SPACE, and duration.
- auto concat = DeprecatedString::formatted("{}: {}", label, duration);
+ auto concat = TRY_OR_THROW_OOM(vm, String::formatted("{}: {}", label, duration));
// 6. Perform Printer("timeEnd", « concat »).
if (m_client) {
MarkedVector<Value> concat_as_vector { vm.heap() };
- concat_as_vector.append(PrimitiveString::create(vm, concat));
+ concat_as_vector.append(PrimitiveString::create(vm, move(concat)));
TRY(m_client->printer(LogLevel::TimeEnd, move(concat_as_vector)));
}
return js_undefined();
@@ -427,7 +449,7 @@ MarkedVector<Value> Console::vm_arguments()
return arguments;
}
-void Console::output_debug_message(LogLevel log_level, DeprecatedString const& output) const
+void Console::output_debug_message(LogLevel log_level, String const& output) const
{
switch (log_level) {
case Console::LogLevel::Debug:
@@ -457,43 +479,49 @@ void Console::report_exception(JS::Error const& exception, bool in_promise) cons
m_client->report_exception(exception, in_promise);
}
-ThrowCompletionOr<DeprecatedString> Console::value_vector_to_deprecated_string(MarkedVector<Value> const& values)
+ThrowCompletionOr<String> Console::value_vector_to_string(MarkedVector<Value> const& values)
{
auto& vm = realm().vm();
- StringBuilder builder;
+ ThrowableStringBuilder builder(vm);
+
for (auto const& item : values) {
if (!builder.is_empty())
- builder.append(' ');
- builder.append(TRY(item.to_deprecated_string(vm)));
+ MUST_OR_THROW_OOM(builder.append(' '));
+
+ MUST_OR_THROW_OOM(builder.append(TRY(item.to_string(vm))));
}
- return builder.to_deprecated_string();
+
+ return builder.to_string();
}
-ThrowCompletionOr<DeprecatedString> Console::format_time_since(Core::ElapsedTimer timer)
+ThrowCompletionOr<String> Console::format_time_since(Core::ElapsedTimer timer)
{
auto& vm = realm().vm();
auto elapsed_ms = timer.elapsed_time().to_milliseconds();
auto duration = TRY(Temporal::balance_duration(vm, 0, 0, 0, 0, elapsed_ms, 0, "0"_sbigint, "year"sv));
- auto append = [&](StringBuilder& builder, auto format, auto... number) {
+ auto append = [&](ThrowableStringBuilder& builder, auto format, auto number) -> ThrowCompletionOr<void> {
if (!builder.is_empty())
- builder.append(' ');
- builder.appendff(format, number...);
+ MUST_OR_THROW_OOM(builder.append(' '));
+ MUST_OR_THROW_OOM(builder.appendff(format, number));
+ return {};
};
- StringBuilder builder;
+
+ ThrowableStringBuilder builder(vm);
+
if (duration.days > 0)
- append(builder, "{:.0} day(s)"sv, duration.days);
+ MUST_OR_THROW_OOM(append(builder, "{:.0} day(s)"sv, duration.days));
if (duration.hours > 0)
- append(builder, "{:.0} hour(s)"sv, duration.hours);
+ MUST_OR_THROW_OOM(append(builder, "{:.0} hour(s)"sv, duration.hours));
if (duration.minutes > 0)
- append(builder, "{:.0} minute(s)"sv, duration.minutes);
+ MUST_OR_THROW_OOM(append(builder, "{:.0} minute(s)"sv, duration.minutes));
if (duration.seconds > 0 || duration.milliseconds > 0) {
double combined_seconds = duration.seconds + (0.001 * duration.milliseconds);
- append(builder, "{:.3} seconds"sv, combined_seconds);
+ MUST_OR_THROW_OOM(append(builder, "{:.3} seconds"sv, combined_seconds));
}
- return builder.to_deprecated_string();
+ return builder.to_string();
}
// 2.1. Logger(logLevel, args), https://console.spec.whatwg.org/#logger
@@ -539,7 +567,7 @@ ThrowCompletionOr<MarkedVector<Value>> ConsoleClient::formatter(MarkedVector<Val
return args;
// 2. Let target be the first element of args.
- auto target = (!args.is_empty()) ? TRY(args.first().to_deprecated_string(vm)) : "";
+ auto target = (!args.is_empty()) ? TRY(args.first().to_string(vm)) : String {};
// 3. Let current be the second element of args.
auto current = (args.size() > 1) ? args[1] : js_undefined();
@@ -621,19 +649,19 @@ ThrowCompletionOr<MarkedVector<Value>> ConsoleClient::formatter(MarkedVector<Val
// 6. TODO: process %c
else if (specifier == "%c"sv) {
// NOTE: This has no spec yet. `%c` specifiers treat the argument as CSS styling for the log message.
- add_css_style_to_current_message(TRY(current.to_deprecated_string(vm)));
+ add_css_style_to_current_message(TRY(current.to_string(vm)));
converted = PrimitiveString::create(vm, String {});
}
// 7. If any of the previous steps set converted, replace specifier in target with converted.
if (converted.has_value())
- target = target.replace(specifier, TRY(converted->to_deprecated_string(vm)), ReplaceMode::FirstOnly);
+ target = TRY_OR_THROW_OOM(vm, target.replace(specifier, TRY(converted->to_string(vm)), ReplaceMode::FirstOnly));
}
// 7. Let result be a list containing target together with the elements of args starting from the third onward.
MarkedVector<Value> result { vm.heap() };
result.ensure_capacity(args.size() - 1);
- result.empend(PrimitiveString::create(vm, target));
+ result.empend(PrimitiveString::create(vm, move(target)));
for (size_t i = 2; i < args.size(); ++i)
result.unchecked_append(args[i]);
diff --git a/Userland/Libraries/LibJS/Console.h b/Userland/Libraries/LibJS/Console.h
index e8db5059c6..34f45a71b5 100644
--- a/Userland/Libraries/LibJS/Console.h
+++ b/Userland/Libraries/LibJS/Console.h
@@ -10,6 +10,7 @@
#include <AK/Function.h>
#include <AK/HashMap.h>
#include <AK/Noncopyable.h>
+#include <AK/String.h>
#include <AK/Vector.h>
#include <LibCore/ElapsedTimer.h>
#include <LibJS/Forward.h>
@@ -45,12 +46,12 @@ public:
};
struct Group {
- DeprecatedString label;
+ String label;
};
struct Trace {
- DeprecatedString label;
- Vector<DeprecatedString> stack;
+ String label;
+ Vector<String> stack;
};
explicit Console(Realm&);
@@ -61,8 +62,8 @@ public:
MarkedVector<Value> vm_arguments();
- HashMap<DeprecatedString, unsigned>& counters() { return m_counters; }
- HashMap<DeprecatedString, unsigned> const& counters() const { return m_counters; }
+ HashMap<String, unsigned>& counters() { return m_counters; }
+ HashMap<String, unsigned> const& counters() const { return m_counters; }
ThrowCompletionOr<Value> debug();
ThrowCompletionOr<Value> error();
@@ -81,18 +82,18 @@ public:
ThrowCompletionOr<Value> time_log();
ThrowCompletionOr<Value> time_end();
- void output_debug_message(LogLevel log_level, DeprecatedString const& output) const;
+ void output_debug_message(LogLevel log_level, String const& output) const;
void report_exception(JS::Error const&, bool) const;
private:
- ThrowCompletionOr<DeprecatedString> value_vector_to_deprecated_string(MarkedVector<Value> const&);
- ThrowCompletionOr<DeprecatedString> format_time_since(Core::ElapsedTimer timer);
+ ThrowCompletionOr<String> value_vector_to_string(MarkedVector<Value> const&);
+ ThrowCompletionOr<String> format_time_since(Core::ElapsedTimer timer);
Realm& m_realm;
ConsoleClient* m_client { nullptr };
- HashMap<DeprecatedString, unsigned> m_counters;
- HashMap<DeprecatedString, Core::ElapsedTimer> m_timer_table;
+ HashMap<String, unsigned> m_counters;
+ HashMap<String, Core::ElapsedTimer> m_timer_table;
Vector<Group> m_group_stack;
};