diff options
author | Timothy Flynn <trflynn89@pm.me> | 2023-02-10 11:40:52 -0500 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2023-02-10 17:26:20 +0000 |
commit | 3b4879d29b3b0c6e44ce175c9738b3ca6c1f86ab (patch) | |
tree | c7b92ecd992f8d6eca6067d894ed83c4cd0c672e /Userland/Libraries/LibJS | |
parent | 8f9659a5495e598dec542b529efd90ca4d737c60 (diff) | |
download | serenity-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.cpp | 126 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Console.h | 21 |
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; }; |