diff options
-rw-r--r-- | AK/SourceGenerator.h | 53 | ||||
-rw-r--r-- | AK/Tests/TestSourceGenerator.cpp | 32 | ||||
-rw-r--r-- | DevTools/IPCCompiler/main.cpp | 30 |
3 files changed, 48 insertions, 67 deletions
diff --git a/AK/SourceGenerator.h b/AK/SourceGenerator.h index c212926861..b5d4b29b82 100644 --- a/AK/SourceGenerator.h +++ b/AK/SourceGenerator.h @@ -34,54 +34,32 @@ namespace AK { class SourceGenerator { + AK_MAKE_NONCOPYABLE(SourceGenerator); + public: using MappingType = HashMap<StringView, String>; - explicit SourceGenerator(SourceGenerator& parent, char opening = '@', char closing = '@') - : m_parent(&parent) + explicit SourceGenerator(StringBuilder& builder, char opening = '@', char closing = '@') + : m_builder(builder) , m_opening(opening) , m_closing(closing) { } - explicit SourceGenerator(char opening = '@', char closing = '@') - : m_parent(nullptr) + explicit SourceGenerator(StringBuilder& builder, const MappingType& mapping, char opening = '@', char closing = '@') + : m_builder(builder) + , m_mapping(mapping) , m_opening(opening) , m_closing(closing) { - m_builder = new StringBuilder(); } - void set(StringView key, String value) { m_mapping.set(key, value); } - - String lookup(StringView key) const - { - if (auto opt = m_mapping.get(key); opt.has_value()) - return opt.value(); + SourceGenerator fork() { return SourceGenerator { m_builder, m_mapping, m_opening, m_closing }; } - if (m_parent == nullptr) { - dbgln("Can't find key '{}'", key); - ASSERT_NOT_REACHED(); - } - - return m_parent->lookup(key); - } - - String generate() const { return builder().build(); } + void set(StringView key, String value) { m_mapping.set(key, value); } + String get(StringView key) const { return m_mapping.get(key).value(); } - StringBuilder& builder() - { - if (m_parent) - return m_parent->builder(); - else - return *m_builder; - } - const StringBuilder& builder() const - { - if (m_parent) - return m_parent->builder(); - else - return *m_builder; - } + StringView as_string_view() const { return m_builder.string_view(); } + String as_string() const { return m_builder.build(); } void append(StringView pattern) { @@ -94,7 +72,7 @@ public: return lexer.consume_while([&](char ch) { return ch != stop; }); }; - builder().append(consume_until_without_consuming_stop_character(m_opening)); + m_builder.append(consume_until_without_consuming_stop_character(m_opening)); if (lexer.consume_specific(m_opening)) { const auto placeholder = consume_until_without_consuming_stop_character(m_closing); @@ -102,7 +80,7 @@ public: if (!lexer.consume_specific(m_closing)) ASSERT_NOT_REACHED(); - builder().append(lookup(placeholder)); + m_builder.append(get(placeholder)); } else { ASSERT(lexer.is_eof()); } @@ -110,9 +88,8 @@ public: } private: - SourceGenerator* m_parent; + StringBuilder& m_builder; MappingType m_mapping; - OwnPtr<StringBuilder> m_builder; char m_opening, m_closing; }; diff --git a/AK/Tests/TestSourceGenerator.cpp b/AK/Tests/TestSourceGenerator.cpp index e686faa5c2..17af81546f 100644 --- a/AK/Tests/TestSourceGenerator.cpp +++ b/AK/Tests/TestSourceGenerator.cpp @@ -28,19 +28,31 @@ #include <AK/SourceGenerator.h> +TEST_CASE(wrap_builder) +{ + StringBuilder builder; + SourceGenerator generator { builder }; + + generator.append("Hello, World!"); + + EXPECT_EQ(builder.string_view(), "Hello, World!"); +} + TEST_CASE(generate_c_code) { - SourceGenerator generator; + StringBuilder builder; + SourceGenerator generator { builder }; generator.set("name", "foo"); generator.append("const char* @name@ (void) { return \"@name@\"; }"); - EXPECT_EQ(generator.generate(), "const char* foo (void) { return \"foo\"; }"); + EXPECT_EQ(generator.as_string_view(), "const char* foo (void) { return \"foo\"; }"); } TEST_CASE(scoped) { - SourceGenerator global_generator; + StringBuilder builder; + SourceGenerator global_generator { builder }; global_generator.append("\n"); @@ -49,8 +61,7 @@ TEST_CASE(scoped) global_generator.append("@foo@ @bar@\n"); // foo-0 bar-0 { - SourceGenerator scoped_generator_1 { global_generator }; - + auto scoped_generator_1 = global_generator.fork(); scoped_generator_1.set("bar", "bar-1"); global_generator.append("@foo@ @bar@\n"); // foo-0 bar-0 } @@ -58,28 +69,25 @@ TEST_CASE(scoped) global_generator.append("@foo@ @bar@\n"); // foo-0 bar-0 { - SourceGenerator scoped_generator_2 { global_generator }; - + auto scoped_generator_2 = global_generator.fork(); scoped_generator_2.set("foo", "foo-2"); scoped_generator_2.append("@foo@ @bar@\n"); // foo-2 bar-0 { - // FIXME: This is never put onto the output? - - SourceGenerator scoped_generator_3 { scoped_generator_2 }; + auto scoped_generator_3 = scoped_generator_2.fork(); scoped_generator_3.set("bar", "bar-3"); scoped_generator_3.append("@foo@ @bar@\n"); // foo-2 bar-3 } { - SourceGenerator scoped_generator_4 { global_generator }; + auto scoped_generator_4 = global_generator.fork(); scoped_generator_4.append("@foo@ @bar@\n"); // foo-0 bar-0 } scoped_generator_2.append("@foo@ @bar@\n"); // foo-2 bar-0 } - EXPECT_EQ(global_generator.generate(), "\nfoo-0 bar-0\nfoo-0 bar-0\nfoo-0 bar-0\nfoo-2 bar-0\nfoo-2 bar-3\nfoo-0 bar-0\nfoo-2 bar-0\n"); + EXPECT_EQ(global_generator.as_string_view(), "\nfoo-0 bar-0\nfoo-0 bar-0\nfoo-0 bar-0\nfoo-2 bar-0\nfoo-2 bar-3\nfoo-0 bar-0\nfoo-2 bar-0\n"); } TEST_MAIN(SourceGenerator) diff --git a/DevTools/IPCCompiler/main.cpp b/DevTools/IPCCompiler/main.cpp index 62e0b05ae7..fcb84153b3 100644 --- a/DevTools/IPCCompiler/main.cpp +++ b/DevTools/IPCCompiler/main.cpp @@ -200,7 +200,8 @@ int main(int argc, char** argv) while (lexer.tell() < file_contents.size()) parse_endpoint(); - SourceGenerator generator; + StringBuilder builder; + SourceGenerator generator { builder }; generator.append(R"~~~( #pragma once @@ -219,7 +220,7 @@ int main(int argc, char** argv) )~~~"); for (auto& endpoint : endpoints) { - SourceGenerator endpoint_generator { generator }; + auto endpoint_generator = generator.fork(); endpoint_generator.set("endpoint.name", endpoint.name); endpoint_generator.set("endpoint.magic", String::number(endpoint.magic)); @@ -234,7 +235,7 @@ namespace Messages::@endpoint.name@ { enum class MessageID : i32 { )~~~"); for (auto& message : endpoint.messages) { - SourceGenerator message_generator { endpoint_generator }; + auto message_generator = endpoint_generator.fork(); message_ids.set(message.name, message_ids.size() + 1); message_generator.set("message.name", message.name); @@ -292,8 +293,7 @@ enum class MessageID : i32 { }; auto do_message = [&](const String& name, const Vector<Parameter>& parameters, const String& response_type = {}) { - SourceGenerator message_generator { endpoint_generator }; - + auto message_generator = endpoint_generator.fork(); message_generator.set("message.name", name); message_generator.set("message.response_type", response_type); message_generator.set("message.constructor", constructor_for_message(name, parameters)); @@ -323,7 +323,7 @@ public: )~~~"); for (auto& parameter : parameters) { - SourceGenerator parameter_generator { message_generator }; + auto parameter_generator = message_generator.fork(); parameter_generator.set("parameter.type", parameter.type); parameter_generator.set("parameter.name", parameter.name); @@ -373,7 +373,7 @@ public: )~~~"); for (auto& parameter : parameters) { - SourceGenerator parameter_generator { message_generator }; + auto parameter_generator = message_generator.fork(); parameter_generator.set("parameter.name", parameter.name); parameter_generator.append(R"~~~( @@ -387,8 +387,7 @@ public: )~~~"); for (auto& parameter : parameters) { - SourceGenerator parameter_generator { message_generator }; - + auto parameter_generator = message_generator.fork(); parameter_generator.set("parameter.type", parameter.type); parameter_generator.set("parameter.name", parameter.name); parameter_generator.append(R"~~~( @@ -401,8 +400,7 @@ private: )~~~"); for (auto& parameter : parameters) { - SourceGenerator parameter_generator { message_generator }; - + auto parameter_generator = message_generator.fork(); parameter_generator.set("parameter.type", parameter.type); parameter_generator.set("parameter.name", parameter.name); parameter_generator.append(R"~~~( @@ -484,7 +482,7 @@ public: for (auto& message : endpoint.messages) { auto do_decode_message = [&](const String& name) { - SourceGenerator message_generator { endpoint_generator }; + auto message_generator = endpoint_generator.fork(); message_generator.set("message.name", name); @@ -532,7 +530,7 @@ public: )~~~"); for (auto& message : endpoint.messages) { auto do_decode_message = [&](const String& name, bool returns_something) { - SourceGenerator message_generator { endpoint_generator }; + auto message_generator = endpoint_generator.fork(); message_generator.set("message.name", name); message_generator.append(R"~~~( @@ -561,7 +559,7 @@ public: )~~~"); for (auto& message : endpoint.messages) { - SourceGenerator message_generator { endpoint_generator }; + auto message_generator = endpoint_generator.fork(); message_generator.set("message.name", message.name); @@ -589,7 +587,7 @@ private: )~~~"); } - outln("{}", generator.generate()); + outln("{}", generator.as_string_view()); #ifdef DEBUG for (auto& endpoint : endpoints) { @@ -612,6 +610,4 @@ private: } } #endif - - return 0; } |