Browse Source

LibJS: Use new format functions everywhere

This changes the remaining uses of the following functions across LibJS:

- String::format() => String::formatted()
- dbg() => dbgln()
- printf() => out(), outln()
- fprintf() => warnln()

I also removed the relevant 'LogStream& operator<<' overloads as they're
not needed anymore.
Linus Groh 4 years ago
parent
commit
5eb1f752ab

+ 67 - 67
Libraries/LibJS/AST.cpp

@@ -48,7 +48,6 @@
 #include <LibJS/Runtime/Shape.h>
 #include <LibJS/Runtime/StringObject.h>
 #include <LibJS/Runtime/WithScope.h>
-#include <stdio.h>
 
 namespace JS {
 
@@ -823,14 +822,13 @@ Value ClassDeclaration::execute(Interpreter& interpreter, GlobalObject& global_o
 
 static void print_indent(int indent)
 {
-    for (int i = 0; i < indent * 2; ++i)
-        putchar(' ');
+    out("{}", String::repeated(' ', indent * 2));
 }
 
 void ASTNode::dump(int indent) const
 {
     print_indent(indent);
-    printf("%s\n", class_name());
+    outln("{}", class_name());
 }
 
 void ScopeNode::dump(int indent) const
@@ -838,13 +836,13 @@ void ScopeNode::dump(int indent) const
     ASTNode::dump(indent);
     if (!m_variables.is_empty()) {
         print_indent(indent + 1);
-        printf("(Variables)\n");
+        outln("(Variables)");
         for (auto& variable : m_variables)
             variable.dump(indent + 2);
     }
     if (!m_children.is_empty()) {
         print_indent(indent + 1);
-        printf("(Children)\n");
+        outln("(Children)");
         for (auto& child : children())
             child.dump(indent + 2);
     }
@@ -923,10 +921,10 @@ void BinaryExpression::dump(int indent) const
     }
 
     print_indent(indent);
-    printf("%s\n", class_name());
+    outln("{}", class_name());
     m_lhs->dump(indent + 1);
     print_indent(indent + 1);
-    printf("%s\n", op_string);
+    outln("{}", op_string);
     m_rhs->dump(indent + 1);
 }
 
@@ -946,10 +944,10 @@ void LogicalExpression::dump(int indent) const
     }
 
     print_indent(indent);
-    printf("%s\n", class_name());
+    outln("{}", class_name());
     m_lhs->dump(indent + 1);
     print_indent(indent + 1);
-    printf("%s\n", op_string);
+    outln("{}", op_string);
     m_rhs->dump(indent + 1);
 }
 
@@ -981,16 +979,19 @@ void UnaryExpression::dump(int indent) const
     }
 
     print_indent(indent);
-    printf("%s\n", class_name());
+    outln("{}", class_name());
     print_indent(indent + 1);
-    printf("%s\n", op_string);
+    outln("{}", op_string);
     m_lhs->dump(indent + 1);
 }
 
 void CallExpression::dump(int indent) const
 {
     print_indent(indent);
-    printf("CallExpression %s\n", is_new_expression() ? "[new]" : "");
+    if (is_new_expression())
+        outln("CallExpression [new]");
+    else
+        outln("CallExpression");
     m_callee->dump(indent + 1);
     for (auto& argument : m_arguments)
         argument.value->dump(indent + 1);
@@ -1005,21 +1006,20 @@ void ClassDeclaration::dump(int indent) const
 void ClassExpression::dump(int indent) const
 {
     print_indent(indent);
-    ASSERT(m_name.characters());
-    printf("ClassExpression: \"%s\"\n", m_name.characters());
+    outln("ClassExpression: \"{}\"", m_name);
 
     print_indent(indent);
-    printf("(Constructor)\n");
+    outln("(Constructor)");
     m_constructor->dump(indent + 1);
 
     if (!m_super_class.is_null()) {
         print_indent(indent);
-        printf("(Super Class)\n");
+        outln("(Super Class)");
         m_super_class->dump(indent + 1);
     }
 
     print_indent(indent);
-    printf("(Methods)\n");
+    outln("(Methods)");
     for (auto& method : m_methods)
         method.dump(indent + 1);
 }
@@ -1029,7 +1029,7 @@ void ClassMethod::dump(int indent) const
     ASTNode::dump(indent);
 
     print_indent(indent);
-    printf("(Key)\n");
+    outln("(Key)");
     m_key->dump(indent + 1);
 
     const char* kind_string = nullptr;
@@ -1045,78 +1045,78 @@ void ClassMethod::dump(int indent) const
         break;
     }
     print_indent(indent);
-    printf("Kind: %s\n", kind_string);
+    outln("Kind: {}", kind_string);
 
     print_indent(indent);
-    printf("Static: %s\n", m_is_static ? "true" : "false");
+    outln("Static: {}", m_is_static);
 
     print_indent(indent);
-    printf("(Function)\n");
+    outln("(Function)");
     m_function->dump(indent + 1);
 }
 
 void StringLiteral::dump(int indent) const
 {
     print_indent(indent);
-    printf("StringLiteral \"%s\"\n", m_value.characters());
+    outln("StringLiteral \"{}\"", m_value);
 }
 
 void SuperExpression::dump(int indent) const
 {
     print_indent(indent);
-    printf("super\n");
+    outln("super");
 }
 
 void NumericLiteral::dump(int indent) const
 {
     print_indent(indent);
-    printf("NumericLiteral %g\n", m_value);
+    outln("NumericLiteral {}", m_value);
 }
 
 void BigIntLiteral::dump(int indent) const
 {
     print_indent(indent);
-    printf("BigIntLiteral %s\n", m_value.characters());
+    outln("BigIntLiteral {}", m_value);
 }
 
 void BooleanLiteral::dump(int indent) const
 {
     print_indent(indent);
-    printf("BooleanLiteral %s\n", m_value ? "true" : "false");
+    outln("BooleanLiteral {}", m_value);
 }
 
 void NullLiteral::dump(int indent) const
 {
     print_indent(indent);
-    printf("null\n");
+    outln("null");
 }
 
 void FunctionNode::dump(int indent, const char* class_name) const
 {
     print_indent(indent);
-    printf("%s '%s'\n", class_name, name().characters());
+    outln("{} '{}'", class_name, name());
     if (!m_parameters.is_empty()) {
         print_indent(indent + 1);
-        printf("(Parameters)\n");
+        outln("(Parameters)\n");
 
         for (auto& parameter : m_parameters) {
             print_indent(indent + 2);
             if (parameter.is_rest)
-                printf("...");
-            printf("%s\n", parameter.name.characters());
+                out("...");
+            outln("{}", parameter.name);
             if (parameter.default_value)
                 parameter.default_value->dump(indent + 3);
         }
     }
     if (!m_variables.is_empty()) {
         print_indent(indent + 1);
-        printf("(Variables)\n");
+        outln("(Variables)");
 
         for (auto& variable : m_variables)
             variable.dump(indent + 2);
     }
     print_indent(indent + 1);
-    printf("(Body)\n");
+    outln("(Body)");
     body().dump(indent + 2);
 }
 
@@ -1142,12 +1142,12 @@ void IfStatement::dump(int indent) const
     ASTNode::dump(indent);
 
     print_indent(indent);
-    printf("If\n");
+    outln("If");
     predicate().dump(indent + 1);
     consequent().dump(indent + 1);
     if (alternate()) {
         print_indent(indent);
-        printf("Else\n");
+        outln("Else");
         alternate()->dump(indent + 1);
     }
 }
@@ -1157,7 +1157,7 @@ void WhileStatement::dump(int indent) const
     ASTNode::dump(indent);
 
     print_indent(indent);
-    printf("While\n");
+    outln("While");
     test().dump(indent + 1);
     body().dump(indent + 1);
 }
@@ -1167,10 +1167,10 @@ void WithStatement::dump(int indent) const
     ASTNode::dump(indent);
 
     print_indent(indent + 1);
-    printf("Object\n");
+    outln("Object");
     object().dump(indent + 2);
     print_indent(indent + 1);
-    printf("Body\n");
+    outln("Body");
     body().dump(indent + 2);
 }
 
@@ -1179,7 +1179,7 @@ void DoWhileStatement::dump(int indent) const
     ASTNode::dump(indent);
 
     print_indent(indent);
-    printf("DoWhile\n");
+    outln("DoWhile");
     test().dump(indent + 1);
     body().dump(indent + 1);
 }
@@ -1189,7 +1189,7 @@ void ForStatement::dump(int indent) const
     ASTNode::dump(indent);
 
     print_indent(indent);
-    printf("For\n");
+    outln("For");
     if (init())
         init()->dump(indent + 1);
     if (test())
@@ -1204,7 +1204,7 @@ void ForInStatement::dump(int indent) const
     ASTNode::dump(indent);
 
     print_indent(indent);
-    printf("ForIn\n");
+    outln("ForIn");
     lhs().dump(indent + 1);
     rhs().dump(indent + 1);
     body().dump(indent + 1);
