147 lines
3.5 KiB
C++
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;
|
|
}
|
|
|
|
}
|