tsl-devkit/lsp-server/src/language/symbol/core/table.cpp

147 lines
3.5 KiB
C++

#include "./table.hpp"
namespace lsp::language::symbol
{
// ==================== LookupResult 实现 ====================
LookupResult LookupResult::Found(Symbol* sym, Table* scp)
{
LookupResult result;
result.symbol = sym;
result.scope = scp;
result.success = true;
return result;
}
LookupResult LookupResult::NotFound()
{
return LookupResult{};
}
LookupResult::operator bool() const
{
return success;
}
// ==================== Table 实现 ====================
Table::Table(ScopeKind kind, Table* parent) :
kind_(kind), parent_(parent)
{
}
ScopeKind Table::Kind() const
{
return kind_;
}
Table* Table::Parent() const
{
return parent_;
}
const std::unordered_map<std::string, SymbolPtr>& Table::Symbols() const
{
return symbols_;
}
const std::unordered_map<std::string, std::vector<FunctionPtr>>& Table::OverloadedFunctions() const
{
return overloaded_functions_;
}
Table* Table::CreateChild(ScopeKind kind)
{
auto child = std::make_unique<Table>(kind, this);
Table* ptr = child.get();
children_.push_back(std::move(child));
return ptr;
}
bool Table::Insert(SymbolPtr symbol)
{
if (!symbol)
return false;
if (symbols_.count(symbol->name) > 0)
return false;
symbol->scope = this;
symbols_[symbol->name] = symbol;
return true;
}
bool Table::InsertFunction(FunctionPtr func)
{
if (!func)
return false;
func->scope = this;
auto& overloads = overloaded_functions_[func->name];
if (func->is_overload)
overloads.push_back(func);
if (overloads.size() == 1)
symbols_[func->name] = func;
return true;
}
LookupResult Table::LookupLocal(const std::string& name) const
{
auto it = symbols_.find(name);
if (it != symbols_.end())
return LookupResult::Found(it->second.get(), const_cast<Table*>(this));
return LookupResult::NotFound();
}
LookupResult Table::Lookup(const std::string& name) const
{
auto result = LookupLocal(name);
if (result)
return result;
if (parent_)
return parent_->Lookup(name);
return LookupResult::NotFound();
}
std::vector<FunctionPtr> Table::LookupOverloads(const std::string& name) const
{
auto it = overloaded_functions_.find(name);
if (it != overloaded_functions_.end())
return it->second;
if (parent_)
return parent_->LookupOverloads(name);
return {};
}
MethodPtr Table::FindMethodInClass(const std::string& class_name, const std::string& method_name) const
{
// 1. 查找类符号
auto class_result = Lookup(class_name);
if (!class_result || class_result.symbol->kind != Kind::kClass)
return nullptr;
auto class_sym = static_cast<Class*>(class_result.symbol);
if (!class_sym->members)
return nullptr;
auto method_result = class_sym->members->LookupLocal(method_name);
if (!method_result || method_result.symbol->kind != Kind::kMethod)
return nullptr;
auto it = class_sym->members->Symbols().find(method_name);
if (it != class_sym->members->Symbols().end())
return std::static_pointer_cast<Method>(it->second);
return nullptr;
}
}