mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 13:27:35 +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/HashMap.h>
|
||||||
#include <AK/LexicalPath.h>
|
#include <AK/LexicalPath.h>
|
||||||
#include <AK/OwnPtr.h>
|
#include <AK/OwnPtr.h>
|
||||||
|
#include <AK/QuickSort.h>
|
||||||
#include <AK/SourceGenerator.h>
|
#include <AK/SourceGenerator.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <AK/Tuple.h>
|
#include <AK/Tuple.h>
|
||||||
|
@ -126,6 +127,19 @@ struct Attribute {
|
||||||
String setter_callback_name;
|
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 {
|
struct Interface {
|
||||||
String name;
|
String name;
|
||||||
String parent_name;
|
String parent_name;
|
||||||
|
@ -149,6 +163,8 @@ struct Interface {
|
||||||
|
|
||||||
Optional<Function> named_property_deleter;
|
Optional<Function> named_property_deleter;
|
||||||
|
|
||||||
|
HashMap<String, Dictionary> dictionaries;
|
||||||
|
|
||||||
// Added for convenience after parsing
|
// Added for convenience after parsing
|
||||||
String wrapper_class;
|
String wrapper_class;
|
||||||
String wrapper_base_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_class = String::formatted("{}Prototype", interface->name);
|
||||||
interface->prototype_base_class = String::formatted("{}Prototype", interface->parent_name.is_empty() ? "Object" : interface->parent_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;
|
return interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue