From ab23ef92b6809a4cc76599840d977a0c77f3de2c Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 14 Mar 2021 17:03:43 +0100 Subject: [PATCH] LibWeb: Allow JS wrappers to customize get() and put() You can now set the CustomGet and/or CustomPut extended attributes on an interface. This allows you to override JS::Object::get/put in the wrapper class. --- .../CodeGenerators/WrapperGenerator.cpp | 54 ++++++++++++------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp b/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp index 5c93f89dee0..2e4d8a21146 100644 --- a/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp +++ b/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp @@ -148,6 +148,8 @@ struct Interface { String name; String parent_name; + HashMap extended_attributes; + Vector attributes; Vector constants; Vector constructors; @@ -190,6 +192,28 @@ static OwnPtr parse_interface(StringView filename, const StringView& report_parsing_error(String::formatted("expected '{}'", expected), filename, input, lexer.tell()); }; + auto parse_extended_attributes = [&] { + HashMap extended_attributes; + for (;;) { + consume_whitespace(); + if (lexer.consume_specific(']')) + break; + auto name = lexer.consume_until([](auto ch) { return ch == ']' || ch == '=' || ch == ','; }); + if (lexer.consume_specific('=')) { + auto value = lexer.consume_until([](auto ch) { return ch == ']' || ch == ','; }); + extended_attributes.set(name, value); + } else { + extended_attributes.set(name, {}); + } + lexer.consume_specific(','); + } + consume_whitespace(); + return extended_attributes; + }; + + if (lexer.consume_specific('[')) + interface->extended_attributes = parse_extended_attributes(); + assert_string("interface"); consume_whitespace(); interface->name = lexer.consume_until([](auto ch) { return isspace(ch); }); @@ -303,25 +327,6 @@ static OwnPtr parse_interface(StringView filename, const StringView& interface->constructors.append(Constructor { interface->name, move(parameters) }); }; - auto parse_extended_attributes = [&] { - HashMap extended_attributes; - for (;;) { - consume_whitespace(); - if (lexer.consume_specific(']')) - break; - auto name = lexer.consume_until([](auto ch) { return ch == ']' || ch == '=' || ch == ','; }); - if (lexer.consume_specific('=')) { - auto value = lexer.consume_until([](auto ch) { return ch == ']' || ch == ','; }); - extended_attributes.set(name, value); - } else { - extended_attributes.set(name, {}); - } - lexer.consume_specific(','); - } - consume_whitespace(); - return extended_attributes; - }; - for (;;) { HashMap extended_attributes; @@ -691,6 +696,17 @@ public: virtual ~@wrapper_class@() override; )~~~"); + if (interface.extended_attributes.contains("CustomGet")) { + generator.append(R"~~~( + virtual JS::Value get(const JS::PropertyName&, JS::Value receiver = {}) const override; +)~~~"); + } + if (interface.extended_attributes.contains("CustomPut")) { + generator.append(R"~~~( + virtual bool put(const JS::PropertyName&, JS::Value, JS::Value receiver = {}) override; +)~~~"); + } + if (interface.wrapper_base_class == "Wrapper") { generator.append(R"~~~( @fully_qualified_name@& impl() { return *m_impl; }