#pragma once #include #include // for clangd #include "symbols_info.hpp" namespace info { // TODO: partitions class GlobalInfo { public: GlobalInfo() { namespace_stack.push_back(&global_namespace_); } template void AddImport(T&& import_info) { if (waiting_usage.has_value()) { usages_[waiting_usage.value()] = std::forward(import_info); waiting_usage = std::nullopt; } else { imports_.push_back(std::forward(import_info)); } } void AddUsageForNextImport(const std::string& name) { if (waiting_usage.has_value()) { // error } waiting_usage = name; } void AddEnterNamespace(const std::optional& var, const std::string& type) { NamespaceInfo* namespace_info = &namespace_stack.back()->namespaces[type].emplace_back(); namespace_stack.push_back(namespace_info); namespace_info->var = var; namespace_info->type_name = type; } void ExitNamespace() { if (namespace_stack.size() <= 1) { // error return; } namespace_stack.pop_back(); } void ToGlobalNamespace() { namespace_stack.clear(); namespace_stack.push_back(&global_namespace_); } template void AddFunctionDeclaration(const std::string& name, T&& function_declaration_info) { FunctionInfo* function_info = &namespace_stack.back()->functions[name]; function_info->declaration = std::forward(function_declaration_info); } template void AddFunctionDefinition(const std::string& name, T&& function_definition_info) { FunctionInfo* function_info = &namespace_stack.back()->functions[name]; function_info->definition = std::forward(function_definition_info); } template void AddType(const std::string& type, T&& type_info) { &namespace_stack.back()->types[type] = std::forward(type_info); } template void AddTypeclass(const std::string& typeclass, T&& typeclass_info) { namespace_stack.back()->typeclasses[typeclass] = std::forward(typeclass_info); } // AddVar ?? // TODO: decide // FindFunction // FindType // FindVar ?? private: std::vector namespace_stack; std::optional waiting_usage; NamespaceInfo global_namespace_; std::vector imports_; std::unordered_map usages_; }; } // namespace info