@@ -1215,7 +1215,7 @@ void ForOfStatement::dump(int indent) const
     ASTNode::dump(indent);
 
     print_indent(indent);
-    printf("ForOf\n");
+    outln("ForOf");
     lhs().dump(indent + 1);
     rhs().dump(indent + 1);
     body().dump(indent + 1);
@@ -1234,7 +1234,7 @@ Value Identifier::execute(Interpreter& interpreter, GlobalObject& global_object)
 void Identifier::dump(int indent) const
 {
     print_indent(indent);
-    printf("Identifier \"%s\"\n", m_string.characters());
+    outln("Identifier \"{}\"", m_string);
 }
 
 void SpreadExpression::dump(int indent) const
@@ -1465,7 +1465,7 @@ void AssignmentExpression::dump(int indent) const
 
     ASTNode::dump(indent);
     print_indent(indent + 1);
-    printf("%s\n", op_string);
+    outln("{}", op_string);
     m_lhs->dump(indent + 1);
     m_rhs->dump(indent + 1);
 }
@@ -1485,12 +1485,12 @@ void UpdateExpression::dump(int indent) const
     ASTNode::dump(indent);
     if (m_prefixed) {
         print_indent(indent + 1);
-        printf("%s\n", op_string);
+        outln("{}", op_string);
     }
     m_argument->dump(indent + 1);
     if (!m_prefixed) {
         print_indent(indent + 1);
-        printf("%s\n", op_string);
+        outln("{}", op_string);
     }
 }
 
@@ -1532,7 +1532,7 @@ void VariableDeclaration::dump(int indent) const
 
     ASTNode::dump(indent);
     print_indent(indent + 1);
-    printf("%s\n", declaration_kind_string);
+    outln("{}", declaration_kind_string);
 
     for (auto& declarator : m_declarations)
         declarator.dump(indent + 1);
@@ -1645,7 +1645,7 @@ Value ObjectExpression::execute(Interpreter& interpreter, GlobalObject& global_o
 void MemberExpression::dump(int indent) const
 {
     print_indent(indent);
-    printf("%s (computed=%s)\n", class_name(), is_computed() ? "true" : "false");
+    outln("%{}(computed={})", class_name(), is_computed());
     m_object->dump(indent + 1);
     m_property->dump(indent + 1);
 }
@@ -1698,7 +1698,7 @@ void MetaProperty::dump(int indent) const
     else
         ASSERT_NOT_REACHED();
     print_indent(indent);
-    printf("%s %s\n", class_name(), name.characters());
+    outln("{} {}", class_name(), name);
 }
 
 Value MetaProperty::execute(Interpreter& interpreter, GlobalObject&) const
@@ -1738,7 +1738,7 @@ Value NullLiteral::execute(Interpreter&, GlobalObject&) const
 void RegExpLiteral::dump(int indent) const
 {
     print_indent(indent);
-    printf("%s (/%s/%s)\n", class_name(), content().characters(), flags().characters());
+    outln("{} (/{}/{})", class_name(), content(), flags());
 }
 
 Value RegExpLiteral::execute(Interpreter&, GlobalObject& global_object) const
@@ -1754,7 +1754,7 @@ void ArrayExpression::dump(int indent) const
             element->dump(indent + 1);
         } else {
             print_indent(indent + 1);
-            printf("<empty>\n");
+            outln("<empty>");
         }
     }
 }
@@ -1812,10 +1812,10 @@ void TaggedTemplateLiteral::dump(int indent) const
 {
     ASTNode::dump(indent);
     print_indent(indent + 1);
-    printf("(Tag)\n");
+    outln("(Tag)");
     m_tag->dump(indent + 2);
     print_indent(indent + 1);
-    printf("(Template Literal)\n");
+    outln("(Template Literal)");
     m_template_literal->dump(indent + 2);
 }
 
@@ -1862,18 +1862,18 @@ void TryStatement::dump(int indent) const
 {
     ASTNode::dump(indent);
     print_indent(indent);
-    printf("(Block)\n");
+    outln("(Block)");
     block().dump(indent + 1);
 
     if (handler()) {
         print_indent(indent);
-        printf("(Handler)\n");
+        outln("(Handler)");
         handler()->dump(indent + 1);
     }
 
     if (finalizer()) {
         print_indent(indent);
-        printf("(Finalizer)\n");
+        outln("(Finalizer)");
         finalizer()->dump(indent + 1);
     }
 }
