mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 13:28:11 +00:00
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.
This commit is contained in:
parent
2341294c20
commit
067a53b7e7
3 changed files with 49 additions and 14 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue