|
@@ -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))
|
|
|
|
- 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))
|
|
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;
|
|
|
|
+}
|
|
|
|
+
|
|
}
|
|
}
|