@@ -1881,10 +1881,10 @@ void TryStatement::dump(int indent) const
 void CatchClause::dump(int indent) const
 {
     print_indent(indent);
-    printf("CatchClause");
-    if (!m_parameter.is_null())
-        printf(" (%s)", m_parameter.characters());
-    printf("\n");
+    if (m_parameter.is_null())
+        outln("CatchClause");
+    else
+        outln("CatchClause ({})", m_parameter);
     body().dump(indent + 1);
 }
 
@@ -2011,13 +2011,13 @@ void SwitchCase::dump(int indent) const
     ASTNode::dump(indent);
     print_indent(indent + 1);
     if (m_test) {
-        printf("(Test)\n");
+        outln("(Test)");
         m_test->dump(indent + 2);
     } else {
-        printf("(Default)\n");
+        outln("(Default)");
     }
     print_indent(indent + 1);
-    printf("(Consequent)\n");
+    outln("(Consequent)");
     for (auto& statement : m_consequent)
         statement.dump(indent + 2);
 }
@@ -2042,13 +2042,13 @@ void ConditionalExpression::dump(int indent) const
 {
     ASTNode::dump(indent);
     print_indent(indent + 1);
-    printf("(Test)\n");
+    outln("(Test)");
     m_test->dump(indent + 2);
     print_indent(indent + 1);
-    printf("(Consequent)\n");
+    outln("(Consequent)");
     m_consequent->dump(indent + 2);
     print_indent(indent + 1);
-    printf("(Alternate)\n");
+    outln("(Alternate)");
     m_alternate->dump(indent + 2);
 }
 

+ 0 - 1
Libraries/LibJS/CMakeLists.txt

@@ -55,7 +55,6 @@ set(SOURCES
     Runtime/Object.cpp
     Runtime/ObjectPrototype.cpp
     Runtime/PrimitiveString.cpp
-    Runtime/PropertyAttributes.cpp
     Runtime/ProxyConstructor.cpp
     Runtime/ProxyObject.cpp
     Runtime/Reference.cpp

+ 14 - 16
Libraries/LibJS/Heap/Heap.cpp

@@ -118,10 +118,9 @@ void Heap::gather_roots(HashTable<Cell*>& roots)
     }
 
 #ifdef HEAP_DEBUG
-    dbg() << "gather_roots:";
-    for (auto* root : roots) {
-        dbg() << "  + " << root;
-    }
+    dbgln("gather_roots:");
+    for (auto* root : roots)
+        dbgln("  + {}", root);
 #endif
 }
 
@@ -130,7 +129,7 @@ void Heap::gather_conservative_roots(HashTable<Cell*>& roots)
     FlatPtr dummy;
 
 #ifdef HEAP_DEBUG
-    dbg() << "gather_conservative_roots:";
+    dbgln("gather_conservative_roots:");
 #endif
 
     jmp_buf buf;
@@ -161,19 +160,19 @@ void Heap::gather_conservative_roots(HashTable<Cell*>& roots)
         if (!possible_pointer)
             continue;
 #ifdef HEAP_DEBUG
