summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-01-23 13:20:24 +0100
committerAndreas Kling <kling@serenityos.org>2021-01-23 13:20:24 +0100
commit25056830f02f68c1819ef68988ca8e9e2ed4258e (patch)
treec0b662f7add90fe7715be4292667dffda96eacb0 /Userland
parent5b91362d4e0e8d61696e153d9925ea1b811df518 (diff)
downloadserenity-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.cpp65
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;