1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 19:37:34 +00:00

LibWeb: Parse IDL interface constructors

WrapperGenerator will now parse and store IDL interface constructors,
including parameters and overloads.
See https://heycam.github.io/webidl/#idl-constructors.
This commit is contained in:
Linus Groh 2021-02-17 22:25:51 +01:00 committed by Andreas Kling
parent ff324fe989
commit e3577f871b

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, Linus Groh <mail@linusgroh.de>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -106,6 +107,17 @@ static void report_parsing_error(StringView message, StringView filename, String
namespace IDL { namespace IDL {
template<typename FunctionType>
static size_t get_function_length(FunctionType& function)
{
size_t length = 0;
for (auto& parameter : function.parameters) {
if (!parameter.optional)
length++;
}
return length;
}
struct Type { struct Type {
String name; String name;
bool nullable { false }; bool nullable { false };
@ -123,15 +135,14 @@ struct Function {
Vector<Parameter> parameters; Vector<Parameter> parameters;
HashMap<String, String> extended_attributes; HashMap<String, String> extended_attributes;
size_t length() const size_t length() const { return get_function_length(*this); }
{ };
size_t length = 0;
for (auto& parameter : parameters) { struct Constructor {
if (!parameter.optional) String name;
length++; Vector<Parameter> parameters;
}
return length; size_t length() const { return get_function_length(*this); }
}
}; };
struct Constant { struct Constant {
@ -157,6 +168,7 @@ struct Interface {
Vector<Attribute> attributes; Vector<Attribute> attributes;
Vector<Constant> constants; Vector<Constant> constants;
Vector<Constructor> constructors;
Vector<Function> functions; Vector<Function> functions;
// Added for convenience after parsing // Added for convenience after parsing
@ -262,17 +274,11 @@ static OwnPtr<Interface> parse_interface(StringView filename, const StringView&
interface->constants.append(move(constant)); interface->constants.append(move(constant));
}; };
auto parse_function = [&](HashMap<String, String>& extended_attributes) { auto parse_parameters = [&] {
auto return_type = parse_type();
consume_whitespace(); consume_whitespace();
auto name = lexer.consume_until([](auto ch) { return isspace(ch) || ch == '('; });
consume_whitespace();
assert_specific('(');
Vector<Parameter> parameters; Vector<Parameter> parameters;
for (;;) { for (;;) {
if (lexer.consume_specific(')')) if (lexer.next_is(')'))
break; break;
bool optional = lexer.consume_specific("optional"); bool optional = lexer.consume_specific("optional");
if (optional) if (optional)
@ -281,18 +287,40 @@ static OwnPtr<Interface> parse_interface(StringView filename, const StringView&
consume_whitespace(); consume_whitespace();
auto name = lexer.consume_until([](auto ch) { return isspace(ch) || ch == ',' || ch == ')'; }); auto name = lexer.consume_until([](auto ch) { return isspace(ch) || ch == ',' || ch == ')'; });
parameters.append({ move(type), move(name), optional }); parameters.append({ move(type), move(name), optional });
if (lexer.consume_specific(')')) if (lexer.next_is(')'))
break; break;
assert_specific(','); assert_specific(',');
consume_whitespace(); consume_whitespace();
} }
return parameters;
};
auto parse_function = [&](HashMap<String, String>& extended_attributes) {
auto return_type = parse_type();
consume_whitespace();
auto name = lexer.consume_until([](auto ch) { return isspace(ch) || ch == '('; });
consume_whitespace();
assert_specific('(');
auto parameters = parse_parameters();
assert_specific(')');
consume_whitespace(); consume_whitespace();
assert_specific(';'); assert_specific(';');
interface->functions.append(Function { return_type, name, move(parameters), move(extended_attributes) }); interface->functions.append(Function { return_type, name, move(parameters), move(extended_attributes) });
}; };
auto parse_constructor = [&] {
assert_string("constructor");
consume_whitespace();
assert_specific('(');
auto parameters = parse_parameters();
assert_specific(')');
consume_whitespace();
assert_specific(';');
interface->constructors.append(Constructor { interface->name, move(parameters) });
};
auto parse_extended_attributes = [&] { auto parse_extended_attributes = [&] {
HashMap<String, String> extended_attributes; HashMap<String, String> extended_attributes;
for (;;) { for (;;) {
@ -327,6 +355,11 @@ static OwnPtr<Interface> parse_interface(StringView filename, const StringView&
extended_attributes = parse_extended_attributes(); extended_attributes = parse_extended_attributes();
} }
if (lexer.next_is("constructor")) {
parse_constructor();
continue;
}
if (lexer.next_is("const")) { if (lexer.next_is("const")) {
parse_constant(); parse_constant();
continue; continue;