1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 06:38:10 +00:00

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.
This commit is contained in:
Andreas Kling 2021-03-14 17:03:43 +01:00
parent c7d1f73990
commit ab23ef92b6

View file

@ -148,6 +148,8 @@ struct Interface {
String name;
String parent_name;
HashMap<String, String> extended_attributes;
Vector<Attribute> attributes;
Vector<Constant> constants;
Vector<Constructor> constructors;
@ -190,6 +192,28 @@ static OwnPtr<Interface> parse_interface(StringView filename, const StringView&
report_parsing_error(String::formatted("expected '{}'", expected), filename, input, lexer.tell());
};
auto parse_extended_attributes = [&] {
HashMap<String, String> 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<Interface> parse_interface(StringView filename, const StringView&
interface->constructors.append(Constructor { interface->name, move(parameters) });
};
auto parse_extended_attributes = [&] {
HashMap<String, String> 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<String, String> 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; }