15namespace fs = std::filesystem;
30 const std::string &relativeToFile) {
32 if (importPath ==
"builtin") {
40 std::vector<std::string> searchDirs;
42 if (!relativeToFile.empty()) {
43 fs::path parentDir = fs::path(relativeToFile).parent_path();
44 searchDirs.push_back(parentDir.string());
45 searchDirs.push_back((parentDir /
".tsuki_modules").
string());
49 searchDirs.push_back(sp);
52 for (
auto &dir : searchDirs) {
53 std::string resolved =
tryResolve(dir, importPath);
54 if (!resolved.empty())
return resolved;
61 const std::string &importPath) {
62 fs::path base(searchDir);
63 fs::path target(importPath);
66 fs::path candidate = base / target;
67 if (fs::exists(candidate) && fs::is_regular_file(candidate)) {
69 auto absPath = fs::absolute(candidate, ec);
70 if (!ec)
return absPath.string();
74 fs::path withExt = base / (target.wstring() + L
".hoshi");
75 if (fs::exists(withExt) && fs::is_regular_file(withExt)) {
77 auto absPath = fs::absolute(withExt, ec);
78 if (!ec)
return absPath.string();
82 fs::path asDir = candidate /
"index.hoshi";
83 if (fs::exists(asDir) && fs::is_regular_file(asDir)) {
85 auto absPath = fs::absolute(asDir, ec);
86 if (!ec)
return absPath.string();
93 if (absolutePath.empty())
return;
96 std::wstring wContent;
98 if (absolutePath ==
"builtin") {
104 std::ifstream file(absolutePath, std::ios::binary);
105 if (!file.is_open())
return;
107 file.seekg(0, std::ios::end);
108 auto size = file.tellg();
109 file.seekg(0, std::ios::beg);
110 std::string content(size,
'\0');
111 file.read(&content[0], size);
120 modules[absolutePath] = std::move(mod);
124 const std::wstring &text,
130 std::wstringstream stream(text);
139 }
catch (
const std::runtime_error &) {
147 auto it =
modules.find(absolutePath);
148 if (it ==
modules.end())
return nullptr;
149 return &it->second.symbols;
153 for (
auto &[path, mod] :
modules) {
154 for (
auto &sym : mod.symbols) {
155 if (sym.isLocal)
continue;
162 out.push_back(tagged);
169 auto it =
modules.find(absolutePath);
171 return it->second.symbols;
178 auto it =
modules.find(absolutePath);
180 if (it->second.ast) {
static const char * __lsp_builtin_module
const yoi::vec< Symbol > & indexAndGet(const std::string &absolutePath)
Parse and index a module, then return its symbols.
std::map< std::string, IndexedModule > modules
void invalidateModule(const std::string &absolutePath)
Clear a module from the cache (e.g., when it changes on disk).
const yoi::vec< Symbol > * getModuleSymbols(const std::string &absolutePath)
Get symbols for a specific module.
void indexModule(const std::string &absolutePath)
std::string resolveModule(const std::string &importPath, const std::string &relativeToFile)
void setSearchPaths(const std::vector< std::string > &paths)
void addSearchPath(const std::string &path)
void getAllSymbols(yoi::vec< Symbol > &out)
Collect all symbols from all indexed modules into flat list.
void parseAndIndex(const std::string &absolutePath, const std::wstring &text, IndexedModule &mod)
std::vector< std::string > searchPaths
std::string tryResolve(const std::string &searchDir, const std::string &importPath)
std::wstring string2wstring(const std::string &v)
thread_local yoi::wstr __current_file_path
void set_current_file_path(const std::wstring &path)
void finalizeAST(funcTypeSpec *ptr)
void parse(yoi::basicLiterals *&o, yoi::lexer &lex)
yoi::vec< Symbol > symbols