diff options
author | Andreas Kling <kling@serenityos.org> | 2021-01-23 13:20:24 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-01-23 13:20:24 +0100 |
commit | 25056830f02f68c1819ef68988ca8e9e2ed4258e (patch) | |
tree | c0b662f7add90fe7715be4292667dffda96eacb0 /Userland | |
parent | 5b91362d4e0e8d61696e153d9925ea1b811df518 (diff) | |
download | serenity-25056830f02f68c1819ef68988ca8e9e2ed4258e.zip |
LibWeb: Add very basic support for IDL constants
You can now put constants on an IDL interface and they will pop up on
both the constructor and prototype objects.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp | 65 |
1 files changed, 63 insertions, 2 deletions
diff --git a/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp b/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp index 7df091e171..3d2f7f5519 100644 --- a/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp +++ b/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -136,6 +136,12 @@ struct Function { } }; +struct Constant { + Type type; + String name; + String value; +}; + struct Attribute { bool readonly { false }; bool unsigned_ { false }; @@ -153,6 +159,7 @@ struct Interface { String parent_name; Vector<Attribute> attributes; + Vector<Constant> constants; Vector<Function> functions; // Added for convenience after parsing @@ -237,6 +244,27 @@ static OwnPtr<Interface> parse_interface(StringView filename, const StringView& interface->attributes.append(move(attribute)); }; + auto parse_constant = [&] { + lexer.consume_specific("const"); + consume_whitespace(); + + Constant constant; + bool unsigned_ = lexer.consume_specific("unsigned"); + if (unsigned_) + consume_whitespace(); + constant.type = parse_type(); + consume_whitespace(); + constant.name = lexer.consume_until([](auto ch) { return isspace(ch) || ch == '='; }); + consume_whitespace(); + lexer.consume_specific('='); + consume_whitespace(); + constant.value = lexer.consume_while([](auto ch) { return !isspace(ch) && ch != ';'; }); + consume_whitespace(); + assert_specific(';'); + + interface->constants.append(move(constant)); + }; + auto parse_function = [&](HashMap<String, String>& extended_attributes) { auto return_type = parse_type(); consume_whitespace(); @@ -302,6 +330,11 @@ static OwnPtr<Interface> parse_interface(StringView filename, const StringView& extended_attributes = parse_extended_attributes(); } + if (lexer.next_is("const")) { + parse_constant(); + continue; + } + if (lexer.next_is("readonly") || lexer.next_is("attribute")) { parse_attribute(extended_attributes); continue; @@ -748,6 +781,20 @@ void @constructor_class@::initialize(JS::GlobalObject& global_object) NativeFunction::initialize(global_object); define_property(vm.names.prototype, &window.ensure_web_prototype<@prototype_class@>("@name@"), 0); define_property(vm.names.length, JS::Value(1), JS::Attribute::Configurable); + +)~~~"); + + for (auto& constant : interface.constants) { + auto constant_generator = generator.fork(); + constant_generator.set("constant.name", constant.name); + constant_generator.set("constant.value", constant.value); + + constant_generator.append(R"~~~( +define_property("@constant.name@", JS::Value((i32)@constant.value@), JS::Attribute::Enumerable); +)~~~"); + } + + generator.append(R"~~~( } } // namespace Web::Bindings @@ -922,6 +969,16 @@ void @prototype_class@::initialize(JS::GlobalObject& global_object) )~~~"); } + for (auto& constant : interface.constants) { + auto constant_generator = generator.fork(); + constant_generator.set("constant.name", constant.name); + constant_generator.set("constant.value", constant.value); + + constant_generator.append(R"~~~( + define_property("@constant.name@", JS::Value((i32)@constant.value@), JS::Attribute::Enumerable); +)~~~"); + } + for (auto& function : interface.functions) { auto function_generator = generator.fork(); function_generator.set("function.name", function.name); @@ -1093,10 +1150,14 @@ static @fully_qualified_name@* impl_from(JS::VM& vm, JS::GlobalObject& global_ob return new_array; )~~~"); - } else if (return_type.name == "long" || return_type.name == "double" || return_type.name == "boolean" || return_type.name == "short") { + } else if (return_type.name == "boolean" || return_type.name == "double" || return_type.name == "long") { scoped_generator.append(R"~~~( return JS::Value(retval); )~~~"); + } else if (return_type.name == "short") { + scoped_generator.append(R"~~~( + return JS::Value((i32)retval); +)~~~"); } else if (return_type.name == "Uint8ClampedArray") { scoped_generator.append(R"~~~( return retval; |