#include #include "./table.hpp" #include "./builder.hpp" namespace lsp::language::symbol { SymbolTable::SymbolTable() { } void SymbolTable::Build(ast::ASTNode& root) { Clear(); Builder builder(*this); builder.Build(root); // 构建完成后优化位置索引 location_index_.RebuildIndex(); } void SymbolTable::Clear() { definition_store_.Clear(); scope_manager_.Clear(); location_index_.Clear(); reference_graph_.Clear(); inheritance_graph_.Clear(); call_graph_.Clear(); unit_imports_.clear(); import_index_.clear(); } const SymbolDefinition* SymbolTable::GetDefinition(SymbolId id) const { return definition_store_.Get(id); } std::vector SymbolTable::GetAllDefinitions() const { return definition_store_.GetAll(); } std::vector SymbolTable::FindDefinitionsByName(const std::string& name) const { return definition_store_.FindByName(name); } std::optional SymbolTable::FindSymbolAt(const ast::Location& location) const { return location_index_.FindSymbolAt(location); } std::optional SymbolTable::FindSymbol(const std::string& name, ScopeId scope_id) const { return scope_manager_.FindInScopeChain(scope_id, name); } std::vector SymbolTable::FindSymbolsByName(const std::string& name) const { std::vector result; auto defs = definition_store_.FindByName(name); for (const auto* def : defs) result.push_back(def->id); return result; } std::optional SymbolTable::FindScopeAt(const ast::Location& location) const { return location_index_.FindScopeAt(location); } std::optional SymbolTable::FindReferenceAt(const ast::Location& location) const { return location_index_.FindReferenceAt(location); } std::vector SymbolTable::GetChildren(SymbolId symbol_id) const { return definition_store_.GetChildren(symbol_id); } ScopeId SymbolTable::GetGlobalScope() const { return scope_manager_.GetGlobalScope(); } const std::vector* SymbolTable::GetReferences(SymbolId symbol_id) const { return reference_graph_.GetReferences(symbol_id); } std::optional SymbolTable::GetDefinitionLocation(SymbolId symbol_id) const { return reference_graph_.GetDefinition(symbol_id); } const std::vector* SymbolTable::GetBaseClasses(SymbolId class_id) const { return inheritance_graph_.GetBaseClasses(class_id); } const std::vector* SymbolTable::GetDerivedClasses(SymbolId class_id) const { return inheritance_graph_.GetDerivedClasses(class_id); } const std::vector* SymbolTable::GetCallers(SymbolId function_id) const { return call_graph_.GetCallers(function_id); } const std::vector* SymbolTable::GetCallees(SymbolId function_id) const { return call_graph_.GetCallees(function_id); } // ===== Unit 导入管理实现 ===== void SymbolTable::AddUnitImport(const std::string& unit_name, const ast::Location& location) { // 检查是否已经导入过(避免重复) if (import_index_.find(unit_name) != import_index_.end()) { // 已经存在,可以选择: // 1. 忽略重复导入 // 2. 记录多次导入(用于诊断) // 这里选择忽略 return; } size_t index = unit_imports_.size(); unit_imports_.push_back(UnitImport{ unit_name, location }); import_index_[unit_name] = index; } const std::vector& SymbolTable::GetUnitImports() const { return unit_imports_; } std::optional SymbolTable::FindImportLocation(const std::string& unit_name) const { auto it = import_index_.find(unit_name); if (it != import_index_.end() && it->second < unit_imports_.size()) { return unit_imports_[it->second].location; } return std::nullopt; } bool SymbolTable::HasImport(const std::string& unit_name) const { return import_index_.find(unit_name) != import_index_.end(); } // ===== LSP 接口实现 ===== std::vector SymbolTable::GetDocumentSymbols() const { std::vector result; for (const auto* def : definition_store_.GetAll()) { // 只返回顶层符号(没有父符号的符号) if (!def->parent_id) result.push_back(def); } return result; } std::vector SymbolTable::GetWorkspaceSymbols(const std::string& query) const { if (query.empty()) return definition_store_.GetAll(); // 使用小写查询字符串进行大小写无关的匹配 std::string lower_query = utils::ToLower(query); std::vector result; for (const auto* def : definition_store_.GetAll()) { std::string lower_name = utils::ToLower(def->name); if (lower_name.find(lower_query) != std::string::npos) result.push_back(def); } return result; } // ===== Builder 专用内部接口实现 ===== SymbolId SymbolTable::CreateSymbol( const std::string& name, SymbolKind kind, const ast::Location& location, ScopeId scope_id, std::optional parent_id, const std::optional& type_hint, bool is_class_method) { // 创建符号定义 SymbolDefinition def; def.name = name; def.kind = kind; def.location = location; def.selection_range = location; def.type_hint = type_hint; def.parent_id = parent_id; def.is_class_method = is_class_method; SymbolId symbol_id = definition_store_.Add(std::move(def)); // 统一处理所有索引更新 scope_manager_.AddSymbol(scope_id, name, symbol_id); location_index_.AddSymbol(symbol_id, location); // 添加定义引用 reference_graph_.AddReference(symbol_id, location, true, false); location_index_.AddReference(symbol_id, location); return symbol_id; } ScopeId SymbolTable::CreateScope(ScopeKind kind, const ast::Location& range, std::optional parent_scope_id, std::optional associated_symbol_id) { ScopeId scope_id = scope_manager_.CreateScope(kind, range, parent_scope_id, associated_symbol_id); // 添加到位置索引 location_index_.AddScope(scope_id, range); return scope_id; } void SymbolTable::AddReference(SymbolId symbol_id, const ast::Location& location, bool is_write) { reference_graph_.AddReference(symbol_id, location, false, is_write); location_index_.AddReference(symbol_id, location); } }