hoshi-lang dev
Yet another programming language
Loading...
Searching...
No Matches
symbolExtractor.h
Go to the documentation of this file.
1//
2// Symbol Extractor for hoshi-lang LSP server
3// Walks the AST and extracts symbol definitions
4//
5
6#ifndef HOSHI_LANG_LSP_SYMBOL_EXTRACTOR_H
7#define HOSHI_LANG_LSP_SYMBOL_EXTRACTOR_H
8
9#include <string>
10#include <vector>
11#include <share/def.hpp>
13
14namespace lsp {
15
16enum class HoshiSymbolKind {
18 Struct,
22 Enum,
23 Module,
24 ModuleAlias, // use alias "path" — the alias name
25 Method,
26 Field,
30 Import, // import func from "path"
31 Export,
33 Lambda,
34};
35
36struct Symbol {
39 yoi::indexT line = 0; // 0-based
40 yoi::indexT column = 0; // 0-based
41 yoi::indexT endLine = 0; // 0-based
42 yoi::indexT endColumn = 0; // 0-based
43 yoi::wstr detail; // e.g. "func foo(a: int, b: string): bool"
44 yoi::wstr typeInfo; // e.g. "int" or "string"
45 yoi::wstr parentName; // e.g. struct name for methods/fields
46 yoi::wstr sourceFile; // absolute path of the defining module (for cross-module tracking)
47 yoi::wstr importPath; // for ModuleAlias/Import: the resolved module path
48 // Locals are retained for editor features, but must not be exported as module symbols.
49 bool isLocal = false;
50 yoi::indexT ownerLine = 0; // Declaration line of the callable that owns this local.
51 std::vector<Symbol> children;
52};
53
54inline bool isCallableSymbol(const Symbol &symbol) {
55 return symbol.kind == HoshiSymbolKind::Function ||
56 symbol.kind == HoshiSymbolKind::Method ||
59}
60
61// A local is visible only in the callable body that owns it.
62// This keeps locals out of global lookups while preserving completion/navigation in bodies.
63inline bool isSymbolVisibleAt(const yoi::vec<Symbol> &symbols, const Symbol &symbol,
64 yoi::indexT line) {
65 if (!symbol.isLocal) return true;
66 if (symbol.line > line) return false;
67
68 const Symbol *owner = nullptr;
69 for (const auto &candidate : symbols) {
70 if (candidate.isLocal || !isCallableSymbol(candidate) || candidate.line > line ||
71 candidate.endLine < line) {
72 continue;
73 }
74 if (!owner || candidate.line > owner->line) owner = &candidate;
75 }
76
77 return owner && owner->line == symbol.ownerLine && owner->name == symbol.parentName;
78}
79
110
111} // namespace lsp
112
113#endif // HOSHI_LANG_LSP_SYMBOL_EXTRACTOR_H
yoi::wstr formatExternModuleAccessExpression(yoi::externModuleAccessExpression *expr)
yoi::wstr formatIdentifierWithDefTemplateArg(yoi::identifierWithDefTemplateArg *id)
yoi::vec< Symbol > symbols
void visitStructDef(yoi::structDefStmt *stmt)
void visitInterfaceDef(yoi::interfaceDefStmt *stmt)
void visitEnum(yoi::enumerationDefinition *stmt)
void visitLetStmt(yoi::letStmt *stmt, const yoi::wstr &inParent=L"", yoi::indexT ownerLine=0)
void visitExport(yoi::exportDecl *stmt)
void visitConceptDef(yoi::conceptDefinition *stmt)
void visitImpl(yoi::implStmt *stmt)
yoi::vec< Symbol > extract(yoi::hoshiModule *module)
yoi::wstr formatDefinitionArgs(yoi::definitionArguments *args)
void visitFuncDef(yoi::funcDefStmt *stmt)
yoi::wstr formatTypeSpec(yoi::typeSpec *spec)
void visitUse(yoi::useStmt *stmt)
void visitDataStruct(yoi::dataStructDefStmt *stmt)
yoi::wstr formatIdentifierWithTemplateArg(yoi::identifierWithTemplateArg *id)
void visitTypeAlias(yoi::typeAliasStmt *stmt)
void visitGlobal(yoi::globalStmt *stmt)
void visitImport(yoi::importDecl *stmt)
void visitInCodeBlock(yoi::inCodeBlockStmt *stmt, const yoi::wstr &inParent=L"", yoi::indexT ownerLine=0)
bool isSymbolVisibleAt(const yoi::vec< Symbol > &symbols, const Symbol &symbol, yoi::indexT line)
bool isCallableSymbol(const Symbol &symbol)
std::vector< t > vec
Definition def.hpp:56
std::wstring wstr
Definition def.hpp:51
uint64_t indexT
Definition def.hpp:54
yoi::indexT ownerLine
yoi::wstr detail
yoi::wstr importPath
yoi::indexT endLine
yoi::indexT column
yoi::indexT line
std::vector< Symbol > children
yoi::wstr parentName
yoi::wstr name
HoshiSymbolKind kind
yoi::indexT endColumn
yoi::wstr typeInfo
yoi::wstr sourceFile