#pragma once #include #include #include // for clangd #include "definitions.hpp" #include "interpreter_tree.hpp" #include "utils.hpp" namespace info { // TODO: partitions class GlobalInfo { friend class NamespaceVisitor; public: class NamespaceVisitor { friend GlobalInfo; NamespaceVisitor() = delete; public: struct Path { std::vector> path_types; definition::Namespace* result; }; void AddImport(definition::Import&& import_info, const std::optional& name = std::nullopt); void AddEnterNamespace(const std::string& name, std::optional modifier = std::nullopt); void EnterNamespace(const std::string& name); void ExitNamespace(); void ToGlobalNamespace(); utils::IdType AddFunctionDeclaration(const std::string& name, definition::FunctionDeclaration&& function_declaration_info); utils::IdType AddFunctionDefinition(const std::string& name, definition::FunctionDefinition&& function_definition_info); utils::IdType AddType(const std::string& type, definition::Type&& type_info, const interpreter::tokens::BaseNode& base_node); utils::IdType AddAbstractType(const std::string& abstract_type, definition::AbstractType&& abstract_type_info, const interpreter::tokens::BaseNode& base_node); utils::IdType AddTypeclass(const std::string& typeclass, definition::Typeclass&& typeclass_info, const interpreter::tokens::BaseNode& base_node); utils::IdType AddConstructor(const std::string& constructor, definition::Constructor&& constructor_info, const interpreter::tokens::BaseNode& base_node); std::optional FindNamespace(const std::optional>& path); std::optional FindFunction(const std::optional>& path, const std::string& name); std::optional FindMethod(const std::optional>& path, const std::string& type, const std::string& name, utils::IsConstModifier modifier); std::optional FindType(const std::optional>& path, const std::string& type); std::optional FindLocalType(const std::string& type); std::optional FindAbstractType(const std::string& abstract_type); std::optional FindTypeclass(const std::string& typeclass); std::optional FindConstructor(const std::optional>& path, const std::string& constructor); NamespaceVisitor CreateVisitor() { return global_info_.CreateVisitor(); } GlobalInfo* GetGlobalInfo() { return &global_info_; } const std::vector& GetCurrentPath() { return current_path_; } definition::Namespace* GetCurrentNamespace() { return namespace_stack_.back(); } private: NamespaceVisitor(GlobalInfo& global_info) : global_info_(global_info), namespace_stack_({&global_info.global_namespace_}) {} template std::optional FindSomething( const std::optional>& path, std::function(definition::Namespace*)> search_func); std::optional FindNamespaceIn( definition::Namespace* current_namespace, const std::vector& path); private: GlobalInfo& global_info_; std::vector namespace_stack_; std::vector current_path_; }; NamespaceVisitor CreateVisitor() { return NamespaceVisitor(*this); } // remember about vector realloc const definition::Function& GetFunctionInfo(utils::IdType id) { return functions_.at(id); } template std::optional GetTypeInfo(utils::IdType id) { if (!std::holds_alternative(types_.at(id).type)) { return std::nullopt; } return &std::get(types_[id].type); } // remember about vector realloc const definition::Type& GetAnyTypeInfo(utils::IdType id) { return types_.at(id); } // remember about vector realloc const definition::Typeclass& GetTypeclassInfo(utils::IdType id) { return typeclasses_.at(id); } // remember about vector realloc const definition::Constructor& GetConstructorInfo(utils::IdType id) { return constructors_.at(id); } private: std::vector functions_; std::vector types_; std::vector abstract_types_; std::vector typeclasses_; std::vector constructors_; std::unordered_map name_to_typeclass_; std::unordered_map name_to_abstract_type_; definition::Namespace global_namespace_; std::vector imports_; std::unordered_map usages_; }; } // namespace info