diff options
author | Andrew Kaster <akaster@serenityos.org> | 2022-10-08 16:48:04 -0600 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-10-09 10:14:57 +0200 |
commit | 067a53b7e7984d193abb0d0b69aad9ddfbd2745a (patch) | |
tree | 19dc5aabf6a51ec2899ad65aaae787d43311725e /Userland/Libraries/LibIDL | |
parent | 2341294c205e826ce87db3c47be94ba69e030dc3 (diff) | |
download | serenity-067a53b7e7984d193abb0d0b69aad9ddfbd2745a.zip |
LibIDL: Remove static maps for interfaces and resolved imports
Instead, create a tree of Parsers all pointing to a top-level Parser.
All module imports and interfaces are stored at the top level, instead
of in a static map. This allows creating multiple IDL::Parsers in the
same process without them stepping on each others toes.
Diffstat (limited to 'Userland/Libraries/LibIDL')
-rw-r--r-- | Userland/Libraries/LibIDL/IDLParser.cpp | 48 | ||||
-rw-r--r-- | Userland/Libraries/LibIDL/IDLParser.h | 12 |
2 files changed, 47 insertions, 13 deletions
diff --git a/Userland/Libraries/LibIDL/IDLParser.cpp b/Userland/Libraries/LibIDL/IDLParser.cpp index 6f840f9b29..531bf764cf 100644 --- a/Userland/Libraries/LibIDL/IDLParser.cpp +++ b/Userland/Libraries/LibIDL/IDLParser.cpp @@ -8,6 +8,7 @@ */ #include "IDLParser.h" +#include <AK/Assertions.h> #include <AK/LexicalPath.h> #include <AK/QuickSort.h> #include <LibCore/File.h> @@ -76,9 +77,6 @@ static String convert_enumeration_value_to_cpp_enum_member(String const& value, namespace IDL { -HashTable<NonnullOwnPtr<Interface>> Parser::s_interfaces {}; -HashMap<String, Interface*> Parser::s_resolved_imports {}; - void Parser::assert_specific(char ch) { if (!lexer.consume_specific(ch)) @@ -143,8 +141,8 @@ Optional<Interface&> Parser::resolve_import(auto path) report_parsing_error(String::formatted("{}: No such file or directory", include_path), filename, input, lexer.tell()); auto real_path = Core::File::real_path_for(include_path); - if (s_resolved_imports.contains(real_path)) - return *s_resolved_imports.find(real_path)->value; + if (top_level_resolved_imports().contains(real_path)) + return *top_level_resolved_imports().find(real_path)->value; if (import_stack.contains(real_path)) report_parsing_error(String::formatted("Circular import detected: {}", include_path), filename, input, lexer.tell()); @@ -155,10 +153,10 @@ Optional<Interface&> Parser::resolve_import(auto path) report_parsing_error(String::formatted("Failed to open {}: {}", real_path, file_or_error.error()), filename, input, lexer.tell()); auto data = file_or_error.value()->read_all(); - auto& result = Parser(real_path, data, import_base_path).parse(); + auto& result = Parser(this, real_path, data, import_base_path).parse(); import_stack.remove(real_path); - s_resolved_imports.set(real_path, &result); + top_level_resolved_imports().set(real_path, &result); return result; } @@ -736,7 +734,7 @@ void Parser::parse_interface_mixin(Interface& interface) { auto mixin_interface_ptr = make<Interface>(); auto& mixin_interface = *mixin_interface_ptr; - VERIFY(s_interfaces.set(move(mixin_interface_ptr)) == AK::HashSetResult::InsertedNewEntry); + VERIFY(top_level_interfaces().set(move(mixin_interface_ptr)) == AK::HashSetResult::InsertedNewEntry); mixin_interface.module_own_path = interface.module_own_path; mixin_interface.is_mixin = true; @@ -856,9 +854,9 @@ Interface& Parser::parse() auto interface_ptr = make<Interface>(); auto& interface = *interface_ptr; - VERIFY(s_interfaces.set(move(interface_ptr)) == AK::HashSetResult::InsertedNewEntry); + VERIFY(top_level_interfaces().set(move(interface_ptr)) == AK::HashSetResult::InsertedNewEntry); interface.module_own_path = this_module; - s_resolved_imports.set(this_module, &interface); + top_level_resolved_imports().set(this_module, &interface); Vector<Interface&> imports; HashTable<String> required_imported_paths; @@ -998,6 +996,9 @@ Interface& Parser::parse() interface.required_imported_paths.set(this_module); interface.imported_modules = move(imports); + if (top_level_parser() == this) + VERIFY(import_stack.is_empty()); + return interface; } @@ -1009,4 +1010,31 @@ Parser::Parser(String filename, StringView contents, String import_base_path) { } +Parser::Parser(Parser* parent, String filename, StringView contents, String import_base_path) + : import_base_path(move(import_base_path)) + , filename(move(filename)) + , input(contents) + , lexer(input) + , parent(parent) +{ +} + +Parser* Parser::top_level_parser() +{ + Parser* current = this; + for (Parser* next = this; next; next = next->parent) + current = next; + return current; +} + +HashMap<String, Interface*>& Parser::top_level_resolved_imports() +{ + return top_level_parser()->resolved_imports; +} + +HashTable<NonnullOwnPtr<Interface>>& Parser::top_level_interfaces() +{ + return top_level_parser()->interfaces; +} + } diff --git a/Userland/Libraries/LibIDL/IDLParser.h b/Userland/Libraries/LibIDL/IDLParser.h index 9cf488513b..4c72030dcf 100644 --- a/Userland/Libraries/LibIDL/IDLParser.h +++ b/Userland/Libraries/LibIDL/IDLParser.h @@ -28,6 +28,8 @@ private: Yes, }; + Parser(Parser* parent, String filename, StringView contents, String import_base_path); + void assert_specific(char ch); void assert_string(StringView expected); void consume_whitespace(); @@ -53,13 +55,17 @@ private: NonnullRefPtr<Type> parse_type(); void parse_constant(Interface&); - static HashTable<NonnullOwnPtr<Interface>> s_interfaces; - static HashMap<String, Interface*> s_resolved_imports; - String import_base_path; String filename; StringView input; GenericLexer lexer; + + HashTable<NonnullOwnPtr<Interface>>& top_level_interfaces(); + HashTable<NonnullOwnPtr<Interface>> interfaces; + HashMap<String, Interface*>& top_level_resolved_imports(); + HashMap<String, Interface*> resolved_imports; + Parser* top_level_parser(); + Parser* parent = nullptr; }; } |