#include "resolver.h" #include "parser.h" #include #include #include #include #include namespace nix_irc { namespace fs = std::filesystem; struct Resolver::Impl { ResolverConfig config; std::vector> resolved_imports; std::unordered_set visited; Parser parser; Impl(const ResolverConfig& cfg) : config(cfg) {} std::string resolve_path(const std::string& path, const std::string& from_file) { fs::path p(path); if (p.is_absolute()) { if (fs::exists(p)) return path; return ""; } fs::path from_dir = fs::path(from_file).parent_path(); fs::path candidate = from_dir / p; if (fs::exists(candidate)) return candidate.string(); for (const auto& search : config.search_paths) { candidate = fs::path(search) / p; if (fs::exists(candidate)) return candidate.string(); } return ""; } ImportResult do_resolve(const std::string& path, const std::string& from_file) { std::string resolved = resolve_path(path, from_file); if (resolved.empty()) { return {false, "", "Cannot find file: " + path, nullptr}; } if (visited.count(resolved)) { return {true, resolved, "", nullptr}; } visited.insert(resolved); try { auto ast = parser.parse_file(resolved); return {true, resolved, "", ast}; } catch (const std::exception& e) { return {false, "", e.what(), nullptr}; } } }; Resolver::Resolver(const ResolverConfig& config) : pImpl(std::make_unique(config)) {} Resolver::~Resolver() = default; void Resolver::add_search_path(const std::string& path) { pImpl->config.search_paths.push_back(path); } void Resolver::set_search_paths(const std::vector& paths) { pImpl->config.search_paths = paths; } ImportResult Resolver::resolve_import(const std::string& path, const std::string& from_file) { auto result = pImpl->do_resolve(path, from_file); if (result.success && result.ast) { pImpl->resolved_imports.push_back({path, result.path}); } return result; } ImportResult Resolver::resolve_import(const Node& import_node, const std::string& from_file) { const ConstPathNode* path_node = import_node.get_if(); if (!path_node) { return {false, "", "Dynamic import not supported", nullptr}; } return resolve_import(path_node->value, from_file); } std::vector Resolver::get_resolved_files() const { std::vector files; for (const auto& [orig, resolved] : pImpl->resolved_imports) { (void) orig; files.push_back(resolved); } return files; } std::vector> Resolver::get_imports() const { return pImpl->resolved_imports; } bool is_static_import(const Node& node) { return node.holds(); } std::string normalize_path(const std::string& path) { fs::path p(path); return fs::absolute(p).string(); } } // namespace nix_irc