-        dbg() << "  ? " << (const void*)possible_pointer;
+        dbgln("  ? {}", (const void*)possible_pointer);
 #endif
         auto* possible_heap_block = HeapBlock::from_cell(reinterpret_cast<const Cell*>(possible_pointer));
         if (all_live_heap_blocks.contains(possible_heap_block)) {
             if (auto* cell = possible_heap_block->cell_from_possible_pointer(possible_pointer)) {
                 if (cell->is_live()) {
 #ifdef HEAP_DEBUG
-                    dbg() << "  ?-> " << (const void*)cell;
+                    dbgln("  ?-> {}", (const void*)cell);
 #endif
                     roots.set(cell);
                 } else {
 #ifdef HEAP_DEBUG
-                    dbg() << "  #-> " << (const void*)cell;
+                    dbgln("  #-> {}", (const void*)cell);
 #endif
                 }
             }
@@ -190,7 +189,7 @@ public:
         if (cell->is_marked())
             return;
 #ifdef HEAP_DEBUG
-        dbg() << "  ! " << cell;
+        dbgln("  ! {}", cell);
 #endif
         cell->set_marked(true);
         cell->visit_edges(*this);
@@ -200,7 +199,7 @@ public:
 void Heap::mark_live_cells(const HashTable<Cell*>& roots)
 {
 #ifdef HEAP_DEBUG
-    dbg() << "mark_live_cells:";
+    dbgln("mark_live_cells:");
 #endif
     MarkingVisitor visitor;
     for (auto* root : roots)
@@ -210,7 +209,7 @@ void Heap::mark_live_cells(const HashTable<Cell*>& roots)
 void Heap::sweep_dead_cells(bool print_report, const Core::ElapsedTimer& measurement_timer)
 {
 #ifdef HEAP_DEBUG
-    dbg() << "sweep_dead_cells:";
+    dbgln("sweep_dead_cells:");
 #endif
     Vector<HeapBlock*, 32> empty_blocks;
     Vector<HeapBlock*, 32> full_blocks_that_became_usable;
@@ -227,7 +226,7 @@ void Heap::sweep_dead_cells(bool print_report, const Core::ElapsedTimer& measure
             if (cell->is_live()) {
                 if (!cell->is_marked()) {
 #ifdef HEAP_DEBUG
-                    dbg() << "  ~ " << cell;
+                    dbgln("  ~ {}", cell);
 #endif
                     block.deallocate(cell);
                     ++collected_cells;
@@ -249,21 +248,21 @@ void Heap::sweep_dead_cells(bool print_report, const Core::ElapsedTimer& measure
 
     for (auto* block : empty_blocks) {
 #ifdef HEAP_DEBUG
-        dbg() << " - HeapBlock empty @ " << block << ": cell_size=" << block->cell_size();
+        dbgln(" - HeapBlock empty @ {}: cell_size={}", block, block->cell_size());
 #endif
         allocator_for_size(block->cell_size()).block_did_become_empty({}, *block);
     }
 
     for (auto* block : full_blocks_that_became_usable) {
 #ifdef HEAP_DEBUG
-        dbg() << " - HeapBlock usable again @ " << block << ": cell_size=" << block->cell_size();
+        dbgln(" - HeapBlock usable again @ {}: cell_size={}", block, block->cell_size());
 #endif
         allocator_for_size(block->cell_size()).block_did_become_usable({}, *block);
     }
 
 #ifdef HEAP_DEBUG
     for_each_block([&](auto& block) {
-        dbg() << " > Live HeapBlock @ " << &block << ": cell_size=" << block.cell_size();
+        dbgln(" > Live HeapBlock @ {}: cell_size={}", &block, block.cell_size());
         return IterationDecision::Continue;
     });
 #endif
@@ -271,7 +270,6 @@ void Heap::sweep_dead_cells(bool print_report, const Core::ElapsedTimer& measure
     int time_spent = measurement_timer.elapsed();
 
     if (print_report) {
-
         size_t live_block_count = 0;
         for_each_block([&](auto&) {
             ++live_block_count;

+ 9 - 9
Libraries/LibJS/Lexer.cpp

@@ -181,7 +181,7 @@ void Lexer::consume()
             type = "LINE SEPARATOR";
         else
             type = "PARAGRAPH SEPARATOR";
-        dbg() << "Found a line terminator: " << type;
+        dbgln("Found a line terminator: {}", type);
 #endif
         // This is a three-char line terminator, we need to increase m_position some more.
         // We might reach EOF and need to check again.
@@ -201,9 +201,9 @@ void Lexer::consume()
             m_line_number++;
             m_line_column = 1;
 #ifdef LEXER_DEBUG
-            dbg() << "Incremented line number, now at: line " << m_line_number << ", column 1";
+            dbgln("Incremented line number, now at: line {}, column 1", m_line_number);
         } else {
-            dbg() << "Previous was CR, this is LF - not incrementing line number again.";
+            dbgln("Previous was CR, this is LF - not incrementing line number again.");
 #endif
         }
     } else {
@@ -638,12 +638,12 @@ Token Lexer::next()
         value_start_column_number);
 
 #ifdef LEXER_DEBUG
-    dbg() << "------------------------------";
-    dbg() << "Token: " << m_current_token.name();
-    dbg() << "Trivia: _" << m_current_token.trivia() << "_";
-    dbg() << "Value: _" << m_current_token.value() << "_";
-    dbg() << "Line: " << m_current_token.line_number() << ", Column: " << m_current_token.line_column();
-    dbg() << "------------------------------";
+    dbgln("------------------------------");
+    dbgln("Token: {}", m_current_token.name());
+    dbgln("Trivia: _{}_", m_current_token.trivia());
+    dbgln("Value: _{}_", m_current_token.value());
+    dbgln("Line: {}, Column: {}", m_current_token.line_number(), m_current_token.line_column());
+    dbgln("------------------------------");
 #endif
 
     return m_current_token;

+ 1 - 1
Libraries/LibJS/Parser.cpp

@@ -93,7 +93,7 @@ public:
     {
         int p = m_token_precedence[static_cast<size_t>(token)];
         if (p == 0) {
-            fprintf(stderr, "Internal Error: No precedence for operator %s\n", Token::name(token));
+            warnln("Internal Error: No precedence for operator {}", Token::name(token));
             ASSERT_NOT_REACHED();
             return -1;
         }

+ 0 - 8
Libraries/LibJS/Runtime/Cell.cpp

@@ -24,7 +24,6 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <AK/LogStream.h>
 #include <LibJS/Heap/Heap.h>
 #include <LibJS/Heap/HeapBlock.h>
 #include <LibJS/Runtime/Cell.h>
@@ -56,11 +55,4 @@ VM& Cell::vm() const
     return heap().vm();
 }
 
-const LogStream& operator<<(const LogStream& stream, const Cell* cell)
-{
-    if (!cell)
-        return stream << "Cell{nullptr}";
-    return stream << cell->class_name() << '{' << static_cast<const void*>(cell) << '}';
-}
-
 }

+ 16 - 1
Libraries/LibJS/Runtime/Cell.h

@@ -26,8 +26,10 @@
 
 #pragma once
 
+#include <AK/Format.h>
 #include <AK/Forward.h>
 #include <AK/Noncopyable.h>
+#include <AK/String.h>
 #include <LibJS/Forward.h>
 
 namespace JS {
@@ -70,6 +72,19 @@ private:
     bool m_live { true };
 };
 
-const LogStream& operator<<(const LogStream&, const Cell*);
+}
+
+namespace AK {
+
+template<>
+struct Formatter<JS::Cell> : Formatter<StringView> {
+    void format(TypeErasedFormatParams& params, FormatBuilder& builder, const JS::Cell* cell)
+    {
+        if (!cell)
+            Formatter<StringView>::format(params, builder, "Cell{nullptr}");
+        else
+            Formatter<StringView>::format(params, builder, String::formatted("{}{{{}}}", cell->class_name(), static_cast<const void*>(cell)));
+    }
+};
 
 }

+ 1 - 2
Libraries/LibJS/Runtime/GlobalObject.cpp

@@ -25,7 +25,6 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <AK/LogStream.h>
 #include <AK/Utf8View.h>
 #include <LibJS/Console.h>
 #include <LibJS/Heap/DeferGC.h>
@@ -179,7 +178,7 @@ void GlobalObject::visit_edges(Visitor& visitor)
 
 JS_DEFINE_NATIVE_FUNCTION(GlobalObject::gc)
 {
-    dbg() << "Forced garbage collection requested!";
+    dbgln("Forced garbage collection requested!");
     vm.heap().collect_garbage();
     return js_undefined();
 }

+ 11 - 14
Libraries/LibJS/Runtime/Object.cpp

@@ -198,11 +198,11 @@ Value Object::get_own_properties(const Object& this_object, PropertyKind kind, b
             if (kind == PropertyKind::Key) {
                 properties_array->define_property(i, js_string(vm(), String::number(i)));
             } else if (kind == PropertyKind::Value) {
-                properties_array->define_property(i, js_string(vm(), String::format("%c", str[i])));
+                properties_array->define_property(i, js_string(vm(), String::formatted("{:c}", str[i])));
             } else {
                 auto* entry_array = Array::create(global_object());
                 entry_array->define_property(0, js_string(vm(), String::number(i)));
-                entry_array->define_property(1, js_string(vm(), String::format("%c", str[i])));
+                entry_array->define_property(1, js_string(vm(), String::formatted("{:c}", str[i])));
                 properties_array->define_property(i, entry_array);
             }
             if (vm().exception())
@@ -400,9 +400,7 @@ bool Object::define_property(const StringOrSymbol& property_name, const Object&
         }
 
 #ifdef OBJECT_DEBUG
-        dbg() << "Defining new property " << property_name.to_display_string() << " with accessor descriptor { attributes=" << attributes << ", "
-              << "getter=" << getter.to_string_without_side_effects() << ", "
-              << "setter=" << setter.to_string_without_side_effects() << "}";
+        dbgln("Defining new property {} with accessor descriptor {{ attributes={}, getter={}, setter={} }}", property_name.to_display_string(), attributes, getter, setter);
 #endif
 
         return define_property(property_name, Accessor::create(vm, getter_function, setter_function), attributes, throw_exceptions);
@@ -422,8 +420,7 @@ bool Object::define_property(const StringOrSymbol& property_name, const Object&
         return {};
 
 #ifdef OBJECT_DEBUG
-    dbg() << "Defining new property " << property_name.to_display_string() << " with data descriptor { attributes=" << attributes
-          << ", value=" << (value.is_empty() ? "<empty>" : value.to_string_without_side_effects()) << " }";
+    dbgln("Defining new property {} with data descriptor {{ attributes={}, value={} }}", property_name.to_display_string(), attributes, value);
 #endif
 
     return define_property(property_name, value, attributes, throw_exceptions);
@@ -503,7 +500,7 @@ bool Object::put_own_property(Object& this_object, const StringOrSymbol& propert
 
     if (!is_extensible() && new_property) {
 #ifdef OBJECT_DEBUG
-        dbg() << "Disallow define_property of non-extensible object";
+        dbgln("Disallow define_property of non-extensible object");
 #endif
         if (throw_exceptions && vm().in_strict_mode())
             vm().throw_exception<TypeError>(global_object(), ErrorType::NonExtensibleDefine, property_name.to_display_string());
@@ -532,7 +529,7 @@ bool Object::put_own_property(Object& this_object, const StringOrSymbol& propert
 
     if (!new_property && mode == PutOwnPropertyMode::DefineProperty && !metadata.value().attributes.is_configurable() && attributes != metadata.value().attributes) {
 #ifdef OBJECT_DEBUG
-        dbg() << "Disallow reconfig of non-configurable property";
+        dbgln("Disallow reconfig of non-configurable property");
 #endif
         if (throw_exceptions)
             vm().throw_exception<TypeError>(global_object(), ErrorType::DescChangeNonConfigurable, property_name.to_display_string());
@@ -548,14 +545,14 @@ bool Object::put_own_property(Object& this_object, const StringOrSymbol& propert
         metadata = shape().lookup(property_name);
 
 #ifdef OBJECT_DEBUG
-        dbg() << "Reconfigured property " << property_name.to_display_string() << ", new shape says offset is " << metadata.value().offset << " and my storage capacity is " << m_storage.size();
+        dbgln("Reconfigured property {}, new shape says offset is {} and my storage capacity is {}", property_name.to_display_string(), metadata.value().offset, m_storage.size());
 #endif
     }
 
     auto value_here = m_storage[metadata.value().offset];
     if (!new_property && mode == PutOwnPropertyMode::Put && !value_here.is_accessor() && !metadata.value().attributes.is_writable()) {
 #ifdef OBJECT_DEBUG
-        dbg() << "Disallow write to non-writable property";
+        dbgln("Disallow write to non-writable property");
 #endif
         return false;
     }
@@ -580,7 +577,7 @@ bool Object::put_own_property_by_index(Object& this_object, u32 property_index,
 
     if (!is_extensible() && new_property) {
 #ifdef OBJECT_DEBUG
-        dbg() << "Disallow define_property of non-extensible object";
+        dbgln("Disallow define_property of non-extensible object");
 #endif
         if (throw_exceptions && vm().in_strict_mode())
             vm().throw_exception<TypeError>(global_object(), ErrorType::NonExtensibleDefine, property_index);
@@ -599,7 +596,7 @@ bool Object::put_own_property_by_index(Object& this_object, u32 property_index,
 
     if (!new_property && mode == PutOwnPropertyMode::DefineProperty && !existing_attributes.is_configurable() && attributes != existing_attributes) {
 #ifdef OBJECT_DEBUG
-        dbg() << "Disallow reconfig of non-configurable property";
+        dbgln("Disallow reconfig of non-configurable property");
 #endif
         if (throw_exceptions)
             vm().throw_exception<TypeError>(global_object(), ErrorType::DescChangeNonConfigurable, property_index);
@@ -609,7 +606,7 @@ bool Object::put_own_property_by_index(Object& this_object, u32 property_index,
     auto value_here = new_property ? Value() : existing_property.value().value;
     if (!new_property && mode == PutOwnPropertyMode::Put && !value_here.is_accessor() && !existing_attributes.is_writable()) {
 #ifdef OBJECT_DEBUG
-        dbg() << "Disallow write to non-writable property";
+        dbgln("Disallow write to non-writable property");
 #endif
         return false;
     }

+ 0 - 36
Libraries/LibJS/Runtime/PropertyAttributes.cpp

@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2020, Matthew Olsson <matthewcolsson@gmail.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- *    list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <LibJS/Runtime/PropertyAttributes.h>
-
-namespace JS {
-
-const LogStream& operator<<(const LogStream& stream, const PropertyAttributes& attributes)
-{
-    return stream << attributes.bits();
-}
-
-}

+ 13 - 3
Libraries/LibJS/Runtime/PropertyAttributes.h

@@ -26,7 +26,7 @@
 
 #pragma once
 
-#include <AK/LogStream.h>
+#include <AK/Format.h>
 #include <AK/Types.h>
 
 namespace JS {
@@ -87,8 +87,18 @@ private:
     u8 m_bits;
 };
 
-const LogStream& operator<<(const LogStream& stream, const PropertyAttributes& attributes);
-
 const PropertyAttributes default_attributes = Attribute::Configurable | Attribute::Writable | Attribute::Enumerable;
 
 }
+
+namespace AK {
+
+template<>
+struct Formatter<JS::PropertyAttributes> : Formatter<u8> {
+    void format(TypeErasedFormatParams& params, FormatBuilder& builder, const JS::PropertyAttributes& attributes)
+    {
+        Formatter<u8>::format(params, builder, attributes.bits());
+    }
+};
+
+}

+ 0 - 2
Libraries/LibJS/Runtime/Reference.h

@@ -98,6 +98,4 @@ private:
     bool m_global_variable { false };
 };
 
-const LogStream& operator<<(const LogStream&, const Value&);
-
 }

+ 1 - 1
Libraries/LibJS/Runtime/VM.cpp

@@ -47,7 +47,7 @@ VM::VM()
 {
     m_empty_string = m_heap.allocate_without_global_object<PrimitiveString>(String::empty());
     for (size_t i = 0; i < 128; ++i) {
-        m_single_ascii_character_strings[i] = m_heap.allocate_without_global_object<PrimitiveString>(String::format("%c", i));
+        m_single_ascii_character_strings[i] = m_heap.allocate_without_global_object<PrimitiveString>(String::formatted("{:c}", i));
     }
 
     m_scope_object_shape = m_heap.allocate_without_global_object<Shape>(Shape::ShapeWithoutGlobalObjectTag::Tag);

+ 5 - 8
Libraries/LibJS/Runtime/Value.cpp

@@ -118,7 +118,8 @@ String Value::to_string_without_side_effects() const
             return is_negative_infinity() ? "-Infinity" : "Infinity";
         if (is_integer())
             return String::number(as_i32());
-        return String::format("%.4f", m_value.as_double);
+        // FIXME: This should be more sophisticated: don't cut off decimals, don't include trailing zeros
+        return String::formatted("{:.4}", m_value.as_double);
     case Type::String:
         return m_value.as_string->string();
     case Type::Symbol:
@@ -162,7 +163,8 @@ String Value::to_string(GlobalObject& global_object, bool legacy_null_to_empty_s
             return is_negative_infinity() ? "-Infinity" : "Infinity";
         if (is_integer())
             return String::number(as_i32());
-        return String::format("%.4f", m_value.as_double);
+        // FIXME: This should be more sophisticated: don't cut off decimals, don't include trailing zeros
+        return String::formatted("{:.4}", m_value.as_double);
     case Type::String:
         return m_value.as_string->string();
     case Type::Symbol:
@@ -237,7 +239,7 @@ Object* Value::to_object(GlobalObject& global_object) const
     case Type::Object:
         return &const_cast<Object&>(as_object());
     default:
-        dbg() << "Dying because I can't to_object() on " << *this;
+        dbgln("Dying because I can't to_object() on {}", *this);
         ASSERT_NOT_REACHED();
     }
 }
@@ -822,11 +824,6 @@ Value ordinary_has_instance(GlobalObject& global_object, Value lhs, Value rhs)
     }
 }
 
-const LogStream& operator<<(const LogStream& stream, const Value& value)
-{
-    return stream << (value.is_empty() ? "<empty>" : value.to_string_without_side_effects());
-}
-
 bool same_value(Value lhs, Value rhs)
 {
     if (lhs.type() != rhs.type())

+ 13 - 2
Libraries/LibJS/Runtime/Value.h

@@ -27,8 +27,9 @@
 #pragma once
 
 #include <AK/Assertions.h>
+#include <AK/Format.h>
 #include <AK/Forward.h>
-#include <AK/LogStream.h>
+#include <AK/String.h>
 #include <AK/Types.h>
 #include <LibJS/Forward.h>
 #include <math.h>
@@ -337,6 +338,16 @@ bool same_value_non_numeric(Value lhs, Value rhs);
 TriState abstract_relation(GlobalObject&, bool left_first, Value lhs, Value rhs);
 size_t length_of_array_like(GlobalObject&, Value);
 
-const LogStream& operator<<(const LogStream&, const Value&);
+}
+
+namespace AK {
+
+template<>
+struct Formatter<JS::Value> : Formatter<StringView> {
+    void format(TypeErasedFormatParams& params, FormatBuilder& builder, const JS::Value& value)
+    {
+        Formatter<StringView>::format(params, builder, value.is_empty() ? "<empty>" : value.to_string_without_side_effects());
+    }
+};
 
 }