mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 12:38:12 +00:00
LibWeb: Add support for parsing IDL dictionaries
This commit is contained in:
parent
87f655f2af
commit
c3810b827a
1 changed files with 77 additions and 0 deletions
|
@ -12,6 +12,7 @@
|
|||
#include <AK/HashMap.h>
|
||||
#include <AK/LexicalPath.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/QuickSort.h>
|
||||
#include <AK/SourceGenerator.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <AK/Tuple.h>
|
||||
|
@ -126,6 +127,19 @@ struct Attribute {
|
|||
String setter_callback_name;
|
||||
};
|
||||
|
||||
struct DictionaryMember {
|
||||
bool required { false };
|
||||
Type type;
|
||||
String name;
|
||||
HashMap<String, String> extended_attributes;
|
||||
Optional<String> default_value;
|
||||
};
|
||||
|
||||
struct Dictionary {
|
||||
String parent_name;
|
||||
Vector<DictionaryMember> members;
|
||||
};
|
||||
|
||||
struct Interface {
|
||||
String name;
|
||||
String parent_name;
|
||||
|
@ -149,6 +163,8 @@ struct Interface {
|
|||
|
||||
Optional<Function> named_property_deleter;
|
||||
|
||||
HashMap<String, Dictionary> dictionaries;
|
||||
|
||||
// Added for convenience after parsing
|
||||
String wrapper_class;
|
||||
String wrapper_base_class;
|
||||
|
@ -564,6 +580,67 @@ static NonnullOwnPtr<Interface> parse_interface(StringView filename, StringView
|
|||
interface->prototype_class = String::formatted("{}Prototype", interface->name);
|
||||
interface->prototype_base_class = String::formatted("{}Prototype", interface->parent_name.is_empty() ? "Object" : interface->parent_name);
|
||||
|
||||
consume_whitespace();
|
||||
while (!lexer.is_eof()) {
|
||||
assert_string("dictionary");
|
||||
consume_whitespace();
|
||||
|
||||
Dictionary dictionary {};
|
||||
|
||||
auto name = lexer.consume_until([](auto ch) { return isspace(ch); });
|
||||
consume_whitespace();
|
||||
|
||||
if (lexer.consume_specific(':')) {
|
||||
consume_whitespace();
|
||||
dictionary.parent_name = lexer.consume_until([](auto ch) { return isspace(ch); });
|
||||
consume_whitespace();
|
||||
}
|
||||
assert_specific('{');
|
||||
|
||||
for (;;) {
|
||||
consume_whitespace();
|
||||
|
||||
if (lexer.consume_specific('}')) {
|
||||
consume_whitespace();
|
||||
assert_specific(';');
|
||||
break;
|
||||
}
|
||||
|
||||
DictionaryMember member {};
|
||||
if (lexer.consume_specific("required")) {
|
||||
member.required = true;
|
||||
consume_whitespace();
|
||||
if (lexer.consume_specific('['))
|
||||
member.extended_attributes = parse_extended_attributes();
|
||||
}
|
||||
|
||||
member.type = parse_type();
|
||||
consume_whitespace();
|
||||
|
||||
member.name = lexer.consume_until([](auto ch) { return isspace(ch) || ch == ';'; });
|
||||
consume_whitespace();
|
||||
|
||||
if (lexer.consume_specific('=')) {
|
||||
VERIFY(!member.required);
|
||||
consume_whitespace();
|
||||
auto default_value = lexer.consume_until([](auto ch) { return isspace(ch) || ch == ';'; });
|
||||
member.default_value = default_value;
|
||||
consume_whitespace();
|
||||
}
|
||||
|
||||
assert_specific(';');
|
||||
dictionary.members.append(move(member));
|
||||
}
|
||||
|
||||
// dictionary members need to be evaluated in lexicographical order
|
||||
quick_sort(dictionary.members, [&](auto& one, auto& two) {
|
||||
return one.name < two.name;
|
||||
});
|
||||
|
||||
interface->dictionaries.set(name, move(dictionary));
|
||||
consume_whitespace();
|
||||
}
|
||||
|
||||
return interface;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue