mirror of
https://github.com/RGBCube/serenity
synced 2025-07-22 21:17:40 +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
|
@ -71,7 +71,8 @@ int main(int argc, char** argv)
|
||||||
if (import_base_path.is_null())
|
if (import_base_path.is_null())
|
||||||
import_base_path = lexical_path.dirname();
|
import_base_path = lexical_path.dirname();
|
||||||
|
|
||||||
auto& interface = IDL::Parser(path, data, import_base_path).parse();
|
IDL::Parser parser(path, data, import_base_path);
|
||||||
|
auto& interface = parser.parse();
|
||||||
|
|
||||||
static constexpr Array libweb_interface_namespaces = {
|
static constexpr Array libweb_interface_namespaces = {
|
||||||
"CSS"sv,
|
"CSS"sv,
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "IDLParser.h"
|
#include "IDLParser.h"
|
||||||
|
#include <AK/Assertions.h>
|
||||||
#include <AK/LexicalPath.h>
|
#include <AK/LexicalPath.h>
|
||||||
#include <AK/QuickSort.h>
|
#include <AK/QuickSort.h>
|
||||||
#include <LibCore/File.h>
|
#include <LibCore/File.h>
|
||||||
|
@ -76,9 +77,6 @@ static String convert_enumeration_value_to_cpp_enum_member(String const& value,
|
||||||
|
|
||||||
namespace IDL {
|
namespace IDL {
|
||||||
|
|
||||||
HashTable<NonnullOwnPtr<Interface>> Parser::s_interfaces {};
|
|
||||||
HashMap<String, Interface*> Parser::s_resolved_imports {};
|
|
||||||
|
|
||||||
void Parser::assert_specific(char ch)
|
void Parser::assert_specific(char ch)
|
||||||
{
|
{
|
||||||
if (!lexer.consume_specific(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());
|
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);
|
auto real_path = Core::File::real_path_for(include_path);
|
||||||
if (s_resolved_imports.contains(real_path))
|
if (top_level_resolved_imports().contains(real_path))
|
||||||
return *s_resolved_imports.find(real_path)->value;
|
return *top_level_resolved_imports().find(real_path)->value;
|
||||||
|
|
||||||
if (import_stack.contains(real_path))
|
if (import_stack.contains(real_path))
|
||||||
report_parsing_error(String::formatted("Circular import detected: {}", include_path), filename, input, lexer.tell());
|
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());
|
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 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);
|
import_stack.remove(real_path);
|
||||||
|
|
||||||
s_resolved_imports.set(real_path, &result);
|
top_level_resolved_imports().set(real_path, &result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -736,7 +734,7 @@ void Parser::parse_interface_mixin(Interface& interface)
|
||||||
{
|
{
|
||||||
auto mixin_interface_ptr = make<Interface>();
|
auto mixin_interface_ptr = make<Interface>();
|
||||||
auto& mixin_interface = *mixin_interface_ptr;
|
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.module_own_path = interface.module_own_path;
|
||||||
mixin_interface.is_mixin = true;
|
mixin_interface.is_mixin = true;
|
||||||
|
|
||||||
|
@ -856,9 +854,9 @@ Interface& Parser::parse()
|
||||||
|
|
||||||
auto interface_ptr = make<Interface>();
|
auto interface_ptr = make<Interface>();
|
||||||
auto& interface = *interface_ptr;
|
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;
|
interface.module_own_path = this_module;
|
||||||
s_resolved_imports.set(this_module, &interface);
|
top_level_resolved_imports().set(this_module, &interface);
|
||||||
|
|
||||||
Vector<Interface&> imports;
|
Vector<Interface&> imports;
|
||||||
HashTable<String> required_imported_paths;
|
HashTable<String> required_imported_paths;
|
||||||
|
@ -998,6 +996,9 @@ Interface& Parser::parse()
|
||||||
interface.required_imported_paths.set(this_module);
|
interface.required_imported_paths.set(this_module);
|
||||||
interface.imported_modules = move(imports);
|
interface.imported_modules = move(imports);
|
||||||
|
|
||||||
|
if (top_level_parser() == this)
|
||||||
|
VERIFY(import_stack.is_empty());
|
||||||
|
|
||||||
return interface;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@ private:
|
||||||
Yes,
|
Yes,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Parser(Parser* parent, String filename, StringView contents, String import_base_path);
|
||||||
|
|
||||||
void assert_specific(char ch);
|
void assert_specific(char ch);
|
||||||
void assert_string(StringView expected);
|
void assert_string(StringView expected);
|
||||||
void consume_whitespace();
|
void consume_whitespace();
|
||||||
|
@ -53,13 +55,17 @@ private:
|
||||||
NonnullRefPtr<Type> parse_type();
|
NonnullRefPtr<Type> parse_type();
|
||||||
void parse_constant(Interface&);
|
void parse_constant(Interface&);
|
||||||
|
|
||||||
static HashTable<NonnullOwnPtr<Interface>> s_interfaces;
|
|
||||||
static HashMap<String, Interface*> s_resolved_imports;
|
|
||||||
|
|
||||||
String import_base_path;
|
String import_base_path;
|
||||||
String filename;
|
String filename;
|
||||||
StringView input;
|
StringView input;
|
||||||
GenericLexer lexer;
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue