summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibIDL
diff options
context:
space:
mode:
authorAndrew Kaster <akaster@serenityos.org>2022-10-08 16:48:04 -0600
committerAndreas Kling <kling@serenityos.org>2022-10-09 10:14:57 +0200
commit067a53b7e7984d193abb0d0b69aad9ddfbd2745a (patch)
tree19dc5aabf6a51ec2899ad65aaae787d43311725e /Userland/Libraries/LibIDL
parent2341294c205e826ce87db3c47be94ba69e030dc3 (diff)
downloadserenity-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.cpp48
-rw-r--r--Userland/Libraries/LibIDL/IDLParser.h12
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;
};
}